2 <!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd">
3 <?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
4 <!-- $LastChangedRevision$ -->
7 Licensed to the Apache Software Foundation (ASF) under one or more
8 contributor license agreements. See the NOTICE file distributed with
9 this work for additional information regarding copyright ownership.
10 The ASF licenses this file to You under the Apache License, Version 2.0
11 (the "License"); you may not use this file except in compliance with
12 the License. You may obtain a copy of the License at
14 http://www.apache.org/licenses/LICENSE-2.0
16 Unless required by applicable law or agreed to in writing, software
17 distributed under the License is distributed on an "AS IS" BASIS,
18 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 See the License for the specific language governing permissions and
20 limitations under the License.
23 <modulesynopsis metafile="mod_brotli.xml.meta">
25 <name>mod_brotli</name>
26 <description>Compress content via Brotli before it is delivered to the
28 <status>Extension</status>
29 <sourcefile>mod_brotli.c</sourcefile>
30 <identifier>brotli_module</identifier>
31 <compatibility>Available in version 2.4.26 and later.</compatibility>
33 <p>The <module>mod_brotli</module> module provides
34 the <code>BROTLI_COMPRESS</code> output filter that allows output from
35 your server to be compressed using the brotli compression format before being sent to the client over
36 the network. This module uses the Brotli library found at
37 <a href="https://github.com/google/brotli">https://github.com/google/brotli</a>.</p>
39 <seealso><a href="../filter.html">Filters</a></seealso>
41 <section id="recommended"><title>Sample Configurations</title>
42 <note type="warning"><title>Compression and TLS</title>
43 <p>Some web applications are vulnerable to an information disclosure
44 attack when a TLS connection carries compressed data. For more
45 information, review the details of the "BREACH" family of attacks.</p>
47 <p>This is a simple configuration that compresses common text-based content types.</p>
49 <example><title>Compress only a few types</title>
50 <highlight language="config">
51 AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/javascript
57 <section id="enable"><title>Enabling Compression</title>
58 <note type="warning"><title>Compression and TLS</title>
59 <p>Some web applications are vulnerable to an information disclosure
60 attack when a TLS connection carries compressed data. For more
61 information, review the details of the "BREACH" family of attacks.</p>
64 <section id="output"><title>Output Compression</title>
65 <p>Compression is implemented by the <code>BROTLI_COMPRESS</code>
66 <a href="../filter.html">filter</a>. The following directive
67 will enable compression for documents in the container where it
70 <highlight language="config">
71 SetOutputFilter BROTLI_COMPRESS
72 SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-brotli
75 <p>If you want to restrict the compression to particular MIME types
76 in general, you may use the <directive module="mod_filter"
77 >AddOutputFilterByType</directive> directive. Here is an example of
78 enabling compression only for the html files of the Apache
81 <highlight language="config">
82 <Directory "/your-server-root/manual">
83 AddOutputFilterByType BROTLI_COMPRESS text/html
87 <note><title>Note</title>
88 The <code>BROTLI_COMPRESS</code> filter is always inserted after RESOURCE
89 filters like PHP or SSI. It never touches internal subrequests.
91 <note><title>Note</title>
92 There is an environment variable <code>no-brotli</code>,
93 set via <directive module="mod_env">SetEnv</directive>, which
94 will disable brotli compression for a particular request, even if
95 it is supported by the client.
102 <section id="proxies"><title>Dealing with proxy servers</title>
104 <p>The <module>mod_brotli</module> module sends a <code>Vary:
105 Accept-Encoding</code> HTTP response header to alert proxies that
106 a cached response should be sent only to clients that send the
107 appropriate <code>Accept-Encoding</code> request header. This
108 prevents compressed content from being sent to a client that will
109 not understand it.</p>
111 <p>If you use some special exclusions dependent
112 on, for example, the <code>User-Agent</code> header, you must
113 manually configure an addition to the <code>Vary</code> header
114 to alert proxies of the additional restrictions. For example,
115 in a typical configuration where the addition of the <code>BROTLI_COMPRESS</code>
116 filter depends on the <code>User-Agent</code>, you should add:</p>
118 <highlight language="config">
119 Header append Vary User-Agent
122 <p>If your decision about compression depends on other information
123 than request headers (<em>e.g.</em> HTTP version), you have to set the
124 <code>Vary</code> header to the value <code>*</code>. This prevents
125 compliant proxies from caching entirely.</p>
127 <example><title>Example</title>
128 <highlight language="config">
134 <section id="precompressed"><title>Serving pre-compressed
137 <p>Since <module>mod_brotli</module> re-compresses content each
138 time a request is made, some performance benefit can be derived by
139 pre-compressing the content and telling mod_brotli to serve them
140 without re-compressing them. This may be accomplished using a
141 configuration like the following:</p>
143 <highlight language="config">
144 <IfModule mod_headers.c>
145 # Serve brotli compressed CSS files if they exist
146 # and the client accepts brotli.
147 RewriteCond "%{HTTP:Accept-encoding}" "br"
148 RewriteCond "%{REQUEST_FILENAME}\.br" "-s"
149 RewriteRule "^(.*)\.css" "$1\.css\.br" [QSA]
151 # Serve brotli compressed JS files if they exist
152 # and the client accepts brotli.
153 RewriteCond "%{HTTP:Accept-encoding}" "br"
154 RewriteCond "%{REQUEST_FILENAME}\.br" "-s"
155 RewriteRule "^(.*)\.js" "$1\.js\.br" [QSA]
158 # Serve correct content types, and prevent double compression.
159 RewriteRule "\.css\.br$" "-" [T=text/css,E=no-brotli:1]
160 RewriteRule "\.js\.br$" "-" [T=text/javascript,E=no-brotli:1]
163 <FilesMatch "(\.js\.br|\.css\.br)$">
164 # Serve correct encoding type.
165 Header append Content-Encoding br
167 # Force proxies to cache brotli &
168 # non-brotli css/js files separately.
169 Header append Vary Accept-Encoding
177 <name>BrotliFilterNote</name>
178 <description>Places the compression ratio in a note for logging</description>
179 <syntax>BrotliFilterNote [<var>type</var>] <var>notename</var></syntax>
180 <contextlist><context>server config</context><context>virtual host</context>
184 <p>The <directive>BrotliFilterNote</directive> directive
185 specifies that a note about compression ratios should be attached
186 to the request. The name of the note is the value specified for
187 the directive. You can use that note for statistical purposes by
188 adding the value to your <a href="../logs.html#accesslog"
191 <example><title>Example</title>
192 <highlight language="config">
193 BrotliFilterNote ratio
195 LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' brotli
196 CustomLog "logs/brotli_log" brotli
200 <p>If you want to extract more accurate values from your logs, you
201 can use the <var>type</var> argument to specify the type of data
202 left as a note for logging. <var>type</var> can be one of:</p>
205 <dt><code>Input</code></dt>
206 <dd>Store the byte count of the filter's input stream in the note.</dd>
208 <dt><code>Output</code></dt>
209 <dd>Store the byte count of the filter's output stream in the note.</dd>
211 <dt><code>Ratio</code></dt>
212 <dd>Store the compression ratio (<code>output/input * 100</code>)
213 in the note. This is the default, if the <var>type</var> argument
217 <p>Thus you may log it this way:</p>
219 <example><title>Accurate Logging</title>
220 <highlight language="config">
221 BrotliFilterNote Input instream
222 BrotliFilterNote Output outstream
223 BrotliFilterNote Ratio ratio
225 LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' brotli
226 CustomLog "logs/brotli_log" brotli
230 <seealso><module>mod_log_config</module></seealso>
234 <name>BrotliCompressionQuality</name>
235 <description>Compression quality</description>
236 <syntax>BrotliCompressionQuality <var>value</var></syntax>
237 <default>BrotliCompressionQuality 5</default>
238 <contextlist><context>server config</context><context>virtual host</context>
242 <p>The <directive>BrotliCompressionQuality</directive> directive specifies
243 the compression quality (a value between 0 and 11). Higher quality values
244 result in better, but also slower compression.
250 <name>BrotliCompressionWindow</name>
251 <description>Brotli sliding compression window size</description>
252 <syntax>BrotliCompressionWindow <var>value</var></syntax>
253 <default>BrotliCompressionWindow 18</default>
254 <contextlist><context>server config</context><context>virtual host</context>
258 <p>The <directive>BrotliCompressionWindow</directive> directive specifies the
259 brotli sliding compression window size (a value between 10 and 24). Larger
260 window sizes can improve compression quality, but require more memory.</p>
266 <name>BrotliCompressionMaxInputBlock</name>
267 <description>Maximum input block size</description>
268 <syntax>BrotliCompressionMaxInputBlock <var>value</var></syntax>
269 <default>(automatic)</default>
270 <contextlist><context>server config</context><context>virtual host</context>
274 <p>The <directive>BrotliCompressionMaxInputBlock</directive> directive specifies
275 the maximum input block size between 16 and 24, with the caveat that
276 larger block sizes require more memory.</p>
281 <name>BrotliAlterETag</name>
282 <description>How the outgoing ETag header should be modified during compression</description>
283 <syntax>BrotliAlterETag AddSuffix|NoChange|Remove</syntax>
284 <default>BrotliAlterETag AddSuffix</default>
285 <contextlist><context>server config</context><context>virtual host</context>
289 <p>The <directive>BrotliAlterETag</directive> directive specifies
290 how the ETag hader should be altered when a response is compressed.</p>
293 <dd><p>Append the compression method onto the end of the ETag, causing
294 compressed and uncompressed representations to have unique ETags.
295 In another dynamic compression module, mod_deflate, this has been
296 the default since 2.4.0. This setting prevents serving "HTTP Not
297 Modified" (304) responses to conditional requests for compressed
300 <dd><p>Don't change the ETag on a compressed response. In another dynamic
301 compression module, mod_deflate, this has been the default prior to
302 2.4.0. This setting does not satisfy the HTTP/1.1 property that all
303 representations of the same resource have unique ETags. </p></dd>
305 <dd><p>Remove the ETag header from compressed responses. This prevents
306 some conditional requests from being possible, but avoids the
307 shortcomings of the preceding options. </p></dd>