use clap::Subcommand; use axum::{extract::Request, response::IntoResponse, Extension}; #[derive(Subcommand)] pub enum WebdavCommand { 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 db_path = std::path::PathBuf::from(crate::FileTree::user_db_path(&user)); if !db_path.exists() { return Err(anyhow::anyhow!( "User database not found: {}", db_path.display() )); } println!("=== MarkBase WebDAV Server ==="); println!("User: {}", user); println!("Port: {}", port); println!("Database: {}", db_path.display()); println!(""); run_webdav_server(port, user, db_path).await?; } } Ok(()) } async fn run_webdav_server( port: u16, user: String, db_path: std::path::PathBuf, ) -> anyhow::Result<()> { use axum::{extract::Request, response::IntoResponse, routing::any, Extension, Router}; use tokio::net::TcpListener; let webdav = markbase_webdav::webdav::MarkBaseWebDAV::new(user, db_path); let dav_handler = webdav.create_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 }