菜单

内容编码

相关源文件

本文档介绍了 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

选择算法

  1. 解析 Accept-Encoding 头部以获取支持的编码和 q 因子
  2. 应用来自 Prefer 配置的服务器偏好顺序
  3. 按 q 因子(降序)然后按服务器偏好排序
  4. 返回可接受编码的有序列表

来源:modules/caddyhttp/encode/encode.go472-536 modules/caddyhttp/encode/encode.go510-520

内容过滤与响应匹配

编码中间件仅压缩符合特定条件的响应,以避免压缩不适当的内容或违反 HTTP 语义。

大小阈值

响应仅在超过配置的最小长度时才会被压缩,以避免对小型响应产生压缩开销。

配置默认值目的
MinLength512 字节压缩的最小响应大小
Content-Length 头部如果可用则检查预检大小验证
动态大小调整首次写入检查运行时大小验证

内容类型匹配

该系统使用 ResponseMatcher 根据内容类型和状态码来确定哪些响应应该被压缩。

来源:modules/caddyhttp/encode/encode.go84-127 modules/caddyhttp/encode/encode.go266-268

编码限制

该系统遵循 HTTP 缓存语义和 WebSocket 协议

  • 带有 Cache-Control: no-transform 的响应永远不会被编码
  • WebSocket 握手(由 Sec-WebSocket-Key 头部检测)永远不会被编码
  • WebSocket 连接只允许使用 identity 编码

来源: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附加编码后缀区分编码变体

ETag 处理

该系统实现了 RFC 9110 第 8.8.3.3 节关于内容编码的 ETag 处理

来源:modules/caddyhttp/encode/encode.go446-449 modules/caddyhttp/encode/encode.go168-174

预压缩文件支持

编码系统提供了用于提供预压缩文件的接口,允许静态文件服务器提供预压缩内容,而无需运行时压缩开销。

预压缩接口

Precompressed 接口定义了预压缩文件处理的方法

可用预压缩格式

格式模块 ID文件后缀Accept-Encoding
Gziphttp.precompressed.gzip.gzgzip
Zstandardhttp.precompressed.zstd.zstzstd
Brotlihttp.precompressed.br.brbr

来源: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 配置结构

Caddyfile 配置映射到以下 JSON 结构

来源:modules/caddyhttp/encode/caddyfile.go40-53 caddytest/integration/caddyfile_adapt/encode_options.caddyfiletest1-101