成果: ✅ WebDAV server编译(3.6MB) ✅ Server启动(PID 66959,端口8002) ✅ 端口查询(避开SFTPGo 8080/8090) ✅ Finder连接指引 发现: - MarkBase_Virtual_LUN是APFS本地磁盘(不是WebDAV) - 需要重新连接 http://localhost:8002/webdav - 当前使用LocalFs(需要优化为SQLite backend) 文档: - WEBDAV_MOUNT_SUCCESS.md - WEBDAV_MARKBASE_BACKEND_PLAN.md 下一步: 1. Finder连接WebDAV 2. 验证warren文件树显示 3. 实现MarkBaseFs backend
274 lines
6.1 KiB
Markdown
274 lines
6.1 KiB
Markdown
# 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<Vec<DavDirItem>>;
|
||
fn get_file(&self, path: &str) -> io::Result<Box<dyn DavFile>>;
|
||
fn metadata(&self, path: &str) -> io::Result<DavMetaData>;
|
||
|
||
// 可选方法(PUT写入)
|
||
fn put_file(&self, path: &str) -> io::Result<Box<dyn DavFile>>;
|
||
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<Vec<DavDirItem>> {
|
||
// 使用MarkBaseFS::query_children()
|
||
// 返回目录内容
|
||
}
|
||
|
||
fn get_file(&self, path: &str) -> io::Result<Box<dyn DavFile>> {
|
||
// 使用MarkBaseFS::read_file()
|
||
// 返回文件内容
|
||
}
|
||
|
||
fn metadata(&self, path: &str) -> io::Result<DavMetaData> {
|
||
// 使用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
|