@@ -37,82 +37,62 @@ pub async fn serve_file<P: AsRef<Path>>(path: P, mime: &Mime) -> Result<Response
3737 Ok ( Response :: success ( mime, file) )
3838}
3939
40- pub enum ResolveResult {
41- Path ( PathBuf ) ,
42- Response ( Response ) ,
40+ pub fn dir_canonicalize < D : AsRef < Path > > ( dir : D ) -> Result < PathBuf , Response > {
41+ let dir = dir. as_ref ( ) ;
42+ dir. canonicalize ( ) . map_err ( |e| match e. kind ( ) {
43+ std:: io:: ErrorKind :: NotFound => {
44+ warn ! (
45+ "Path {} not found. Check your configuration." ,
46+ dir. display( )
47+ ) ;
48+ Response :: server_error ( "Server incorrectly configured" ) . unwrap ( )
49+ }
50+ std:: io:: ErrorKind :: PermissionDenied => {
51+ warn ! (
52+ "Permission denied for {}. Check that the server has access." ,
53+ dir. display( )
54+ ) ;
55+ Response :: server_error ( "Server incorrectly configured" ) . unwrap ( )
56+ }
57+ _ => warn_unexpected ( e, dir, line ! ( ) ) . unwrap ( ) ,
58+ } )
4359}
4460
45- #[ cfg( feature = "serve_dir" ) ]
4661pub fn resolve_virtual_path < D : AsRef < Path > , P : AsRef < Path > > (
4762 dir : D ,
4863 virtual_path : & [ P ] ,
49- ) -> ResolveResult {
64+ ) -> Result < PathBuf , Response > {
5065 // Check server directory
5166 debug ! ( "Dir: {}" , dir. as_ref( ) . display( ) ) ;
52- let dir = dir. as_ref ( ) ;
53- let dir = match dir. canonicalize ( ) {
54- Ok ( dir) => dir,
55- Err ( e) => match e. kind ( ) {
56- std:: io:: ErrorKind :: NotFound => {
57- warn ! (
58- "Path {} not found. Check your configuration." ,
59- dir. display( )
60- ) ;
61- return ResolveResult :: Response (
62- Response :: server_error ( "Server incorrectly configured" ) . unwrap ( ) ,
63- ) ;
64- }
65- std:: io:: ErrorKind :: PermissionDenied => {
66- warn ! (
67- "Permission denied for {}. Check that the server has access." ,
68- dir. display( )
69- ) ;
70- return ResolveResult :: Response (
71- Response :: server_error ( "Server incorrectly configured" ) . unwrap ( ) ,
72- ) ;
73- }
74- _ => return ResolveResult :: Response ( warn_unexpected ( e, dir, line ! ( ) ) . unwrap ( ) ) ,
75- } ,
76- } ;
67+ let dir = dir_canonicalize ( dir) ?;
7768
7869 // Virtual path is an uri, that - when coming from the server - is already normalized,
7970 // so fragment below will create proper path that is "below" base `dir`.
80- let mut path = dir. to_path_buf ( ) ;
71+ let mut path = dir. clone ( ) ;
8172 for segment in virtual_path {
8273 path. push ( segment) ;
8374 }
8475
8576 // Check virtual path inside filesystem.
86- let path = match path. canonicalize ( ) {
87- Ok ( dir) => dir,
88- Err ( e) => {
89- match e. kind ( ) {
90- std:: io:: ErrorKind :: NotFound => {
91- return ResolveResult :: Response ( Response :: not_found ( ) ) ;
92- }
93- std:: io:: ErrorKind :: PermissionDenied => {
94- // Runs when asked to serve a file in a restricted dir
95- // i.e. not /noaccess, but /noaccess/file
96- warn ! (
97- "Asked to serve {}, but permission denied by OS" ,
98- path. display( )
99- ) ;
100- return ResolveResult :: Response ( Response :: not_found ( ) ) ;
101- }
102- _ => {
103- return ResolveResult :: Response (
104- warn_unexpected ( e, path. as_ref ( ) , line ! ( ) ) . unwrap ( ) ,
105- ) ;
106- }
107- }
77+ let path = path. canonicalize ( ) . map_err ( |e| match e. kind ( ) {
78+ std:: io:: ErrorKind :: NotFound => Response :: not_found ( ) ,
79+ std:: io:: ErrorKind :: PermissionDenied => {
80+ // Runs when asked to serve a file in a restricted dir
81+ // i.e. not /noaccess, but /noaccess/file
82+ warn ! (
83+ "Asked to serve {}, but permission denied by OS" ,
84+ path. display( )
85+ ) ;
86+ Response :: not_found ( )
10887 }
109- } ;
88+ _ => warn_unexpected ( e, path. as_ref ( ) , line ! ( ) ) . unwrap ( ) ,
89+ } ) ?;
11090
11191 if !path. starts_with ( & dir) {
112- return ResolveResult :: Response ( Response :: not_found ( ) ) ;
92+ Err ( Response :: not_found ( ) )
93+ } else {
94+ Ok ( path)
11395 }
114-
115- ResolveResult :: Path ( path)
11696}
11797
11898#[ cfg( feature = "serve_dir" ) ]
@@ -121,8 +101,8 @@ pub async fn serve_dir<D: AsRef<Path>, P: AsRef<Path>>(
121101 virtual_path : & [ P ] ,
122102) -> Result < Response > {
123103 let path = match resolve_virtual_path ( dir, virtual_path) {
124- ResolveResult :: Path ( path_buf) => path_buf,
125- ResolveResult :: Response ( response) => return Ok ( response) ,
104+ Ok ( path_buf) => path_buf,
105+ Err ( response) => return Ok ( response) ,
126106 } ;
127107
128108 if !path. is_dir ( ) {
0 commit comments