Use RewriteCond based on environment variable in .htaccess

Bit late - but for all the others searching ...

use SetEnvIf - see: mod_rewrite rule and setenv

SetEnvIf Request_URI ".*" ENVIRONMENT=maintenance

...


I found that nearly every example fell short of complete, so I'm bringing my solution to the table. I needed to create a variable based on my server environment - either local or production - then run rewrites based on that server environment. Specifically, if the environment is production, I want to force https and www.

Why not have a unique .htaccess file for each server environment? Because, I want to include .htaccess in my Git repository and not worry about screwing up one of my environments.

The first thing you need to know is that all of this must occur within mod_rewrite, which means that you must have mod_rewrite enabled in your Apache instance. If you do not know how to check this, create a phpinfo page (http://www.phpinfofile.com/) and do a search for "mod_rewrite" in the "Loaded Modules" section.

The .htaccess code:

<IfModule mod_rewrite.c>

# Set SERVER_ENV=production if HTTP_HOST matches my production URL
RewriteCond %{HTTP_HOST} ^(www\.)?mysite\.com$ [NC]
RewriteRule .* - [E=SERVER_ENV:production]

# Force www. if SERVER_ENV is production
RewriteCond %{ENV:SERVER_ENV} ^production$
RewriteCond %{HTTP_HOST} !^www [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Force https if SERVER_ENV is production
RewriteCond %{ENV:SERVER_ENV} ^production$
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Set SERVER_ENV=local if HTTP_HOST matches my local URL
RewriteCond %{HTTP_HOST} ^www-local\.mysite\.local$ [NC]
RewriteRule .* - [E=SERVER_ENV:local]

</IfModule>

Notes:

  1. The first variable name is "SERVER_ENV" and the value is "production". This variable name/value could be anything. For example, you could use MY_ENVIRONMENT:live. After you've created this variable in .htaccess, you should be able to find it referenced in your phpinfo file - a great way to check that it's there.

enter image description here

  1. The RewriteCond lines should be before the RewriteRule and should be grouped together as shown. You can have 1 or more rewrite conditions that must be met before the rewrite rule kicks in.

  2. I'm setting a different variable if HTTP_HOST is "local". I don't have any rewrite conditions/rules that use the "local" variable - I'm just setting it here for the sake of instruction.


mod_rewrite doesn't use variables set via SetEnv, instead use this method:

#set to 'live' or 'maintenance'
RewriteRule .* - [E=STATUS:maintenance]

#If the ENVIRONMENT variable is 'maintenance' then show a maintenance page
RewriteCond %{REQUEST_URI} !maintenance.html [NC]
RewriteCond %{ENV:STATUS} ^maintenance$
RewriteRule ^.*$ /maintenance.html [L]

The first line of the bottom three, makes sure that once the user is redirected to the file "maintenance.html", it will not be redirected again. Else the user keeps getting redirected to the same file, causing an 500 internal server error saying "AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error."