Using Drupal Clean URLs with IIS and ISAPI Rewrite Version 3

Yes I know I've already written a guide for using ISAPI Rewrite to generate clean URL's with Drupal, however Helicon have taken a vastly different approach with the release of ISAPI Rewrite 3 to the extent where it is more than likely your ISAPI Rewrite 2.x rules will not work with it. The reason for this is that Helicon have restructured ISAPI Rewrite so that it now uses the same syntax as the popular Mod Rewrite module for the Apache web server. Why they have done this after having established a solid product over the last 5 years is anyones guess, but I'd say it has a lot to do with the fact the ISAPI Rewrite support forums are swamped with "how do I convert these .htaccess rules to ISAPI Rewrite" style questions. So lets take a look.

Helicon have done a comprehensive job with implementing the Mod Rewrite structure into ISAPI Rewrite 3, but as there are several Mod Rewrite directives that are tied directly to the Apache architecture they haven't been able to implement everything. You can find more information on ISAPI Rewrite 3 compatibility with Apache here. Fortunately this has no effect for us with Drupal as all the rewrite rules used here can be used directly. And I do mean directly.

If you have purchased the full version of ISAPI Rewrite 3, then there is little for you do to as ISAPI Rewrite 3 should be able to read the rules from the Drupal .htaccess file directly. Although I have purchased the full version myself, I am yet to make the upgrade from 2.x as I don't feel I've done enough testing with it yet. I will update this section with any tips and tricks I might discover after I have made the upgrade myself.

For those of us unable to shell out the $99USD for a license to get the full version of ISAPI Rewrite, then there is still the option of using the Lite version which is free to use. The Lite version of ISAPI Rewrite has most of the functionality of the full version, but as you might expect is operating with a few limitations of which the biggest one being it only supports a single global level httpd.conf file. This in nothing new as this limitation has always existed in the Lite version and in no way means that you can't get all the functionality you need for creating clean URL's for Drupal. All we need to do here is transpose the .htaccess rules along with a few other tricks over to the global httpd.conf

Step 1 - Transpose your .htaccess rules

First step after installing ISAPI Rewrite 3.x Lite is to open your httpd.conf file which stores all the global level rules which is located in your ISAPI Rewrite installation directory. Once opened, enter the following;

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]


If you installed Drupal in the root of your website and it is the only website to be server on this server, then all you need to do from here is save the file and move onto step 4. However, if you have installed Drupal into a sub directory and/or have several websites on your server and only want these rules applied to your Drupal site then you'll need to read on through steps 2 and 3.

Step 2 - Adding a rule for sub directory Drupal installations

If you have installed Drupal into a sub directory off your website root, then you'll need to make a small modification to the RewriteBase directive as shown below;

RewriteEngine on
RewriteBase /drupal/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]


This example assumes you have installed into a sub directory called drupal. If you have installed into another directory simple exchange "drupal" in the RewriteBase rule with the name of the directory you installed into.

Step 3 - Rewriting only for specific domains

One of the biggest limitations of the Lite version of ISAPI Rewrite is that you have only one global configuration file which is applied to all your websites. This meaning that any other websites on your server not using Drupal will have these rules applied to them which could very well break them. The work around to this is to use the RewriteCond directive to specify which hosts these rules should be applied for as shown below;

RewriteEngine on
RewriteCond %{HTTP:Host} ^(?:www\.)?example\.com$
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]


This example assumes that you only want these rules to apply to www.example.com and example.com. Simply exchange this domain name for the one you installed Drupal on and you should find that your Drupal rules are only applied to this domain.

Step 4 - Configuring settings.php

The final step is to tell Drupal to turn on Clean URL's. This is a little more complicated for IIS users than it is for Apache users as Drupal uses the REQUEST_URI server variable to check for clean url compatibility. The problem is that while Apache supports the modification of server variables, IIS does not. So no matter what URL rewriting tool you use for IIS, it is never going to pass the clean url test from the Drupal admin control panel.

There are two ways in which you can get around this though. First is to manually override the Clean URL test by setting the following directive in your settings.php file for your site;

$conf['clean_url'] = 1; // 1 enables, 0 clears clean_url

The other way is to use the HTTP_X_REWRITE_URL variable that ISAPI Rewrite 3.x uses for Apache compatibility. This requires you to add the following to your settings.php file;

// Isapi_Rewrite 3.x
if (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
$_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_REWRITE_URL'];
}


The advantage of using this method is that Drupal will now pass the clean url test, so you can enable/disable clean url's from the Drupal admin panel rather than having to comment out the the manual override setting.

That's it. You should now have clean URL's with you Drupal installation using ISAPI Rewrite 3.x. If you have any comments, questions or other feedback please feel free to leave a post in the comments section here or in the forums.

Average rating
(13 votes)

Comments

Anonymous's picture

Thank you

Works great as you explained.

Anonymous's picture

ISAPI Rewrite working not in all browsers

We have installed the ISAPI Rewrite 2 on our VPS server.
Our domain is http://www.easygolanguages.com

In firefox the URL rewrite works fine. In internet explorer, in some computers it works, in others it doesn't. We are not sure what else to do!!! I have 3 computers; in 2 computers the website works fine, in the third one it doesnt.

We have already checked the permissions and we have also confirmed with the server to make sure these where correct.

We had a VPS server where we had to install the ISAPI re-write.

Now we got another server which already has the ISAPI re-write installed. In both server we have uploaded the same web files, the VPS with the httpd.ini with the following code:

[ISAPI_Rewrite]
# 3600 = 1 hora de cache
CacheClockRate 3600
RepeatLimit 32

# Bloquea los intentos de acceso al archivo httpd.ini y httpd.parse.errors
RewriteRule /httpd(?:.ini|.parse.errors).* / [F,I,O]
# Bloquea el acceso externo al fichero de ayuda de Isapi Rewrite
RewriteRule .*.isrwhlp / [F,I,O]
# Instrucciones Rewrite
RewriteCond Host: (.+)
# Evita que el usuario acceda al fichero global.asa y redirige el archivo index.html a index.asp
RewriteRule ^/global.asa /index.asp
RewriteRule ^/index.html /index.asp

RewriteRule (.*?\.asp)(\?[^/]*)?/([^/]*)/([^/]*)(.*) $1(?2$2&:\?)$3=$4$5 [NS,I]

In the new host we have generated this from the control panel:

[ISAPI_Rewrite]
# Helm ISAPI - Start Of Rule
# Helm ISAPI - Rule ID: 20071016192826
# Helm ISAPI - Rule Name: Simular Carpetas
# Helm ISAPI - Status: ACTIVE
RewriteRule (.*?.asp)(?[^/]*)?/([^/]*)/([^/]*)(.*) $1(?2$2&:?)$3=$4$5 [NS,I]
# Helm ISAPI - End Of Rule

# Helm ISAPI - Signature Hash: 6181C1AB133941F0C8AFBC9559B6F495
# WARNING: THIS FILE CANNOT BE MODIFIED OUSTIDE OF HELM AND HELM ISAPI!

We get errors from both servers; some explorers see the the site, some give error 500.

In the second hosting, the httpd.parse.errors sais "Bad regular expression at lines 6 - 6."

We have tried opening both sites which have the same files but hosted in differente servers on the same computer. One of the sites works in explorer and one doesnt.

I am willing to pay someone to work on this for us. Any suggestions on someone I could contact?

thanks,

cm

Anonymous's picture

Helicon upgrading to v3

I found that v3 is worth the $99 for the full version. I like it a little better than MicroNovae's. Hopefully they remove the necessity to define the $_SERVER['Request_URI']. That is unnecessary in MicroNovae, however it is necessary to trim down .htaccess files to only mod_rewrite rules with MicroNovae, where Helicon successfully ignores the extraneous Apache stuff.

Here is a useful discussion regarding rewriting with Drupal: http://drupal.org/node/159836#comment-282905

Brashquido's picture

I didn't actually realize

I didn't actually realize that it wasn't necessary to define the REQEUST_URI variable with MicroNovae's IIS Mod Rewrite. As a rule IIS does not allow the modification of server variables, so I'd like to know how IIS Mod Rewrite does this. Regardless, I'm happy you got it sorted and are now up and running with Drupal creal url's ;) !
----------------
Dominic Ryan
3 x Microsoft IIS MVP, MCSE, MCSA
IIS Aid owner/webmaster

Anonymous's picture

Some comments

1. It is better to use following rules instead:

RewriteEngine on
RewriteBase /
RewriteCond %{HTTP:Host} ^(?:www\.)?example\.com$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

Note changed order. While your variant is working now, it may stop working in future versions of ISAPI_Rewrite since it is lexically incorrect (RewriteCond cannot apply to RewriteBase).

2. Bug with newest IE7 release was fixed in ISAPI_Rewrite 3 build 22 (about two month ago).

3. Our tests confirm that no IIS URL rewriter can set REQUEST_URI variable for scripts like ASP, etc. Possibly support of X-Original-URL HTTP header is already plugged into Drupal engine?

Brashquido's picture

Cheers for the updates. You

Cheers for the updates. You are correct that no IIS URL rewriters can modify the REQUEST_URI variable, but your can use scripts to do this like I did in my REQUEST_URI work around article for PHP.

----------------
Dominic Ryan
3 x Microsoft IIS MVP, MCSE, MCSA
IIS Aid owner/webmaster

Anonymous's picture

Decoding of URLs containing Unicode

Thanks for the explanation which works great. However, I found the following shortcoming: If you use the search engine of drupal and the search term contains non-ASCII characters, like umlauts (ä, ...) you end up with a 404 file not found error. E.g, if your search term is a single umlaut (say 'ä') it get's translates into an URL like http://www.mydrupalsite.tld/search/node/%C3%A4
This URL works fine without the ISAPI Rewrite Filter in action, however as soon as the rewrite filter is activated, you end up with a 404 page not found error (with the lastest version, behaviour was different in previous versions, but things didn't work with any version).
I found the following resource which addresses that issue: "Getting the correct Unicode path within an ISAPI filter"
http://www.kirit.com/Getting%20the%20correct%20Unicode%20path%20within%20an%20ISAPI%20filter
However I still wasn't able to resolve that issue.
Any help on that ist appreciated.

Thanks in advance
Andreas Deininger

Brashquido's picture

Hi Andreas, Have you tried

Hi Andreas,

Have you tried using the "NE" option in your RewriteRule? This should stop ISAPI Rewrite from escaping non ANSI characters.

----------------
Dominic Ryan
3 x Microsoft IIS MVP, MCSE, MCSA
IIS Aid owner/webmaster

Anonymous's picture

that didn't help

Hi Dominic,
thanks for your tip. Even after using the "NE" option, I still get an 404 error.
That's strange since the following URL works:
http://www.mysite.tld/index.php?q=search/node/%C3%84
while this URL does not work.
http://www.mysite.tld/search/node/%C3%84

Thanks for investigating that case.
Andreas

Anonymous's picture

Issue solved

Hi,

I was finally able to resolve that issue. The problems mentioned above were caused by the commands

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

which lead to 404 errors if the URL contains characters like '%C3%84'
So I replaced these commands as described here:
http://drupal.org/node/43788

My httpd.conf file now looks like

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !^/$
RewriteCond %{REQUEST_FILENAME} !^/(files|misc|uploads)(/.*)?
RewriteCond %{REQUEST_FILENAME} !\.(php|ico|png|jpg|gif|css|js|html?)(\W.*)?
RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA,NE]

This does exactly what I want and does not lead to 404 errors if the search string contains umlauts. It also seems to me like this variant is faster since now we do not check for the existence of a file and a directory before we apply the rewrite rule.

Regards
Andreas