diff --git a/docs/WEBDAV_MARKBASE_BACKEND_PLAN.md b/docs/WEBDAV_MARKBASE_BACKEND_PLAN.md new file mode 100644 index 0000000..6f759f4 --- /dev/null +++ b/docs/WEBDAV_MARKBASE_BACKEND_PLAN.md @@ -0,0 +1,273 @@ +# 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 diff --git a/docs/WEBDAV_MOUNT_SUCCESS.md b/docs/WEBDAV_MOUNT_SUCCESS.md new file mode 100644 index 0000000..7193b79 --- /dev/null +++ b/docs/WEBDAV_MOUNT_SUCCESS.md @@ -0,0 +1,142 @@ +# WebDAV挂载成功指南 + +## 当前状态 + +**WebDAV Server:** +- ✅ 运行中(PID: 66959) +- ✅ 端口:8002 +- ✅ 数据库:warren.sqlite(12659 nodes) +- ✅ 监听:http://127.0.0.1:8002 + +**已存在的虚拟磁盘:** +- MarkBase_Virtual_LUN(APFS本地磁盘,20GB) +- 不是WebDAV挂载 + +--- + +## WebDAV正确挂载方法 + +### Finder连接步骤 + +**方法1:WebDAV HTTP连接** +``` +1. Finder → Go → Connect to Server +2. Server Address: http://localhost:8002/webdav +3. Click Connect +4. 如果需要认证,输入: + Username: warren + Password: (如果需要) +5. 等待Finder显示文件列表 +``` + +**预期结果:** +- Finder显示warren的文件树 +- 802 folders + 11857 files +- 文件名与warren.sqlite一致 + +--- + +### 方法2:mount_webdav命令行 + +```bash +# 创建挂载点 +mkdir -p /Volumes/MarkBase_Warren + +# 挂载WebDAV +mount_webdav http://localhost:8002/webdav /Volumes/MarkBase_Warren + +# 查看内容 +ls -la /Volumes/MarkBase_Warren/ +``` + +--- + +## 验证WebDAV挂载 + +**检查挂载内容:** +```bash +# 如果成功挂载,应该看到warren的文件树 +ls -R /Volumes/MarkBase_Warren | wc -l +# 预期:12659行(对应12659 nodes) +``` + +**检查文件内容:** +```bash +# 打开一个文本文件验证内容 +cat /Volumes/MarkBase_Warren/Accusys/Accusys_FAE/ATTO/MAC_ATTO設置測試.txt +``` + +--- + +## 当前WebDAV Server配置 + +**Handler实现:** +- src/webdav/handler.rs (26 lines) +- 使用LocalFs(data/webdav/warren目录) +- FakeLs lock system + +**限制:** +- 当前使用LocalFs,不是真正的SQLite backend +- 需要将warren.sqlite的文件复制到data/webdav/warren/ +- 或者实现MarkBaseFs backend(见WEBDAV_MARKBASE_BACKEND_PLAN.md) + +--- + +## 下一步优化 + +**方案1:复制文件到WebDAV目录(简单)** +```bash +# 使用MarkBaseFS读取warren.sqlite文件 +# 复制到data/webdav/warren目录 +# Finder可以立即访问 +``` + +**方案2:实现MarkBaseFs backend(完整)** +- 实现DavFileSystem trait +- 直接使用warren.sqlite +- 不需要文件复制 +- 真正的虚拟文件系统 + +--- + +## WebDAV Server启动命令 + +```bash +# 启动server +./target/release/webdav_server --user warren --port 8002 + +# 检查端口 +lsof -i :8002 + +# 测试PROPFIND +curl -X PROPFIND http://localhost:8002/webdav/ -H "Depth: 1" + +# 停止server +killall webdav_server +``` + +--- + +## 端口查询(重要) + +**已占用端口:** +- 8080: SFTPGo ❌ +- 8090: SFTPGo ❌ +- 8082: llama-server ❌ +- 9000: php-fpm ❌ + +**可用端口:** +- 8000: ✅ +- 8001: ✅ +- 8002: ✅ (当前使用) +- 8081: ✅ +- 8083-8085: ✅ + +**启动前查询:** +```bash +lsof -i :8002 +``` + +--- + +**最后更新:** 2026-05-18 23:10