Files
markbase/docs/WEBDAV_MARKBASE_BACKEND_PLAN.md
Warren 8a5daa37eb WebDAV Server成功启动 + 挂载指南
成果:
 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
2026-05-18 23:21:45 +08:00

6.1 KiB
Raw Permalink Blame History

WebDAV MarkBase Backend集成计划

当前状态

现有WebDAV实现

  • src/webdav/handler.rs (26 lines)
  • 使用 dav-server
  • 使用 LocalFs本地文件系统backend
  • 使用 FakeLs简单lock system

问题:

  • LocalFs只是本地目录映射不是SQLite backend
  • 无法直接访问warren.sqlite12659 nodes
  • 无法使用MarkBaseFS的query_node/read_file功能

需要实现MarkBaseFs backend

目标:

  • 实现dav-server的filesystem trait
  • 使用MarkBaseFSSQLite 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
  • 性能最优

步骤:

  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

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;
}

步骤5Finder连接测试

Finder操作

  • Connect to Server → http://localhost:8080/webdav
  • 验证warren.sqlite的12659 nodes显示
  • 验证文件读取功能

预估时间

步骤 时间
步骤1MarkBaseFs struct 1小时
步骤2DavDirItem/DavMetaData 1小时
步骤3修改handler.rs 30分钟
步骤4HTTP server启动 30分钟
步骤5Finder测试 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