aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
authorSven-Hendrik Haase <svenstaro@gmail.com>2025-03-07 11:38:10 +0000
committerGitHub <noreply@github.com>2025-03-07 11:38:10 +0000
commit419204c291273e073cb4e1049655bea848dbc441 (patch)
tree341cb7ac4bd5915deb8fe58947b3cc352687556d /src/main.rs
parentReformat style.scss (diff)
parentAdd asynchronous directory size counting (diff)
downloadminiserve-419204c291273e073cb4e1049655bea848dbc441.tar.gz
miniserve-419204c291273e073cb4e1049655bea848dbc441.zip
Merge pull request #1482 from svenstaro/add-asynchronous-directory-size-loading
Add asynchronous directory size counting
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs45
1 files changed, 42 insertions, 3 deletions
diff --git a/src/main.rs b/src/main.rs
index 856d22d..adda3f7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -14,6 +14,7 @@ use actix_web::{
};
use actix_web_httpauth::middleware::HttpAuthentication;
use anyhow::Result;
+use bytesize::ByteSize;
use clap::{CommandFactory, Parser, crate_version};
use colored::*;
use dav_server::{
@@ -21,7 +22,8 @@ use dav_server::{
actix::{DavRequest, DavResponse},
};
use fast_qr::QRBuilder;
-use log::{error, warn};
+use log::{error, info, warn};
+use serde::Deserialize;
mod archive;
mod args;
@@ -38,6 +40,7 @@ mod webdav_fs;
use crate::config::MiniserveConfig;
use crate::errors::{RuntimeError, StartupError};
+use crate::file_op::recursive_dir_size;
use crate::webdav_fs::RestrictedFs;
static STYLESHEET: &str = grass::include!("data/style.scss");
@@ -215,7 +218,7 @@ async fn run(miniserve_config: MiniserveConfig) -> Result<(), StartupError> {
let srv = actix_web::HttpServer::new(move || {
App::new()
.wrap(configure_header(&inside_config.clone()))
- .app_data(inside_config.clone())
+ .app_data(web::Data::new(inside_config.clone()))
.app_data(stylesheet.clone())
.wrap(from_fn(errors::error_page_middleware))
.wrap(middleware::Logger::default())
@@ -224,6 +227,7 @@ async fn run(miniserve_config: MiniserveConfig) -> Result<(), StartupError> {
middleware::Compress::default(),
))
.route(&inside_config.healthcheck_route, web::get().to(healthcheck))
+ .route(&inside_config.api_route, web::post().to(api))
.route(&inside_config.favicon_route, web::get().to(favicon))
.route(&inside_config.css_route, web::get().to(css))
.service(
@@ -353,7 +357,7 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) {
files = files.default_handler(fn_service(|req: ServiceRequest| async {
let (req, _) = req.into_parts();
let conf = req
- .app_data::<MiniserveConfig>()
+ .app_data::<web::Data<MiniserveConfig>>()
.expect("Could not get miniserve config");
let mut path_base = req.path()[1..].to_string();
if path_base.ends_with('/') {
@@ -438,6 +442,41 @@ async fn healthcheck() -> impl Responder {
HttpResponse::Ok().body("OK")
}
+#[derive(Deserialize, Debug)]
+enum ApiCommand {
+ /// Request the size of a particular directory
+ DirSize(String),
+}
+
+/// This "API" is pretty shitty but frankly miniserve doesn't really need a very fancy API. Or at
+/// least I hope so.
+async fn api(
+ command: web::Json<ApiCommand>,
+ config: web::Data<MiniserveConfig>,
+) -> Result<impl Responder, RuntimeError> {
+ match command.into_inner() {
+ ApiCommand::DirSize(dir) => {
+ // Convert the relative dir to an absolute path on the system
+ let sanitized_path =
+ file_utils::sanitize_path(&dir, 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())
+ }
+ }
+ }
+}
+
async fn favicon() -> impl Responder {
let logo = include_str!("../data/logo.svg");
HttpResponse::Ok()