第 10 章 / 共 51 章
卷二 · 配置与服务装配

静态层四旋钮与穿越防御

XS_FALLBACK 之后接手的就是静态层。它默认安全、默认快——四个 host 级旋钮足够覆盖绝大多数静态站点需求,而它的穿越防御在测试套件里有八个向量的看护。

本章导读

站位:静态层是"脚本优先、静态兜底"组合的后半。本章讲它的行为边界与四个旋钮;安全敏感读者重点读 10.4 的八向量。

10.1 引入

Web 应用的资源大头通常是静态的:前端产物、图片、字体。给静态资源写代码是浪费,用外置静态服务器又破坏"单文件部署"。XServer 的答案是一个内建的静态层:脚本没处理的 GET/HEAD 落进来,按 host 的 path 找文件——你一行代码不写,就有了一个安全的静态服务器。

10.2 静态层行为

  • 方法:GET 取内容,HEAD 只发头;其他方法不属于静态层语义
  • 路径:percent-decode 后规范化;目录请求按 index 数组逐个回落(默认 index.html)
  • 传输:SendFile 512KB 分块;TLS 下 64KB 明文泵(含 AGAIN/重入合并)——大文件背压在 func_test 有 4MiB 跨多轮的实测用例
  • MIME:18 种内建类型映射
  • 错误页:未配自定义页时用内置极简页

10.3 四旋钮(host 级 Custom)

静态层旋钮示例
"host_default": {
    "name": "app",
    "path": "wwwroot",
    "static": {
        "headers": {                       /* ≤8 字段;禁 8 种保留头 */
            "X-Frame-Options": "DENY",
            "Cache-Control": "public, max-age=3600"
        },
        "index": ["index.html", "home.html"],  /* 逐个回落 */
        "error_pages": { "404": "404.html", "500": "5xx.html" },
        "deny_dotfiles": true              /* 默认 true,恒拒点开头文件 */
    }
}
旋钮约束效果
static.headers≤8 字段;Transfer-Encoding / Connection 等 8 种保留头禁入(fail-fast)每个静态响应附带头。装配期预渲染成字段数组——请求路径只做 memcpy,零字符串处理
static.index字符串数组目录索引候选,按序回落
static.error_pages键 400–599;值相对 path对应状态码改用自定义错误页(文件存在才生效)
static.deny_dotfilesbool · true点开头文件恒拒——即使它在常规路径上

10.4 穿越防御八向量

静态层的红线:URL 永远走不出 path。func_test 用八个向量持续看护这条红线,全部应得到 403/404 而非文件内容:

GET /../secret → 拒 GET /..%2Fsecret → 拒 GET /%2e%2e/secret → 拒 GET /%2E%2E/secret → 拒 /* 百分号大小写 */ GET //../secret → 拒 GET /..%5Csecret → 拒 /* 反斜杠 */ GET /%00secret → 拒 symlink 出根 → 拒

实现要点:percent-decode 先于路径规范化执行,所以编码绕过不存在;deny_dotfiles 是叠加层(穿越尝试里带点文件双重命中);符号链接出根被根锚定拒绝。

10.5 契约

  • 边界线:静态层只服务 GET/HEAD,只在 host path 内,点开头文件默认恒拒。
  • 性能线:headers 装配期预渲染——请求路径零字符串处理,这是它可以承受高并发的关键设计。
  • 回退线:自定义错误页缺文件时回内置页,不会 500。

常见错误

headers 里放了 Content-Length
症状
启动失败:static headers 含保留头。
原因
Content-Length / Transfer-Encoding / Connection 等 8 种头由协议层管理,配置覆盖会破坏报文正确性——所以是 fail-fast 而不是运行期覆盖。
error_pages 键写成 "404.html"
症状
启动失败:error_pages 键越界。
原因
键是状态码(400–599 的数字串),值才是页面路径。写反或写非状态码都 fail-fast。

编程练习

基础自定义 404

给 demo 配一个 404.html 并在 error_pages 注册,访问不存在路径验证。

验收:404 状态码 + 自定义页面内容;删掉文件后回内置页。
进阶八向量全测

在 wwwroot 外放一个 secret.txt,用 10.4 的八个向量逐个尝试读取。

验收:八个向量无一返回文件内容;记录各自的状态码。
挑战安全头基线

为静态站配置一组安全响应头(CSP、X-Content-Type-Options、Referrer-Policy…),并验证预渲染路径的零开销设计(对比无 headers 配置的压测差异应可忽略)。

验收:所有静态响应带头;两组压测 RPS 差 < 2%。

小结

要点结论
触发XS_FALLBACK 的 GET/HEAD 落入静态层
四旋钮headers(预渲染)/ index / error_pages / deny_dotfiles
防御decode 先于规范化;八向量测试看护;symlink 锚定
传输SendFile 512KB 分块;TLS 64KB 明文泵;18 种 MIME
本章涉及的 API 参考
xrt 延伸阅读