How to configure mod_deflate to serve gzipped assets prepared with assets:precompile
Asked Answered
Y

1

11

When running the assets:precompile rake task, gzipped versions of your app's assets are created. According to the Rails guide for the asset pipeline, you can configure your web server (in my case Apache 2.2) to serve these precompressed files instead of having the web server do the work.

What I can't figure out is how to get mod_deflate configured so that these files are served instead of being double-compressed and then served?

I have mod_deflate enabled via httpd.conf:

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

And I've converted the code on the rails guide to go into the .htaccess in public/assets:

# Some browsers still send conditional-GET requests if there's a
# Last-Modified header or an ETag header even if they haven't
# reached the expiry date sent in the Expires header.

Header unset Last-Modified
Header unset ETag
FileETag None

# RFC says only cache for 1 year

ExpiresActive On
ExpiresDefault "access plus 1 year"

# Serve gzipped versions instead of requiring Apache to do the work

RewriteEngine on
RewriteCond %{REQUEST_FILENAME}.gz -s
RewriteRule ^(.+) $1.gz [L]

# without it, Content-Type will be "application/x-gzip"

<FilesMatch .*\.css.gz>
    ForceType text/css
</FilesMatch>

<FilesMatch .*\.js.gz>
    ForceType text/javascript
</FilesMatch>

Any ideas how to set this up properly?

Yirinec answered 22/9, 2011 at 4:16 Comment(0)
S
25

First, you don't want mod_deflate to operate here. So in your assets .htaccess file add:

SetEnv no-gzip

This should turn off mod_deflate for your assets.

Second, I hate to disagree with the rails folks, but I think there are a couple deficiencies in their assets .htaccess recipe. The top part is fine but for RewriteEngine and beyond I'd have:

RewriteEngine on
# Make sure the browser supports gzip encoding before we send it
RewriteCond %{HTTP:Accept-Encoding} \b(x-)?gzip\b
RewriteCond %{REQUEST_URI} .*\.(css|js)
RewriteCond %{REQUEST_FILENAME}.gz -s
RewriteRule ^(.+) $1.gz [L]

# without it, Content-Type will be "application/x-gzip"
# also add a content-encoding header to tell the browser to decompress

<FilesMatch \.css\.gz$>
    ForceType text/css
    Header set Content-Encoding gzip
</FilesMatch>

<FilesMatch \.js\.gz$>
    ForceType application/javascript
    Header set Content-Encoding gzip
</FilesMatch>
Squeaky answered 22/9, 2011 at 6:58 Comment(4)
Small comment - if this is not in .htaccess, it NEEDS to be in Directory section, otherwise -s will not work.Windcheater
Also, you probably should recommend the use of application/javascript instead of text/javascript. See RFC4329 on Scripting Media Types.Frohne
i had to do <IfModule mod_mime.c> AddEncoding gzip .gz </IfModule> otherwise goodBeery
Sprockets > 3.4 now compiles assets as .gz files. Having this code in your .htaccess file when using sprockets > 3.4 will prevent browser from reading compiled css and js, so using this solution is unnecessary.Runthrough

© 2022 - 2024 — McMap. All rights reserved.