8

I want Apache to send static files gzip'ed over the wire, but also want Apache to not always gzip them over and over again. So I thought if it wouldn't be possible to deliver an .gz file if it exists. This set-up:

File structure:

static/
|
|--- style.css
|
\--- style.css.gz

And the following in an .htaccess:

mod_rewrite rule:

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

And this setting:

AddEncoding x-gzip .gz

Actually, this works insofar as the .gz file is sent instead of the .css, if the request goes to /static/style.css. The problem is only, that the file is delivered as "application/x-gzip" and not as "text/css". Using mod_rewrite's T flag doesn't alter this. Neither does an explicit

AddType text/css .css

Has anyone an idea, how I could achieve the desired behaviour? Or is it unnecessary for some reason I didn't reckon?

EDIT: There is an additional difficulty: Sending the original file to clients without gzip support. Has anyone an idea how this could work?

Boldewyn
  • 239
  • 4
  • 13
  • I'm amazed this isn't way more obvious, as it seems crazy to have a web server that doesn't do this. I think IIS has a system to cache gzipped copies of static files on first access. mod_deflate doesn't mention such a feature. – rjmunro Nov 11 '09 at 12:54
  • apache's mod_deflate docs have their own example now: http://httpd.apache.org/docs/2.4/mod/mod_deflate.html#precompressed – cweiske Aug 10 '15 at 06:41

2 Answers2

5

A solution for sending the correct version to browsers that don't accept gzip would be something along the lines of:

RewriteCond %{HTTP:Accept-Encoding} !gzip
...your rules here...

Also, there is another way to change the type, namely:

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

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

HTH.

Sam Halicke
  • 6,122
  • 1
  • 24
  • 35
  • Cool, thanks! Are there docs for the %{HTTP:...} thingy? I didn't see any mentioning of it in the RewriteCond section of Apache 2.2. The FilesMatch was another idea I had but I thought it more verbose. Since both rules need to fire up the regexp engine, there should be no real difference. – Boldewyn Oct 27 '09 at 07:34
  • OK, found the docs. http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html I just skipped the interesting part. – Boldewyn Oct 27 '09 at 08:05
  • This isn't a huge problem, but reading that config, if someone manually fetched the .css.gz file, they would get the text/css, when they should get the application/x-gzip type. – rjmunro Nov 11 '09 at 12:56
  • Why the ! before gzip on the Accept-Encoding line? Surely that's the opposite of what you need? – rjmunro Nov 11 '09 at 13:39
  • I was thinking the same, it makes sense to have the `RewriteCond` only match when the client _does_ accept gzip encoding. – David Z Apr 11 '10 at 21:56
3

Ah, it seems I found a solution: The T flag does not work if set on the same rule, but it sure does, if you spend it a rule of its own:

RewriteCond %{REQUEST_FILENAME}.gz -s
RewriteRule ^(.+) $1.gz

RewriteRule \.css\.gz$ - [T=text/css]
RewriteRule \.js\.gz$ - [T=text/javascript]

Still I would like to hear others' solutions and opinions.

Boldewyn
  • 239
  • 4
  • 13