11use crate :: log;
22use crate :: { Body , Endpoint , Request , Response , Result , StatusCode } ;
33
4- use async_std:: path :: PathBuf as AsyncPathBuf ;
4+ use async_std:: io :: BufReader ;
55
6- use std:: path:: { Path , PathBuf } ;
7- use std:: { ffi:: OsStr , io} ;
6+ use cap_async_std:: fs;
87
98pub ( crate ) struct ServeDir {
109 prefix : String ,
11- dir : PathBuf ,
10+ dir : fs :: Dir ,
1211}
1312
1413impl ServeDir {
1514 /// Create a new instance of `ServeDir`.
16- pub ( crate ) fn new ( prefix : String , dir : PathBuf ) -> Self {
15+ pub ( crate ) fn new ( prefix : String , dir : fs :: Dir ) -> Self {
1716 Self { prefix, dir }
1817 }
1918}
@@ -29,33 +28,14 @@ where
2928 . strip_prefix ( & self . prefix . trim_end_matches ( '*' ) )
3029 . unwrap ( ) ;
3130 let path = path. trim_start_matches ( '/' ) ;
32- let mut file_path = self . dir . clone ( ) ;
33- for p in Path :: new ( path) {
34- if p == OsStr :: new ( "." ) {
35- continue ;
36- } else if p == OsStr :: new ( ".." ) {
37- file_path. pop ( ) ;
38- } else {
39- file_path. push ( & p) ;
40- }
41- }
42-
43- log:: info!( "Requested file: {:?}" , file_path) ;
44-
45- let file_path = AsyncPathBuf :: from ( file_path) ;
46- if !file_path. starts_with ( & self . dir ) {
47- log:: warn!( "Unauthorized attempt to read: {:?}" , file_path) ;
48- Ok ( Response :: new ( StatusCode :: Forbidden ) )
49- } else {
50- match Body :: from_file ( & file_path) . await {
51- Ok ( body) => Ok ( Response :: builder ( StatusCode :: Ok ) . body ( body) . build ( ) ) ,
52- Err ( e) if e. kind ( ) == io:: ErrorKind :: NotFound => {
53- log:: warn!( "File not found: {:?}" , & file_path) ;
54- Ok ( Response :: new ( StatusCode :: NotFound ) )
55- }
56- Err ( e) => Err ( e. into ( ) ) ,
57- }
58- }
31+
32+ log:: info!( "Requested file: {:?}" , path) ;
33+
34+ let file = self . dir . open ( path) . await ?;
35+ // TODO: This always uses `mime::BYTE_STREAM`; with http-types 3.0
36+ // we'll be able to use `Body::from_open_file` which fixes this.
37+ let body = Body :: from_reader ( BufReader :: new ( file) , None ) ;
38+ Ok ( Response :: builder ( StatusCode :: Ok ) . body ( body) . build ( ) )
5939 }
6040}
6141
0 commit comments