<p>This is a sample configuration for the impatient. But please take
the time and read the sections below for a detailed description!</p>
- <div class="example"><p><code>
+ <div class="example"><h3>Compress only a few types</h3><p><code>
+ AddOutputFilterByType DEFLATE text/html text/plain text/xml
+ </code></p></div>
+
+ <div class="example"><h3>Compress everything except images</h3><p><code>
<Location /><br />
<span class="indent">
- # insert filter<br />
+ # Insert filter<br />
SetOutputFilter DEFLATE<br />
<br />
# Netscape 4.x has some problems...<br />
# Netscape 4.06-4.08 have some more problems<br />
BrowserMatch ^Mozilla/4\.0[678] no-gzip<br />
<br />
- # fix identity<br />
+ # MSIE masquerades as Netscape, but it is fine<br />
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html<br />
<br />
- # don't bother:<br />
+ # Don't compress images<br />
SetEnvIfNoCase Request_URI \<br />
<span class="indent">
\.(?:gif|jpe?g|png)$ no-gzip dont-vary<br />
</span>
<br />
- # be verbose about configuration<br />
+ # Make sure proxies don't deliver the wrong content<br />
Header append Vary User-Agent env=!dont-vary<br />
</span>
</Location>
</code></p></div>
- <p>Note, that gzip compression of binary files (<em>e.g.</em> images)
- usually has only little effect. Therefore in the example above we use
- an exclusion list of some file types. Alternatively you may use a
- positive list using <code class="directive"><a href="../mod/mod_mime.html#addoutputfilter">AddOutputFilter</a></code> or <code class="directive"><a href="../mod/core.html#addoutputfilterbytype">AddOutputFilterByType</a></code> instead of the <code class="directive"><a href="../mod/core.html#setoutputfilter">SetOutputFilter</a></code> directive.</p>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div><div class="section"><h2><a name="enable" id="enable">Enabling Compression</a></h2>
<h3><a name="output" id="output">Output Compression</a></h3>
<p>At first we probe for a <code>User-Agent</code> string that
indicates a Netscape Navigator version of 4.x. These versions
- have some big problems to decompress content types different
- from <code>text/html</code>. The versions 4.06, 4.07 and 4.08 have
- also sometimes problems to decompress html files. Thus, we
- completely turn off the deflate filter for them.</p>
+ cannot handle compression of types other than
+ <code>text/html</code>. The versions 4.06, 4.07 and 4.08 also
+ have problems with decompressing html files. Thus, we completely
+ turn off the deflate filter for them.</p>
<p>The third <code class="directive"><a href="../mod/mod_setenvif.html#browsermatch">BrowserMatch</a></code>
directive fixes the guessed identity of the user agent, because
</Location>
</code></p></div>
- <p>Now if a request contains a <code>Content-Encoding: gzip</code>
- header, the body will be automatically decompressed. Ordinary
- browsers usually don't have the ability to gzip e.g. <code>POST</code>
- request bodies. However, some special applications actually do
- support request compression, for instance <a href="http://www.webdav.org">WebDAV</a> clients.</p>
+ <p>Now if a request contains a <code>Content-Encoding:
+ gzip</code> header, the body will be automatically decompressed.
+ Few browsers have the ability to gzip request bodies. However,
+ some special applications actually do support request
+ compression, for instance some <a href="http://www.webdav.org">WebDAV</a> clients.</p>
<div class="warning"><h3>Note on Content-Length</h3>
<p>If you evaluate the request body yourself, <em>don't trust
- the <code>Content-Length</code> header!</em> For example, a
- wide-spread code to read the request body in perl is:</p>
-
- <div class="example"><p><code>
- # WRONG!<br />
- if (($len = $ENV{'CONTENT_LENGTH'}) > 0) {<br />
- <span class="indent">
- read(STDIN, $body, $len);<br />
- </span>
- }
- </code></p></div>
-
- <p>Since the Content-Length header reflects the length of the
+ the <code>Content-Length</code> header!</em>
+ The Content-Length header reflects the length of the
incoming data from the client and <em>not</em> the byte count of
- the decompressed data, you would read too less and cut off the
- stream.</p>
-
- <p>Thus, if you want to slurp the whole request body, use for
- example:</p>
-
- <div class="example"><p><code>
- {<br />
- <span class="indent">
- local $/; # undef input record separator<br />
- $body = <STDIN>;<br />
- </span>
- }
- </code></p></div>
+ the decompressed data stream.</p>
</div>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div><div class="section"><h2><a name="proxies" id="proxies">Dealing with proxy servers</a></h2>
- <p>Since the <code>DEFLATE</code> output filter actually performs a
- kind of <a href="../content-negotiation.html">content negotiation</a>,
- you should take care of caching proxy servers. In order to prevent a
- proxy cache from delivering the wrong data (<em>e.g.</em> gzip
- compressed data to a client which doesn't send an appropriate
- <code>Accept-Encoding</code> header), the origin server
- (<em>i.e.</em> you) has to indicate the negotiation parameters in the
- <code>Vary</code> response header.</p>
- <p>If the <code>DEFLATE</code> filter is involved in the request, the
- following header will be set:</p>
+ <p>The <code class="module"><a href="../mod/mod_deflate.html">mod_deflate</a></code> 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>
- <div class="example"><p><code>
- Vary: Accept-Encoding
- </code></p></div>
-
- <p>A HTTP compiliant proxy now delivers the cached data to any client,
- which sends the <em>same</em> <code>Accept-Encoding</code> header as
- the client, which did the initial request that was cached.</p>
-
- <p>Fine. But what happens, if you use some special exclusions dependant
- on, say the <code>User-Agent</code> header? The proxy server doesn't
- know anything about your server configuration, thus you have to tell
- him, what you're doing. You have to use the <code class="module"><a href="../mod/mod_headers.html">mod_headers</a></code>
- module to add appropriate values to the <code>Vary</code> header, for
- example:</p>
+ <p>If you use some special exclusions dependant
+ 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>DEFLATE</code>
+ filter depends on the <code>User-Agent</code>, you should add:</p>
<div class="example"><p><code>
Header append Vary User-Agent
</code></p></div>
- <p>would result in the following response header:</p>
-
- <div class="example"><p><code>
- Vary: Accept-Encoding,User-Agent
- </code></p></div>
-
<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
- documents from caching by HTTP compiliant proxies at all.</p>
+ compliant proxies from caching entirely.</p>
<div class="example"><h3>Example</h3><p><code>
Header set Vary *
<p>This is a sample configuration for the impatient. But please take
the time and read the sections below for a detailed description!</p>
- <example>
+ <example><title>Compress only a few types</title>
+ AddOutputFilterByType DEFLATE text/html text/plain text/xml
+ </example>
+
+ <example><title>Compress everything except images</title>
<Location /><br />
<indent>
- # insert filter<br />
+ # Insert filter<br />
SetOutputFilter DEFLATE<br />
<br />
# Netscape 4.x has some problems...<br />
# Netscape 4.06-4.08 have some more problems<br />
BrowserMatch ^Mozilla/4\.0[678] no-gzip<br />
<br />
- # fix identity<br />
+ # MSIE masquerades as Netscape, but it is fine<br />
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html<br />
<br />
- # don't bother:<br />
+ # Don't compress images<br />
SetEnvIfNoCase Request_URI \<br />
<indent>
\.(?:gif|jpe?g|png)$ no-gzip dont-vary<br />
</indent>
<br />
- # be verbose about configuration<br />
+ # Make sure proxies don't deliver the wrong content<br />
Header append Vary User-Agent env=!dont-vary<br />
</indent>
</Location>
</example>
- <p>Note, that gzip compression of binary files (<em>e.g.</em> images)
- usually has only little effect. Therefore in the example above we use
- an exclusion list of some file types. Alternatively you may use a
- positive list using <directive module="mod_mime"
- >AddOutputFilter</directive> or <directive module="core"
- >AddOutputFilterByType</directive> instead of the <directive
- module="core">SetOutputFilter</directive> directive.</p>
</section>
<section id="enable"><title>Enabling Compression</title>
<p>At first we probe for a <code>User-Agent</code> string that
indicates a Netscape Navigator version of 4.x. These versions
- have some big problems to decompress content types different
- from <code>text/html</code>. The versions 4.06, 4.07 and 4.08 have
- also sometimes problems to decompress html files. Thus, we
- completely turn off the deflate filter for them.</p>
+ cannot handle compression of types other than
+ <code>text/html</code>. The versions 4.06, 4.07 and 4.08 also
+ have problems with decompressing html files. Thus, we completely
+ turn off the deflate filter for them.</p>
<p>The third <directive module="mod_setenvif">BrowserMatch</directive>
directive fixes the guessed identity of the user agent, because
</Location>
</example>
- <p>Now if a request contains a <code>Content-Encoding: gzip</code>
- header, the body will be automatically decompressed. Ordinary
- browsers usually don't have the ability to gzip e.g. <code>POST</code>
- request bodies. However, some special applications actually do
- support request compression, for instance <a
+ <p>Now if a request contains a <code>Content-Encoding:
+ gzip</code> header, the body will be automatically decompressed.
+ Few browsers have the ability to gzip request bodies. However,
+ some special applications actually do support request
+ compression, for instance some <a
href="http://www.webdav.org">WebDAV</a> clients.</p>
<note type="warning"><title>Note on Content-Length</title>
<p>If you evaluate the request body yourself, <em>don't trust
- the <code>Content-Length</code> header!</em> For example, a
- wide-spread code to read the request body in perl is:</p>
-
- <example>
- # WRONG!<br />
- if (($len = $ENV{'CONTENT_LENGTH'}) > 0) {<br />
- <indent>
- read(STDIN, $body, $len);<br />
- </indent>
- }
- </example>
-
- <p>Since the Content-Length header reflects the length of the
+ the <code>Content-Length</code> header!</em>
+ The Content-Length header reflects the length of the
incoming data from the client and <em>not</em> the byte count of
- the decompressed data, you would read too less and cut off the
- stream.</p>
-
- <p>Thus, if you want to slurp the whole request body, use for
- example:</p>
-
- <example>
- {<br />
- <indent>
- local $/; # undef input record separator<br />
- $body = <STDIN>;<br />
- </indent>
- }
- </example>
+ the decompressed data stream.</p>
</note>
</section>
</section>
<section id="proxies"><title>Dealing with proxy servers</title>
- <p>Since the <code>DEFLATE</code> output filter actually performs a
- kind of <a href="../content-negotiation.html">content negotiation</a>,
- you should take care of caching proxy servers. In order to prevent a
- proxy cache from delivering the wrong data (<em>e.g.</em> gzip
- compressed data to a client which doesn't send an appropriate
- <code>Accept-Encoding</code> header), the origin server
- (<em>i.e.</em> you) has to indicate the negotiation parameters in the
- <code>Vary</code> response header.</p>
-
- <p>If the <code>DEFLATE</code> filter is involved in the request, the
- following header will be set:</p>
-
- <example>
- Vary: Accept-Encoding
- </example>
- <p>A HTTP compiliant proxy now delivers the cached data to any client,
- which sends the <em>same</em> <code>Accept-Encoding</code> header as
- the client, which did the initial request that was cached.</p>
+ <p>The <module>mod_deflate</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>Fine. But what happens, if you use some special exclusions dependant
- on, say the <code>User-Agent</code> header? The proxy server doesn't
- know anything about your server configuration, thus you have to tell
- him, what you're doing. You have to use the <module>mod_headers</module>
- module to add appropriate values to the <code>Vary</code> header, for
- example:</p>
+ <p>If you use some special exclusions dependant
+ 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>DEFLATE</code>
+ filter depends on the <code>User-Agent</code>, you should add:</p>
<example>
Header append Vary User-Agent
</example>
- <p>would result in the following response header:</p>
-
- <example>
- Vary: Accept-Encoding,User-Agent
- </example>
-
<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
- documents from caching by HTTP compiliant proxies at all.</p>
+ compliant proxies from caching entirely.</p>
<example><title>Example</title>
Header set Vary *