11#![ allow( clippy:: trivial_regex) ]
22
3- use std:: { convert:: Infallible , net:: TcpListener , sync:: OnceLock } ;
3+ use std:: { convert:: Infallible , future :: ready , net:: TcpListener , sync:: OnceLock } ;
44
5- use hyper:: {
6- service:: { make_service_fn, service_fn} ,
7- Body , Method , Request , Response , Server ,
8- } ;
5+ use actix_http:: { HttpService , Method , Request , Response , StatusCode } ;
6+ use actix_server:: { Server , ServerHandle } ;
7+ use actix_web:: body:: MessageBody ;
98use regex:: Regex ;
10- use tokio:: sync:: oneshot;
119
1210static RE_URL : OnceLock < Regex > = OnceLock :: new ( ) ;
1311
@@ -17,16 +15,16 @@ fn re_url() -> &'static Regex {
1715
1816pub struct TestServer {
1917 pub dir_url : String ,
20- shutdown : Option < oneshot :: Sender < ( ) > > ,
18+ handle : ServerHandle ,
2119}
2220
2321impl Drop for TestServer {
2422 fn drop ( & mut self ) {
25- self . shutdown . take ( ) . unwrap ( ) . send ( ( ) ) . ok ( ) ;
23+ drop ( self . handle . stop ( false ) ) ;
2624 }
2725}
2826
29- fn get_directory ( url : & str ) -> Response < Body > {
27+ fn get_directory ( url : & str ) -> Response < impl MessageBody > {
3028 const BODY : & str = r#"{
3129 "keyChange": "<URL>/acme/key-change",
3230 "newAccount": "<URL>/acme/new-acct",
@@ -40,25 +38,24 @@ fn get_directory(url: &str) -> Response<Body> {
4038 }
4139 }"# ;
4240
43- Response :: new ( Body :: from (
41+ Response :: with_body (
42+ StatusCode :: OK ,
4443 RE_URL
4544 . get_or_init ( || Regex :: new ( "<URL>" ) . unwrap ( ) )
4645 . replace_all ( BODY , url) ,
47- ) )
46+ )
4847}
4948
50- fn head_new_nonce ( ) -> Response < Body > {
51- Response :: builder ( )
52- . status ( 204 )
53- . header (
49+ fn head_new_nonce ( ) -> Response < impl MessageBody > {
50+ Response :: build ( StatusCode :: NO_CONTENT )
51+ . insert_header ( (
5452 "Replay-Nonce" ,
5553 "8_uBBV3N2DBRJczhoiB46ugJKUkUHxGzVe6xIMpjHFM" ,
56- )
57- . body ( Body :: empty ( ) )
58- . unwrap ( )
54+ ) )
55+ . finish ( )
5956}
6057
61- fn post_new_acct ( url : & str ) -> Response < Body > {
58+ fn post_new_acct ( url : & str ) -> Response < impl MessageBody > {
6259 const BODY : & str = r#"{
6360 "id": 7728515,
6461 "key": {
@@ -81,14 +78,12 @@ fn post_new_acct(url: &str) -> Response<Body> {
8178 . replace_all ( "<URL>/acme/acct/7728515" , url)
8279 . into_owned ( ) ;
8380
84- Response :: builder ( )
85- . status ( 201 )
86- . header ( "Location" , location)
87- . body ( Body :: from ( BODY ) )
88- . unwrap ( )
81+ Response :: build ( StatusCode :: CREATED )
82+ . insert_header ( ( "Location" , location) )
83+ . body ( BODY )
8984}
9085
91- fn post_new_order ( url : & str ) -> Response < Body > {
86+ fn post_new_order ( url : & str ) -> Response < impl MessageBody > {
9287 const BODY : & str = r#"{
9388 "status": "pending",
9489 "expires": "2019-01-09T08:26:43.570360537Z",
@@ -108,14 +103,12 @@ fn post_new_order(url: &str) -> Response<Body> {
108103 . replace_all ( "<URL>/acme/order/YTqpYUthlVfwBncUufE8" , url)
109104 . into_owned ( ) ;
110105
111- Response :: builder ( )
112- . status ( 201 )
113- . header ( "Location" , location)
114- . body ( Body :: from ( re_url ( ) . replace_all ( BODY , url) ) )
115- . unwrap ( )
106+ Response :: build ( StatusCode :: CREATED )
107+ . insert_header ( ( "Location" , location) )
108+ . body ( re_url ( ) . replace_all ( BODY , url) )
116109}
117110
118- fn post_get_order ( url : & str ) -> Response < Body > {
111+ fn post_get_order ( url : & str ) -> Response < impl MessageBody > {
119112 const BODY : & str = r#"{
120113 "status": "<STATUS>",
121114 "expires": "2019-01-09T08:26:43.570360537Z",
@@ -134,13 +127,10 @@ fn post_get_order(url: &str) -> Response<Body> {
134127
135128 let body = re_url ( ) . replace_all ( BODY , url) . into_owned ( ) ;
136129
137- Response :: builder ( )
138- . status ( 200 )
139- . body ( Body :: from ( body) )
140- . unwrap ( )
130+ Response :: build ( StatusCode :: OK ) . body ( body)
141131}
142132
143- fn post_authz ( url : & str ) -> Response < Body > {
133+ fn post_authz ( url : & str ) -> Response < impl MessageBody > {
144134 const BODY : & str = r#"{
145135 "identifier": {
146136 "type": "dns",
@@ -170,70 +160,70 @@ fn post_authz(url: &str) -> Response<Body> {
170160 ]
171161 }"# ;
172162
173- Response :: builder ( )
174- . status ( 201 )
175- . body ( Body :: from ( re_url ( ) . replace_all ( BODY , url) ) )
176- . unwrap ( )
163+ Response :: build ( StatusCode :: CREATED ) . body ( re_url ( ) . replace_all ( BODY , url) )
177164}
178165
179- fn post_finalize ( _url : & str ) -> Response < Body > {
180- Response :: builder ( ) . status ( 200 ) . body ( Body :: empty ( ) ) . unwrap ( )
166+ fn post_finalize ( _url : & str ) -> Response < impl MessageBody > {
167+ Response :: ok ( )
181168}
182169
183- fn post_certificate ( _url : & str ) -> Response < Body > {
184- Response :: builder ( )
185- . status ( 200 )
186- . body ( "CERT HERE" . into ( ) )
187- . unwrap ( )
170+ fn post_certificate ( _url : & str ) -> Response < impl MessageBody > {
171+ Response :: build ( StatusCode :: OK ) . body ( "CERT HERE" )
188172}
189173
190- fn route_request ( req : Request < Body > , url : & str ) -> Response < Body > {
191- match ( req. method ( ) , req. uri ( ) . path ( ) ) {
192- ( & Method :: GET , "/directory" ) => get_directory ( url) ,
193- ( & Method :: HEAD , "/acme/new-nonce" ) => head_new_nonce ( ) ,
194- ( & Method :: POST , "/acme/new-acct" ) => post_new_acct ( url) ,
195- ( & Method :: POST , "/acme/new-order" ) => post_new_order ( url) ,
196- ( & Method :: POST , "/acme/order/YTqpYUthlVfwBncUufE8" ) => post_get_order ( url) ,
197- ( & Method :: POST , "/acme/authz/YTqpYUthlVfwBncUufE8IRWLMSRqcSs" ) => post_authz ( url) ,
198- ( & Method :: POST , "/acme/finalize/7738992/18234324" ) => post_finalize ( url) ,
199- ( & Method :: POST , "/acme/cert/fae41c070f967713109028" ) => post_certificate ( url) ,
200- ( _, _) => Response :: builder ( ) . status ( 404 ) . body ( Body :: empty ( ) ) . unwrap ( ) ,
174+ fn route_request ( req : Request , url : & str ) -> Response < impl MessageBody > {
175+ match ( req. method ( ) , req. path ( ) ) {
176+ ( & Method :: GET , "/directory" ) => get_directory ( url) . map_into_boxed_body ( ) ,
177+ ( & Method :: HEAD , "/acme/new-nonce" ) => head_new_nonce ( ) . map_into_boxed_body ( ) ,
178+ ( & Method :: POST , "/acme/new-acct" ) => post_new_acct ( url) . map_into_boxed_body ( ) ,
179+ ( & Method :: POST , "/acme/new-order" ) => post_new_order ( url) . map_into_boxed_body ( ) ,
180+
181+ ( & Method :: POST , "/acme/order/YTqpYUthlVfwBncUufE8" ) => {
182+ post_get_order ( url) . map_into_boxed_body ( )
183+ }
184+
185+ ( & Method :: POST , "/acme/authz/YTqpYUthlVfwBncUufE8IRWLMSRqcSs" ) => {
186+ post_authz ( url) . map_into_boxed_body ( )
187+ }
188+
189+ ( & Method :: POST , "/acme/finalize/7738992/18234324" ) => {
190+ post_finalize ( url) . map_into_boxed_body ( )
191+ }
192+
193+ ( & Method :: POST , "/acme/cert/fae41c070f967713109028" ) => {
194+ post_certificate ( url) . map_into_boxed_body ( )
195+ }
196+
197+ ( _, _) => Response :: build ( StatusCode :: NOT_FOUND )
198+ . finish ( )
199+ . map_into_boxed_body ( ) ,
201200 }
202201}
203202
204203pub fn with_directory_server ( ) -> TestServer {
205- let tcp = TcpListener :: bind ( "127.0.0.1:0" ) . unwrap ( ) ;
206- let port = tcp . local_addr ( ) . unwrap ( ) . port ( ) ;
204+ let lst = TcpListener :: bind ( "127.0.0.1:0" ) . unwrap ( ) ;
205+ let port = lst . local_addr ( ) . unwrap ( ) . port ( ) ;
207206
208207 let url = format ! ( "http://127.0.0.1:{port}" ) ;
209208 let dir_url = format ! ( "{url}/directory" ) ;
210209
211- let ( tx, rx) = oneshot:: channel :: < ( ) > ( ) ;
212-
213- let make_service = make_service_fn ( move |_| {
214- let url = url. clone ( ) ;
215- async move {
210+ let server = Server :: build ( )
211+ . listen ( "acme" , lst, move || {
216212 let url = url. clone ( ) ;
217- hyper:: Result :: Ok ( service_fn ( move |req| {
218- let url = url. clone ( ) ;
219- async move { Ok :: < _ , Infallible > ( route_request ( req, & url) ) }
220- } ) )
221- }
222- } ) ;
223213
224- let server = Server :: from_tcp ( tcp)
214+ HttpService :: build ( )
215+ . finish ( move |req| ready ( Ok :: < _ , Infallible > ( route_request ( req, & url) ) ) )
216+ . tcp ( )
217+ } )
225218 . unwrap ( )
226- . serve ( make_service )
227- . with_graceful_shutdown ( async {
228- rx . await . ok ( ) ;
229- } ) ;
219+ . workers ( 1 )
220+ . run ( ) ;
221+
222+ let handle = server . handle ( ) ;
230223
231224 tokio:: spawn ( server) ;
232225
233- TestServer {
234- dir_url,
235- shutdown : Some ( tx) ,
236- }
226+ TestServer { dir_url, handle }
237227}
238228
239229#[ tokio:: test]
0 commit comments