From 81df80c1c91f77847da9c8a4a71df51b8526392c Mon Sep 17 00:00:00 2001 From: Sven-Hendrik Haase Date: Mon, 10 Jun 2024 01:06:16 +0200 Subject: Bump rustls to v0.23 --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index aa40585..7b04f7c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -228,7 +228,7 @@ async fn run(miniserve_config: MiniserveConfig) -> Result<(), StartupError> { #[cfg(feature = "tls")] let srv = match &miniserve_config.tls_rustls_config { - Some(tls_config) => srv.listen_rustls(listener, tls_config.clone()), + Some(tls_config) => srv.listen_rustls_0_23(listener, tls_config.clone()), None => srv.listen(listener), }; -- cgit v1.2.3 From 1fdbbd5f5759544f6e9c28c435d2e925fb7fbd61 Mon Sep 17 00:00:00 2001 From: Sven-Hendrik Haase Date: Thu, 12 Sep 2024 02:49:34 +0200 Subject: Fix lints --- src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 7b04f7c..1434a0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,9 +52,8 @@ fn main() -> Result<()> { let miniserve_config = MiniserveConfig::try_from_args(args)?; - run(miniserve_config).map_err(|e| { + run(miniserve_config).inspect_err(|e| { errors::log_error_chain(e.to_string()); - e })?; Ok(()) -- cgit v1.2.3 From 317bd6a5d42a83c9c5e874788282a6e76f638211 Mon Sep 17 00:00:00 2001 From: Lukas Stabe Date: Thu, 6 Feb 2025 00:03:05 +0100 Subject: add read-only webdav support --- src/main.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 1434a0c..ccf611c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,13 +6,18 @@ use std::time::Duration; use actix_files::NamedFile; use actix_web::{ dev::{fn_service, ServiceRequest, ServiceResponse}, - http::header::ContentType, + guard, + http::{header::ContentType, Method}, middleware, web, App, HttpRequest, HttpResponse, Responder, }; use actix_web_httpauth::middleware::HttpAuthentication; use anyhow::Result; use clap::{crate_version, CommandFactory, Parser}; use colored::*; +use dav_server::{ + actix::{DavRequest, DavResponse}, + DavConfig, DavHandler, DavMethodSet, +}; use fast_qr::QRBuilder; use log::{error, warn}; @@ -27,9 +32,11 @@ mod file_utils; mod listing; mod pipe; mod renderer; +mod webdav_fs; use crate::config::MiniserveConfig; use crate::errors::{RuntimeError, StartupError}; +use crate::webdav_fs::RestrictedFs; static STYLESHEET: &str = grass::include!("data/style.scss"); @@ -88,6 +95,12 @@ async fn run(miniserve_config: MiniserveConfig) -> Result<(), StartupError> { )); } + if miniserve_config.webdav_enabled && miniserve_config.path.is_file() { + return Err(StartupError::WebdavWithFileServePath( + miniserve_config.path.to_string_lossy().to_string(), + )); + } + let inside_config = miniserve_config.clone(); let canon_path = miniserve_config @@ -307,7 +320,9 @@ fn configure_header(conf: &MiniserveConfig) -> middleware::DefaultHeaders { /// This is where we configure the app to serve an index file, the file listing, or a single file. fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { let dir_service = || { - let mut files = actix_files::Files::new("", &conf.path); + // use routing guard so propfind and options requests fall through to the webdav handler + let mut files = actix_files::Files::new("", &conf.path) + .guard(guard::Any(guard::Get()).or(guard::Head())); // Use specific index file if one was provided. if let Some(ref index_file) = conf.index { @@ -376,6 +391,38 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { // Handle directories app.service(dir_service()); } + + if conf.webdav_enabled { + let fs = RestrictedFs::new(&conf.path, conf.show_hidden); + + let dav_server = DavHandler::builder() + .filesystem(fs) + .methods(DavMethodSet::WEBDAV_RO) + .hide_symlinks(conf.no_symlinks) + .strip_prefix(conf.route_prefix.to_owned()) + .build_handler(); + + app.app_data(web::Data::new(dav_server.clone())); + + app.service( + // actix requires tail segment to be named, even if unused + web::resource("/{tail}*") + .guard( + guard::Any(guard::Options()) + .or(guard::Method(Method::from_bytes(b"PROPFIND").unwrap())), + ) + .to(dav_handler), + ); + } +} + +async fn dav_handler(req: DavRequest, davhandler: web::Data) -> DavResponse { + if let Some(prefix) = req.prefix() { + let config = DavConfig::new().strip_prefix(prefix); + davhandler.handle_with(config, req.request).await.into() + } else { + davhandler.handle(req.request).await.into() + } } async fn error_404(req: HttpRequest) -> Result { -- cgit v1.2.3