aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamian <damian@autistici.org>2019-12-17 20:00:04 +0000
committerDamian <damian@autistici.org>2020-03-02 06:07:20 +0000
commitd0be1f2ea97342ef577ebe879971776422b08038 (patch)
tree8af7ecae6095619957e719b763407b9bd8bd3501
parentMerge pull request #254 from svenstaro/dependabot/cargo/rstest-0.5.3 (diff)
downloadminiserve-d0be1f2ea97342ef577ebe879971776422b08038.tar.gz
miniserve-d0be1f2ea97342ef577ebe879971776422b08038.zip
Added option to disable archives
-rw-r--r--src/args.rs5
-rw-r--r--src/listing.rs21
-rw-r--r--src/main.rs5
-rw-r--r--src/renderer.rs9
-rw-r--r--tests/archive.rs46
5 files changed, 83 insertions, 3 deletions
diff --git a/src/args.rs b/src/args.rs
index fe976ed..4484943 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..8ee6ead 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;
@@ -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,
&current_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 1821c48..0db6f1c 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 download {
+ 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