成果: ✅ 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
6.1 KiB
6.1 KiB
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需要实现:
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
- 性能最优
步骤:
- 创建
MarkBaseFsstruct,实现DavFileSystemtrait - 使用
MarkBaseFS::query_node()获取文件节点 - 使用
MarkBaseFS::query_children()实现read_dir - 使用
MarkBaseFS::read_file()实现get_file - 集成到DavHandler
预估时间: 3-4小时
方案B:修改handler.rs,使用SQLite backend(简化)
优势:
- 快速实现
- 不需要自定义filesystem trait
- 利用现有handler结构
步骤:
- 修改
MarkBaseWebDAV::create_handler() - 使用
data/users/warren.sqlite作为数据源 - 创建虚拟文件映射
- 保留LocalFs,但映射到SQLite虚拟目录
预估时间: 1-2小时
方案C:使用WebDAV handler + HTTP server(最简单)
优势:
- 最快实现
- 不需要自定义filesystem
- 使用现有的localfs
步骤:
- 创建
data/webdav/warren/目录 - 使用
MarkBaseFS::read_file()将warren.sqlite文件复制到该目录 - LocalFs自动映射目录结构
- Finder可通过HTTP访问
缺点:
- 不是真正的SQLite backend
- 需要文件复制(占用磁盘空间)
- 性能较差
预估时间: 30分钟
推荐方案:方案A(完整实现)
理由:
- 完全使用SQLite backend
- 真正的虚拟文件系统
- 性能最优
- 可扩展(未来可添加PUT写入)
实现步骤(方案A)
步骤1:创建MarkBaseFs struct
文件: src/webdav/markbase_fs.rs
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结构:
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结构:
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
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
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小时 |
快速开始
立即可执行:
- 创建
src/webdav/markbase_fs.rs - 实现
DavFileSystemtrait - 修改
src/webdav/handler.rs - 启动HTTP server
- Finder连接测试
最后更新: 2026-05-18 20:50