4.3 KiB
4.3 KiB
技术选型 · 定案记录
2026-09-28 定案。每个结论后面都跟着当时的实测证据,便于以后回看"为什么这么选"。
0. 一句话
Go + golang.org/x/net/webdav(官方底盘)+ React/Vite/TS 内嵌前端 + JSON 账号文件 = 单个静态二进制。
1. 底盘:为什么是 Go 的官方 WebDAV 实现
| 维度 | 事实(实测 ✓) |
|---|---|
| 归属 | golang.org/x/net/webdav —— Go 官方仓库 ✓ BSD-3 ✓ |
| 体量 | 实现 7,543 行 / 测试 4,275 行、32 个测试函数 ✓ 测试厚度接近实现的 60% |
| 自带合规测试 | 仓库内含 litmus_test_server.go ✓ → 可直接跑标准 WebDAV 合规套件 lighttpd litmus ✓ |
| 动词覆盖 | PROPFIND / PROPPATCH / MKCOL / GET / HEAD / PUT / DELETE / COPY / MOVE / LOCK / UNLOCK ✓ |
| 关键能力 | LOCK/UNLOCK(LockSystem 接口,NewMemLS 内存锁)✓ Range 分段读(走 http.ServeContent)✓ If-Match / If-None-Match ✓ MOVE/COPY 的 Overwrite ✓ Depth: infinity ✓ 路径逃逸防护(slashClean + 前缀校验)✓ |
| 已知缺口 | 不支持配额(RFC 4331 quota-available-bytes) ✗ → 需要时自己在写入前预检 + 统计目录用量 ✓ |
| 产物 | 静态链接单二进制 ✓ 无运行时 ✓ 无中间件 ✓ "停掉不伤心" ✓ |
本地实测:x/net v0.59.0(2026-09-08)✓ 已缓存 ✓ Go 1.24.4 编译通过 ✓
(proxy.golang.org 返回 200,模块可正常拉取 ✓)
2. 被否掉的方案(都查过真实状态)
| 方案 | 真实状态(实测 ✓) | 否掉的理由 |
|---|---|---|
Node + webdav-server |
2.6.3,2026-08-04 ✓ 仍在维护 | 底盘非官方 ✗ 需带运行时;bun 编译产物大、常驻内存高 ✗ |
Rust + dav-server |
0.11.0,2026-02-21,累计 62.4 万下载 ✓ | 可行但无官方背书 + 迭代慢 + 生态熟悉度低 ✗ |
Python + wsgidav |
4.3.5 ✓ 我实测六动词全过(207/201/201/200/204)✓ | 功能没问题 ✗ 但要 Python 运行时 + venv,部署形态不划算 ✗ |
| dufs(套壳 + 自研 admin) | 3.02 MiB ✓ 隔离实测通过(403/403/400)✓ | 要两个进程 + 改写启动参数 + 重启同步 ✗ 脆弱且多一层 |
| SFTPGo(fork / 裁剪) | 12,588★ ✓ 功能全但是"十二概念"平台 ✗ | fork 大项目与"概念少"直接冲突 ✗ |
| hacdias/webdav | 7.09 MiB ✓ 但两种配置写法隔离实测都没锁住 ✗ | 隔离不可信 ✗ |
| 自研协议本身 | RFC 4918 的 XML / LOCK / If / Depth 细节是无底洞 | 已有官方实现 ✓ 重写零收益 ✗ |
3. 前端:React + Vite + TypeScript
- 生态成熟、构建产物小、长期可维护 ✓
- 构建产物用
//go:embed打进二进制 ✓ 保持"后端自带前端静态服务 + nginx 只做反代/网关"的架构 ✓ - 只有两个页面:admin(账号管理)/ client(登录后管文件)✓ 不需要路由框架、不需要状态管理库
- 不引 UI 组件库 ✓ 手写少量 CSS(Swiss 极简)
4. 账号存储:JSON,不上数据库
- 账号量级 < 100 ✓ JSON 足够 ✓ 写的时候临时文件 + 原子 rename ✓
- 好处:人类可读可手改 ✓ 备份 = 拷一个文件 ✓ grep 得出来 ✓ 没有迁移/连不上的问题 ✓
- 审计日志用 JSONL 追加 ✓(谁在什么时候对哪个目录做了什么)
- 磁盘用量:admin 页按需
walk目录算 ✓ 不维护缓存计数(省掉一整类不一致 bug ✓) - 什么时候才考虑上 SQLite:账号数上千、或需要历史趋势图 ✗ 现在远没到 ✓
5. 交付与部署形态
- 单静态二进制 + systemd unit ✓
- nginx 只做反代 + TLS ✓(证书交给 certbot)
- 不做容器 ✓(没有隔离需求,单二进制直接跑最省事 ✓)
- 认证:自带账号体系且开箱即用 ✓;管理端可关闭自带口令(
AUTH_MODE=sso),协议端点永远保留自带账号 ✓- admin 页:独立管理员账号
- client 页与 WebDAV 接口:同一套应用账号(一个应用一个账号一个目录 ✓ 这正是立项原因 ✓)
6. 命名
davbox —— 查重结果:GitHub 同名仓库最大 1★ ✓ npm 上的同名包是空壳(无正式版本)✓
(备选 cubby 498 个同名仓库、hutch 已有 876★ 项目在用 ✗ 都不用)