Reputation: 318
I am trying to define an environment variable in my .htaccess file, and then run a rewrite condition using that variable. Below is what I have in my .htaccess file, but the rewrite is not working:
RewriteEngine on
#set to 'live' or 'maintenance'
SetEnv ENVIRONMENT maintenance
#If the ENVIRONMENT variable is 'mainetnance' then show a maintenance page to the users
RewriteCond %{ENV:ENVIRONMENT} maintenance
RewriteRule ^(.*)$ /maintenance.html
The purpose of this is to set the site to maintenance mode programmatically by having PHP edit the .htaccess file when it receives a post request from one of GitHub's hooks to pull the repo for an update.
Upvotes: 15
Views: 36527
Reputation: 637
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:
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.
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.
Upvotes: 11
Reputation: 51
Bit late - but for all the others searching ...
use SetEnvIf - see: mod_rewrite rule and setenv
SetEnvIf Request_URI ".*" ENVIRONMENT=maintenance
...
Upvotes: 5
Reputation: 1804
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."
Upvotes: 23