Apache 模块 mod_brotli

Description:在将内容交付给 Client 端之前,先通过 Brotli 对其进行压缩
Status:Extension
Module Identifier:brotli_module
Source File:mod_brotli.c
Compatibility:在版本 2.4.26 和更高版本中可用。

Summary

mod_brotli模块提供了BROTLI_COMPRESS输出过滤器,该过滤器允许使用 brotli 压缩格式对服务器的输出进行压缩,然后再通过网络将其发送到 Client 端。该模块使用位于https://github.com/google/brotli的 Brotli 库。

Sample Configurations

Compression and TLS

当 TLS 连接传输压缩数据时,某些 Web 应用程序容易受到信息泄露攻击。有关更多信息,请查看“ BREACH”攻击家族的详细信息。

这是压缩常见的基于文本的 Content Type 的简单配置。

仅压缩几种类型

AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/javascript

Enabling Compression

Compression and TLS

当 TLS 连接传输压缩数据时,某些 Web 应用程序容易受到信息泄露攻击。有关更多信息,请查看“ BREACH”攻击家族的详细信息。

Output Compression

压缩是由BROTLI_COMPRESS filter实现的。以下伪指令将启用对其所在容器中文档的压缩:

SetOutputFilter BROTLI_COMPRESS
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-brotli

通常,如果要将压缩限制为特定的 MIME 类型,则可以使用AddOutputFilterByType指令。这是仅对 Apache 文档的 html 文件启用压缩的示例:

<Directory "/your-server-root/manual">
    AddOutputFilterByType BROTLI_COMPRESS text/html
</Directory>

Note

BROTLI_COMPRESS过滤器始终插入在 PHP 或 SSI 之类的 RESOURCE 过滤器之后。它从不涉及内部子请求。

Note

通过SetEnv设置了一个环境变量no-brotli,即使 Client 端支持,该变量也将禁用针对特定请求的 brotli 压缩。

处理代理服务器

mod_brotli模块发送Vary: Accept-Encoding HTTP 响应 Headers,以警告代理应将缓存的响应仅发送给发送适当的Accept-Encoding请求 Headers 的 Client 端。这样可以防止将压缩的内容发送给无法理解的 Client 端。

如果您使用某些特殊的排除项,例如User-AgentHeaders,则必须手动配置VaryHeaders 的附加项,以向代理警告其他限制。例如,在BROTLI_COMPRESS过滤器的添加取决于User-Agent的典型配置中,应添加:

Header append Vary User-Agent

如果您对压缩的决定取决于请求 Headers(例如* HTTP 版本)以外的其他信息,则必须将VaryHeaders 设置为值*。这样可以防止兼容代理完全缓存。

Example

Header set Vary *

提供预压缩的内容

由于每次发出请求时mod_brotli都会重新压缩内容,因此可以通过预压缩内容并告诉 mod_brotli 无需重新压缩内容就可以提供一些性能优势。可以使用类似以下的配置来完成此操作:

<IfModule mod_headers.c>
    # Serve brotli compressed CSS files if they exist
    # and the client accepts brotli.
    RewriteCond "%{HTTP:Accept-encoding}" "br"
    RewriteCond "%{REQUEST_FILENAME}\.br" "-s"
    RewriteRule "^(.*)\.css"              "$1\.css\.br" [QSA]

    # Serve brotli compressed JS files if they exist
    # and the client accepts brotli.
    RewriteCond "%{HTTP:Accept-encoding}" "br"
    RewriteCond "%{REQUEST_FILENAME}\.br" "-s"
    RewriteRule "^(.*)\.js"               "$1\.js\.br" [QSA]

    # Serve correct content types, and prevent double compression.
    RewriteRule "\.css\.br$" "-" [T=text/css,E=no-brotli:1]
    RewriteRule "\.js\.br$"  "-" [T=text/javascript,E=no-brotli:1]

    <FilesMatch "(\.js\.br|\.css\.br)$">
      # Serve correct encoding type.
      Header append Content-Encoding br

      # Force proxies to cache brotli &
      # non-brotli css/js files separately.
      Header append Vary Accept-Encoding
    </FilesMatch>
</IfModule>

BrotliAlterETag Directive

Description:压缩期间如何修改传出的 ETag Headers
Syntax:BrotliAlterETag AddSuffix|NoChange|Remove
Default:BrotliAlterETag AddSuffix
Context:服务器配置,虚拟主机
Status:Extension
Module:mod_brotli

BrotliAlterETag指令指定在压缩响应时应如何更改 ETag hader。

  • AddSuffix

    • 将压缩方法追加到 ETag 的末尾,使压缩和未压缩的表示形式具有唯一的 ETag。在另一个动态压缩模块 mod_deflate 中,这是自 2.4.0 开始的默认设置。该设置防止将“ HTTP 未修改”(304)响应提供给对压缩内容的条件请求。
  • NoChange

    • 不要在压缩响应上更改 ETag。在另一个动态压缩模块 mod_deflate 中,这是 2.4.0 之前的默认设置。此设置不满足 HTTP/1.1 属性,即同一资源的所有表示形式都具有唯一的 ETag。
  • Remove

    • 从压缩响应中删除 ETag Headers。这防止了某些条件请求的发生,但避免了前面选项的缺点。

BrotliCompressionMaxInputBlock Directive

Description:最大 Importing 块大小
Syntax:BrotliCompressionMaxInputBlock value
Default:(automatic)
Context:服务器配置,虚拟主机
Status:Extension
Module:mod_brotli

BrotliCompressionMaxInputBlock指令指定最大 Importing 块大小在 16 到 24 之间,但要注意的是,更大的块大小需要更多的内存。

BrotliCompressionQuality Directive

Description:Compression quality
Syntax:BrotliCompressionQuality value
Default:BrotliCompressionQuality 5
Context:服务器配置,虚拟主机
Status:Extension
Module:mod_brotli

BrotliCompressionQuality伪指令指定压缩质量(0 到 11 之间的值)。质量值越高,压缩效果越好,但压缩速度也较慢。

BrotliCompressionWindow Directive

Description:Brotli 滑动压缩窗口大小
Syntax:BrotliCompressionWindow value
Default:BrotliCompressionWindow 18
Context:服务器配置,虚拟主机
Status:Extension
Module:mod_brotli

BrotliCompressionWindow指令指定 brotli 滑动压缩窗口的大小(介于 10 到 24 之间的值)。较大的窗口大小可以提高压缩质量,但需要更多的内存。

BrotliFilterNote Directive

Description:将压缩率放在 Logging 的 Comments 中
Syntax:BrotliFilterNote [type] notename
Context:服务器配置,虚拟主机
Status:Extension
Module:mod_brotli

BrotliFilterNote指令指定有关压缩率的 Comments 应附加到请求中。Comments 的名称是为指令指定的值。您可以通过将该值添加到access log来将该 Comments 用于统计目的。

Example

BrotliFilterNote ratio

LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' brotli
CustomLog "logs/brotli_log" brotli

如果要从日志中提取更准确的值,则可以使用 type 参数来指定作为日志记录留下的数据类型。类型可以是以下之一:

  • Input

    • 将过滤器 Importing 流的字节数存储在 Comments 中。
  • Output

    • 将过滤器输出流的字节数存储在 Comments 中。
  • Ratio

    • 将压缩率(output/input * 100)存储在笔记中。如果省略 type 参数,则这是默认设置。

因此,您可以这样记录它:

Accurate Logging

BrotliFilterNote Input instream
BrotliFilterNote Output outstream
BrotliFilterNote Ratio ratio

LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' brotli
CustomLog "logs/brotli_log" brotli

See also