@@ -6,9 +6,11 @@ use std::path::Path;
6
6
use std:: sync:: mpsc:: { channel, Sender } ;
7
7
use std:: thread;
8
8
9
- use hyper:: server:: conn:: AddrStream ;
10
- use hyper:: service:: { make_service_fn, service_fn} ;
11
- use hyper:: { Body , Request } ;
9
+ use http_body_util:: Full ;
10
+ use hyper:: body:: Bytes ;
11
+ use hyper:: server:: conn:: http1;
12
+ use hyper:: service:: service_fn;
13
+ use hyper:: Request ;
12
14
use tempfile:: TempDir ;
13
15
14
16
pub fn tmp_dir ( ) -> TempDir {
@@ -31,26 +33,38 @@ pub fn write_file(path: &Path, contents: &str) {
31
33
file. sync_data ( ) . expect ( "writing test data" ) ;
32
34
}
33
35
36
+ // A dead simple hyper server implementation.
37
+ // For more info, see:
38
+ // https://hyper.rs/guides/1/server/hello-world/
34
39
async fn run_server ( addr_tx : Sender < SocketAddr > , addr : SocketAddr , contents : Vec < u8 > ) {
35
- let make_svc = make_service_fn ( |_ : & AddrStream | {
40
+ let svc = service_fn ( move | req : Request < hyper :: body :: Incoming > | {
36
41
let contents = contents. clone ( ) ;
37
42
async move {
38
- Ok :: < _ , Infallible > ( service_fn ( move |req : Request < Body > | {
39
- let contents = contents. clone ( ) ;
40
- async move {
41
- let res = serve_contents ( req, contents) ;
42
- Ok :: < _ , Infallible > ( res)
43
- }
44
- } ) )
43
+ let res = serve_contents ( req, contents) ;
44
+ Ok :: < _ , Infallible > ( res)
45
45
}
46
46
} ) ;
47
47
48
- let server = hyper:: server:: Server :: bind ( & addr) . serve ( make_svc) ;
49
- let addr = server. local_addr ( ) ;
48
+ let listener = tokio:: net:: TcpListener :: bind ( & addr)
49
+ . await
50
+ . expect ( "can not bind" ) ;
51
+
52
+ let addr = listener. local_addr ( ) . unwrap ( ) ;
50
53
addr_tx. send ( addr) . unwrap ( ) ;
51
54
52
- if let Err ( e) = server. await {
53
- eprintln ! ( "server error: {e}" ) ;
55
+ loop {
56
+ let ( stream, _) = listener
57
+ . accept ( )
58
+ . await
59
+ . expect ( "could not accept connection" ) ;
60
+ let io = hyper_util:: rt:: TokioIo :: new ( stream) ;
61
+
62
+ let svc = svc. clone ( ) ;
63
+ tokio:: spawn ( async move {
64
+ if let Err ( err) = http1:: Builder :: new ( ) . serve_connection ( io, svc) . await {
65
+ eprintln ! ( "failed to serve connection: {:?}" , err) ;
66
+ }
67
+ } ) ;
54
68
}
55
69
}
56
70
@@ -69,9 +83,9 @@ pub fn serve_file(contents: Vec<u8>) -> SocketAddr {
69
83
}
70
84
71
85
fn serve_contents (
72
- req : hyper:: Request < hyper:: Body > ,
86
+ req : hyper:: Request < hyper:: body :: Incoming > ,
73
87
contents : Vec < u8 > ,
74
- ) -> hyper:: Response < hyper :: Body > {
88
+ ) -> hyper:: Response < Full < Bytes > > {
75
89
let mut range_header = None ;
76
90
let ( status, body) = if let Some ( range) = req. headers ( ) . get ( hyper:: header:: RANGE ) {
77
91
// extract range "bytes={start}-"
@@ -95,7 +109,7 @@ fn serve_contents(
95
109
let mut res = hyper:: Response :: builder ( )
96
110
. status ( status)
97
111
. header ( hyper:: header:: CONTENT_LENGTH , body. len ( ) )
98
- . body ( hyper :: Body :: from ( body) )
112
+ . body ( Full :: new ( Bytes :: from ( body) ) )
99
113
. unwrap ( ) ;
100
114
if let Some ( range) = range_header {
101
115
res. headers_mut ( )
0 commit comments