|  | <?xml version="1.0"?> | 
|  | <!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd"> | 
|  | <?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?> | 
|  | <!-- $LastChangedRevision: 1726578 $ --> | 
|  |  | 
|  | <!-- | 
|  | 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> | 
|  |  | 
|  | <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.</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> |