diff options
author | Sven-Hendrik Haase <svenstaro@gmail.com> | 2020-03-11 14:37:56 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-11 14:37:56 +0000 |
commit | fdf6836f7516661d01cc2c0494106ea5ebb26b60 (patch) | |
tree | ee989cd0597499c1b65b1df22da793b1eb7cfa96 | |
parent | Bump reqwests to v0.10 (diff) | |
parent | Ignore clippy warning (diff) | |
download | miniserve-fdf6836f7516661d01cc2c0494106ea5ebb26b60.tar.gz miniserve-fdf6836f7516661d01cc2c0494106ea5ebb26b60.zip |
Merge pull request #235 from DamianX/archives
Added option to disable archives
-rw-r--r-- | src/args.rs | 5 | ||||
-rw-r--r-- | src/listing.rs | 23 | ||||
-rw-r--r-- | src/main.rs | 5 | ||||
-rw-r--r-- | src/renderer.rs | 9 | ||||
-rw-r--r-- | tests/archive.rs | 46 |
5 files changed, 84 insertions, 4 deletions
diff --git a/src/args.rs b/src/args.rs index 3910d06..78340dd 100644 --- a/src/args.rs +++ b/src/args.rs @@ -83,6 +83,10 @@ struct CLIArgs { /// Enable overriding existing files during file upload #[structopt(short = "o", long = "overwrite-files")] overwrite_files: bool, + + /// Disable archive generation + #[structopt(short = "r", long = "disable-archives")] + disable_archives: bool, } /// Checks wether an interface is valid, i.e. it can be parsed into an IP address @@ -172,6 +176,7 @@ pub fn parse_args() -> crate::MiniserveConfig { index: args.index, overwrite_files: args.overwrite_files, file_upload: args.file_upload, + archives: !args.disable_archives, } } diff --git a/src/listing.rs b/src/listing.rs index d419775..256e062 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -1,4 +1,5 @@ use actix_web::{fs, Body, FromRequest, HttpRequest, HttpResponse, Query, Result}; +use actix_web::http::StatusCode; use bytesize::ByteSize; use futures::Stream; use htmlescape::encode_minimal as escape_html_entity; @@ -126,7 +127,7 @@ pub fn file_handler(req: &HttpRequest<crate::MiniserveConfig>) -> Result<fs::Nam /// 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::identity_conversion)] +#[allow(clippy::identity_conversion, clippy::too_many_arguments)] pub fn directory_listing<S>( dir: &fs::Directory, req: &HttpRequest<S>, @@ -135,6 +136,7 @@ pub fn directory_listing<S>( random_route: Option<String>, default_color_scheme: ColorScheme, upload_route: String, + archives_enabled: bool, ) -> Result<HttpResponse, io::Error> { let serve_path = req.path(); @@ -249,6 +251,24 @@ pub fn directory_listing<S>( let color_scheme = query_params.theme.unwrap_or(default_color_scheme); if let Some(compression_method) = query_params.download { + if !archives_enabled { + return Ok(HttpResponse::Forbidden() + .content_type("text/html; charset=utf-8") + .body( + renderer::render_error( + "Archive creation is disabled.", + StatusCode::FORBIDDEN, + "/", + None, + None, + color_scheme, + default_color_scheme, + false, + false, + ).into_string() + ) + ); + } log::info!( "Creating an archive ({extension}) of {path}...", extension = compression_method.extension(), @@ -313,6 +333,7 @@ pub fn directory_listing<S>( file_upload, &upload_route, ¤t_dir.display().to_string(), + archives_enabled, ) .into_string(), )) diff --git a/src/main.rs b/src/main.rs index 9b9c628..2885c59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,6 +62,9 @@ pub struct MiniserveConfig { /// Enable upload to override existing files pub overwrite_files: bool, + + /// If false, creation of archives is disabled + pub archives: bool, } fn main() { @@ -251,6 +254,7 @@ fn configure_app(app: App<MiniserveConfig>) -> App<MiniserveConfig> { 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; upload_route = if let Some(random_route) = app.state().random_route.clone() { format!("/{}/upload", random_route) } else { @@ -279,6 +283,7 @@ fn configure_app(app: App<MiniserveConfig>) -> App<MiniserveConfig> { random_route.clone(), default_color_scheme, u_r.clone(), + archives_enabled ) }) .default_handler(error_404), diff --git a/src/renderer.rs b/src/renderer.rs index 32591c3..face6ff 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -22,6 +22,7 @@ pub fn page( file_upload: bool, upload_route: &str, current_dir: &str, + archives: bool, ) -> Markup { let upload_action = build_upload_action( upload_route, @@ -49,9 +50,11 @@ pub fn page( span#top { } h1.title { "Index of " (serve_path) } div.toolbar { - div.download { - @for compression_method in CompressionMethod::iter() { - (archive_button(compression_method, sort_method, sort_order, color_scheme, default_color_scheme)) + @if archives { + div.download { + @for compression_method in CompressionMethod::iter() { + (archive_button(compression_method, sort_method, sort_order, color_scheme, default_color_scheme)) + } } } @if file_upload { diff --git a/tests/archive.rs b/tests/archive.rs new file mode 100644 index 0000000..c692d90 --- /dev/null +++ b/tests/archive.rs @@ -0,0 +1,46 @@ +mod fixtures; + +use assert_cmd::prelude::*; +use assert_fs::fixture::TempDir; +use fixtures::{port, tmpdir, Error}; +use rstest::rstest; +use select::document::Document; +use select::predicate::Text; +use std::process::{Command, Stdio}; +use std::thread::sleep; +use std::time::Duration; +use reqwest::StatusCode; + +#[rstest] +fn archives_are_disabled(tmpdir: TempDir, port: u16) -> Result<(), Error> { + let mut child = Command::cargo_bin("miniserve")? + .arg(tmpdir.path()) + .arg("-p") + .arg(port.to_string()) + .arg("-r") + .stdout(Stdio::null()) + .spawn()?; + + sleep(Duration::from_secs(1)); + + // Ensure the links to the archives are not present + let body = reqwest::get(format!("http://localhost:{}", port).as_str())?.error_for_status()?; + let parsed = Document::from_read(body)?; + assert!(parsed.find(Text).all(|x| x.text() != "Download .tar.gz" && x.text() != "Download .tar")); + + // Try to download anyway, ensure it's forbidden + assert_eq!( + reqwest::get( + format!("http://localhost:{}/?download=tar_gz", port).as_str())? + .status(), + StatusCode::FORBIDDEN); + assert_eq!( + reqwest::get( + format!("http://localhost:{}/?download=tar", port).as_str())? + .status(), + StatusCode::FORBIDDEN); + + child.kill()?; + + Ok(()) +}
\ No newline at end of file |