22
33use std:: net:: SocketAddr ;
44
5- use hyper:: server:: conn:: http1;
6- use tokio:: net:: TcpListener ;
7-
85use bytes:: Bytes ;
9- use http_body_util:: Full ;
6+ use futures_util:: TryStreamExt ;
7+ use http_body_util:: { combinators:: BoxBody , BodyExt , Full , StreamBody } ;
8+ use hyper:: body:: Frame ;
9+ use hyper:: server:: conn:: http1;
1010use hyper:: service:: service_fn;
1111use hyper:: { Method , Request , Response , Result , StatusCode } ;
12+ use tokio:: { fs:: File , net:: TcpListener } ;
13+ use tokio_util:: io:: ReaderStream ;
1214
1315#[ path = "../benches/support/mod.rs" ]
1416mod support;
@@ -41,7 +43,9 @@ async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
4143 }
4244}
4345
44- async fn response_examples ( req : Request < hyper:: body:: Incoming > ) -> Result < Response < Full < Bytes > > > {
46+ async fn response_examples (
47+ req : Request < hyper:: body:: Incoming > ,
48+ ) -> Result < Response < BoxBody < Bytes , std:: io:: Error > > > {
4549 match ( req. method ( ) , req. uri ( ) . path ( ) ) {
4650 ( & Method :: GET , "/" ) | ( & Method :: GET , "/index.html" ) => simple_file_send ( INDEX ) . await ,
4751 ( & Method :: GET , "/no_file.html" ) => {
@@ -53,18 +57,35 @@ async fn response_examples(req: Request<hyper::body::Incoming>) -> Result<Respon
5357}
5458
5559/// HTTP status code 404
56- fn not_found ( ) -> Response < Full < Bytes > > {
60+ fn not_found ( ) -> Response < BoxBody < Bytes , std :: io :: Error > > {
5761 Response :: builder ( )
5862 . status ( StatusCode :: NOT_FOUND )
59- . body ( Full :: new ( NOTFOUND . into ( ) ) )
63+ . body ( Full :: new ( NOTFOUND . into ( ) ) . map_err ( |e| match e { } ) . boxed ( ) )
6064 . unwrap ( )
6165}
6266
63- async fn simple_file_send ( filename : & str ) -> Result < Response < Full < Bytes > > > {
64- if let Ok ( contents) = tokio:: fs:: read ( filename) . await {
65- let body = contents. into ( ) ;
66- return Ok ( Response :: new ( Full :: new ( body) ) ) ;
67+ async fn simple_file_send ( filename : & str ) -> Result < Response < BoxBody < Bytes , std:: io:: Error > > > {
68+ // Open file for reading
69+ let file = File :: open ( filename) . await ;
70+ if file. is_err ( ) {
71+ eprintln ! ( "ERROR: Unable to open file." ) ;
72+ return Ok ( not_found ( ) ) ;
6773 }
6874
69- Ok ( not_found ( ) )
75+ let file: File = file. unwrap ( ) ;
76+
77+ // Wrap to a tokio_util::io::ReaderStream
78+ let reader_stream = ReaderStream :: new ( file) ;
79+
80+ // Convert to http_body_util::BoxBody
81+ let stream_body = StreamBody :: new ( reader_stream. map_ok ( Frame :: data) ) ;
82+ let boxed_body = stream_body. boxed ( ) ;
83+
84+ // Send response
85+ let response = Response :: builder ( )
86+ . status ( StatusCode :: OK )
87+ . body ( boxed_body)
88+ . unwrap ( ) ;
89+
90+ Ok ( response)
7091}
0 commit comments