diff options
author | Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com> | 2021-05-12 11:53:29 +0000 |
---|---|---|
committer | Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com> | 2021-08-30 17:48:49 +0000 |
commit | 79963079fae23668cb0694834faa5d43d0d99f3b (patch) | |
tree | 033bce5f4ddbe68a639229598f1fca8737cf8257 /src/listing.rs | |
parent | Bump deps (diff) | |
download | miniserve-79963079fae23668cb0694834faa5d43d0d99f3b.tar.gz miniserve-79963079fae23668cb0694834faa5d43d0d99f3b.zip |
Fix clippy::too_many_arguments and rework error ..
... page rendering
Too many arguments are moved around and many of them are already stored
in MiniserveConfig. Many of these are used to render error pages.
To fix this issue, it was necessary to rework error page rendering:
1. Implement `ResponseError` for `ContextualError` so that it can be
returned from service handlers as is and will then be automatically
logged to the console and converted into an error response.
2. At service handler level, all error responses are now rendered as
plain text.
3. 'error_page_middleware' is now responsible for the rendering of the
final error page from plain text reponses.
Signed-off-by: Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com>
Diffstat (limited to 'src/listing.rs')
-rw-r--r-- | src/listing.rs | 92 |
1 files changed, 26 insertions, 66 deletions
diff --git a/src/listing.rs b/src/listing.rs index 8147113..b2730de 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -1,6 +1,5 @@ use actix_web::body::Body; use actix_web::dev::ServiceResponse; -use actix_web::http::StatusCode; use actix_web::web::Query; use actix_web::{HttpRequest, HttpResponse}; use bytesize::ByteSize; @@ -149,33 +148,16 @@ pub async fn file_handler(req: HttpRequest) -> actix_web::Result<actix_files::Na /// List a directory and renders a HTML file accordingly /// Adapted from https://docs.rs/actix-web/0.7.13/src/actix_web/fs.rs.html#564 -#[allow(clippy::too_many_arguments)] pub fn directory_listing( dir: &actix_files::Directory, req: &HttpRequest, - skip_symlinks: bool, - show_hidden: bool, - file_upload: bool, - random_route: Option<String>, - favicon_route: String, - css_route: String, - default_color_scheme: &str, - default_color_scheme_dark: &str, - show_qrcode: bool, - upload_route: String, - tar_enabled: bool, - tar_gz_enabled: bool, - zip_enabled: bool, - dirs_first: bool, - hide_version_footer: bool, - show_symlink_info: bool, - title: Option<String>, ) -> io::Result<ServiceResponse> { use actix_web::dev::BodyEncoding; + let conf = req.app_data::<crate::MiniserveConfig>().unwrap(); let serve_path = req.path(); let base = Path::new(serve_path); - let random_route_abs = format!("/{}", random_route.clone().unwrap_or_default()); + let random_route_abs = format!("/{}", conf.random_route.clone().unwrap_or_default()); let is_root = base.parent().is_none() || Path::new(&req.path()) == Path::new(&random_route_abs); let encoded_dir = match base.strip_prefix(random_route_abs) { @@ -186,13 +168,18 @@ pub fn directory_listing( .to_string(); let breadcrumbs = { - let title = title.unwrap_or_else(|| req.connection_info().host().into()); + let title = conf + .title + .clone() + .unwrap_or_else(|| req.connection_info().host().into()); let decoded = percent_decode_str(&encoded_dir).decode_utf8_lossy(); let mut res: Vec<Breadcrumb> = Vec::new(); - let mut link_accumulator = - format!("/{}", random_route.map(|r| r + "/").unwrap_or_default()); + let mut link_accumulator = match &conf.random_route { + Some(random_route) => format!("/{}/", random_route), + None => "/".to_string(), + }; let mut components = Path::new(&*decoded).components().peekable(); @@ -242,7 +229,7 @@ pub fn directory_listing( let mut entries: Vec<Entry> = Vec::new(); for entry in dir.path.read_dir()? { - if dir.is_visible(&entry) || show_hidden { + if dir.is_visible(&entry) || conf.show_hidden { let entry = entry?; // show file url as relative to static path let file_name = entry.file_name().to_string_lossy().to_string(); @@ -253,11 +240,10 @@ pub fn directory_listing( } res => (false, res), }; - let symlink_dest = if is_symlink && show_symlink_info { - Some(std::fs::read_link(entry.path())?) - } else { - None - }; + let symlink_dest = (is_symlink && conf.show_symlink_info) + .then(|| entry.path()) + .and_then(|path| std::fs::read_link(path).ok()) + .map(|path| path.to_string_lossy().into_owned()); let file_url = base .join(&utf8_percent_encode(&file_name, PATH_SEGMENT).to_string()) .to_string_lossy() @@ -265,7 +251,7 @@ pub fn directory_listing( // if file is a directory, add '/' to the end of the name if let Ok(metadata) = metadata { - if skip_symlinks && is_symlink { + if conf.no_symlinks && is_symlink { continue; } let last_modification_date = match metadata.modified() { @@ -280,7 +266,7 @@ pub fn directory_listing( file_url, None, last_modification_date, - symlink_dest.and_then(|s| s.into_os_string().into_string().ok()), + symlink_dest, )); } else if metadata.is_file() { entries.push(Entry::new( @@ -289,7 +275,7 @@ pub fn directory_listing( file_url, Some(ByteSize::b(metadata.len())), last_modification_date, - symlink_dest.and_then(|s| s.into_os_string().into_string().ok()), + symlink_dest, )); } } else { @@ -323,33 +309,17 @@ pub fn directory_listing( } // List directories first - if dirs_first { + if conf.dirs_first { entries.sort_by_key(|e| !e.is_dir()); } if let Some(archive_method) = query_params.download { - if !archive_method.is_enabled(tar_enabled, tar_gz_enabled, zip_enabled) { + if !archive_method.is_enabled(conf.tar_enabled, conf.tar_gz_enabled, conf.zip_enabled) { return Ok(ServiceResponse::new( req.clone(), HttpResponse::Forbidden() - .content_type("text/html; charset=utf-8") - .body( - renderer::render_error( - "Archive creation is disabled.", - StatusCode::FORBIDDEN, - "/", - None, - None, - false, - false, - &favicon_route, - &css_route, - default_color_scheme, - default_color_scheme_dark, - hide_version_footer, - ) - .into_string(), - ), + .content_type("text/plain; charset=utf-8") + .body("Archive creation is disabled."), )); } log::info!( @@ -372,6 +342,7 @@ pub fn directory_listing( // Start the actual archive creation in a separate thread. let dir = dir.path.to_path_buf(); + let skip_symlinks = conf.no_symlinks; std::thread::spawn(move || { if let Err(err) = archive_method.create_archive(dir, skip_symlinks, pipe) { log::error!("Error during archive creation: {:?}", err); @@ -399,21 +370,10 @@ pub fn directory_listing( renderer::page( entries, is_root, - query_params.sort, - query_params.order, - show_qrcode, - file_upload, - &upload_route, - &favicon_route, - &css_route, - default_color_scheme, - default_color_scheme_dark, - &encoded_dir, + query_params, breadcrumbs, - tar_enabled, - tar_gz_enabled, - zip_enabled, - hide_version_footer, + &encoded_dir, + conf, ) .into_string(), ), |