From 5fed730516005f9c494fb3ba6edc782647963a0e Mon Sep 17 00:00:00 2001 From: Jose Quintana Date: Sun, 14 Feb 2021 23:18:13 +0100 Subject: [PATCH] refactor: minor error handling tweaks on directory listing feature --- src/helpers.rs | 19 +++++++++---------- src/staticfile_middleware/staticfile.rs | 37 ++++++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/helpers.rs b/src/helpers.rs index f8b1713..99921c0 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -2,16 +2,15 @@ use std::error; use std::path::{Path, PathBuf}; /// Validate and return a directory path. -pub fn get_valid_dirpath>(path: P) -> Result> +pub fn get_valid_dirpath>(p: P) -> Result> where PathBuf: From

, { - match PathBuf::from(path) { - v if !v.exists() => Result::Err(From::from(format!("path \"{:?}\" was not found", &v))), - v if !v.is_dir() => { - Result::Err(From::from(format!("path \"{:?}\" is not a directory", &v))) - } - v => Result::Ok(v), + let p: PathBuf = p.into(); + match p { + v if !v.exists() => Err(From::from(format!("path \"{:?}\" was not found", &v))), + v if !v.is_dir() => Err(From::from(format!("path \"{:?}\" is not a directory", &v))), + v => Ok(v), } } @@ -21,13 +20,13 @@ where PathBuf: From

, { let path = match get_valid_dirpath(path) { - Err(e) => return Result::Err(e), Ok(v) => v, + Err(e) => return Err(e), }; match path.iter().last() { - Some(v) => Result::Ok(v.to_str().unwrap().to_string()), - _ => Result::Err(From::from(format!( + Some(v) => Ok(v.to_str().unwrap().to_string()), + None => Err(From::from(format!( "directory name for path \"{:?}\" was not determined", path, ))), diff --git a/src/staticfile_middleware/staticfile.rs b/src/staticfile_middleware/staticfile.rs index 4df9ff8..a2a84f4 100644 --- a/src/staticfile_middleware/staticfile.rs +++ b/src/staticfile_middleware/staticfile.rs @@ -40,12 +40,13 @@ impl Staticfile { }) } + /// Resolve a specific path which should be relative to base path. fn resolve_path(&self, path: &[&str]) -> Result> { let current_dirname = percent_decode_str(path[0]).decode_utf8()?; let asserts_dirname = self.assets.iter().last().unwrap().to_str().unwrap(); let mut is_assets = false; - let path_resolved = if current_dirname.as_ref() == asserts_dirname { + let path_resolved = if current_dirname == asserts_dirname { // Assets path validation resolve is_assets = true; @@ -91,7 +92,7 @@ impl Handler for Staticfile { // Resolve path on file system let path_resolved = match self.resolve_path(&req.url.path()) { - Ok(file_path) => file_path, + Ok(p) => p, Err(e) => { trace!("{}", e); return Ok(Response::with(status::NotFound)); @@ -100,13 +101,13 @@ impl Handler for Staticfile { // 1. Check if "directory listing" feature is enabled, // if current path is a valid directory and - // if it does not contain an index.html file + // if it does not contain an `index.html` file if self.dir_listing && path_resolved.is_dir() && !path_resolved.join("index.html").exists() { - let read_dir = match std::fs::read_dir(path_resolved) { - Ok(dir) => dir, - Err(err) => { - error!("{}", err); + let read_dir = match std::fs::read_dir(&path_resolved) { + Ok(d) => d, + Err(e) => { + error!("{}", e); return Ok(Response::with(status::InternalServerError)); } }; @@ -118,13 +119,19 @@ impl Handler for Staticfile { .map(|i| format!("/{}", i)) .collect::(); - // Redirect if current path does not end with slash + // Redirect if current path does not end with a slash if !current_path.ends_with('/') { let mut u: url::Url = req.url.clone().into(); current_path.push('/'); u.set_path(¤t_path); - let url = iron::Url::from_generic_url(u).expect("Unable to parse redirect url"); + let url = match iron::Url::from_generic_url(u) { + Ok(u) => u, + Err(e) => { + error!("Unable to parse redirection url: {}", e); + return Ok(Response::with(status::BadRequest)); + } + }; return Ok(Response::with(( status::PermanentRedirect, @@ -132,7 +139,7 @@ impl Handler for Staticfile { ))); } - // Read current directory and create the index page + // Read current directory and create the index page content let mut entries_str = String::new(); if current_path != "/" { entries_str = @@ -187,7 +194,7 @@ impl Handler for Staticfile { // 2. Otherwise proceed with the normal file- process // Search a file and its metadata by the resolved path - let static_file = match StaticFileWithMeta::search(path_resolved.clone()) { + let static_file = match StaticFileWithMeta::search(&path_resolved) { Ok(f) => f, Err(e) => { trace!("{}", e); @@ -262,8 +269,12 @@ struct StaticFileWithMeta { impl StaticFileWithMeta { /// Search for a regular source file in file system. /// If source file is a directory then it attempts to search for an index.html. - pub fn search(mut src: PathBuf) -> Result> { - trace!("Opening {}", src.display()); + pub fn search>(src: P) -> Result> + where + PathBuf: From

, + { + let mut src: PathBuf = src.into(); + trace!("Opening path {}", src.display()); let mut auto_index = false; let meta = std::fs::metadata(&src)?; -- libgit2 1.7.2