From 848557762c1c4eed2ba16713ead97308d1841220 Mon Sep 17 00:00:00 2001 From: marawan ragab Date: Sun, 10 May 2020 17:14:51 -0400 Subject: make sure archiving is opt-in --- src/archive.rs | 13 +++++++++++-- src/args.rs | 15 +++++++++++---- src/listing.rs | 8 +++++--- src/main.rs | 13 +++++++++---- src/renderer.rs | 9 ++++++--- tests/archive.rs | 1 - 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/archive.rs b/src/archive.rs index 785e1e8..c96814f 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -1,7 +1,6 @@ use actix_web::http::ContentEncoding; use libflate::gzip::Encoder; use zip::{ZipWriter, write}; -use std::io::BufWriter; use std::fs::File; use std::path::PathBuf; use serde::Deserialize; @@ -54,6 +53,14 @@ impl CompressionMethod { } } + pub fn is_enabled(self, tar_enabled: bool, zip_enabled: bool,) -> bool { + match self { + CompressionMethod::TarGz => tar_enabled, + CompressionMethod::Tar => tar_enabled, + CompressionMethod::Zip => zip_enabled, + } + } + /// Make an archive out of the given directory, and write the output to the given writer. /// /// Recursively includes all files and subdirectories. @@ -258,7 +265,9 @@ where } } - zip_writer.finish().unwrap(); + zip_writer.finish().map_err(|_| { + ContextualError::CustomError("Could not finish writing ZIP archive".to_string()) + })?; Ok(()) } diff --git a/src/args.rs b/src/args.rs index 49fe276..1525b41 100644 --- a/src/args.rs +++ b/src/args.rs @@ -84,9 +84,15 @@ struct CLIArgs { #[structopt(short = "o", long = "overwrite-files")] overwrite_files: bool, - /// Disable archive generation - #[structopt(short = "r", long = "disable-archives")] - disable_archives: bool, + /// Enable tar archive generation + #[structopt(short = "r", long = "tar-enabled")] + tar_enabled: bool, + + /// Enable zip archive generation + /// Zipping large directories can result in out-of-memory exception + /// because zip generation is done in memory and cannot be sent on the fly + #[structopt(short = "z", long = "zip-enabled")] + zip_enabled: bool, } /// Checks wether an interface is valid, i.e. it can be parsed into an IP address @@ -176,7 +182,8 @@ pub fn parse_args() -> crate::MiniserveConfig { index: args.index, overwrite_files: args.overwrite_files, file_upload: args.file_upload, - archives: !args.disable_archives, + tar_enabled: args.tar_enabled, + zip_enabled: args.zip_enabled, } } diff --git a/src/listing.rs b/src/listing.rs index d28824c..45b3732 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -136,7 +136,8 @@ pub fn directory_listing( random_route: Option, default_color_scheme: ColorScheme, upload_route: String, - archives_enabled: bool, + tar_enabled: bool, + zip_enabled: bool, ) -> Result { let serve_path = req.path(); @@ -250,7 +251,7 @@ pub fn directory_listing( let color_scheme = query_params.theme.unwrap_or(default_color_scheme); if let Some(compression_method) = query_params.download { - if !archives_enabled { + if !compression_method.is_enabled(tar_enabled, zip_enabled) { return Ok(HttpResponse::Forbidden() .content_type("text/html; charset=utf-8") .body( @@ -332,7 +333,8 @@ pub fn directory_listing( file_upload, &upload_route, ¤t_dir.display().to_string(), - archives_enabled, + tar_enabled, + zip_enabled, ) .into_string(), )) diff --git a/src/main.rs b/src/main.rs index a1ee303..3ff35c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -63,8 +63,11 @@ pub struct MiniserveConfig { /// Enable upload to override existing files pub overwrite_files: bool, - /// If false, creation of archives is disabled - pub archives: bool, + /// If false, creation of tar archives is disabled + pub tar_enabled: bool, + + /// If false, creation of zip archives is disabled + pub zip_enabled: bool, } fn main() { @@ -256,7 +259,8 @@ fn configure_app(app: App) -> App { let random_route = app.state().random_route.clone(); let default_color_scheme = app.state().default_color_scheme; let file_upload = app.state().file_upload; - let archives_enabled = app.state().archives; + let tar_enabled = app.state().tar_enabled; + let zip_enabled = app.state().zip_enabled; upload_route = if let Some(random_route) = app.state().random_route.clone() { format!("/{}/upload", random_route) } else { @@ -285,7 +289,8 @@ fn configure_app(app: App) -> App { random_route.clone(), default_color_scheme, u_r.clone(), - archives_enabled, + tar_enabled, + zip_enabled, ) }) .default_handler(error_404), diff --git a/src/renderer.rs b/src/renderer.rs index face6ff..accb49b 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -22,7 +22,8 @@ pub fn page( file_upload: bool, upload_route: &str, current_dir: &str, - archives: bool, + tar_enabled: bool, + zip_enabled: bool, ) -> Markup { let upload_action = build_upload_action( upload_route, @@ -50,10 +51,12 @@ pub fn page( span#top { } h1.title { "Index of " (serve_path) } div.toolbar { - @if archives { + @if tar_enabled || zip_enabled { div.download { @for compression_method in CompressionMethod::iter() { - (archive_button(compression_method, sort_method, sort_order, color_scheme, default_color_scheme)) + @if compression_method.is_enabled(tar_enabled, zip_enabled) { + (archive_button(compression_method, sort_method, sort_order, color_scheme, default_color_scheme)) + } } } } diff --git a/tests/archive.rs b/tests/archive.rs index 37da0e3..c170bc3 100644 --- a/tests/archive.rs +++ b/tests/archive.rs @@ -17,7 +17,6 @@ fn archives_are_disabled(tmpdir: TempDir, port: u16) -> Result<(), Error> { .arg(tmpdir.path()) .arg("-p") .arg(port.to_string()) - .arg("-r") .stdout(Stdio::null()) .spawn()?; -- cgit v1.2.3