use axum::{extract::Request, response::IntoResponse, Extension}; use clap::Subcommand; use dav_server::{fakels::FakeLs, DavHandler}; use std::path::PathBuf; use std::sync::Arc; #[derive(Subcommand)] pub enum WebdavCommand { #[command(name = "webdav-start")] Start { #[arg(short, long, default_value = "8002")] port: u16, #[arg(short, long)] user: String, }, } pub async fn handle_webdav_command(cmd: WebdavCommand) -> anyhow::Result<()> { match cmd { WebdavCommand::Start { port, user } => { let home_dir = PathBuf::from("/Users/accusys/momentry/var/sftpgo/data").join(&user); if !home_dir.exists() { return Err(anyhow::anyhow!( "User home directory not found: {}", home_dir.display() )); } println!("=== MarkBase WebDAV Server (VFS) ==="); println!("User: {}", user); println!("Port: {}", port); println!("Home: {}", home_dir.display()); println!(); run_webdav_server(port, home_dir, user).await?; } } Ok(()) } async fn run_webdav_server( port: u16, home_dir: PathBuf, user: String, ) -> anyhow::Result<()> { use axum::{routing::any, Router}; use tokio::net::TcpListener; let vfs = Box::new(crate::vfs::local_fs::LocalFs::new()); let upload_hook = None; let dav_fs = crate::webdav::VfsDavFs::new(vfs, home_dir, upload_hook, user); let dav_handler = DavHandler::builder() .filesystem(dav_fs) .locksystem(FakeLs::new()) .strip_prefix("/webdav") .build_handler(); let app = Router::new() .route("/webdav", any(handle_dav)) .route("/webdav/", any(handle_dav)) .route("/webdav/*path", any(handle_dav)) .layer(Extension(dav_handler)); let addr = format!("127.0.0.1:{}", port); let listener = TcpListener::bind(&addr).await?; println!("WebDAV server listening on http://{}", addr); println!("Mount point: /webdav"); println!(); println!("Press Ctrl+C to stop"); axum::serve(listener, app).await?; Ok(()) } async fn handle_dav( Extension(dav): Extension, req: Request, ) -> impl IntoResponse { dav.handle(req).await }