Monthly Archives: October 2008

Fun with Apache’s mod_rewrite

Part of my duties over at Cobi involve taking care of some web applications we built for our clients. We based those on top of Linux, Apache, MySQL and PHP (the so-called LAMP platform.)

We use Apache’s deflate module to automatically compress the sometimes huge web pages that get sent to the browsers in order to save bandwidth, and gain speed.

Then the need arose to leave some of the pages uncompressed.

It looked quite easy, all is needed after all is to set the Apache’s internal variable no-gzip each time we need to skip the compression step.

Because the URI’s for those uncompressed requests do not follow a particular pattern, I thought that adding a “no-gzip” parameter to the query string and configuring Apache to set (with the help of the module setenvif) the internal variable no-gzip wherever it would encounter it would be enough.

But I was wrong. You can’t do that. Well, at least not with mod_setenvif, because you can’t use the query string with the SetEnvIf directive.

Take #2, I devised that I would then put my “no-gzip” string inside the request URI itself, even if it smelled like a kludge, and then SetEnvIf would be able to see it and do its job.

But it didn’t work either! Because, we happen to also use the rewrite module, with which we rewrite all URI’s so that the web application’s FrontController gets launched for each request. And it seems that mod_rewrite gets to rewrite the request URI before mod_setenvif gets to touch it.

So mod_setenvif was always seeing the FrontController’s URI, without my little “no-gzip” addition, and compression could not be disabled.

So back to my first idea with a “no-gzip” at the beginning of the query string, but with a twist: it is now mod_rewrite, not mod_setenvif which is setting Apache’s no-gzip internal variable:

RewriteCond %{QUERY_STRING} ^no-gzip
RewriteRule ^(.*)$ $1 [NS,E=no-gzip:1,E=dont-vary:1]

Note: it didn’t work until the variable got an actual value assigned. In other words, E=no-gzip didn’t work, but E=no-gzip:1 did.