| <?xml version="1.0"?> |
| <!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd"> |
| <?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?> |
| <!-- $LastChangedRevision$ --> |
| |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| <modulesynopsis metafile="mod_brotli.xml.meta"> |
| |
| <name>mod_brotli</name> |
| <description>Compress content via Brotli before it is delivered to the |
| client</description> |
| <status>Extension</status> |
| <sourcefile>mod_brotli.c</sourcefile> |
| <identifier>brotli_module</identifier> |
| <compatibility>Available in version 2.4.26 and later.</compatibility> |
| <summary> |
| <p>The <module>mod_brotli</module> module provides |
| the <code>BROTLI_COMPRESS</code> output filter that allows output from |
| your server to be compressed using the brotli compression format before being sent to the client over |
| the network. This module uses the Brotli library found at |
| <a href="https://github.com/google/brotli">https://github.com/google/brotli</a>.</p> |
| </summary> |
| <seealso><a href="../filter.html">Filters</a></seealso> |
| |
| <section id="recommended"><title>Sample Configurations</title> |
| <note type="warning"><title>Compression and TLS</title> |
| <p>Some web applications are vulnerable to an information disclosure |
| attack when a TLS connection carries compressed data. For more |
| information, review the details of the "BREACH" family of attacks.</p> |
| </note> |
| <p>This is a simple configuration that compresses common text-based content types.</p> |
| |
| <example><title>Compress only a few types</title> |
| <highlight language="config"> |
| AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/javascript |
| </highlight> |
| </example> |
| |
| </section> |
| |
| <section id="enable"><title>Enabling Compression</title> |
| <note type="warning"><title>Compression and TLS</title> |
| <p>Some web applications are vulnerable to an information disclosure |
| attack when a TLS connection carries compressed data. For more |
| information, review the details of the "BREACH" family of attacks.</p> |
| </note> |
| |
| <section id="output"><title>Output Compression</title> |
| <p>Compression is implemented by the <code>BROTLI_COMPRESS</code> |
| <a href="../filter.html">filter</a>. The following directive |
| will enable compression for documents in the container where it |
| is placed:</p> |
| |
| <highlight language="config"> |
| SetOutputFilter BROTLI_COMPRESS |
| SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-brotli |
| </highlight> |
| |
| <p>If you want to restrict the compression to particular MIME types |
| in general, you may use the <directive module="mod_filter" |
| >AddOutputFilterByType</directive> directive. Here is an example of |
| enabling compression only for the html files of the Apache |
| documentation:</p> |
| |
| <highlight language="config"> |
| <Directory "/your-server-root/manual"> |
| AddOutputFilterByType BROTLI_COMPRESS text/html |
| </Directory> |
| </highlight> |
| |
| <note><title>Note</title> |
| The <code>BROTLI_COMPRESS</code> filter is always inserted after RESOURCE |
| filters like PHP or SSI. It never touches internal subrequests. |
| </note> |
| <note><title>Note</title> |
| There is an environment variable <code>no-brotli</code>, |
| set via <directive module="mod_env">SetEnv</directive>, which |
| will disable brotli compression for a particular request, even if |
| it is supported by the client. |
| </note> |
| |
| </section> |
| |
| </section> |
| |
| <section id="proxies"><title>Dealing with proxy servers</title> |
| |
| <p>The <module>mod_brotli</module> module sends a <code>Vary: |
| Accept-Encoding</code> HTTP response header to alert proxies that |
| a cached response should be sent only to clients that send the |
| appropriate <code>Accept-Encoding</code> request header. This |
| prevents compressed content from being sent to a client that will |
| not understand it.</p> |
| |
| <p>If you use some special exclusions dependent |
| on, for example, the <code>User-Agent</code> header, you must |
| manually configure an addition to the <code>Vary</code> header |
| to alert proxies of the additional restrictions. For example, |
| in a typical configuration where the addition of the <code>BROTLI_COMPRESS</code> |
| filter depends on the <code>User-Agent</code>, you should add:</p> |
| |
| <highlight language="config"> |
| Header append Vary User-Agent |
| </highlight> |
| |
| <p>If your decision about compression depends on other information |
| than request headers (<em>e.g.</em> HTTP version), you have to set the |
| <code>Vary</code> header to the value <code>*</code>. This prevents |
| compliant proxies from caching entirely.</p> |
| |
| <example><title>Example</title> |
| <highlight language="config"> |
| Header set Vary * |
| </highlight> |
| </example> |
| </section> |
| |
| <section id="precompressed"><title>Serving pre-compressed |
| content</title> |
| |
| <p>Since <module>mod_brotli</module> re-compresses content each |
| time a request is made, some performance benefit can be derived by |
| pre-compressing the content and telling mod_brotli to serve them |
| without re-compressing them. This may be accomplished using a |
| configuration like the following:</p> |
| |
| <highlight language="config"> |
| <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> |
| </highlight> |
| |
| </section> |
| |
| <directivesynopsis> |
| <name>BrotliFilterNote</name> |
| <description>Places the compression ratio in a note for logging</description> |
| <syntax>BrotliFilterNote [<var>type</var>] <var>notename</var></syntax> |
| <contextlist><context>server config</context><context>virtual host</context> |
| </contextlist> |
| |
| <usage> |
| <p>The <directive>BrotliFilterNote</directive> directive |
| specifies that a note about compression ratios should be attached |
| to the request. The name of the note is the value specified for |
| the directive. You can use that note for statistical purposes by |
| adding the value to your <a href="../logs.html#accesslog" |
| >access log</a>.</p> |
| |
| <example><title>Example</title> |
| <highlight language="config"> |
| BrotliFilterNote ratio |
| |
| LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' brotli |
| CustomLog "logs/brotli_log" brotli |
| </highlight> |
| </example> |
| |
| <p>If you want to extract more accurate values from your logs, you |
| can use the <var>type</var> argument to specify the type of data |
| left as a note for logging. <var>type</var> can be one of:</p> |
| |
| <dl> |
| <dt><code>Input</code></dt> |
| <dd>Store the byte count of the filter's input stream in the note.</dd> |
| |
| <dt><code>Output</code></dt> |
| <dd>Store the byte count of the filter's output stream in the note.</dd> |
| |
| <dt><code>Ratio</code></dt> |
| <dd>Store the compression ratio (<code>output/input * 100</code>) |
| in the note. This is the default, if the <var>type</var> argument |
| is omitted.</dd> |
| </dl> |
| |
| <p>Thus you may log it this way:</p> |
| |
| <example><title>Accurate Logging</title> |
| <highlight language="config"> |
| BrotliFilterNote Input instream |
| BrotliFilterNote Output outstream |
| BrotliFilterNote Ratio ratio |
| |
| LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' brotli |
| CustomLog "logs/brotli_log" brotli |
| </highlight> |
| </example> |
| </usage> |
| <seealso><module>mod_log_config</module></seealso> |
| </directivesynopsis> |
| |
| <directivesynopsis> |
| <name>BrotliCompressionQuality</name> |
| <description>Compression quality</description> |
| <syntax>BrotliCompressionQuality <var>value</var></syntax> |
| <default>BrotliCompressionQuality 5</default> |
| <contextlist><context>server config</context><context>virtual host</context> |
| </contextlist> |
| |
| <usage> |
| <p>The <directive>BrotliCompressionQuality</directive> directive specifies |
| the compression quality (a value between 0 and 11). Higher quality values |
| result in better, but also slower compression. |
| </p> |
| </usage> |
| </directivesynopsis> |
| |
| <directivesynopsis> |
| <name>BrotliCompressionWindow</name> |
| <description>Brotli sliding compression window size</description> |
| <syntax>BrotliCompressionWindow <var>value</var></syntax> |
| <default>BrotliCompressionWindow 18</default> |
| <contextlist><context>server config</context><context>virtual host</context> |
| </contextlist> |
| |
| <usage> |
| <p>The <directive>BrotliCompressionWindow</directive> directive specifies the |
| brotli sliding compression window size (a value between 10 and 24). Larger |
| window sizes can improve compression quality, but require more memory.</p> |
| </usage> |
| </directivesynopsis> |
| |
| <directivesynopsis> |
| |
| <name>BrotliCompressionMaxInputBlock</name> |
| <description>Maximum input block size</description> |
| <syntax>BrotliCompressionMaxInputBlock <var>value</var></syntax> |
| <default>(automatic)</default> |
| <contextlist><context>server config</context><context>virtual host</context> |
| </contextlist> |
| |
| <usage> |
| <p>The <directive>BrotliCompressionMaxInputBlock</directive> directive specifies |
| the maximum input block size between 16 and 24, with the caveat that |
| larger block sizes require more memory.</p> |
| </usage> |
| </directivesynopsis> |
| |
| <directivesynopsis> |
| <name>BrotliAlterETag</name> |
| <description>How the outgoing ETag header should be modified during compression</description> |
| <syntax>BrotliAlterETag AddSuffix|NoChange|Remove</syntax> |
| <default>BrotliAlterETag AddSuffix</default> |
| <contextlist><context>server config</context><context>virtual host</context> |
| </contextlist> |
| |
| <usage> |
| <p>The <directive>BrotliAlterETag</directive> directive specifies |
| how the ETag hader should be altered when a response is compressed.</p> |
| <dl> |
| <dt>AddSuffix</dt> |
| <dd><p>Append the compression method onto the end of the ETag, causing |
| compressed and uncompressed representations to have unique ETags. |
| In another dynamic compression module, mod_deflate, this has been |
| the default since 2.4.0. This setting prevents serving "HTTP Not |
| Modified" (304) responses to conditional requests for compressed |
| content.</p></dd> |
| <dt>NoChange</dt> |
| <dd><p>Don't change the ETag on a compressed response. In another dynamic |
| compression module, mod_deflate, this has been the default prior to |
| 2.4.0. This setting does not satisfy the HTTP/1.1 property that all |
| representations of the same resource have unique ETags. </p></dd> |
| <dt>Remove</dt> |
| <dd><p>Remove the ETag header from compressed responses. This prevents |
| some conditional requests from being possible, but avoids the |
| shortcomings of the preceding options. </p></dd> |
| </dl> |
| </usage> |
| </directivesynopsis> |
| |
| </modulesynopsis> |