How to host static content pre-compressed in apache? How to host static content pre-compressed in apache? apache apache

How to host static content pre-compressed in apache?


This is how i fixed once the same problem.

Add new types in .htaccess:

AddEncoding gzip .jsgz .cssgz .htmlgz .datagzAddType application/javascript .jsgzAddType text/css .cssgzAddType text/html .htmlgz       AddType text/plain .datagz

This was done this way because AddType instruction didn't accept extensions in the form .html.gz.

Then modify your rewrite rule:

RewriteRule ^(.+)\.(html|css|js|data)$ $1.$2gz [L] 

And finally rename your files. Remove dots from .html.gz, .js.gz and so on.

The full .htaccess would look like this:

AddEncoding gzip .jsgz .cssgz .htmlgz .datagzAddType application/x-javascript .jsgzAddType text/css .cssgzAddType text/html .htmlgz       AddType text/plain .datagzRewriteEngine on # If client accepts compressed files RewriteCond %{HTTP:Accept-Encoding} gzip # and if compressed file exists RewriteCond %{REQUEST_FILENAME}gz -f # send .html.gz instead of .html RewriteRule ^(.+)\.(html|css|js|data)$ $1.$2gz [L] 


The first question you should ask yourself is, is there any point in doing this? Do you notice too high cpu load and/or performance difference because of this? My guess would be that you are probably not running into this problem :)

Regardless though, there are multiple ways of fixing your problem.

  1. Probably the best option for you, use a CDN. They are designed for fast delivery of static files and will make it fast for people in a different geographical area as well as people close to your server. Also, in my experience CDN's are usually much cheaper than your own bandwidth will be.

  2. Use Nginx. For hosting static files much faster and has support for pre generating static content like you are doing right now. It will automatically detect if there's a .gz file and serve that instead when needed.

  3. Use one of the Apache cache mechanisms like mod_mem_cache or mod_disk_cache to make sure that every regularly used file will be in cache. Tutorial: http://webdirect.no/linux/apache-caching-with-gzip-enabled/

  4. Use a caching proxy like Varnish in front of it, these type of servers have a much smarter caching mechanism and will actually cache the files that matter most.

For your current version however, something like this (untested) should do the trick:

RewriteEngine On    RewriteCond %{HTTP:Accept-encoding} gzipRewriteCond %{REQUEST_FILENAME}\.gz -sRewriteRule ^(.*)\.(html|css|js|data) $1\.$2\.gz [QSA]# Prevent double gzip and give the correct mime-typeRewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1,E=FORCE_GZIP]RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1,E=FORCE_GZIP]RewriteRule \.html\.gz$ - [T=text/html,E=no-gzip:1,E=FORCE_GZIP]RewriteRule \.data\.gz$ - [T=text/plain,E=no-gzip:1,E=FORCE_GZIP]Header set Content-Encoding gzip env=FORCE_GZIP


The accepted answer seems quite painful. Wolph's answer seems better, but still requires separate configuration for each file extension and lacks support for more advanced negotiation (q-values, status 406, TCN, etc.). Rather than implementing content negotiation yourself using mod_rewrite, you may want to consider using mod_negotiation as discussed in this question. Copying my answer from there:

Options +MultiViewsRemoveType .gzAddEncoding gzip .gz<FilesMatch ".+\.tar\.gz$">    RemoveEncoding .gz    # Note:  Can use application/x-gzip for backwards-compatibility    AddType application/gzip .gz</FilesMatch>

This has the added bonus of working for all .gz files rather than only explicitly-configured ones and being easily extended for brotli or other encodings.

It does have one major drawback, since only requests for files which do not exist are negotiated a file named foo.js would make requests for /foo.js (but not /foo) return the uncompressed version. This can be avoided using François Marier's solution of renaming uncompressed files with a double extension, so foo.js is deployed as foo.js.js.