# WebDAV MarkBase Backend集成计划 ## 当前状态 **现有WebDAV实现:** - src/webdav/handler.rs (26 lines) - 使用 `dav-server` 库 - 使用 `LocalFs`(本地文件系统backend) - 使用 `FakeLs`(简单lock system) **问题:** - ❌ LocalFs只是本地目录映射,不是SQLite backend - ❌ 无法直接访问warren.sqlite(12659 nodes) - ❌ 无法使用MarkBaseFS的query_node/read_file功能 --- ## 需要实现:MarkBaseFs backend **目标:** - 实现dav-server的filesystem trait - 使用MarkBaseFS(SQLite backend) - 支持warren.sqlite的12659 nodes - 实现PROPFIND、GET、PUT操作 --- ## dav-server filesystem trait分析 **dav-server库的filesystem trait需要实现:** ```rust pub trait DavFileSystem: Send + Sync { // 必须实现的方法 fn read_dir(&self, path: &str, meta: bool) -> io::Result>; fn get_file(&self, path: &str) -> io::Result>; fn metadata(&self, path: &str) -> io::Result; // 可选方法(PUT写入) fn put_file(&self, path: &str) -> io::Result>; fn create_dir(&self, path: &str) -> io::Result<()>; fn remove_file(&self, path: &str) -> io::Result<()>; fn remove_dir(&self, path: &str) -> io::Result<()>; } ``` --- ## 实现方案 ### 方案A:直接实现filesystem trait(推荐) **优势:** - 完全控制 - 直接使用MarkBaseFS - 性能最优 **步骤:** 1. 创建 `MarkBaseFs` struct,实现 `DavFileSystem` trait 2. 使用 `MarkBaseFS::query_node()` 获取文件节点 3. 使用 `MarkBaseFS::query_children()` 实现read_dir 4. 使用 `MarkBaseFS::read_file()` 实现get_file 5. 集成到DavHandler **预估时间:** 3-4小时 --- ### 方案B:修改handler.rs,使用SQLite backend(简化) **优势:** - 快速实现 - 不需要自定义filesystem trait - 利用现有handler结构 **步骤:** 1. 修改 `MarkBaseWebDAV::create_handler()` 2. 使用 `data/users/warren.sqlite` 作为数据源 3. 创建虚拟文件映射 4. 保留LocalFs,但映射到SQLite虚拟目录 **预估时间:** 1-2小时 --- ### 方案C:使用WebDAV handler + HTTP server(最简单) **优势:** - 最快实现 - 不需要自定义filesystem - 使用现有的localfs **步骤:** 1. 创建 `data/webdav/warren/` 目录 2. 使用 `MarkBaseFS::read_file()` 将warren.sqlite文件复制到该目录 3. LocalFs自动映射目录结构 4. Finder可通过HTTP访问 **缺点:** - 不是真正的SQLite backend - 需要文件复制(占用磁盘空间) - 性能较差 **预估时间:** 30分钟 --- ## 推荐方案:方案A(完整实现) **理由:** - 完全使用SQLite backend - 真正的虚拟文件系统 - 性能最优 - 可扩展(未来可添加PUT写入) --- ## 实现步骤(方案A) ### 步骤1:创建MarkBaseFs struct **文件:** `src/webdav/markbase_fs.rs` ```rust use dav_server::{DavFileSystem, DavDirItem, DavMetaData, DavFile}; use crate::fskit::filesystem::MarkBaseFS; use std::io; pub struct MarkBaseFs { markbase_fs: MarkBaseFS, user_id: String, } impl MarkBaseFs { pub fn new(user_id: String, db_path: &str) -> Self { let markbase_fs = MarkBaseFS::new(&user_id, db_path); Self { markbase_fs, user_id } } } impl DavFileSystem for MarkBaseFs { fn read_dir(&self, path: &str, meta: bool) -> io::Result> { // 使用MarkBaseFS::query_children() // 返回目录内容 } fn get_file(&self, path: &str) -> io::Result> { // 使用MarkBaseFS::read_file() // 返回文件内容 } fn metadata(&self, path: &str) -> io::Result { // 使用MarkBaseFS::query_node() // 返回文件元数据 } } ``` --- ### 步骤2:实现DavDirItem和DavMetaData **DavDirItem结构:** ```rust pub struct MarkBaseDavDirItem { name: String, is_dir: bool, size: u64, } impl DavDirItem for MarkBaseDavDirItem { fn name(&self) -> &str { &self.name } fn is_dir(&self) -> bool { self.is_dir } } ``` **DavMetaData结构:** ```rust pub struct MarkBaseMetaData { is_dir: bool, size: u64, modified: SystemTime, } impl DavMetaData for MarkBaseMetaData { fn is_dir(&self) -> bool { self.is_dir } fn len(&self) -> u64 { self.size } fn modified(&self) -> SystemTime { self.modified } } ``` --- ### 步骤3:修改handler.rs **文件:** `src/webdav/handler.rs` ```rust use crate::webdav::markbase_fs::MarkBaseFs; impl MarkBaseWebDAV { pub fn create_handler(&self) -> DavHandler { let db_path = format!("data/users/{}/{}.sqlite", self.user_id, self.user_id); DavHandler::builder() .filesystem(MarkBaseFs::new(self.user_id.clone(), &db_path)) .locksystem(FakeLs::new()) .strip_prefix("/webdav") .build_handler() } } ``` --- ### 步骤4:启动HTTP server **文件:** `src/bin/webdav_server.rs` ```rust use axum::Router; use markbase::webdav::handler::MarkBaseWebDAV; fn main() { let webdav = MarkBaseWebDAV::new("warren", PathBuf::from("data/users/warren.sqlite")); let handler = webdav.create_handler(); let app = Router::new() .route("/webdav/*path", get(handler.handle_get)) .route("/webdav/*path", put(handler.handle_put)); // 启动server let addr = SocketAddr::from(([127, 0, 0, 1], 8080)); axum::Server::bind(&addr).serve(app.into_make_service()).await; } ``` --- ### 步骤5:Finder连接测试 **Finder操作:** - Connect to Server → `http://localhost:8080/webdav` - 验证warren.sqlite的12659 nodes显示 - 验证文件读取功能 --- ## 预估时间 |步骤 |时间 | |------|------| | 步骤1:MarkBaseFs struct | 1小时 | | 步骤2:DavDirItem/DavMetaData | 1小时 | | 步骤3:修改handler.rs | 30分钟 | | 步骤4:HTTP server启动 | 30分钟 | | 步骤5:Finder测试 | 30分钟 | | **总计** | **3.5小时** | --- ## 快速开始 **立即可执行:** 1. 创建 `src/webdav/markbase_fs.rs` 2. 实现 `DavFileSystem` trait 3. 修改 `src/webdav/handler.rs` 4. 启动HTTP server 5. Finder连接测试 --- **最后更新:** 2026-05-18 20:50