1
1
#![ deny( warnings) ]
2
2
3
3
use tokio:: fs:: File ;
4
- use tokio:: io:: AsyncReadExt ;
4
+
5
+ use tokio_util:: codec:: { BytesCodec , FramedRead } ;
5
6
6
7
use hyper:: service:: { make_service_fn, service_fn} ;
7
8
use hyper:: { Body , Method , Request , Response , Result , Server , StatusCode } ;
8
9
9
10
static INDEX : & str = "examples/send_file_index.html" ;
10
- static INTERNAL_SERVER_ERROR : & [ u8 ] = b"Internal Server Error" ;
11
11
static NOTFOUND : & [ u8 ] = b"Not Found" ;
12
12
13
13
#[ tokio:: main]
@@ -30,9 +30,7 @@ async fn main() {
30
30
31
31
async fn response_examples ( req : Request < Body > ) -> Result < Response < Body > > {
32
32
match ( req. method ( ) , req. uri ( ) . path ( ) ) {
33
- ( & Method :: GET , "/" ) | ( & Method :: GET , "/index.html" ) | ( & Method :: GET , "/big_file.html" ) => {
34
- simple_file_send ( INDEX ) . await
35
- }
33
+ ( & Method :: GET , "/" ) | ( & Method :: GET , "/index.html" ) => simple_file_send ( INDEX ) . await ,
36
34
( & Method :: GET , "/no_file.html" ) => {
37
35
// Test what happens when file cannot be be found
38
36
simple_file_send ( "this_file_should_not_exist.html" ) . await
@@ -49,26 +47,13 @@ fn not_found() -> Response<Body> {
49
47
. unwrap ( )
50
48
}
51
49
52
- /// HTTP status code 500
53
- fn internal_server_error ( ) -> Response < Body > {
54
- Response :: builder ( )
55
- . status ( StatusCode :: INTERNAL_SERVER_ERROR )
56
- . body ( INTERNAL_SERVER_ERROR . into ( ) )
57
- . unwrap ( )
58
- }
59
-
60
50
async fn simple_file_send ( filename : & str ) -> Result < Response < Body > > {
61
- // Serve a file by asynchronously reading it entirely into memory.
62
- // Uses tokio_fs to open file asynchronously, then tokio::io::AsyncReadExt
63
- // to read into memory asynchronously.
64
-
65
- if let Ok ( mut file) = File :: open ( filename) . await {
66
- let mut buf = Vec :: new ( ) ;
67
- if let Ok ( _) = file. read_to_end ( & mut buf) . await {
68
- return Ok ( Response :: new ( buf. into ( ) ) ) ;
69
- }
51
+ // Serve a file by asynchronously reading it by chunks using tokio-util crate.
70
52
71
- return Ok ( internal_server_error ( ) ) ;
53
+ if let Ok ( file) = File :: open ( filename) . await {
54
+ let stream = FramedRead :: new ( file, BytesCodec :: new ( ) ) ;
55
+ let body = Body :: wrap_stream ( stream) ;
56
+ return Ok ( Response :: new ( body) ) ;
72
57
}
73
58
74
59
Ok ( not_found ( ) )
0 commit comments