Setting Apache environment variables with mod_rewrite
Apache’s mod_rewrite module is most commonly used to generate clean URLs, by covertly “rewriting” incoming paths to different internal paths. (Drupal rewrites /some/url
as index.php?q=some/url
and works off the querystring, for example.) It can also be used to overtly redirect users with the same kind of rules.
But mod_rewrite’s flexibility allows it to be used for a whole lot more than simple URL handling. Regex patterns can be tested to set environment variables, for example (the kind retrieved with PHP’s
This functionality is documented reasonably well at Apache.org; see the "Documentation" section at the bottom.
Here are some examples I’m using. They’re all wrapped in:
<IfModule mod_rewrite.c> RewriteEngine On ... </IfModule>
This sets environment variables for each server environment:
## set env vars for domains ## dash indicates no subst ## '.*' (any string) is critical!! thanks http://www.askapache.com/htaccess/crazy-advanced-mod_rewrite-tutorial.html # siteenv = local, live, dev RewriteCond %{SERVER_NAME} ben.local RewriteRule .* - [E=siteenv:local] RewriteCond %{SERVER_NAME} ^benbuck.net$ [OR] RewriteCond %{SERVER_NAME} ^benbuckman.net$ RewriteRule .* - [E=siteenv:live] RewriteCond %{SERVER_NAME} ^dev.benbuck.net$ RewriteRule .* - [E=siteenv:dev]
Uncomment this for debugging:
## stop all following rules on local (for debugging) ## RewriteCond %{ENV:siteenv} local ## RewriteRule .* - [L]
This rule redirects tech.benbuck.net to benbuckman.net/tech. It excludes my local and dev sites, redirects ([R]
), and stops checking for other rules ([L]
):
# tech home RewriteCond %{SERVER_NAME} ^tech.benbuck RewriteCond %{ENV:siteenv} !local RewriteCond %{ENV:siteenv} !dev RewriteRule ^$ http://benbuckman.net/tech [R,L]
This powers the "shortcut" URLs which I use to tweet my posts. !-f
and !-d
exclude valid file and directory paths, respectively.
RewriteCond %{SERVER_NAME} ^benbuck.net$ [OR] RewriteCond %{SERVER_NAME} ^benbuckman.net$ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^b/([0-9]*)/?$ http://benbuckman.net/node/$1 [L]
On a multi-site setup, RewriteRules can send /files
to /sites/somesite/files
based on the subdomain. (This only works for HTTP-requested paths, however; unlike symlinks, these rules have no effect on
The next thing I’d like to try is virtual document roots (*.domain) that map to different folders.
If you have any other cool mod_rewrite
tips, or see any errors in my examples here, please post a comment!