tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rainer Jung <>
Subject Re: Serving gz files in DefaultServlet (Re: r1531115, BZ 54095)
Date Tue, 15 Oct 2013 18:59:23 GMT
On 15.10.2013 18:43, Christopher Schultz wrote:

> It's also worth pointing out that what has been implemented for Tomcat
> is a serious pain in the neck to do in httpd. Basically, to get it to
> work as expected in httpd, you need several animal sacrifices and a fair
> amount of arcane words to get it done. At this point, I have the animal
> part done but my pronunciation must be off because I still don't have it
> working properly.

It seems I sacrificed the right animals. Here's an old recipe of mine
once done for Apache 2.2. Might be a bit easier in 2.4 using the more
powerful expressions:


1) mod_rewrite checks, whether the browser accepts gzip encoded
responses (RewriteCond using Accept-Encoding header from the request)

2) If "yes", check whether the URL indicates that we do have pre
compressed content on disk

3) If both are "yes", then add a .gz in front of the file suffix,
rewrite URI and remember the decision in an env var. Not adding .gz at
the end of the file name is important to let Apache still set the
correct Content-Type header from the original and unchanged file ending.

4) Finally use mod_headers to set the response Content-Encoding header
to "gzip" (if we find that the env var is set).

5) Caches will be informed by the Vary response header that there was a
content "negiotiation" going on (without mod_negotiation). This is done
by mod_rewrite automatically, it adds "Accept-Encoding" to the Vary header.

Example config:

# This needs mod_rewrite and mod_headers
# loaded as modules.

# Make static content available.
# Not needed if already mounted elsewhere.

Alias /static /my/path/to/static

# Activate mod_rewrite and debug logging.
# Not needed if mod_rewrite is already
# activated for this VHost elsewhere.

RewriteEngine On
RewriteLog "|/path/to/bin/rotatelogs /oath/to/rewrite_log 43200"
# Only for debugging
RewriteLogLevel 255

# Flip in compressed content if allowed.
# Assumes all the compressed files are on disk
# having the correct names:
# something.css -> something.gz.css
# something.js -> something.gz.js

# 1) Check whether browser accepts "gzip" encoding
RewriteCond %{HTTP:Accept-Encoding} gzip
# 2) Check whether request belongs to our
#    static URLs and has the right suffix
#    If yes, add ".gz" to URL before existing suffix
#    and remember this in our custom environment variable.
RewriteRule (/static/.*)\.(css|js)$ $1.gz.$2 [E=gz:1]

# Fix returned encoding header, the file was gzipped.
Header set Content-Encoding gzip env=gz

# Notes:
# - Be careful when introducing loops for rewrite rules:
#   The new .gz.js etc. file would again match the rule
#   leading to unterminated recursion.
#   Make regexp more precise in that case (not allowing the .gz.)
#   to match again.
# - Content-Type header is OK, because file suffix hasn't changed.
#   This would not work for files without suffix, because then
#   we end up with a ".gz" suffix!
# - Vary header is automatically extended with "Accept-Encoding"
#   by mod_rewrite because of using the "Accept-Encoding" header
#   in the RewriteCond
# - Old-style "Accept-Encoding: x-gzip" in request also works.
#   The "gzip" is a sub pattern match (not anchored).
# Open Questions:
# - Is there any interoperability issue when mod_deflate is
#   activated in addition (double compress or similar).
#   If so, try to set env var "no-gzip" to deactivate mod_deflate
#   for those requests.

Finally a simple script to add the pre-compressed content to the disk:

for suffix in css js
for file in `find $CONTENT_DIR -type f -name "*.$suffix" -a ! -name
gzfile=`echo $file | sed -e 's#\.'$suffix'#.gz.'$suffix'#'`
gzip --best -c $file > $gzfile
chmod 644 $gzfile
echo === $file $gzfile ===
ls -ld $file $gzfile

Or similar.



To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message