1
1
#![ allow( unused_must_use) ]
2
2
3
- use std:: { convert:: Infallible , future:: Future , pin:: Pin , sync:: Arc } ;
3
+ use std:: { convert:: Infallible , future:: Future , net :: SocketAddr , pin:: Pin , sync:: Arc } ;
4
4
5
+ use bytes:: Bytes ;
6
+ use http_body_util:: Full ;
5
7
use hyper:: {
6
- server:: Server ,
7
- service:: { make_service_fn, service_fn} ,
8
- Body , Request , Response , StatusCode ,
8
+ body:: Incoming , server:: conn:: http1, service:: service_fn, Request , Response , StatusCode ,
9
9
} ;
10
+ use hyper_util:: rt:: TokioIo ;
10
11
use path_tree:: PathTree ;
12
+ use tokio:: net:: TcpListener ;
11
13
12
14
static NOT_FOUND : & [ u8 ] = b"Not Found" ;
13
15
14
16
type Params = Vec < ( String , String ) > ;
17
+ type Body = Full < Bytes > ;
15
18
16
19
trait Handler : Send + Sync + ' static {
17
20
fn call < ' a > (
18
21
& ' a self ,
19
- req : Request < Body > ,
22
+ req : Request < Incoming > ,
20
23
) -> Pin < Box < dyn Future < Output = Response < Body > > + Send + ' a > > ;
21
24
}
22
25
23
26
impl < F , R > Handler for F
24
27
where
25
- F : Send + Sync + ' static + Fn ( Request < Body > ) -> R ,
26
- R : Future < Output = Response < Body > > + Send + ' static ,
28
+ F : Send + Sync + ' static + Fn ( Request < Incoming > ) -> R ,
29
+ R : Future < Output = Response < Full < Bytes > > > + Send + ' static ,
27
30
{
28
31
fn call < ' a > (
29
32
& ' a self ,
30
- req : Request < Body > ,
33
+ req : Request < Incoming > ,
31
34
) -> Pin < Box < dyn Future < Output = Response < Body > > + Send + ' a > > {
32
35
let fut = ( self ) ( req) ;
33
36
Box :: pin ( async move { fut. await } )
34
37
}
35
38
}
36
39
37
- async fn index ( _: Request < Body > ) -> Response < Body > {
40
+ async fn index ( _: Request < Incoming > ) -> Response < Body > {
38
41
Response :: new ( Body :: from ( "Hello, Web!" ) )
39
42
}
40
43
41
- async fn hello_world ( req : Request < Body > ) -> Response < Body > {
44
+ async fn hello_world ( req : Request < Incoming > ) -> Response < Body > {
42
45
let params = req. extensions ( ) . get :: < Params > ( ) . unwrap ( ) ;
43
46
let mut s = String :: new ( ) ;
44
47
s. push_str ( "Hello, World!\n " ) ;
@@ -48,7 +51,7 @@ async fn hello_world(req: Request<Body>) -> Response<Body> {
48
51
Response :: new ( Body :: from ( s) )
49
52
}
50
53
51
- async fn hello_user ( req : Request < Body > ) -> Response < Body > {
54
+ async fn hello_user ( req : Request < Incoming > ) -> Response < Body > {
52
55
let params = req. extensions ( ) . get :: < Params > ( ) . unwrap ( ) ;
53
56
let mut s = String :: new ( ) ;
54
57
s. push_str ( "Hello, " ) ;
@@ -59,17 +62,19 @@ async fn hello_user(req: Request<Body>) -> Response<Body> {
59
62
Response :: new ( Body :: from ( s) )
60
63
}
61
64
62
- async fn hello_rust ( _: Request < Body > ) -> Response < Body > {
65
+ async fn hello_rust ( _: Request < Incoming > ) -> Response < Body > {
63
66
Response :: new ( Body :: from ( "Hello, Rust!" ) )
64
67
}
65
68
66
- async fn login ( _req : Request < Body > ) -> Response < Body > {
69
+ async fn login ( _req : Request < Incoming > ) -> Response < Body > {
67
70
Response :: new ( Body :: from ( "I'm logined!" ) )
68
71
}
69
72
70
73
#[ tokio:: main]
71
74
async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error + Send + Sync > > {
72
- let addr = ( [ 127 , 0 , 0 , 1 ] , 3000 ) . into ( ) ;
75
+ let addr: SocketAddr = ( [ 127 , 0 , 0 , 1 ] , 3000 ) . into ( ) ;
76
+
77
+ let listener = TcpListener :: bind ( addr) . await ?;
73
78
74
79
// /
75
80
// ├── GET/ •0
@@ -87,40 +92,42 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
87
92
88
93
let tree = Arc :: new ( tree) ;
89
94
90
- let make_service = make_service_fn ( move |_| {
95
+ loop {
96
+ let ( tcp, _) = listener. accept ( ) . await ?;
97
+ let io = TokioIo :: new ( tcp) ;
91
98
let router = Arc :: clone ( & tree) ;
92
99
93
- async move {
94
- Ok :: < _ , Infallible > ( service_fn ( move |mut req| {
95
- let router = router. clone ( ) ;
96
- let path = "/" . to_owned ( ) + req. method ( ) . as_str ( ) + req. uri ( ) . path ( ) ;
97
-
98
- async move {
99
- Ok :: < _ , Infallible > ( match router. find ( & path) {
100
- Some ( ( handler, route) ) => {
101
- let p = route
102
- . params ( )
103
- . iter ( )
104
- . map ( |p| ( p. 0 . to_string ( ) , p. 1 . to_string ( ) ) )
105
- . collect :: < Params > ( ) ;
106
- req. extensions_mut ( ) . insert ( p) ;
107
- handler. call ( req) . await
100
+ tokio:: task:: spawn ( async move {
101
+ if let Err ( err) = http1:: Builder :: new ( )
102
+ . serve_connection (
103
+ io,
104
+ service_fn ( move |mut req| {
105
+ let router = router. clone ( ) ;
106
+ let path = "/" . to_owned ( ) + req. method ( ) . as_str ( ) + req. uri ( ) . path ( ) ;
107
+
108
+ async move {
109
+ Ok :: < _ , Infallible > ( match router. find ( & path) {
110
+ Some ( ( handler, route) ) => {
111
+ let p = route
112
+ . params ( )
113
+ . iter ( )
114
+ . map ( |p| ( p. 0 . to_string ( ) , p. 1 . to_string ( ) ) )
115
+ . collect :: < Params > ( ) ;
116
+ req. extensions_mut ( ) . insert ( p) ;
117
+ handler. call ( req) . await
118
+ }
119
+ None => Response :: builder ( )
120
+ . status ( StatusCode :: NOT_FOUND )
121
+ . body ( NOT_FOUND . into ( ) )
122
+ . unwrap ( ) ,
123
+ } )
108
124
}
109
- None => Response :: builder ( )
110
- . status ( StatusCode :: NOT_FOUND )
111
- . body ( NOT_FOUND . into ( ) )
112
- . unwrap ( ) ,
113
- } )
114
- }
115
- } ) )
116
- }
117
- } ) ;
118
-
119
- let server = Server :: bind ( & addr) . serve ( make_service) ;
120
-
121
- println ! ( "Listening on http://{addr}" ) ;
122
-
123
- server. await ?;
124
-
125
- Ok ( ( ) )
125
+ } ) ,
126
+ )
127
+ . await
128
+ {
129
+ println ! ( "Error serving connection: {:?}" , err) ;
130
+ }
131
+ } ) ;
132
+ }
126
133
}
0 commit comments