Files

WebDrop 服务端

.NET 10,NativeAOT。设计见 ../docs,接口契约见 ../docs/openapi.yaml。

结构

项目 职责
src/WebDrop.Core 领域类型、规则和业务逻辑(ChannelService、ShareService),不做 IO,只依赖抽象
src/WebDrop.Storage SQLite 存储(SqliteChannelStore)和磁盘 blob(DiskBlobStore)
src/WebDrop.Frontend 可选嵌入 Vite dist,提供静态文件、SPA fallback 与页面 CSP;不依赖业务层
src/WebDrop.Api Minimal API、WebSocket / SSE / 长轮询、订阅枢纽、后台清理、限流、安全头
tests/ Core.Tests(单元与服务层,真实 SQLite)、Api.Tests(真实 Kestrel 上的集成测试)

常用命令

dotnet test                                   # 全部测试
dotnet run --project src/WebDrop.Api          # 开发运行,默认 http://localhost:5000
npm --prefix ../web run build                 # 先构建前端时,dotnet publish 会自动嵌入 web/dist

# NativeAOT 发布(Windows 需要 vswhere.exe 在 PATH 里)
$env:PATH += ";${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer"
dotnet publish src/WebDrop.Api -c Release -r win-x64 -o out/win-x64
pwsh scripts/smoke.ps1 -Exe out/win-x64/webdrop.exe   # 对原生产物做端到端冒烟(含 WebSocket)
python3 scripts/smoke.py out/linux-x64/webdrop         # 跨平台版本,只用标准库,不含 WebSocket

配置

配置节 WebDrop,环境变量写法 WebDrop__DataDir、WebDrop__Captcha__Provider。完整默认值见 src/WebDrop.Api/appsettings.json。

键 默认 说明
DataDir data SQLite 数据库和 blob 目录
CorsOrigins 空 前端所在的源;前端托管在独立域名,必须列出,否则不发 CORS 头
TrustForwardedHeaders false 在反向代理之后开启,限流按真实 IP 分区
EnableHttp3 false 仅在 /info 里通告,服务进程不内置 QUIC
RequestsPerMinute / ChannelCreatesPerMinute 600 / 30 按 IP 的限流,只在内存里
ShareDraftTtlSeconds 86400 未完成分享草稿的保留时间
Captcha:Provider none 创建频道的验证码:none 或 cap。选 cap 时下面三项必填,缺失会在启动时报错
Captcha:ApiEndpoint 空 浏览器里 Cap widget 连接的地址,形如 https://cap.example.com/<site_key>/,经 /info 下发
Captcha:SiteverifyUrl 空 本服务调用 Cap 校验 token 的地址,形如 https://cap.example.com/<site_key>/siteverify,可以是内网地址
Captcha:Secret 空 Cap 站点密钥的 secret,只在服务端使用
Limits:* 见 ServerLimits 负载、帧数、频道字节数、成员人数上限、TTL 上限等

约束

  • 单实例部署:订阅枢纽在进程内,多实例需要换成外部发布订阅。
  • 日志不记录请求头、请求体、完整 URL;Hosting 诊断日志已关闭,避免频道 id 进入日志。
  • NativeAOT:不用 SignalR、EF Core、MVC、反射式 JSON;所有 AOT / 裁剪警告视为错误。
  • WebDrop.Frontend 只负责嵌入静态资源与 SPA fallback。Containerfile 自动构建 web/;单独发布 API 时,只有 web/dist 存在或指定 WebDropFrontendDist 后才包含前端。

验证码(Cap)

工作量证明不由本项目实现,交给 Cap。默认 Provider=none,适合开发和小型自托管。需要防刷时:

  1. 部署 Cap Standalone(官方是 Docker 容器,依赖 Redis/Valkey),建一个站点密钥。
  2. 配置 Captcha:Provider=cap、ApiEndpoint、SiteverifyUrl、Secret。
  3. 前端读取 /info 的 captcha.api_endpoint,用 Cap widget 求解后把 token 放进 X-WD-Cap 创建频道。

测试状态:服务端对 Cap 的调用只用一个假 Cap 服务(按其文档的 POST /<site_key>/siteverify、{secret, response} → {success} 实现)测过,尚未与真实的 Cap 联调。部署前请用真实实例跑一遍创建流程。Cap 不可用时创建频道会返回 503 captcha_unavailable(fail closed),不会放行。