diff options
author | Sven-Hendrik Haase <svenstaro@gmail.com> | 2025-03-20 12:48:26 +0000 |
---|---|---|
committer | Sven-Hendrik Haase <svenstaro@gmail.com> | 2025-03-20 12:48:30 +0000 |
commit | 900c0035b374845a9af505748ad54c97c1e916e8 (patch) | |
tree | 6d189237c998db7c6580f41a35acd13b445c661d | |
parent | Merge pull request #1488 from AlecDivito/issue-1485 (diff) | |
download | miniserve-900c0035b374845a9af505748ad54c97c1e916e8.tar.gz miniserve-900c0035b374845a9af505748ad54c97c1e916e8.zip |
Add --directory-size flag to enable directory size calculation
This is turned off by default as it's potentially quite IO intensive, especially on HDDs.
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | src/args.rs | 6 | ||||
-rw-r--r-- | src/config.rs | 4 | ||||
-rw-r--r-- | src/main.rs | 46 | ||||
-rw-r--r-- | tests/api.rs | 7 |
5 files changed, 41 insertions, 23 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 14f2a58..3da022a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Add well-known healthcheck route at `/__miniserve_internal/healthcheck` (of `/<prefix>/__miniserve_internal/healthcheck` when using `--route-prefix`) - Add asynchronous recursive directory size counting [#1482](https://github.com/svenstaro/miniserve/pull/1482) - Add link to miniserve GitHub page to footer +- Add `--directory-size` flag to enable directory size counting ## [0.29.0] - 2025-02-06 - Make URL encoding fully WHATWG-compliant [#1454](https://github.com/svenstaro/miniserve/pull/1454) (thanks @cyqsimon) diff --git a/src/args.rs b/src/args.rs index d078ef2..04c7a76 100644 --- a/src/args.rs +++ b/src/args.rs @@ -217,6 +217,12 @@ pub struct CliArgs { )] pub web_upload_concurrency: usize, + /// Enable recursive directory size calculation + /// + /// This is disabled by default because it is a potentially fairly IO intensive operation. + #[arg(long = "directory-size", env = "MINISERVE_DIRECTORY_SIZE")] + pub directory_size: bool, + /// Enable creating directories #[arg( short = 'U', diff --git a/src/config.rs b/src/config.rs index eecc45e..dee69e7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -104,6 +104,9 @@ pub struct MiniserveConfig { /// Enable QR code display pub show_qrcode: bool, + /// Enable recursive directory size calculation + pub directory_size: bool, + /// Enable creating directories pub mkdir_enabled: bool, @@ -320,6 +323,7 @@ impl MiniserveConfig { pretty_urls: args.pretty_urls, overwrite_files: args.overwrite_files, show_qrcode: args.qrcode, + directory_size: args.directory_size, mkdir_enabled: args.mkdir_enabled, file_upload: args.allowed_upload_dir.is_some(), web_upload_concurrency: args.web_upload_concurrency, diff --git a/src/main.rs b/src/main.rs index cd54bd8..c4432bf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -457,28 +457,32 @@ async fn api( ) -> Result<impl Responder, RuntimeError> { match command.into_inner() { ApiCommand::DirSize(path) => { - // The dir argument might be percent-encoded so let's decode it just in case. - let decoded_path = percent_decode_str(&path) - .decode_utf8() - .map_err(|e| RuntimeError::ParseError(path.clone(), e.to_string()))?; - - // Convert the relative dir to an absolute path on the system. - let sanitized_path = file_utils::sanitize_path(&*decoded_path, true) - .expect("Expected a path to directory"); - - let full_path = config - .path - .canonicalize() - .expect("Couldn't canonicalize path") - .join(sanitized_path); - info!("Requested directory listing for {full_path:?}"); - - let dir_size = recursive_dir_size(&full_path).await?; - if config.show_exact_bytes { - Ok(format!("{dir_size} B")) + if config.directory_size { + // The dir argument might be percent-encoded so let's decode it just in case. + let decoded_path = percent_decode_str(&path) + .decode_utf8() + .map_err(|e| RuntimeError::ParseError(path.clone(), e.to_string()))?; + + // Convert the relative dir to an absolute path on the system. + let sanitized_path = file_utils::sanitize_path(&*decoded_path, true) + .expect("Expected a path to directory"); + + let full_path = config + .path + .canonicalize() + .expect("Couldn't canonicalize path") + .join(sanitized_path); + info!("Requested directory listing for {full_path:?}"); + + let dir_size = recursive_dir_size(&full_path).await?; + if config.show_exact_bytes { + Ok(format!("{dir_size} B")) + } else { + let dir_size = ByteSize::b(dir_size); + Ok(dir_size.to_string()) + } } else { - let dir_size = ByteSize::b(dir_size); - Ok(dir_size.to_string()) + Ok("-".to_string()) } } } diff --git a/tests/api.rs b/tests/api.rs index fe313b0..5dc6b52 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -16,7 +16,10 @@ use crate::fixtures::{DIRECTORIES, Error, TestServer, server}; #[case(utf8_percent_encode(DIRECTORIES[0], NON_ALPHANUMERIC).to_string())] #[case(utf8_percent_encode(DIRECTORIES[1], NON_ALPHANUMERIC).to_string())] #[case(utf8_percent_encode(DIRECTORIES[2], NON_ALPHANUMERIC).to_string())] -fn api_dir_size(#[case] dir: String, server: TestServer) -> Result<(), Error> { +fn api_dir_size( + #[case] dir: String, + #[with(&["--directory-size"])] server: TestServer, +) -> Result<(), Error> { let mut command = HashMap::new(); command.insert("DirSize", dir); @@ -44,7 +47,7 @@ fn api_dir_size(#[case] dir: String, server: TestServer) -> Result<(), Error> { #[case(r"C:\foo")] #[case(r"\foo")] fn api_dir_size_prevent_path_transversal_attacks( - server: TestServer, + #[with(&["--directory-size"])] server: TestServer, #[case] path: &str, ) -> Result<(), Error> { let mut command = HashMap::new(); |