第 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_dotfiles | bool · 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 延伸阅读
- xrt 参考 · file — SendFile 与异步 IO 的底层能力
- xrt 参考 · path — 路径规范化与根锚定的实现基础