Custom 404 Page using Isapi_Rewrite in IIS

Recently, I’ve been working on a website that’s running Coldfusion 9 on an IIS server. The major limitation is that we were only given FTP access on the web host, we don’t have any kind of access to the Helm control panel whatsoever. We could easily create and edit files and upload it to the server, but we can never modify or customize its behavior. Then it came to the point where I need to have custom 404 error pages. Why? Because I’m an SEO wannabe.

Given the limited resources and access that we have, I at least have to try making this work. In IIS, you can easily make custom error pages, that is if you have access to the box directly. In our case, custom error pages can be configured if you log in to the web host control panel. But as I say we were only given FTP access. It really was a good thing that the web host offered Isapi_rewrite that is already installed on the servers. For beginners, Isapi_rewrite is like IIS’s version of Apache web server’s mod_rewrite, which in layman’s terms allows you to manipulate URLs based on certain conditions. Basically, you can redirect a certain URL to another server resource, a pretty powerful module for a pretty complex tool.

First, I started to design the actual custom 404 error page that I will be using. I named this 404.cfm for clarity’s sake and resided in the root directory. As for the actual redirect code, as I researched, I found some code to be placed on .htaccess file as shown below:

[bash]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ 404.cfm [R=301]
[/bash]

The first two lines indicates that the URL rewriting will only be executed if the requested filename, whether a file or a directory, is not found. If it is not found, the request will redirect to a certain 404.cfm, which is the custom 404 error page. The part where it says, [R=301], means that the page will redirect to the custom error page with an HTTP status code of 301 or Permanently moved. This would mean that if we go to, for example http://www.example.com/notfound, on our browser and it is not found, we will be redirected to http://www.example.com/404.cfm. There are two things that I dislike with this method. First, we will be literally redirected to 404.cfm. What I wanted was if I typed http://www.example.com/notfound, I want the URL to remain as http://www.example.com/notfound with the custom 404 error page displayed and not redirect us to http://www.example.com/404.cfm instead. Second, since we are making a custom 404 page, the ideal HTTP status code to return is 404 Not Found and not 301 Permanently Moved, hell not even 200 Status OK.

Well, the code above was the first step. In order to make the content of the custom 404 error page (404.cfm) appear as the content of http://www.example.com/notfound, I had the following code:

[bash]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ 404.cfm [L]
[/bash]

Well this was partly a success. When I typed the URL in the browser, the URL remains the same but the content is that of my custom error page. The other part of this problem is to make the HTTP status code return 404 and not 200. So I edit my 404.cfm and typed this code on the first line of the file:

[coldfusion light=”true”]<cfheader statuscode="404" statustext="Not Found" />[/coldfusion]

What this code does is returns a status code of 404 when this file is requested on the server. And that completes everything that I needed for a custom 404 error page without any kind of access to the server control panel. And what about PHP? Well, you could use the header function:
[php light=”true”]
<?php
header("HTTP/1.0 404 Not Found");
?>
[/php]

As for the .htaccess file, you probably can use the ErrorDocument directive of mod_rewrite, if you are using Apache, otherwise, you could also use the code above.