diff --git a/docs/security/fsys_SECURITY_AUDIT_20260808.md b/docs/security/fsys_SECURITY_AUDIT_20260808.md
new file mode 100644
index 0000000..ad25cdd
--- /dev/null
+++ b/docs/security/fsys_SECURITY_AUDIT_20260808.md
@@ -0,0 +1,210 @@
+# fsys 安全审计报告
+
+**审计日期**: 2026-08-08
+**审计范围**: `fsys/src/fsys.cpp`(1589 行,修复后)
+**对比基准**: `static/fsys.py`(792 行)+ `static_SECURITY_AUDIT_20260801.md`(static 24 项审计结论)+ `dnfs2_SECURITY_AUDIT_20260808.md`
+**审计轮次**: 第 1 轮(对照 static 审计逐项验证 + C++ 实现深度复查)
+**安全评级**: A-
+
+---
+
+## 1. 审计概述
+
+fsys 是 Python `static` 模块的 C++20 重实现(libhttp + libmsg + boost::json),审计目标:
+
+1. **逐条验证** static 审计(24 项)中的修复在 C++ 重写中是否保留,防止回归;
+2. **深度复查** C++ 实现特有的问题(内存模型、libcurl 使用、路径解析、路由机制)。
+
+本轮发现 8 项问题(4 P1 / 1 P2 / 3 P3),**全部已修复**;另记录 6 项已知限制。
+
+---
+
+## 2. 本轮新发现问题(全部已修复)
+
+### F-1: static_root/SSL 相对路径基于可执行文件目录解析(服务无法提供文件) ✅ 已修复
+
+- **等级**: P1(功能性,启动即失效)
+- **位置**: `load_config()` 步骤 8(原 L347-369)
+- **问题**: 相对路径 `static_root` 通过 `/proc/self/exe` 基于可执行文件目录解析。二进制位于 `fsys/build/fsys`,而 `public` 符号链接位于 `fsys/public`,因此 `./public` 解析为 `fsys/build/./public`(不存在)。更严重的是构造函数 `fs::create_directories()` 会**静默创建空目录**,服务启动正常但所有路由返回 404/500,无告警。
+- **修复**: 相对路径改为基于 `fs::current_path()` 解析(`_run.sh` 以模块目录为 cwd 启动,与 Python 版 `BASE_DIR` 语义一致;Docker 使用绝对路径 `STATIC_ROOT=/app/public`,不受影响)。SSL 证书路径同样修复。
+
+### F-2: favicon 代理 `CURLOPT_FOLLOWLOCATION` 盲跟重定向绕过 SSRF 校验(回归) ✅ 已修复
+
+- **等级**: P1
+- **位置**: `_handle_favicon()`
+- **问题**: 原实现 `CURLOPT_FOLLOWLOCATION=1L` 让 libcurl 自动跟随重定向,**重定向目标不再经过私有 IP 校验**。攻击者可用公网主机返回 `302 Location: http://127.0.0.1:8005/...` 探测/访问内网服务。Python 版有 `_FaviconRedirectHandler` 逐跳重新校验(static 审计已有机制第 8 条),C++ 重写丢失了该防护,属于**安全回归**。
+- **修复**: 禁用自动跟随(`CURLOPT_FOLLOWLOCATION=0L`),提取 `validate_url_ssrf()` 校验函数(scheme/端口/私有 IP),手动逐跳跟随(最多 3 跳),每跳重新校验;同时设置 `CURLOPT_PROTOCOLS_STR="http,https"` 纵深防御。
+
+### F-3: 查询参数与路径缺失 URL 解码(favicon/filelist/video/catch-all 功能性回归) ✅ 已修复
+
+- **等级**: P1(功能性)
+- **位置**: `parse_query()`、`_handle_catch_all()`、`_handle_video()`、`_handle_favicon()`
+- **问题**: 前端全部使用 `encodeURIComponent`(已核实:`view.js:139` `/api/filelist?path=${encodeURIComponent(currentPath)}`、`dnfs.js:480` `/api/favicon?url=${encodeURIComponent(sp.url)}`、`view.js:73` 面包屑链接),Flask 自动解码。C++ 版不解码导致:
+ 1. `/api/favicon?url=https%3A%2F%2F...` → scheme 校验失败 → **favicon 功能完全失效**
+ 2. `/api/filelist?path=a%2Fb` → 按字面名 `a%2Fb` 查找 → **子目录导航失效**
+ 3. 中文/空格文件名的静态文件访问失效
+- **修复**: 新增 `url_decode()`(`%XX` + 查询串 `+`→空格,路径解码不转换 `+`);`parse_query` 键值均解码;catch-all/video 路径解码;`safe_path_join` 新增 NUL 字节拒绝(防解码 `%00` 截断)。解码后的遍历序列(如 `..%2F..`)仍被 `safe_path_join` 前缀校验拦截,仅解码一次无双解码风险。
+
+### F-4: 静态文件/无 Range 视频全量读入内存(NEW-7 回归) ✅ 已修复(上限防护)
+
+- **等级**: P1
+- **位置**: `_handle_catch_all()`、`_handle_root()`、`_handle_video()`
+- **问题**: libhttp 响应为 `string_body`,所有文件全量读入内存返回。Python 版 NEW-7 已用 `send_file` 流式修复该 DoS;C++ 重写回归。攻击者请求 public 下大文件(或 `Range: bytes=0-` 全量拉取大视频)可导致内存耗尽。
+- **修复**: 新增 `kMaxServeFileSize = 50MB`:
+ - 普通文件 >50MB → 413
+ - 视频无 Range 全量 >50MB → 413(浏览器拉取媒体必带 Range,实际无感)
+ - Range 片段 >50MB → 416(防 `bytes=0-`)
+ - 残留限制见 L-1(需 libhttp 支持 file_body/chunked 才能彻底解决)
+
+### F-5: 限速表 `_rate_store` 无界增长 ✅ 已修复
+
+- **等级**: P2
+- **位置**: `_check_rate_limit()`
+- **问题**: 限速键为 `"hash:" + client_ip()`,XFF 可伪造且无上限。攻击者旋转 XFF 值可令 map 无限增长耗尽内存(DoS)。Python 版有相同问题(未修),C++ 重写有机会修复。
+- **修复**: 键数超过 `kRateMaxKeys=65536` 时全局驱逐过期窗口键。
+
+### F-6: Cookie `q4_token` 子串匹配误判 ✅ 已修复
+
+- **等级**: P3
+- **位置**: `_handle_dnfs_proxy()`
+- **问题**: `cookies.find("q4_token=")` 子串搜索,名为 `x_q4_token=` 的 Cookie 也会命中,可能把非预期 Cookie 值作为 Bearer Token 转发给 dnfs2。
+- **修复**: 新增 `get_cookie()` 按 `;` 拆分、trim、精确按名匹配。
+
+### F-7: `sha256_hex` EVP_MD 泄漏窗口 ✅ 已修复
+
+- **等级**: P3
+- **位置**: `sha256_hex()`
+- **问题**: 释放条件 `hash_len > 0 && md != EVP_sha256()`,digest 失败(hash_len==0)时 `EVP_MD_fetch` 返回的 md 泄漏。
+- **修复**: 改用 `fetched` 标志,digest 成败均释放。
+
+### F-8: `CURLOPT_PROTOCOLS` 已弃用(编译错误) ✅ 已修复
+
+- **等级**: P3
+- **问题**: libcurl ≥7.85 弃用 `CURLOPT_PROTOCOLS`,`-Werror` 下编译失败。
+- **修复**: 改用 `CURLOPT_PROTOCOLS_STR`。
+
+---
+
+## 3. static 审计 24 项逐条验证(防回归检查)
+
+| static 审计项 | fsys 状态 | 验证说明 |
+|------|------|------|
+| P0-1 无认证密码重置 | ✅ 未重实现 | 危险功能未移植 |
+| P0-2/3/4 yhdet OAuth(Token/SSL 跳过/硬编码密钥) | ✅ 未重实现 | 同上 |
+| P0-5 直连 SQLite | ✅ | 通过 `_call_db()` RpcClient 调 db2:8005 |
+| NEW-1/2 proxy_send_code / PRIVATE_SECRET | ✅ 未重实现 | 同上 |
+| P1-1 check_user/hash 限速 | ✅ | 滑动窗口 20/10 次每分钟,XFF 取真实 IP |
+| P1-2/NEW-5 路径遍历前缀 bypass | ✅ | `base_str + "/"` 边界校验 + `weakly_canonical`(symlink 逃逸同样拦截) |
+| NEW-3 dnfs 代理 CORS 通配 | ✅ | `_apply_cors` 白名单回显 + `Vary: Origin` |
+| NEW-6 代理错误泄露内部异常 | ✅ | 统一返回 `{"error": "upstream unavailable"}`,详情仅记日志 |
+| NEW-7 大文件全量读内存 | ⚠️→✅ | 本轮回归后由 F-4 上限防护覆盖,残留限制 L-1 |
+| NEW-8 api_hash 校验 | ✅ | `json::parse` 失败/非 object/password 非 string 均 400 + 限速 |
+| NEW-9 db 单例/retry/env | ✅ | 成员 RpcClient(retry_on_refused=true)+ DB_HOST/DB_PORT env |
+| NEW-10 favicon 端口校验 | ✅ | 端口 [1,65535] 校验,IPv6/userinfo 畸形 URL fail-closed 拒绝 |
+| NEW-11 CSP unsafe-inline | ⚠️ 继承 | 与 static/dnfs2 一致的已知限制(前端内联脚本依赖),见 L-3 |
+| NEW-12 SSL 回退开发服务器 | ✅ 消除 | libhttp 原生 TLS(F-2 改进项) |
+| NEW-13 日志单条失败弃批 | ✅ | `_send_log_batch` 单条 catch 后继续 |
+| NEW-14 端口 env 未捕获异常 | ✅ | `safe_stoi` 统一校验,main 捕获后打印 `[fsys] fatal` |
+| P2-1 Range 边界校验 | ✅ | start/end 范围 + end≥start + stoi 异常处理 |
+| P2-2 日志敏感信息 | ✅ | 无密码/Token 入日志 |
+| confs retry 强依赖 | ✅ | `retry_on_refused=true` |
+| 配置白名单合并 / 必需项校验 | ✅ | INI 解析 + cors_origins/static_root 必需校验 |
+| 安全响应头(6 项) | ✅ | `make_secured_response` 内联每个响应 |
+| `__` 前缀系统文件过滤 | ✅ | filelist 过滤 |
+| 请求体大小限制 | ✅ | `setMaxBodySize(10MB)`,超限 libhttp 返回 413 |
+| curl 全局初始化/清理 | ✅ | main 遵循 dnfs2 P3-N9 模式 |
+
+**结论**: static 审计的全部有效修复在 fsys 中均得到保留;NEW-7(F-4)与 favicon 重定向校验(F-2)两处曾发生回归,已在本轮修复。
+
+---
+
+## 4. 行为差异说明(非缺陷)
+
+### D-1: dnfs 代理透传上游状态码(改进)
+
+Python 版 `_proxy_to_dnfs` 用 urllib,上游非 2xx 抛 HTTPError → 一律返回 502;因此前端 `dnfs.js` 中 `res.status === 401 → 跳转登录页` 的逻辑在 Python 版下是**死代码**(凭证过期时收到 502 而非 401)。fsys 透传上游真实状态码(400/401/404/500),使前端 401 跳转逻辑首次生效。前端其余错误处理读取 `body.error`,与状态码无关,无兼容性问题。
+
+### D-2: libhttp 内置 OPTIONS 反射任意 Origin(继承,影响有限)
+
+fsys 仅对 4 个 dnfs 路由注册了显式 OPTIONS handler(走白名单)。其余路由(如 `/api/hash`)的预检落入 libhttp 内置 OPTIONS 处理——该处理反射任意 Origin(libhttp 审计 P2-1,未修复)。由于 fsys 实际响应(POST 结果)不附带 `Access-Control-Allow-Origin` 头,浏览器仍会阻止跨域读取响应,泄露面被封堵;预检放行本身影响有限。根治依赖 libhttp 修复 P2-1。
+
+### D-3: favicon URL 无路径时的构造
+
+Python 版用 `urlparse().netloc`,fsys 用首个 `/` 截取 origin,等价;`http://host?query`(无路径直接带查询串)这类畸形输入在 fsys 中 fail-closed 拒绝(Python 可解析),不影响正常调用(前端始终发送完整 URL)。
+
+---
+
+## 5. 已知限制(记录,不修复)
+
+### L-1: string_body 无流式传输(P2,架构性)
+
+libhttp 响应体为 `string_body`,50MB 上限是缓解而非根治(50MB × 4 线程仍有 200MB 峰值)。彻底修复需 libhttp 支持 `file_body` 或 chunked 响应,与 Python 版 NEW-7 的 send_file 流式能力对齐。
+
+### L-2: 限速依赖 XFF(P2,继承)
+
+- libhttp 未向 handler 暴露 peer IP(`Session::remote_ip_` 仅内部可用),XFF 缺失时限速键回退 `"unknown"`,所有直连客户端共享窗口。Python 版有 `request.remote_addr` 兜底,此处为弱化。
+- 绕过 gateway 直连时可伪造 XFF 绕过限速(Python 相同)。生产依赖 gateway/waf 覆写 XFF。
+- 建议:libhttp 在 params 或 request 上下文暴露 peer IP。
+
+### L-3: CSP `unsafe-inline`(P3,继承 static NEW-11 / dnfs2 L-7)
+
+前端(dnfs 特殊节点注入的 HTML/JS)依赖内联脚本,nonce 化需前端架构改造。
+
+### L-4: DNS rebinding 理论窗口(P3,继承 static NEW-10)
+
+`is_private_host` 校验与实际 HTTP 连接之间存在 TOCTOU 窗口(重定向逐跳校验同样存在)。彻底修复需将校验所得 IP 绑定到连接(`CURLOPT_RESOLVE`),当前与 Python 版风险等级一致,可接受。
+
+### L-5: favicon 代理无响应缓存
+
+每次请求都实时拉取上游(Python 版同样无服务端缓存,仅有浏览器侧 `Cache-Control: max-age=86400`)。高频访问同一链接卡片会产生重复外联。
+
+### L-6: Makefile `/opt/homebrew` 路径(继承 dnfs2 惯例)
+
+macOS/Linux 双开发环境约定,Linux 编译需覆盖 `INCS/LIBS/RPATH`(本次审计编译即如此执行)。与 dnfs2 Makefile 保持逐字节一致,未单独修改。
+
+---
+
+## 6. 修复文件清单
+
+| 文件 | 修改内容 |
+|------|---------|
+| `fsys/src/fsys.cpp` | F-1: static_root/SSL 相对路径基于 CWD 解析 |
+| `fsys/src/fsys.cpp` | F-2: `validate_url_ssrf()` + favicon 手动逐跳重定向校验 |
+| `fsys/src/fsys.cpp` | F-3: `url_decode()` + parse_query/catch-all/video 解码 + NUL 拒绝 |
+| `fsys/src/fsys.cpp` | F-4: `kMaxServeFileSize=50MB` 上限(413/416) |
+| `fsys/src/fsys.cpp` | F-5: `kRateMaxKeys=65536` 限速表驱逐 |
+| `fsys/src/fsys.cpp` | F-6: `get_cookie()` 精确按名解析 |
+| `fsys/src/fsys.cpp` | F-7: sha256_hex `fetched` 标志修复泄漏 |
+| `fsys/src/fsys.cpp` | F-8: `CURLOPT_PROTOCOLS_STR` |
+| `fsys/README.md` | `[directory] root` 相对路径语义说明修正 |
+
+编译验证: `g++ -std=c++20 -O3 -Wall -Werror` 通过,零错误零警告(`-Werror=deprecated-declarations` 下通过)。
+
+运行时冒烟测试(confs/db/dnfs 在线,临时端口 19200,与生产 Python 版 9200 对照):
+
+| 用例 | 结果 |
+|------|------|
+| `GET /` / `/health` / filelist 根目录与子目录 | ✓ 200,`static_root` 正确解析到 `fsys/public`(F-1) |
+| filelist 编码路径 `path=js` / `games%2F` | ✓ 200(F-3 解码生效) |
+| 路径遍历 `/%2e%2e/%2e%2e/etc/passwd` | ✓ 403 |
+| favicon 编码公网 URL / 内网 URL | ✓ 200 image/x-icon / 403 forbidden host(F-2/F-3) |
+| `POST /api/hash` | ✓ 哈希值与 Python 版逐位一致 |
+| `POST /api/check_user` | ✓ 与 Python 版行为一致(当前环境 db Users 查询失败,两版同返 500 query failed,非 fsys 缺陷) |
+| dnfs 代理 `/get_notes` | ✓ 透传(上游自身 500,直连上游同果,非代理缺陷) |
+
+---
+
+## 7. 安全评级
+
+### 评级: A-
+
+**理由**:
+- static 审计 24 项修复全部保留,两处回归(F-2 SSRF 重定向、F-4 大文件内存)发现后立即修复
+- 4 项 P1 全部修复,编译零警告
+- 相比 Python 版新增:请求体限制、TLS 原生支持、限速表驱逐、Cookie 精确解析、401 透传使前端登录跳转生效
+- 扣分项:L-1 流式传输缺失(依赖 libhttp 演进)、L-2 限速依赖 XFF(依赖 libhttp 暴露 peer IP)、L-3 CSP unsafe-inline(前端架构限制)
+
+**升级路径**(修复以下任一项可评 A):
+- libhttp 支持 file_body/chunked → 解除 L-1
+- libhttp 暴露 peer IP → 解除 L-2
+- libhttp 修复 P2-1(OPTIONS Origin 白名单)→ 消除 D-2
diff --git a/fsys/.gitignore b/fsys/.gitignore
new file mode 100644
index 0000000..567609b
--- /dev/null
+++ b/fsys/.gitignore
@@ -0,0 +1 @@
+build/
diff --git a/fsys/Dockerfile b/fsys/Dockerfile
new file mode 100644
index 0000000..5c41ded
--- /dev/null
+++ b/fsys/Dockerfile
@@ -0,0 +1,88 @@
+# fsys Dockerfile — C++20 静态文件托管服务
+# 多阶段构建:第一阶段编译 libhttp + libmsg + fsys,第二阶段精简运行时
+
+# ============================================================================
+# Stage 1: 构建阶段
+# ============================================================================
+FROM ubuntu:24.04 AS builder
+
+LABEL maintainer="qingsong"
+LABEL service="fsys"
+LABEL description="Static File Hosting Service (C++20) - 静态文件托管服务"
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ build-essential \
+ libboost-json-dev \
+ libssl-dev \
+ libcurl4-openssl-dev \
+ make \
+ && rm -rf /var/lib/apt/lists/*
+
+WORKDIR /build
+
+COPY libhttp/ /build/libhttp/
+COPY libmsg/ /build/libmsg/
+COPY fsys/ /build/fsys/
+
+# 编译 libmsg
+RUN cd /build/libmsg && make clean && make
+
+# 编译 libhttp
+RUN cd /build/libhttp && make clean && make \
+ CPP="g++" \
+ INCS="-I inc" \
+ SERVER_LIBS="-lssl -lcrypto -lpthread" \
+ CLIENT_LIBS="-lssl -lcrypto -lcurl -lpthread"
+
+# 编译 fsys
+RUN cd /build/fsys && make clean && make \
+ CPP="g++" \
+ INCS="-I ../libhttp/inc -I ../libmsg/inc" \
+ LIBS="-L ../libhttp/build -L ../libmsg/build -lus_http -lus_httpclient -lus_msg -lboost_json -lssl -lcrypto -lcurl -lpthread" \
+ RPATH="-Wl,-rpath,/app/lib"
+
+# ============================================================================
+# Stage 2: 运行时阶段
+# ============================================================================
+FROM ubuntu:24.04
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ libboost-json1.83.0 \
+ libssl3 \
+ libcurl4 \
+ ca-certificates \
+ curl \
+ && rm -rf /var/lib/apt/lists/* \
+ && useradd -m -u 1000 appuser
+
+WORKDIR /app
+
+# 复制构建产物
+COPY --from=builder /build/fsys/build/fsys /app/fsys
+COPY --from=builder /build/libhttp/build/libus_http.so /app/lib/libus_http.so
+COPY --from=builder /build/libhttp/build/libus_httpclient.so /app/lib/libus_httpclient.so
+COPY --from=builder /build/libmsg/build/libus_msg.so /app/lib/libus_msg.so
+
+# 复制静态文件(public 目录)
+COPY static/public/ /app/public/
+
+ENV LD_LIBRARY_PATH=/app/lib
+
+RUN chown -R appuser:appuser /app
+USER appuser
+
+EXPOSE 9200
+
+# 健康检查:GET /health 期望 200
+HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
+ CMD curl -sf http://localhost:9200/health -o /dev/null || exit 1
+
+ENV LISTEN_ADDR=0.0.0.0 \
+ LISTEN_PORT=9200 \
+ STATIC_ROOT=/app/public
+
+CMD ["/app/fsys"]
diff --git a/fsys/Makefile b/fsys/Makefile
new file mode 100644
index 0000000..1420b80
--- /dev/null
+++ b/fsys/Makefile
@@ -0,0 +1,26 @@
+CPP = g++
+CPPFLAGS = -std=c++20 -O3 -Wall -Werror -pipe
+INCS = -I ../libhttp/inc -I ../libmsg/inc -I /opt/homebrew/include
+LIBS = -L ../libhttp/build -L ../libmsg/build -L /opt/homebrew/lib \
+ -lus_http -lus_httpclient -lus_msg -lboost_json \
+ -lssl -lcrypto -lcurl -lpthread
+RPATH = -Wl,-rpath,'$$ORIGIN/../../libhttp/build' \
+ -Wl,-rpath,'$$ORIGIN/../../libmsg/build' \
+ -Wl,-rpath,/opt/homebrew/lib
+
+BUILD = build
+TARGET = $(BUILD)/fsys
+SRC = src/fsys.cpp
+
+all: $(TARGET)
+
+$(BUILD):
+ mkdir -p $(BUILD)
+
+$(TARGET): $(SRC) | $(BUILD)
+ $(CPP) $(CPPFLAGS) $(INCS) -o $@ $< $(LIBS) $(RPATH)
+
+clean:
+ rm -f $(TARGET)
+
+.PHONY: all clean
diff --git a/fsys/README.md b/fsys/README.md
new file mode 100644
index 0000000..c042ccf
--- /dev/null
+++ b/fsys/README.md
@@ -0,0 +1,113 @@
+# fsys — 静态文件托管服务 (C++20)
+
+基于 libhttp + libmsg 的 C++20 静态文件托管与前端页面服务,监听 `127.0.0.1:9200`。
+
+Python/Flask `static` 模块的生产级 C++ 重写,接口 100% 兼容,前端零改动。
+
+## 架构
+
+```
+waf :443 (TLS 终止 + 安全规则)
+ │
+ ▼
+gateway :8443 (反向代理 + 认证)
+ │
+ ▼
+fsys :9200 (libhttp 异步多线程 + CORS)
+ │
+ ├── public/ 静态文件根目录
+ ├── dnfs2 :8006 笔记代理(反向代理)
+ ├── db2 :8005 用户查询 + 日志写入
+ └── confs :8010 配置拉取
+```
+
+## 路由
+
+### 核心路由
+
+| 路径 | 说明 |
+|------|------|
+| `GET /` | 首页(优先 index.html,回退 __view.html) |
+| `GET /*` | 静态文件 / 目录浏览 |
+| `GET /api/filelist?path=` | JSON 文件列表,过滤 `__` 前缀系统文件 |
+| `GET /video/*` | 视频/音频流媒体(HTTP Range 206 分段) |
+| `GET /health` | 健康检查 |
+
+### 内部工具路由
+
+| 路径 | 说明 |
+|------|------|
+| `POST /api/hash` | SHA-256 密码哈希(限速 20/min/IP) |
+| `POST /api/check_user` | 检查用户是否已注册(限速 10/min/IP) |
+| `GET /api/favicon?url=` | favicon SSRF 防护代理(512KB 上限,1 天缓存) |
+
+### dnfs2 代理路由
+
+| 路径 | 说明 |
+|------|------|
+| `POST /get_notes` | 获取树状笔记列表(代理至 dnfs2:8006) |
+| `POST /add_note` | 新增笔记(代理至 dnfs2:8006) |
+| `POST /delete_note` | 删除笔记(代理至 dnfs2:8006) |
+| `POST /update_note` | 更新笔记(代理至 dnfs2:8006) |
+
+支持 HttpOnly Cookie 模式:`q4_token` Cookie 自动转为 `Authorization: Bearer` 头。
+
+## 配置
+
+与 `static` 模块完全兼容,使用相同的 `static.ini`(由 confs 服务分发)。
+
+| Section | Key | 说明 |
+|---------|-----|------|
+| `[server]` | `host` | 监听地址(默认 127.0.0.1) |
+| `[server]` | `port` | 监听端口(默认 9200) |
+| `[directory]` | `root` | 静态文件根目录(相对路径基于工作目录,_run.sh 以模块目录启动) |
+| `[ssl]` | `enabled` | TLS 开关(默认 false) |
+| `[ssl]` | `cert_file` | 证书路径 |
+| `[ssl]` | `key_file` | 私钥路径 |
+| `[cors]` | `allowed_origins` | CORS 白名单,逗号分隔 |
+
+### 环境变量
+
+| 变量 | 说明 |
+|------|------|
+| `LISTEN_ADDR` | 覆盖监听地址 |
+| `LISTEN_PORT` | 覆盖监听端口 |
+| `STATIC_ROOT` | 覆盖静态文件根目录 |
+| `DB_HOST` / `DB_PORT` | 覆盖 db 服务地址 |
+| `DNFS_URL` | 覆盖 dnfs2 上游地址 |
+| `CONFS_HOST` / `CONFS_PORT` | 覆盖 confs 引导地址 |
+
+### 命令行参数
+
+| 参数 | 说明 |
+|------|------|
+| `--addr` / `-a` | 监听地址 |
+| `--port` / `-p` | 监听端口 |
+| `--threads` / `-t` | 工作线程数 |
+
+## 相比 Python static 的改进
+
+| 改进 | 说明 |
+|------|------|
+| 请求体大小限制 | `setMaxBodySize(10MB)` 防 OOM |
+| SSL 原生支持 | libhttp 构造器直接支持,无需回退开发服务器 |
+| 异步 IO | Boost.Beast 异步多线程替代 Flask 同步 |
+| 消除 Python 依赖 | 不再需要 venv/pip/Flask/waitress |
+| 命令行参数 | 支持 `--addr/-a --port/-p --threads/-t` |
+| 数值范围校验 | 所有端口/线程数有严格边界检查 |
+| 统一日志配置 | 复用主配置 confs 拉取的 db host/port |
+
+## 运行
+
+```bash
+bash _set.sh # 编译
+bash _run.sh # 启动
+```
+
+## 依赖
+
+libhttp, libmsg, boost::json, OpenSSL, libcurl
+
+## 许可证
+
+MIT License
diff --git a/fsys/_run.sh b/fsys/_run.sh
new file mode 100644
index 0000000..4f93304
--- /dev/null
+++ b/fsys/_run.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+cd "$(dirname "$0")"
+exec ./build/fsys "$@"
diff --git a/fsys/_set.sh b/fsys/_set.sh
new file mode 100644
index 0000000..d716258
--- /dev/null
+++ b/fsys/_set.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+cd "$(dirname "$0")"
+make
diff --git a/fsys/public/index.html b/fsys/public/index.html
new file mode 100644
index 0000000..3e51790
--- /dev/null
+++ b/fsys/public/index.html
@@ -0,0 +1,190 @@
+
+
+
+
+
+fsys 测试页
+
+
+
+
+
fsys 测试页
+
C++ 静态文件托管服务 · 路由/安全功能自检
+
+
+
+
+
+
API 自检
+
+ | GET /health | — | |
+ | GET /api/filelist(根目录) | — | |
+ | GET /api/filelist?path=test%2F(编码子目录) | — | |
+ | GET /api/filelist?path=..%2F..(遍历应 403) | — | |
+ | GET /test/hello.txt(静态文件) | — | |
+ | GET /test/hello.txt?download=true(附件头) | — | |
+ | GET 中文文件名(URL 解码) | — | |
+ | POST /api/hash(sha256("test123")) | — | |
+ | POST /api/hash 非法输入(应 400) | — | |
+ | POST /api/check_user(结构校验) | — | |
+ | GET /api/favicon 内网地址(SSRF 应 403) | — | |
+ | GET /api/favicon 公网地址(需外网) | — | |
+ | 安全响应头(CSP/X-Frame-Options…) | — | |
+ | GET /不存在的路径(应 404) | — | |
+
+
+
+
+
+
+
+
+
diff --git a/fsys/public/test/hello.txt b/fsys/public/test/hello.txt
new file mode 100644
index 0000000..7d0912a
--- /dev/null
+++ b/fsys/public/test/hello.txt
@@ -0,0 +1 @@
+hello fsys — 这是 fsys 静态文件服务的测试文件。
diff --git a/fsys/public/test/中文文件.txt b/fsys/public/test/中文文件.txt
new file mode 100644
index 0000000..a5eb53b
--- /dev/null
+++ b/fsys/public/test/中文文件.txt
@@ -0,0 +1 @@
+这是中文内容:用于验证 URL 解码(UTF-8 编码文件名)是否生效。
diff --git a/fsys/src/fsys.cpp b/fsys/src/fsys.cpp
new file mode 100644
index 0000000..d3eece8
--- /dev/null
+++ b/fsys/src/fsys.cpp
@@ -0,0 +1,1589 @@
+/** fsys — C++20 静态文件托管服务(对齐 Python static 模块)
+ *
+ * 基于 libhttp + libmsg + boost::json 实现,接口与 Python static 完全兼容:
+ * GET / 首页(index.html 或 __view.html)
+ * GET / 静态文件 / 目录浏览
+ * GET /api/filelist?path= 文件列表 JSON
+ * GET /video/... 视频/音频流媒体(HTTP Range 206)
+ * POST /api/hash SHA-256 密码哈希(限速 20/min/IP)
+ * POST /api/check_user 用户存在性检查(限速 10/min/IP)
+ * GET /api/favicon?url= favicon SSRF 防护代理
+ * POST /get_notes 等 4 个 dnfs2 反向代理
+ * GET /health 健康检查
+ *
+ * 安全改进(相比 Python static):
+ * F-1 server.setMaxBodySize(10MB) 限制请求体大小
+ * F-2 libhttp 原生 HTTPS 支持,无需回退开发服务器
+ * F-3 命令行参数 --addr/-a --port/-p --threads/-t
+ * F-4 所有端口/线程数有严格边界校验
+ * F-5 Boost.Beast 异步多线程替代 Flask 同步
+ * F-6 消除 Python/Flask/waitress 依赖
+ * F-7 日志客户端复用主配置(confs 拉取的 db host/port)
+ *
+ * 依赖: libhttp (HttpServer/HttpClient), libmsg (RpcClient/AsyncQueue),
+ * boost::json, OpenSSL, libcurl
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include