Apache: Redirecting All Requests to a Single Page

Server Administration No Comments

This morning we had a big power outage at our sister site. Needless to say, all of their servers were shut off and all of the thousands of users were getting errors trying to reach their sites. I got a feverish phone call with a simple request: set up a dummy Apache server with some notifications to let the users know whats going on. No big deal. I set up a base Apache server with all the necessary VirtualHosts in a matter of minutes, but when I went to test it, I realized that I had not set up any mechanism to catch URLs that might have been bookmarked, or that other sites had hard linked. In essence, if you had gone to www.example.com, you would have gotten a nice little notice about the outage, but if you had gone to www.example.com/some_function.jsp, you would have gotten hit by a 404 notice.

I dug into one of my old sites where I set up a maintenance notification system and grabbed the code and all was well again. I think its a good idea to have this code handy in case of whatever, so here is what you need to do.

  1. Apache must have mod_rewrite enabled
    LoadModule rewrite_module modules/mod_rewrite.so
  2. Insert the following code in either the .htaccess file in the root directory of your server, or in the httpd.conf file directly. Since I use VirtualHosts for most of my systems, I insert it directly in the VirtualHosts section.
    <VirtualHost 1.2.3.4:80>
         DocumentRoot /var/www/sites/example
         ServerName www.example.com
         ErrorLog /var/log/example-error.log
         CustomLog /var/log/example-access.log common
         Options +FollowSymlinks
         RewriteEngine on
         RewriteCond %{REQUEST_URI} !^/maint/ [NC]
         RewriteCond %{REQUEST_URI} !/maintenance.html$
         RewriteRule $ /maintenance.html [R=302,L]
    </VirtualHost>

Let me explain what each of these mean. RewriteEngine on enables the runtime rewriting engine telling the server to apply all of the rewrite rules.

RewriteCond is a directive that allows you to set the conditions for rewriting. In this case I defined 2 exclusion rules. %{REQUEST_URI} !^/maint/ [NC] means exclude all requests that are going to www.example.com/maint/*. The [NC] flag means ignore case. All files in /maint/ will be read normally. This is where you would store any static images, css files, etc. that you want available when in maintenance mode. The other exclusion rule RewriteCond %{REQUEST_URI} !/maintenance.html$ is more specific naming only /mantenance.html from being redirected. This rule is very important because without it, you would hit an infinite redirect loop.

Finally RewriteRule is where you specify what you want forwarded and how. In my condition RewriteRule $ /maintenance.html [R=302,L], I wanted all possible requests to be forwarded to /maintenance.html. The $ works as a catchall for any and all URLs that meet the conditions I specified above. The flags that are set here are R=302 which sends a 302 redirection response code to the client and L signifying that it is the last rule.
Additional example include forwarding requests from an old page to a new one:

RewriteRule ^/old.jsp$ /new.do [L]

For more info on mod_rewrite, check out Apaches documentation on it. (link)

Powered by WordPress | Theme by Bojan Beran Feedburner Posts RSS