1
1
// #![deny(warnings)] // FIXME: https://github.com/rust-lang/rust/issues/62411
2
2
#![ warn( rust_2018_idioms) ]
3
3
4
+ use bytes:: Bytes ;
5
+ use http_body_util:: { combinators:: BoxBody , BodyExt , Empty , Full } ;
4
6
use hyper:: server:: conn:: Http ;
5
7
use hyper:: service:: service_fn;
6
8
use hyper:: { Body , Method , Request , Response , StatusCode } ;
7
9
use tokio:: net:: TcpListener ;
8
10
9
11
use std:: collections:: HashMap ;
12
+ use std:: convert:: Infallible ;
10
13
use std:: net:: SocketAddr ;
11
14
use url:: form_urlencoded;
12
15
@@ -15,9 +18,11 @@ static MISSING: &[u8] = b"Missing field";
15
18
static NOTNUMERIC : & [ u8 ] = b"Number field is not numeric" ;
16
19
17
20
// Using service_fn, we can turn this function into a `Service`.
18
- async fn param_example ( req : Request < Body > ) -> Result < Response < Body > , hyper:: Error > {
21
+ async fn param_example (
22
+ req : Request < Body > ,
23
+ ) -> Result < Response < BoxBody < Bytes , Infallible > > , hyper:: Error > {
19
24
match ( req. method ( ) , req. uri ( ) . path ( ) ) {
20
- ( & Method :: GET , "/" ) | ( & Method :: GET , "/post" ) => Ok ( Response :: new ( INDEX . into ( ) ) ) ,
25
+ ( & Method :: GET , "/" ) | ( & Method :: GET , "/post" ) => Ok ( Response :: new ( full ( INDEX ) ) ) ,
21
26
( & Method :: POST , "/post" ) => {
22
27
// Concatenate the body...
23
28
let b = hyper:: body:: to_bytes ( req) . await ?;
@@ -43,7 +48,7 @@ async fn param_example(req: Request<Body>) -> Result<Response<Body>, hyper::Erro
43
48
} else {
44
49
return Ok ( Response :: builder ( )
45
50
. status ( StatusCode :: UNPROCESSABLE_ENTITY )
46
- . body ( MISSING . into ( ) )
51
+ . body ( full ( MISSING ) )
47
52
. unwrap ( ) ) ;
48
53
} ;
49
54
let number = if let Some ( n) = params. get ( "number" ) {
@@ -52,13 +57,13 @@ async fn param_example(req: Request<Body>) -> Result<Response<Body>, hyper::Erro
52
57
} else {
53
58
return Ok ( Response :: builder ( )
54
59
. status ( StatusCode :: UNPROCESSABLE_ENTITY )
55
- . body ( NOTNUMERIC . into ( ) )
60
+ . body ( full ( NOTNUMERIC ) )
56
61
. unwrap ( ) ) ;
57
62
}
58
63
} else {
59
64
return Ok ( Response :: builder ( )
60
65
. status ( StatusCode :: UNPROCESSABLE_ENTITY )
61
- . body ( MISSING . into ( ) )
66
+ . body ( full ( MISSING ) )
62
67
. unwrap ( ) ) ;
63
68
} ;
64
69
@@ -69,15 +74,15 @@ async fn param_example(req: Request<Body>) -> Result<Response<Body>, hyper::Erro
69
74
// responses such as InternalServiceError may be
70
75
// needed here, too.
71
76
let body = format ! ( "Hello {}, your number is {}" , name, number) ;
72
- Ok ( Response :: new ( body . into ( ) ) )
77
+ Ok ( Response :: new ( full ( body ) ) )
73
78
}
74
79
( & Method :: GET , "/get" ) => {
75
80
let query = if let Some ( q) = req. uri ( ) . query ( ) {
76
81
q
77
82
} else {
78
83
return Ok ( Response :: builder ( )
79
84
. status ( StatusCode :: UNPROCESSABLE_ENTITY )
80
- . body ( MISSING . into ( ) )
85
+ . body ( full ( MISSING ) )
81
86
. unwrap ( ) ) ;
82
87
} ;
83
88
let params = form_urlencoded:: parse ( query. as_bytes ( ) )
@@ -88,19 +93,27 @@ async fn param_example(req: Request<Body>) -> Result<Response<Body>, hyper::Erro
88
93
} else {
89
94
return Ok ( Response :: builder ( )
90
95
. status ( StatusCode :: UNPROCESSABLE_ENTITY )
91
- . body ( MISSING . into ( ) )
96
+ . body ( full ( MISSING ) )
92
97
. unwrap ( ) ) ;
93
98
} ;
94
99
let body = format ! ( "You requested {}" , page) ;
95
- Ok ( Response :: new ( body . into ( ) ) )
100
+ Ok ( Response :: new ( full ( body ) ) )
96
101
}
97
102
_ => Ok ( Response :: builder ( )
98
103
. status ( StatusCode :: NOT_FOUND )
99
- . body ( Body :: empty ( ) )
104
+ . body ( empty ( ) )
100
105
. unwrap ( ) ) ,
101
106
}
102
107
}
103
108
109
+ fn empty ( ) -> BoxBody < Bytes , Infallible > {
110
+ Empty :: < Bytes > :: new ( ) . boxed ( )
111
+ }
112
+
113
+ fn full < T : Into < Bytes > > ( chunk : T ) -> BoxBody < Bytes , Infallible > {
114
+ Full :: new ( chunk. into ( ) ) . boxed ( )
115
+ }
116
+
104
117
#[ tokio:: main]
105
118
async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error + Send + Sync > > {
106
119
pretty_env_logger:: init ( ) ;
0 commit comments