From 79963079fae23668cb0694834faa5d43d0d99f3b Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Wed, 12 May 2021 14:53:29 +0300 Subject: 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 --- src/listing.rs | 92 +++++++++++++++++----------------------------------------- 1 file changed, 26 insertions(+), 66 deletions(-) (limited to 'src/listing.rs') 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, - 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, ) -> io::Result { use actix_web::dev::BodyEncoding; + let conf = req.app_data::().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 = 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 = 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(), ), -- cgit v1.2.3