The configuration described so far works fine when the browser talks directly to the web server. The web server determines whether to compress the response based on Accept-Encoding. The browser caches the response, whether or not it has been compressed, based on other HTTP headers in the response such as Expires andCache-Control(see Chapter 3).
When the browser sends the request through a proxy it gets more complicated. Suppose that the first request to the proxy for a certain URL comes from a browser that does not support gzip. This is the first request to the proxy, so its cache is empty. The proxy forwards that request to the web server. The web server’s response is uncompressed. That uncompressed response is cached by the proxy and sent on to the browser. Now, suppose the second request to the proxy for the same URL comes from a browser that does support gzip. The proxy responds with the (uncompressed) contents in its cache, missing the opportunity to use gzip. The situation is worse if the sequence is reversed: when the first request is from a browser that supports gzip and the second request is from a browser that doesn’t. In this case, the proxy has a compressed version of the contents in its cache and serves that version to all subsequent browsers whether they support gzip or not.
The way around this problem is to add theVaryheader in the response from your web server. The web server tells the proxy to vary the cached responses based on one or more request headers. Because the decision to compress is based on theAccept-Encodingrequest header, it makes sense to includeAccept-Encodingin the server’sVaryresponse header.
This causes the proxy to cache multiple versions of the response, one for each value of theAccept-Encodingrequest header. In our previous example, the proxy would cache two versions of each response: the compressed content for whenAccept-Encodingisgzipand the uncompressed content for whenAccept-Encodingis not specified at all. When a browser hits the proxy with the request headerAccept-Encoding: gzipit receives the compressed response. Browsers without anAccept-Encodingrequest header receive the uncompressed response. By default,mod_gzipadds theVary: Accept Encodingheader to all responses to provoke the right behavior from the proxy. For more information aboutVary, visit http://www.w3.org/Protocols/ rfc2616/rfc2616-sec14.html#sec14.44.
Please check back next week for the conclusion to this article.
DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.