本文档介绍了 Caddy 的内容编码中间件系统,该系统使用 gzip、zstd 和 brotli 等算法提供 HTTP 响应的自动压缩。该系统根据客户端的 Accept-Encoding 头部处理内容协商,根据内容类型和大小阈值选择性地应用压缩,并支持提供预压缩文件。
有关可能利用预压缩文件的静态文件服务的信息,请参阅静态文件服务器。有关响应处理和中间件链的详细信息,请参阅HTTP 处理器。
内容编码系统作为 HTTP 中间件运行,它拦截响应并在适当时候应用压缩。该系统遵循 HTTP 内容协商和缓存标准。
来源:modules/caddyhttp/encode/encode.go153-179 modules/caddyhttp/encode/encode.go472-536 modules/caddyhttp/encode/encode.go301-348
该编码系统由多个关键接口和实现组成,它们协同工作以提供灵活的内容压缩。
来源:modules/caddyhttp/encode/encode.go42-58 modules/caddyhttp/encode/encode.go546-557 modules/caddyhttp/encode/gzip/gzip_precompressed.go12-28
该系统通过解析客户端的 Accept-Encoding 头部,并根据质量因子(q 值)和服务器偏好选择最佳可用编码来实施 HTTP 内容协商。
| 组件 | 目的 | 主要功能 |
|---|---|---|
AcceptedEncodings | 解析 Accept-Encoding 头部 | encode.go472-536 |
Prefer 字段 | 服务器端编码偏好 | encode.go48 |
| 质量因子 | 客户端偏好权重 | encode.go486-496 |
| WebSocket 检测 | 防止对 WS 握手进行编码 | encode.go504-507 |
选择算法
Prefer 配置的服务器偏好顺序来源:modules/caddyhttp/encode/encode.go472-536 modules/caddyhttp/encode/encode.go510-520
编码中间件仅压缩符合特定条件的响应,以避免压缩不适当的内容或违反 HTTP 语义。
响应仅在超过配置的最小长度时才会被压缩,以避免对小型响应产生压缩开销。
| 配置 | 默认值 | 目的 |
|---|---|---|
MinLength | 512 字节 | 压缩的最小响应大小 |
| Content-Length 头部 | 如果可用则检查 | 预检大小验证 |
| 动态大小调整 | 首次写入检查 | 运行时大小验证 |
该系统使用 ResponseMatcher 根据内容类型和状态码来确定哪些响应应该被压缩。
来源:modules/caddyhttp/encode/encode.go84-127 modules/caddyhttp/encode/encode.go266-268
该系统遵循 HTTP 缓存语义和 WebSocket 协议
Cache-Control: no-transform 的响应永远不会被编码Sec-WebSocket-Key 头部检测)永远不会被编码来源:modules/caddyhttp/encode/encode.go149-151 modules/caddyhttp/encode/encode.go504-507
该 responseWriter 类型包装了标准的 http.ResponseWriter,以便拦截响应数据并在适当时候应用压缩。
当应用压缩时,响应写入器会修改多个 HTTP 头部
| 标题 | 修改 | 目的 |
|---|---|---|
Content-Encoding | 设置为编码名称 | 表示已应用压缩 |
Content-Length | 移除 | 长度随压缩而变化 |
Vary | 添加 "Accept-Encoding" | 表示内容因编码而异 |
Accept-Ranges | 移除 | 范围与动态压缩不兼容 |
ETag | 附加编码后缀 | 区分编码变体 |
该系统实现了 RFC 9110 第 8.8.3.3 节关于内容编码的 ETag 处理
来源:modules/caddyhttp/encode/encode.go446-449 modules/caddyhttp/encode/encode.go168-174
编码系统提供了用于提供预压缩文件的接口,允许静态文件服务器提供预压缩内容,而无需运行时压缩开销。
该 Precompressed 接口定义了预压缩文件处理的方法
| 格式 | 模块 ID | 文件后缀 | Accept-Encoding |
|---|---|---|---|
| Gzip | http.precompressed.gzip | .gz | gzip |
| Zstandard | http.precompressed.zstd | .zst | zstd |
| Brotli | http.precompressed.br | .br | br |
来源:modules/caddyhttp/encode/gzip/gzip_precompressed.go12-28 modules/caddyhttp/encode/zstd/zstd_precompressed.go13-29 modules/caddyhttp/encode/brotli/brotli_precompressed.go13-32
Caddyfile 配置映射到以下 JSON 结构
来源:modules/caddyhttp/encode/caddyfile.go40-53 caddytest/integration/caddyfile_adapt/encode_options.caddyfiletest1-101