Introduction

ISAPI_Rewrite is a powerful regular-expressions-based URL manipulation module for IIS. It is compatible with Apache mod_rewrite syntax, which makes it possible to move configurations from Apache to IIS and vice versa just by copying .htaccess files. Please see this compatibility chart.

Top features of ISAPI_Rewrite:

  • ISAPI_Rewrite offers the same syntax and behavior as Apache mod_rewrite making it possible to migrate configurations just by copying .htaccess files. Read more about mod_rewrite compatibility here.
  • Regular expressions for flexible and powerful configurations.
  • Extremely fast and highly scalable pure C++ code.
  • Real distributed configurations: global (server) level, virtual host (web site) level, directory level .htaccess files with real-time monitoring.
  • Isolation – user level configuration affects only local user environment making ISAPI_Rewrite ideal solution for web hosting providers.

Top usage examples:

  • Search engine optimization. Read more.
  • Proxy content of one web server through another web server. Read more.
  • Prevent content leeching (direct linking). See example.
  • Block specific hosts, referrers or annoying robots.
  • Content negotiation - serving different files for different languages or different browsers. See example.
  • Emulate load balancing for web cluster. See example.

Please find more useful examples in ISAPI_Rewrite documentation here and in Apache documentation here. Most Apache examples can run with ISAPI_Rewrite without modification.

Pricing details

  • Free 45-day trial period.
  • Single server (computer) license - $99.
  • ISAPI_Rewrite Lite version is Freeware! (Read on specific limitations).
  • Volume discounts available!

© 2002 - 2007 Helicon Tech. All rights reserved.


System requirements

ISAPI_Rewrite can be installed on the following operating systems:

  • Windows 2000 with IIS 5
  • Windows XP with IIS 5.1
  • Windows Server 2003 with IIS 6.0
  • Windows Vista with IIS 7.0
  • Windows Server 2008 with IIS 7.0

IIS should be installed on the operating system before installing ISAPI_Rewrite.
Both 32 and 64 bit versions of Windows are supported, but you need to download distinct installation package for 32 and 64 bit versions.
Windows Installer 2.0 is required to run installation program. You can download last version of Windows Installer from the Microsoft website.

On Windows Vista and Windows Server 2008 installation of ISAPI_Rewrite also requires following modules, not installed by default:

  • ISAPI Filters
  • ISAPI Extensions


Installation process

Please read system requirements section before running installation. Download and run ISAPI_RewriteXXXX.msi. Follow instructions from the installation wizard. Installation process is automatic and self-describing. ISAPI_Rewrite will restart IIS during automatic installation, the following services will be restarted: IISADMIN, W3SVC. Also there is no need to manually add any ISAPI filters or extensions to the site or global lists. It will be done automatically during installation and configuration process.

Command line installation

ISAPI_Rewrite can be installed quietly from the command line. Please use the following command line syntax for installation:

msiexec /i ISAPI_Rewrite3.msi /qn AcceptEULA=Yes REGISTRATIONCODE=Code REGISTRATIONNAME=Name

Where ISAPI_Rewrite3.msi is the name of ISAPI_Rewrite MSI package file, AcceptEULA=Yes indicates your acceptance of EULA, REGISTRATIONCODE and REGISTRATIONNAME are optional.

To uninstall ISAPI_Rewrite quietly from command line use following syntax:

msiexec /x ISAPI_Rewrite3.msi /qn KEEPUSERFILES=Yes


Manual installation

To install ISAPI_Rewrite manually you will need to download distinct installation package (ISAPI_Rewrite3_00xx_manual.exe) containing all required files. You can install all features or only a part of them.

Manual installation package includes the following files:

  • ISAPI_Rewrite.dll - this is the ISAPI filter itself
  • ISAPI_RewriteProxy.dll - this is ISAPI extension module required for proxy operations
  • license.rtf - product EULA
  • ISAPI_Rewrite.chm - documentation file
  • httpd.conf - sample global configuration file

Note! Lite version of ISAPI_Rewrite does not support manual installation.

To install ISAPI_Rewrite first you need to register ISAPI_Rewrite.dll as ISAPI filter in your IIS system. By default ISAPI_Rewrite.dll was designed to work as a global ISAPI filter.

While it is still possible to install it on a particular web site, you need to remember that only one instance of ISAPI_Rewrite.dll can be loaded at a time to one IIS worker process. This means that if you decide to install ISAPI_Rewrite ISAPI filter separately on each site, you'll need to turn on high isolation mode for these sites to spawn separate worker processes for each of them. This is only required if you install ISAPI_Rewrite.dll on each web site separately and we usually recommend to install it globally on entire IIS.

To register ISAPI filter on Windows 2000, Windows XP and Windows Server 2003 use IIS MMC snap-in to add ISAPI_Rewrite.dll to ISAPI filters list either for the whole IIS server or for specific web sites only. On Windows Vista and Windows Server 2008 you'll need to install the following optional IIS component first: World Wide Web Services\Application Development Features\ISAPI Filters.

If you need proxy functions, you will need to register ISAPI_RewriteProxy.dll as ISAPI extension to serve *.rwhlp file extensions. On different IIS versions it requires slightly different actions. Please refer to the documentation of your IIS version for explanation of how to register new ISAPI extension and map it to file extension in IIS system. On Windows Vista and Windows Server 2008 first install optional IIS component World Wide Web Services\Application Development Features\ISAPI Extensions. Use short (8.3-style) path name for ISAPI_RewriteProxy.dll module path or IIS will fail to load the module if there is a space character in the path.

Put httpd.conf file near ISAPI_Rewrite.dll file and put the necessary rules into it.

To register ISAPI_Rewrite product add the following lines the httpd.conf file:

RegistrationName=Your registration name
RegistrationCode=REG-CODE-PROVIDED-FROM-HELICON

Check file system permissions as described in Permissions required to run ISAPI_Rewrite section.


Uninstalling

Uninstallation program removes all files created by installation, unregisters filter form matabase and removes all other metabase changes that where added by installation program. The following user data files can be left after uninstallation if user decided to keep user files during uninstall:

Filename: | Description:
Program Files/Helicon/ISAPI_Rewrite/httpd.conf | main configuration file with user rules
Program Files/Helicon/ISAPI_Rewrite/error.log | file containing error log
Program Files/Helicon/ISAPI_Rewrite/rewrite.log | file containing rewrite log
.htaccess (various folders) | user created configuration files with rules

When uninstalling option to remove user created files will be available to user. When enabling this option uninstallation program will also remove user created files located in Program Files. .htaccess files will not be removed.

To uninstall ISAPI_Rewrite quietly form command line use following syntax:

msiexec /x ISAPI_Rewrite3.msi /qn KEEPUSERFILES=Yes


Permissions required to run ISAPI_Rewrite

Automatic installation of ISAPI_Rewrite on a clean default Windows system does not require any permission tweaking. But installing of some other products like Plesk, IIS Lock Down Tool, etc. may tighten server security and prevent ISAPI_Rewrite from correct operation. Here is a list of premissions required by ISAPI_Rewrite.

On Windows 2000, Windows XP and Windows 2003 in IIS5 compatibility mode filter runs in the inetinfo.exe process under the System account. Thus System account should be given at least Read and List Folder Content access to the folder locating ISAPI_Rewrite installation files. We also recommend giving System account general Modify permissions on this folder. That will allow creation of log files containing parse and other errors. The same permissions should be given to any web site folder containing .htaccess files or ISAPI_Rewrite will be unable to load and monitor it.

Pay special attention to any Deny permission settings on ISAPI_Rewrite installation directory because in Windows OS Deny permissions override any Allow premissions records.

On Windows 2003 in native IIS mode (WPI mode) and Windows Server 2008 both the filter and the proxy run in the w3wp.exe worker process corresponding to an application pool hosting particular web application. Each application pool could be configured to use its own identity. This could turn permissions configuration into a tricky task. However in a correct IIS configuration each used identity should be a member of IIS_WPG group. So, IIS_WPG group could be used instead of System account to assign required permissions as noted above.

On Windows Vista permissions configuration is almost the same as Windows 2003 configuration except that there is no IIS_WPG group there. So, all WPI accounts (usually NETWORK SERVICE is the only such account) should be given required permissions.

Additionally for proxy function to work you will need to enable at least "Scripts only" execution permission in the properties of web site or web application which will be running proxy.


MSI custom actions

Custom action:

Description:

WiseAltStartup

Saves current state of properties for use by the custom actions running in deferred mode.
uses an executable (dll)
occurs during: Install,Uninstall

WiseCleanup

This action is called to clean up any temporary files left over from the custom action.
uses an executable (dll)
occurs during: Install,Uninstall

WiseStartup

This action enables parameter passing for actions that call a .DLL file and extracts the necessary Wisescript .EXE and .DLL files.
uses an executable (dll)
occurs during: Install,Uninstall

WiseUpgradeCheck

This action is called to work around issues where the Windows Installer runtime does not detect previous versions of the application.
uses an executable (dll)
occurs during: Install

WiseUpgradeCheckEx

This action is added to work around issues where the Windows Installer runtime does not detect previous versions of the application.
uses an executable (dll)
occurs during: Install

WiseGetIISVersion

Set a property with the major IIS version (IISVERSION).
uses an executable (dll)
occurs during: Install

RegisterFilterInMetabase

This action adds global ISAPI filter with the name ISAPI_Rewrite3 to IIS metabase.
IIS5, IIS6 metabase path: IIS:/LM/W3SVC/Filters/ add key ISAPI_Rewrite3
IIS:/LM/W3SVC/Filters/FilterLoadOrder append "ISAPI_Rewrite3"
uses an executable (dll)
occurs during: Install

RemoveFilterFromMetabase

This action removes global ISAPI filter with the name ISAPI_Rewrite3 from IIS metabase.
IIS5, IIS6 metabase: IIS://localhost/W3SVC/LM/W3SVC/Filters/ delete key ISAPI_Rewrite3
IIS:/LM/W3SVC/Filters/FilterLoadOrder remove"ISAPI_Rewrite3"
uses an executable (dll)
occurs during: Uninstall, Rollback

AddApplicationExtension

Only for Windows 2003 machines adds ISAPI_RewriteProxy.dll to ISAPI extensions and enables this ISAPI extension in Web Service Extensions list.
IS6 metabase: IIS:/LM/W3SVC/
adds entry to the WebSvcExtRestrictionList metabase property "ISAPI_Rewrite3 proxy";
adds an entry to the ApplicationDependencies metabase property "ISAPI_Rewrite3 proxy;ISAPI_Rewrite3"
uses an executable (dll)
occurs during: Install

RemoveApplicationExtension

Only for Windows 2003 machines removes ISAPI_RewriteProxy.dll from ISAPI extensions and removes this ISAPI extension from Web Service Extensions list.
IS6 metabase: IIS:/LM/W3SVC/
1. delete "ISAPI_Rewrite3 proxy" entry from WebSvcExtRestrictionList metabase property;
2.delete "ISAPI_Rewrite3 proxy;ISAPI_Rewrite3" from ApplicationDependencies metabase property;
uses an executable (dll)
occurs during: Uninstall, Rollback

RegisterExtensionInScriptMap

Register ISAPI_RewriteProxy.dll as ISAPI extension to handle "*.rwhlp" file extension in IIS metabase.
IIS5,IIS6 metabase: IIS://LM/W3SVC/
uses an executable (dll)
occurs during: Install

RemoveExtensionFromScriptMap

Remove ISAPI_RewriteProxy.dll registration as ISAPI extension to handle "*.rwhlp" file extension from IIS metabase.
IIS5, IIS6 metabase: IIS://LM/W3SVC/
uses an executable (dll)
occurs during: Uninstall, Rollback

GetServisesStatus

Saves current status of IISADMIN, W2WC, NNTP, SMTP and FTP services.
creates msi property [SERVICES_STATUS]
uses an executable (dll)
occurs during: Install,Uninstall

StartServicesEx

Starts ISADMIN, W2WC, NNTP, SMTP and FTP services according to their initial state.
uses msi property [SERVICES_STATUS]
uses an executable (dll)
occurs during: Install,Uninstall

SaveProductID

Saves REGISTRATIONNAME and REGISTRATIONCODE properties values if specified to register product.
uses msi property: [REGISTRATIONNAME] , [REGISTRATIONCODE];
uses file: [INSTALLDIR]\ISAPI_Rewrite3\httpd.conf
uses an executable (dll)
occurs during: Install

Check32bitMode

Checks whether 32-bit IIS compatibility mode enabled on 64-bit system to install correct version of ISAPI filter. IIS6, IIS7
uses metabase path: IIS://LM/W3SVC/AppPools property Enable32bitAppOnWin64;
uses msi property:[ENABLE32BITAPPONWIN64]
Checks whether to enable a 32-bit application to run on a computer that has a 64-bit version of Windows.
uses an javascript
occurs during: Install

CheckIISModules

Checks whether required IsapiFilterModule and IsapiModule modules installed on IIS7 machines.
IIS7 metabase path:

<system.webServer>

<globalModules>

<add name="IsapiModule" image="%windir%\System32\inetsrv\isapi.dll" />

<add name="IsapiFilterModule" image="%windir%\System32\inetsrv\filter.dll" />
</globalModules>

</system.webServer>

uses javascript;
occurs during: Install

AddGlobalIsapiFilter

Only for IIS7 machines this action adds global ISAPI filter with the name ISAPI_Rewrite3 to IIS metabase.
IIS7 metabase path:

<configuration>
<system.webServer>
<isapiFilters>
<filters>
<filter
name="ISAPI_Rewrite3"
path="C:\Program Files\Helicon\ISAPI_Rewrite3\ISAPI_Rewrite.dll"
enabled="true"
enableCache="false"
>
 </filter>
</filters>
</isapiFilters>
</system.webServer>
</configuration>

uses javascript;
occurs during: Install

DeleteGlobalIsapiFilter

Only for IIS7 machines this action removes global ISAPI filter with the name ISAPI_Rewrite3 from IIS metabase.

IIS7 metabase path:

<configuration>
<system.webServer>
<isapiFilters>
<filters>
<filter
name="ISAPI_Rewrite3"
path="C:\Program Files\Helicon\ISAPI_Rewrite3\ISAPI_Rewrite.dll"
enabled="true"
enableCache="false"
>
 </filter>
</filters>
</isapiFilters>
</system.webServer>
</configuration>

uses javascript;
occurs during: Uninstall, Rollback

AddIsapiCgiRestriction

Only for IIS7 machines register ISAPI_RewriteProxy.dll as ISAPI extension in IIS metabase.
IIS7 metabase path

<configuration>
<system.webServer>
<security>
<isapiCgiRestriction>

<add
path="C:\Program Files\Helicon\ISAPI_Rewrite3\ISAPI_RewriteProxy.dll"
allowed="true"
description="Helicon Proxy" />
</isapiCgiRestriction>
</security>

</system.webServer>
</configuration>

uses javascript;
occurs during: Install

DeleteIsapiCgiRestriction

Only for IIS7 machines remove ISAPI_RewriteProxy.dll registration as ISAPI extension form IIS metabase.
IIS7 metabase path:

<configuration>
<system.webServer>
<security>
<isapiCgiRestriction>
<add
path="C:\Program Files\Helicon\ISAPI_Rewrite3\ISAPI_RewriteProxy.dll"
allowed="true"
description="Helicon Proxy" />
</isapiCgiRestriction>
</security>

uses an javascript;
occurs during: Uninstall, Rollback

AddScriptMap

Only for IIS7 machines register ISAPI_RewriteProxy.dll as ISAPI extension to handle *.rwhlp file extension in IIS metabase.
IIS7 metabase path:

<configuration>
<system.webServer>
<handlers>
<add name="Helicon Proxy" path="*.rwhlp" verb="*" modules="IsapiModule" scriptProcessor="C:\Program
Files\Helicon\ISAPI_Rewrite3\ISAPI_RewriteProxy.dll" resourceType="Unspecified"
/>

 </handlers>

 </system.webServer>
</configuration>

uses an javascript
occurs during: Install

DeleteScriptMap

Only for IIS7 machines remove ISAPI_RewriteProxy.dll registration as ISAPI extension to handle *.rwhlp file extension from IIS metabase.
IIS7 metabase path:

<configuration>
<system.webServer>
<handlers>
<add name="Helicon Proxy" path="*.rwhlp" verb="*" modules="IsapiModule" scriptProcessor="C:\Program
Files\Helicon\ISAPI_Rewrite3\ISAPI_RewriteProxy.dll" resourceType="Unspecified"
/>
 </handlers>
</system.webServer>
</configuration>

uses an javascript;
occurs during: Uninstall, Rollback


Basic concept

ISAPI_Rewrite provides a rule-based rewriting engine to modify requested URLs on the fly. It supports virtually unlimited number of rules and rule conditions to provide really flexible and powerful URL manipulation mechanism. URL manipulations can depend on states/values of HTTP headers, server variables, requested URL itself and many other conditions.

URL manipulations are established using text configuration files with a set of directives inside. There are several levels of configurations.

  • Global (server wide) configuration directives are placed into httpd.conf configuration file located in ISAPI_Rewrite installation folder.
  • Tags that can restrict the scope to be affected by the directives: <VirtualHost>, <Directory>, <DirectoryMatch>, <Files>, <FilesMatch>, <Location> and <LocationMatch> (all these tags may occur only in global config).
  • Distributed .htaccess files that can appear on any directory level inside a web site. The rules from these files will be applied to this location and its subdirectories only.

All configuration files are reloaded automatically every time the file is changed. It is possible to change configuration files content from third-party programs and scripts.

In most cases ISAPI_Rewrite is used to rewrite requested URL. In addition to rewrite ISAPI_Rewrite can modify, create or remove any other HTTP header of the client REQUEST. Module operation may lead in rewriting, proxying, redirection, or blocking of an original client request to a server.

Rewriting will cause server to continue request processing with a new URL as if it has been originally requested by a client. New URL can include query string section (following the question mark) and may point to any plain static files, scripts (like ASP), programs (like EXE), etc. within the same web application (which usually means same web site). Rewriting is completely transparent to the user and web site applications because it is done internally on a server and before web application receives request.

Proxying causes the resulting URL to be internally treated as a target on another server and immediately (i.e. rules processing stops here) passed to the remote server. Response of the remote server will then be passed back to the client. Proxy requires you to specify fully qualified URL, starting from protocol, host name, etc. ISAPI_Rewrite uses ISAPI extension to handle proxy requests. You can read more about this in configuring proxy chapter.

Redirection will result in sending of immediate response with a redirect instruction (HTTP response code 302 or 301) setting substituted URL as a new location. You can use an absolute URL format (and that is required by the RFC 2616) in redirection instruction to redirect the request to a different host, port and protocol. If this information is omitted, ISAPI_Rewrite will automatically supply URL with the current request's protocol, server name and directory location. Redirect instruction always causes rewriting engine to stop rules processing sequence.

Rules are applied in the order of appearance in configuration files. Directory level configuration files are processed file by file starting from the parents. Rules from global (server wide) configuration file are applied first. Order of rules is important because substitution result of one rule will become a source for subsequent rules.

RewiteCond directives followed by RewriteRule (or RewriteProxy) directive affect only that single rule. If some condition has to be used for more than one rule, it (RewriteCond) should be repeated for every rule to apply.

Note for those using non-FastCGI environment!

Before any URL modification ISAPI_Rewrite saves original URL into the HTTP header named X-Rewrite-URL. Then it can be retrieved in script as HTTP_X_REWRITE_URL server variable. Since in IIS world server variables cannot be modified, ISAPI_Rewrite cannot provide this variable as REQUEST_URI (for Apache compatibility). If your application is designed to rely on REQUEST_URI variable, you will need to patch it to work with HTTP_X_REWRITE_URL variable instead. Here is a patch code for PHP:

if (isset($_SERVER['HTTP_X_REWRITE_URL']))
{
$_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_REWRITE_URL'];
}

Note that if occasionally you have ISAPI_Rewrite 2 and 3 installed together, the above patch won't work.

If you are on IIS/FastCGI web server, this fix is not needed.


Apache mod_rewrite compatibility

This version of ISAPI_Rewrite was designed to maintain maximum Apache mod_rewrite compatibility. This objective was attained to at very high level, though some features could not be implemented due to their high tie-up with Apache and UNIX architecture and their implementation on IIS is senseless. For instance [H] – “force content handler” flag cannot be implemented because in IIS content handler is bounded to file extension. Or [NS] – “no sub request” flag is meaningless because there are no sub requests in IIS.
Here is a complete compatibility chart for ISAPI_Rewrite and mod_rewrite. Features or directives marked in green are fully supported, yellow features are partially supported or planned for support in next minor version, and features marked in red are unsupported.

  • Perl Compatible Regular Expressions (plus extended syntax)
  • Server level httpd.conf configuration
  • Virtual site .htaccess configuration files
  • Directory .htaccess configuration files
  • <VirtualHost>
  • <Directory>
  • <DirectoryMatch>
  • <Files>
  • <FilesMatch>
  • <Location>
  • <LocationMatch>
  • AccessFileName
  • RewriteEngine
  • RewriteRule
    • $N rule backreferences
    • %N RewriteCond backreferences
    • ${mapname:key|default}
    • %{VARNAME} server variables
    • '!' negation
    • [C] chain with next rule
    • [CO=name:val:domain:lifetime:path] set cookie
    • [E=var:val] set environment variable
    • [F] force forbidden response
    • [G] force gone response
    • [H=content-handler] explicit content handler (unapplicable)
    • [L] last rule flag
    • [N] apply rules again
    • [NC] ignore case
    • [NE] don't escape output
    • [NS] no internal subrequest
    • [P] proxy pass
    • [PT] pass through the next handler (always on)
    • [QSA] append query string
    • [R =code] redirect
    • [S=num] skip next n rules
    • [T=MIME-type] force explicit response MIME type
  • RewriteCond
    • [NC] ignore case
    • [OR] logical or combining
    • %{HTTP:header}
    • '!' negation
    • '<CondPattern' more than comparison
    • '>CondPattern' less then comparison
    • '=CondPattern' equal to comparison
    • '-d' directory exist
    • '-f' file exist
    • '-s' non zero file
    • '-l' symbolic link
    • '-x' file with executable permissions
    • '-F' file exist via subrequest
    • '-U' URL exist via subrequest
  • RewriteBase
  • RewriteMap
    • txt: text mapping
    • rnd: random mapping
    • int: internal functions toupper, tolower, escape, unescape
    • prg: external program
    • dbm: hash file
  • RewriteLog
  • RewriteLogLevel
  • RewriteOptions
  • RewriteLock
  • AllowOverride

Server variables compatibility:

  • HTTP_USER_AGENT
  • HTTP_REFERER
  • HTTP_COOKIE
  • HTTP_FORWARDED
  • HTTP_HOST
  • HTTP_PROXY_CONNECTION
  • HTTP_ACCEPT
  • REMOTE_ADDR
  • REMOTE_HOST
  • REMOTE_PORT
  • REMOTE_USER
  • REMOTE_IDENT
  • REQUEST_METHOD
  • SCRIPT_FILENAME
  • PATH_INFO
  • QUERY_STRING
  • AUTH_TYPE
  • DOCUMENT_ROOT
  • SERVER_ADMIN
  • SERVER_NAME
  • SERVER_ADDR
  • SERVER_PORT
  • SERVER_PROTOCOL
  • SERVER_SOFTWARE
  • TIME_YEAR
  • TIME_MON
  • TIME_DAY
  • TIME_HOUR
  • TIME_MIN
  • TIME_SEC
  • TIME_WDAY
  • TIME
  • API_VERSION (returns IIS version)
  • THE_REQUEST
  • REQUEST_URI
  • REQUEST_FILENAME
  • IS_SUBREQ
  • HTTPS
  • All special IIS variables are also supported


Context and processing order

The following context specifiers are used in this documentation:

server config

This indicates that directive can be used in global httpd.conf configuration file but not within any section like <VirtualHost> or <Directory>. It is not allowed in .htaccess files at all.

virtual host

This means directive may appear inside <VirtualHost> containers.

directory

This mark indicates directive is valid inside <Directory>, <Location>, <Files> containers and their regular expression equivalents.

.htaccess

Directive marked with this context can appear inside per-directory .htaccess files. Remember when RewriteRule directive is used inside .htaccess configuration files it will automatically strip the local directory prefix from the path and apply rules only to the remainder. You can use RewriteBase directive to explicitly specify a base path for the rules.

Application order

While directives within one section always apply simulteneously, it is important to understand the order of application of each section because it may have effect on a final result. So the order of application is as follows:

  1. <Directory> (except regular expressions). Multiple <Directory> sections can be applied to a single request. If multiple (non-regular expression) <Directory> sections match the directory (or one of its parents) containing a document, then the directives are applied in the order of shortest match first.
  2. .htaccess files are applied from parent to descendant.
  3. <Files> and <FilesMatch> are executed simultaneously.
  4. <Location> and <LocationMatch> are executed simultaneously.

Sections and directives inside <VirtualHost> sections are applied after the corresponding sections and directives outside the virtual host definition. Only one <VirtualHost> section can apply to request at a time. Later sections override earlier ones.


Regular expression syntax

This regular expression syntax guide is a part of Regex++ documentation, kindly provided by Dr John Maddock, Copyright © 1998-2004 and covered by a Boost license. Complete description of the syntax could be found in the Boost.Regex documentation.

Literals

All characters are literals except: ".", "*", "?", "+", "(", ")", "{", "}", "[", "]", "^" and "$". These characters are literals when preceded by a "\". A literal is a character that matches itself.

Wildcard

The dot character "." matches any single character except null character and newline character.

Repeats

A repeat is an expression that is repeated an arbitrary number of times. An expression followed by "*" can be repeated any number of times including zero. An expression followed by "+" can be repeated any number of times, but at least once. An expression followed by "?" may be repeated zero or one times only. When it is necessary to specify the minimum and maximum number of repeats explicitly, the bounds operator "{}" may be used, thus "a{2}" is the letter "a" repeated exactly twice, "a{2,4}" represents the letter "a" repeated between 2 and 4 times, and "a{2,}" represents the letter "a" repeated at least twice with no upper limit. Note that there must be no white-space inside the {}, and there is no upper limit on the values of the lower and upper bounds. All repeat expressions refer to the shortest possible previous sub-expression: a single character; a character set, or a sub-expression grouped with "()" for example.

Examples:

  • "ba*" will match all of "b", "ba", "baaa" etc.
  • "ba+" will match "ba" or "baaaa" for example but not "b".
  • "ba?" will match "b" or "ba".
  • "ba{2,4}" will match "baa", "baaa" and "baaaa".

Non-greedy repeats

Non-greedy repeats are possible by appending a '?' after the repeat; a non-greedy repeat is one which will match the shortest possible string.

For example to match html tag pairs one could use something like:

"<\s*tagname[^>]*>(.*?)<\s*/tagname\s*>"

In this case $1 will contain the text between the tag pairs, and will be the shortest possible matching string.

Parenthesis

Parentheses serve two purposes, to group items together into a sub-expression, and to mark what generated the match. For example the expression "(ab)*" would match all of the string "ababab". All sub matches marked by parenthesis can be back referenced using \N or $N syntax. It is permissible for sub-expressions to match null strings. Sub-expressions are indexed from left to right starting from 1, sub-expression 0 is the whole expression.

Non-Marking Parenthesis

Sometimes you need to group sub-expressions with parenthesis, but don't want the parenthesis to spit out another marked sub-expression, in this case a non-marking parenthesis (?:expression) can be used. For example the following expression creates no sub-expressions:

"(?:abc)*"

Alternatives

Alternatives occur when the expression can match either one sub-expression or another, each alternative is separated by a "|". Each alternative is the largest possible previous sub-expression; this is the opposite behavior from repetition operators.

Examples:

  • "a(b|c)" could match "ab" or "ac".
  • "abc|def" could match "abc" or "def".

Sets

A set is a set of characters that can match any single character that is a member of the set. Sets are delimited by "[" and "]" and can contain literals, character ranges, character classes, collating elements and equivalence classes. Set declarations that start with "^" contain the compliment of the elements that follow.

Examples:

Character literals:

  • "[abc]" will match either of "a", "b", or "c".
  • "[^abc] will match any character other than "a", "b", or "c".

Character ranges:

  • "[a-z]" will match any character in the range "a" to "z".
  • "[^A-Z]" will match any character other than those in the range "A" to "Z".

Character classes

Character classes are denoted using the syntax "[:classname:]" within a set declaration, for example "[[:space:]]" is the set of all whitespace characters. The available character classes are:

alnum | Any alpha numeric character.
alpha | Any alphabetical character a-z and A-Z. Other characters may also be included depending upon the locale.
blank | Any blank character, either a space or a tab.
cntrl | Any control character.
digit | Any digit 0-9.
graph | Any graphical character.
lower | Any lower case character a-z. Other characters may also be included depending upon the locale.
print | Any printable character.
punct | Any punctuation character.
space | Any whitespace character.
upper | Any upper case character A-Z. Other characters may also be included depending upon the locale.
xdigit | Any hexadecimal digit character, 0-9, a-f and A-F.
word | Any word character - all alphanumeric characters plus the underscore.
unicode | Any character whose code is greater than 255, this applies to the wide character traits classes only.

There are some shortcuts that can be used in place of the character classes:

  • \w in place of [:word:]
  • \s in place of [:space:]
  • \d in place of [:digit:]
  • \l in place of [:lower:]
  • \u in place of [:upper:]

Collating elements

Collating elements take the general form [.tagname.] inside a set declaration, where tagname is either a single character, or a name of a collating element, for example [[.a.]] is equivalent to [a], and [[.comma.]] is equivalent to [,]. ISAPI_Rewrite supports all the standard POSIX collating element names, and in addition the following digraphs: "ae", "ch", "ll", "ss", "nj", "dz", "lj", each in lower, upper and title case variations. Multi-character collating elements can result in the set matching more than one character, for example [[.ae.]] would match two characters, but note that [^[.ae.]] would only match one character.

Equivalence classes

Equivalence classes take the general form [=tagname=] inside a set declaration, where tagname is either a single character, or a name of a collating element, and matches any character that is a member of the same primary equivalence class as the collating element [.tagname.]. An equivalence class is a set of characters that collate the same, a primary equivalence class is a set of characters whose primary sort key are all the same (for example strings are typically collated by character, then by accent, and then by case; the primary sort key then relates to the character, the secondary to the accentation, and the tertiary to the case). If there is no equivalence class corresponding to tagname, then [=tagname=] is exactly the same as [.tagname.].

To include a literal "-" in a set declaration then: make it the first character after the opening "[" or "[^", the endpoint of a range, a collating element, or precede it with an escape character as in "[\-]". To include a literal "[" or "]" or "^" in a set then make them the endpoint of a range, a collating element, or precede with an escape character.

Line anchors

An anchor is something that matches the null string at the start or end of a line: "^" matches the null string at the start of a line, "$" matches the null string at the end of a line.

Back references

A back reference is a reference to a previous sub-expression that has already been matched, the reference is to what the sub-expression matched, not to the expression itself. A back reference consists of the escape character "\" followed by a digit "1" to "9", "\1" refers to the first sub-expression, "\2" to the second etc. For example the expression "(.*)\1" matches any string that is repeated about its mid-point for example "abcabc" or "xyzxyz". A back reference to a sub-expression that did not participate in any match, matches the null string. In ISAPI_Rewrite all back references are global for entire RewriteRule and corresponding RewriteCond directives. Sub matches are numbered up to down and left to right beginning from the first RewriteCond directive of the corresponding RewriteRule directive, if there is one.

Forward Lookahead Asserts

There are two forms of these; one for positive forward lookahead asserts, and one for negative lookahead asserts:

  • "(?=abc)" matches zero characters only if they are followed by the expression "abc".
  • "(?!abc)" matches zero characters only if they are not followed by the expression "abc".

Word operators

The following operators are provided for compatibility with the GNU regular expression library.

  • "\w" matches any single character that is a member of the "word" character class, this is identical to the expression "[[:word:]]".
  • "\W" matches any single character that is not a member of the "word" character class, this is identical to the expression "[^[:word:]]".
  • "\<" matches the null string at the start of a word.
  • "\>" matches the null string at the end of the word.
  • "\b" matches the null string at either the start or the end of a word.
  • "\B" matches a null string within a word.

Escape operator

The escape character "\" has several meanings.

  • The escape operator may introduce an operator for example: back references, or a word operator.
  • The escape operator may make the following character normal, for example "\*" represents a literal "*" rather than the repeat operator.

Single character escape sequences:

The following escape sequences are aliases for single characters:

Escape sequence | Character code | Meaning
\a | 0x07 | Bell character.
\t | 0x09 | Tab character.
\v | 0x0B | Vertical tab.
\e | 0x1B | ASCII Escape character.
\0dd | 0dd | An octal character code, where dd is one or more octal digits.
\xXX | 0xXX | A hexadecimal character code, where XX is one or more hexadecimal digits.
\x{XX} | 0xXX | A hexadecimal character code, where XX is one or more hexadecimal digits, optionally a unicode character.
\cZ | z-@ | An ASCII escape sequence control-Z, where Z is any ASCII character greater than or equal to the character code for '@'.

Miscellaneous escape sequences:

The following are provided mostly for perl compatibility, but note that there are some differences in the meanings of \l \L \u and \U:

Escape sequence | Meaning
\w | Equivalent to [[:word:]].
\W | Equivalent to [^[:word:]].
\s | Equivalent to [[:space:]].
\S | Equivalent to [^[:space:]].
\d | Equivalent to [[:digit:]].
\D | Equivalent to [^[:digit:]].
\l | Equivalent to [[:lower:]].
\L | Equivalent to [^[:lower:]].
\u | Equivalent to [[:upper:]].
\U | Equivalent to [^[:upper:]].
\C | Any single character, equivalent to '.'.
\X | Match any Unicode combining character sequence, for example "a\x 0301" (a letter a with an acute).
\Q | The begin quote operator, everything that follows is treated as a literal character until a \E end quote operator is found.
\E | The end quote operator, terminates a sequence begun with \Q.

What gets matched?

The regular expression will match the first possible matching string, if more than one string starting at a given location can match then it matches the longest possible string. In cases where their are multiple possible matches all starting at the same location, and all of the same length, then the match chosen is the one with the longest first sub-expression, if that is the same for two or more matches, then the second sub-expression will be examined and so on. Note that ISAPI_Rewrite uses MATCH algorithm. The result is matched only if the expression matches the whole input sequence. For example:

  • RewriteCond URL ^/somedir/.* #will match any request to somedir directory and subdirectories, while
  • RewriteCond URL ^/somedir/ #will match only request to the root of the somedir.

Special note about "pathological" regular expressions

ISAPI_Rewrite uses a very powerful regular expressions engine Regex++ from Boost library. However it has some limitations: There exists some "pathological" expressions which may require exponential time for matching; these all involve nested repetition operators, for example attempting to match the expression "(a*a)*b" against N letter a's requires time proportional to 2N. These expressions can (almost) always be rewritten in such a way as to avoid the problem, for example "(a*a)*b" could be rewritten as "a*b" which requires only time linearly proportional to N to solve. In the general case, non-nested repeat expressions require time proportional to N2, however if the clauses are mutually exclusive then they can be matched in linear time - this is the case with "a*b", for each character the matcher will either match an "a" or a "b" or fail, where as with "a*a" the matcher can't tell which branch to take (the first "a" or the second) and so has to try both.

Regex++ can detect such "pathological" regular expressions and terminate theirs matching. This will cause ISAPI_Rewrite's rule to fail. When a rule fails ISAPI_Rewrite sends "500 Internal Server error - Rule Failed" status to a client to indicate configuration error.


AccessFileNamee

AccessFileName directive

Description: | Sets name of distributed configuration file
Syntax: | AccessFileName filename [filename] ...
Default: | AccessFileName .htaccess
Context: | server config

Specifies a list of file names that ISAPI_Rewrite will look for distributed configurations. Default file name is .htaccess. ISAPI_Rewrite will only load the first found file in this list. By default ISAPI_Rewrite Manager will mark configuration files with hidden attribute - this will prevent the file from being requested directly by a remote user.

When any changes are applied to the configuration file it will be reloaded automatically upon the next request to the server.


AllowOverride

AllowOverride directive

Description: | Explicitly sets the base URL for per-directory rewrites.
Syntax: | AllowOverride All|None|directive-type [directive-type] ...
Default: | AllowOverride All
Context: | server config, virtual host, directory

This directive decalres which directives in distributed .htaccess files can override directives from the parent levels (httpd.conf). In context of ISAPI_Rewrite this directive in fact enables or disables .htaccess files for specific virtual host (web site) or directory. Only three values are currently supported: All, None and FileInfo.

All and FileInfo enables .htaccess file and all ISAPI_Rewrite directives in it. None disables all .htaccess files and directives. This directive is inheritable. This means if you specify AllowOverride none for some directory or virtual host .htaccess files will also be disabled for all subdirectories.


RewriteEngine

RewriteEngine directive

Description: | Enables or disables runtime rewriting engine
Syntax: | RewriteEngine on|off
Default: | RewriteEngine off
Context: | server config, virtual host, directory, .htaccess

Enables or disables rewriting runtime. Use RewriteEngine off instead of commenting out rewrite rules if you need to disable ISAPI_Rewrite module or specific .htaccess file.

WARNING! Due to the number of support queries we had to enable rewriting engine by default whilst in Apache rewriting engine by default is off. Please keep in mind this small incompatibility and always specify explicit status of rewriting engine in each configuration file, whether you need it on or off.


RewriteRule

RewriteRule directive

Description: | Defines URL rewriting rule
Syntax: | RewriteRule Pattern Substitution [flags]
Context: | server config, virtual host, directory, .htaccess

This directive defines a single URL rewriting operation. It may occur more that once in configuration file with each instance defining a rule to rewrite URL. RewriteRule directive consists of URL matching Pattern, Substitution string and optional set of flags.

Pattern is a Perl compatible regular expression which will be matched against current URL. The current URL can be originally requested URL or URL already altered by preceding rules. URL never includes protocol or host name and starts from the first slash character (true for httpd.conf only). Also current URL differs depending on a level of configuration that is applied, i.e. for directory level configuration (.htaccess file) trailing slash and configuration file directory name will be omitted from the URL to match against. Please see Regular expression syntax section of the documentation for more information on building regular expressions.

Preceding pattern by a '!' character will negate entire expression. Negated pattern cannot generate submatches so you cannot use $N references in substitution.

Substitution string specifies format string to generate new URL if the Pattern was matched. In addition to plain text, it can include these special characters:

  • back references to RewriteRule pattern $N ($0-$9) and $$NN ($$10-$$99)
  • back references to RewriteCond patterns %N (%0-%9) and %%NN (%%10-%%99)
  • server variables %{VARNAME}
  • conditional format patterns ?Ntrue_string:false_string
  • grouping parenthesis ‘(‘ and ‘)’

Substitution strings treat all characters as literals except for '$', '\', '(', ')', '?', ':' and '\'. For special characters to be interpreted literally, they must be escaped with '\'. The following special characters are allowed:

$& | Outputs what matched the whole expression.
$` | Outputs the text between the end of the last match found (or the start of the text if no previous match was found), and the start of the current match.
$' | Outputs all the text following the end of the current match.
$$ | Outputs a literal '$'
\a | The bell character.
\f | The form feed character.
\n | The newline character.
\r | The carriage return character.
\t | The tab character.
\v | A vertical tab character.
\x | A hexadecimal character - for example \x0D.
\x{} | A possible Unicode hexadecimal character - for example \x{1A0}
\cx | The ASCII escape character x, for example \c@ is equivalent to escape-@.
\e | The ASCII escape character.
\dd | An octal character constant, for example \10.
\l | Causes the next character to be outputted, to be output in lower case.
\u | Causes the next character to be outputted, to be output in upper case.
\L | Causes all subsequent characters to be output in lower case, until a \E is found.
\U | Causes all subsequent characters to be output in upper case, until a \E is found.
\E | Terminates a \L or \U sequence.
\\ | Single back slash character '\'

RewriteRules are applied in the order of appearance in configuration file, starting from the parent configuration files. Each rule will apply only if its Pattern matches a URL and all related conditions (RewriteCond) are also matched. After that URL is completely replaced by a Substitution and rewriting process continues until the end of configuration file or a rule with any of the stop flags. Special string '-' (dash) in Substitution means no substitution and is useful when you need to apply the rule while leaving original URL untouched.

Additionally here is the list of supported flags that can alter rule behavior. Fully Apache compatible flags are marked green, unsupported flags are red, and additional flags supported by ISAPI_Rewrite only are yellow. ISAPI_Rewrite will ignore all unsupported flags.

  • CU (Case Upper)

    Changes the case of substitution result to upper.
  • CL (Case Lower)

    Changes the case of substitution result to lower.
  • chain|C

    Chains current rule with the next rule. Next rule will be executed only if current rule is matched. Chain can be subsequent.
  • cookie|CO=NAME:VAL:domain[:lifetime[:path]]

    Sets a cookie header with the fields specified and send it to the client with the response to the current request.
  • env|E=VAR:VAL

    Unsupported. In UNIX environment sets an environment variable. Meaningless for Windows systems.
  • forbidden|F

    Sends immediate 403 FORBIDDEN response to the client. Stops rule processing and all other subsequent processing on this request.
  • gone|G

    Sends immediate 401 GONE response to the client. Stops rule processing and all other subsequent processing on this request.
  • handler|H=Content-handler

    Unsupported. Explicitly specifies handler for a request. In IIS world this can be achieved by rewriting file extension of requested file but there is no direct translation from Apache handlers to IIS file extensions.
  • last|L

    Stops rewrite process here and doesn’t apply any more rules from the current configuration file. Descendant .htaccess files will still be applied if any.
  • loop|LP

    Re-runs current single rule in the loop while it’s pattern and conditions are matched. Number of iterations is limited to a value of 200 to avoid infinite loops.
  • next|N

    Re-runs rewriting process starting from the beginning of current configuration file. Number of iterations is limited to a value of 200 to avoid infinite loops.
  • nocase|NC

    This flag makes the Pattern case-insensitive.
  • noescape|NE

    Don't escape output. By default ISAPI_Rewrite will encode all non-ANSI characters as %xx hex codes in output.
  • nosubreq|NS

    ISAPI_Rewrite meaning of this flag differs from Apache. Exact translation isn't possible, but this flag may still be useful. Every time when configuration file processing has been finished and URL has been rewritten, ISAPI_Rewrite will start processing with this new URL again (same as Apache) making it possible to apply another configuration file. This flag means that the rule should be executed only for initial user request and not for rewritten requests, to prevent possible loops. ISAPI_Rewrite limits the number of loops to 10 repetitions.
  • nounicode|NU

    If NU flag is set, transformation from Unicode to UTF-8 will not take place and all Unicode characters remain encoded in %xx format.
  • O (nOrmalize)

    Left for compatibility with ISAPI_Rewrite 2.x. If RewriteCompatibility2 on is used, this directive normalizes URL before processing. Normalization includes removing of an URL-encoding, illegal characters, etc. Also normalization of URL completely removes query string from it. If no RewriteCompatibility2 on is used, URLs are normalized by default (as it is done in mod_rewrite) and meaning of this flag is inverted.
  • proxy|P

    Forces the resulting URL to be internally treated as a target on another server and immediately (i.e. rules processing stops here) passed to the remote server. Response of the remote server will then be passed back to the client. Proxy requires you to specify fully qualified URL, starting from protocol, host name, etc. ISAPI_Rewrite uses ISAPI extension to handle proxy requests. You can read more about this in configuring proxy chapter.
  • passthrough|PT

    Unsupported or always on. Result is always passed through the next handler in IIS.
  • qsappend|QSA

    Appends current query string data to a substitution string instead of replacing it by a substitution. Use this when you need to add more query string parameters while preserving original parameters.
  • redirect|R [=code]

    Forces server to send immediate response to client with redirect instruction, providing Substitution as a new location. It can optionally prefix Substitution with http://thishost[:thisport]/ bringing URL to a valid absolute form. If no code is given, a HTTP response of 302 (MOVED TEMPORARILY) will be used. You can optionally specify any code from 3xx range.
  • skip|S=num

    Forces the rewriting engine to skip the next num rules in sequence if the current rule matches.
  • type|T=MIME-type

    Forces the MIME-type of the target file to be MIME-type. This can be used to set up the content-type based on some conditions.
  • U (Unmangle log)

    Unmangle log. Log the URL as it was originally requested and not as the URL was rewritten.


RewriteCond

RewriteCond directive

Description: | Defines a condition for the subsequent RewriteRule
Syntax: | RewriteCond TestString CondPattern
Context: | server config, virtual host, directory, .htaccess

This directive defines a single condition for the following RewriteRule, RewriteHeader or RewriteProxy directive. There can be one or more conditions preceding a rule directive and the rule will only apply if all of the conditions are met.

TestString additionally to plain text can contain the following constructs:

  • Back references to RewriteRule pattern using syntax $N.
  • Back references to preceding RewriteCond patterns using syntax %N.
  • RewriteMap expansions using syntax ${mapname:key|default}.
  • HTTP header value with the syntax %{HTTP:header}.
  • Server variable using the syntax %{ NAME_OF_VARIABLE }.
    Here is a list of available server variables:|

    HTTP_USER_AGENT
    HTTP_REFERER
    HTTP_COOKIE
    HTTP_FORWARDED
    HTTP_HOST
    HTTP_PROXY_CONNECTION
    HTTP_ACCEPT

    REMOTE_ADDR
    REMOTE_HOST
    REMOTE_PORT
    REMOTE_USER
    REMOTE_IDENT
    REQUEST_METHOD
    SCRIPT_FILENAME
    PATH_INFO
    QUERY_STRING
    AUTH_TYPE

    DOCUMENT_ROOT
    SERVER_NAME
    SERVER_ADDR
    SERVER_PORT
    SERVER_PROTOCOL
    SERVER_SOFTWARE

    API_VERSION
    THE_REQUEST
    REQUEST_URI
    REQUEST_FILENAME
    HTTPS

    TIME_YEAR
    TIME_MON
    TIME_DAY
    TIME_HOUR
    TIME_MIN
    TIME_SEC
    TIME_WDAY
    TIME

    Additionally all special IIS server variables are supported.

CondPattern specifies a regular expression that will be applied to the instance of TestString. Following special values are also supported:

  1. Prefix regular expression with '!' symbol to specify negation pattern.
  2. '<CondPattern' Treats CondPattern as a plain string that will be lexicographically compared as more than.
  3. '>CondPattern' Lexicographically less then comparison.
  4. '=CondPattern' Lexicographically equals comparison.
  5. '-d' Test string is existing directory.
  6. '-f' Test string is existing file.
  7. '-s' Test string is a file with nonzero size.
  8. '-l' (link) Unsupported, always false.
  9. '-x' (has executable permissions) Unsupported, always true.
  10. '-F' (is existing file, via subrequest) Unsupported, same as '–f'.
  11. '-U' (is existing URL, via subrequest) Unsupported, always false.

The following flags are also supported:

  • 'nocase|NC'

    This flag makes the Pattern case-insensitive.
  • 'ornext|OR'

    This flag combines subsequent RewriteCond directives with logical OR instead of implicit AND.
  • O

    Leaved for compatibility with ISAPI_Rewrite 2.x. Normalizes string before processing. Normalization includes removing of an URL-encoding, illegal characters, etc. Also, IIS normalization of a URL completely removes query string from it.


RewriteBase

RewriteBase directive

Description: | Explicitly sets the base URL for per-directory rewrites.
Syntax: | RewriteBase URL-path
Default: | RewriteBase requested-directory-path
Context: | directory, .htaccess

When RewriteRule directive is used in per-directory configuration files (.htaccess) it will automatically strip the local directory prefix from the path and apply rules only to the remainder. RewriteBase directive allows you to explicitly specify a base for the rules, i.e. the part that will be stripped.

Unlike Apache mod_rewrite, ISAPI_Rewrite has access not only to the physical path, but also to the virtual path and can automatically choose correct base. So this directive is preserved only for the compatibility reasons.

URL-path can be root relative path or empty. Empty URL-path value meand thet rule base will equal to web site root.


RewriteProxy

RewriteProxy directive

Description: | Proxy request to a distant server
Syntax: | RewriteProxy Pattern Substitution [flags]
Context: | server config, virtual host, directory, .htaccess

RewriteProxy directive causes the resulting URL to be internally treated as a target on another server and immediately (i.e. rules processing stops here) passed to the remote server. Response of the remote server will then be passed back to the client. Proxy requires you to specify fully qualified URL, starting from protocol, host name, etc. ISAPI_Rewrite uses ISAPI extension to handle proxy requests.

Syntax and operation is the same as for RewriteRule directive, but RewriteProxy directive supports some additional flags:

  • H (preserve Host)

    Proxy module will use Host header sent in original request when connecting to remote server. Without this flag proxy will compose Host header from a host name and a port of a remote server.
  • A (Add authentication headers)

    Allows passing of an authentication information from proxy to an internal server when client authentication against a proxy server is used. Proxy module will append headers
    X-ISRW-Proxy-AUTH-TYPE,
    X-ISRW-Proxy-AUTH-USER,
    X-ISRW-Proxy-LOGON-USER,
    X-ISRW-Proxy-REMOTE-USER
    corresponding to server variables
    AUTH_TYPE,
    AUTH_USER,
    LOGON_USER,
    REMOTE_USER
    to a request sent to a proxied server.

  • CR (use Credentials)

    Proxy module will try to login on a remote server with the credentials specified in the URL or basic authentication headers. With this flag you can use http://user:password@host.com/path/ syntax as a URL within substitution string.

Proxy settings

ISAPI_Rewrite provides an opportunity to adjust some general proxy settings:

  • ProxyConnectTimeout — if a connection request takes longer than this time-out value, the request is canceled.
  • ProxySendTimeout — if sending a request takes longer than this time-out value, the send is canceled.
  • ProxyReceiveTimeout — if a response takes longer than this time-out value, the request is canceled.
  • ProxySuppressErrors — when On, proxy module will give out 500 Internal Server Error for any failures that may occur, while with Off, detailed error explanation is provided (helpful for maintenance).

Default values (in seconds) are shown in the example below:

<Helicon>
ProxyConnectTimeout 60
ProxySendTimeout 30
ProxyReceiveTimeout 30
ProxySuppressErrors On
</Helicon>

Note! <Helicon> section may be located either in the httpd.conf or in a specific <VirtualHost>.


RewriteHeader

RewriteHeader directive

Description: | Rewrites any HTTP header in request
Syntax: | RewriteHeader HeaderName: Pattern Substitution [flags]
Context: | server config, virtual host, directory, .htaccess

RewriteHeader directive is more general variant of RewriteRule directive and it is designed to rewrite not only the URL part of client request, but any HTTP header. Technically RewriteRule directive is equivalent to the RewriteHeader URL Pattern Substitution [flags]. This directive can be used to rewrite, create or delete any HTTP headers in the client request before it will be processed by further applications on IIS.

HeaderName: specifies name of HTTP header that will be rewritten.

Pattern, Substitution and flags are the same as for RewriteRule directive.


RewriteMap

RewriteMap directive

Description: | Defines a key to value mapping function
Syntax: | RewriteMap MapName MapType:MapSource
Context: | server config, virtual host, directory, .htaccess

RewriteMap directive is used to define a key-to-value lookup function. This is useful when you need to map large amount of values since it is much faster than doing it with rule matching. Performance of map function rely on a size of map file insignificantly. There are three types of mapping:

  • txt: mapping using text file map;
  • rnd: random value select from multiple choices;
  • int: internal functions.

MapName is the name of mapping function that will be used to refer to this map from RewriteRule command. Make sure that every mapping is defined with a unique name. You can call mapping function in the Substitution value of RewriteRule directive using the following syntax:

${ MapName : LookupKey | DefaultValue }

If this construction is found in Substitution, ISAPI_Rewrite will lookup for the key in the map and if one is found, substitute the construct by its value. If no key is found, optional DefaultValue will be used. If no DefaultValue is specified, it will be substituted by an empty string.

The following flag is also supported:

  • 'nocase|NC'

    This flag makes the LookupKey case-insensitive.

Here is an example of case-insensitive mapfile declaration:

RewriteMap examplemap txt:C:/path/to/file/map.txt [NC]

Path to MapSource file could be either absolute or relative. Relative path is calculated from the folder with current configuration file, i.e. from the configuration file path where this map has been declared.

Then you may use this map in RewriteRule as follows:

RewriteRule ^/ex/(.*) ${examplemap:$1}

The following combinations for MapType and MapSource can be used:

txt: Plain text mapping. The source is a Windows file system path to a valid text file. Text file should be of the following format:

#This is a comment

key1 value1
key2 value2
keyN valueN

rnd: Random multiple values lookup. Source is the path to a text file of the following format:

#This is a comment

key1 value1|value2|value3
key2 value4|value5|value6|valueN

int: Internal function call. Source should be one of the following pre-defined internal functions:

  • toupper: Converts the key to all upper case.
  • tolower: Converts the key to all lower case.
  • escape: Encode special characters to hex values.
  • unescape: Un-encode hex values to special characters.


RewriteLog

RewriteLog directive

Description: | Sets name of ISAPI_Rewrite log file
Syntax: | RewriteLog file-path
Default: | RewriteLog installdir\rewrite.log
Context: | server config

This directive sets the name of the log file where ISAPI_Rewrite will log all its actions.

RewriteLog "C:\local\path\rewrite.log"


RewriteLogLevel

RewriteLogLevel directive

Description: | Sets the level of logging
Syntax: | RewriteLogLevel Level
Default: | RewriteLogLevel 0
Context: | server config

This directive sets the verbosity of logging output. The default value of 0 means no logging while maximum level of 9 means all actions will be logged.

Using higher values of logging may slow down ISAPI_Rewrite operation. We recommend you to disable logging by setting log level to 0 after debugging of your ruleset has been completed.


RewriteOptions

RewriteOptions directive

Description: | Specify special options
Syntax: | RewriteOptions Options
Context: | server config, virtual host, directory, .htaccess

This directive can set special options for ISAPI_Rewrite. Currently only one option is available - inherit.

inherit: Forces current config to inherit all options and rules from the parent. This means that all rules from the parent config will be executed again but from the context as if they were written in the current config.


RewriteCompatibility2

RewriteCompatibility2 directive

Description: | Enables or disables ISAPI_Rewrite 2.x compatibility mode
Syntax: | RewriteCompatibility2 on|off
Default: | RewriteCompatibility2 off
Context: | server config, virtual host, directory, .htaccess

This directive enables compatibility features with ISAPI_Rewrite version 2.x and it is required for correct translation of some 2.x rules into 3.0 version syntax. This does not mean that ISAPI_Rewrite 3 will start to understand old syntax without modification. If you have old rules designed for ISAPI_Rewrite 2.x please use translation tool provided with ISAPI_Rewrite manager to translate these rules into new syntax.

For now the only thing changed by setting RewriteCompatibility2 on directive is that it turns off URL pre-normalisation and removal of query string. Apache mod_rewrite remove query string part from the matching URL, while ISAPI_Rewrite 2.x match entire URL including query string. Also meaning of [O] flag will be inverted by this directive.


ErrorLog

ErrorLog directive

Description: | Location of general errors file
Syntax: | ErrorLog file-path
Default: | ErrorLog installdir\error.log
Context: | server config

This directive sets the name of the log file where ISAPI_Rewrite will log general errors and messages such as httpd.conf file load, .htaccess file(s) load, permissions issues etc.

ErrorLog "C:\local\path\error.log"


LogLevel

LogLevel directive

Description: | Sets the level of logging for general errors
Syntax: | LogLevel Level
Default: | LogLevel warn
Context: | server config

This directive sets the verbosity of general logging output, not related to rewriting process itself. Here is a list of available values for level: emerg, alert, crit, error, warn, notice, info, debug. Currently ISAPI_Rewrite logs only debug and crit error messages.

Set LogLevel debug to troubleshoot configuration file loading problems.


<VirtualHost>

<VirtualHost> directive

Description: | Group directives that will be applied to specific IP address or host name
Syntax: | <VirtualHost addr[:port] [addr[:port]] ...> ... </VirtualHost>
Context: | server config

<VirtualHost> ... </VirtualHost> tag is used to group directives that will apply to specific virtual host.

Possible values for addr are:

  • Specific IP address;
  • Fully qualified domain name;
  • The character '*' to match any host or any port number for specific host.

Example:

RewriteEngine off
AllowOverride none

<VirtualHost onesite.com www.onesite.com>

RewriteEngine on
AllowOverride all

</VirtualHost>

Don't forget to include RewriteEngine on directive in every <VirtualHost> tag or enclosed rules will not be applied.


<Directory>

<Directory> directive

Description: | Group directives that will be applied to specific file-system directory and sub-directories
Syntax: | <Directory directory-path> ... </Directory>
Context: | server config, virtual host

<Directory> ... </Directory> tag is used to group directives that will apply to specific file-system directory and sub-directories. Wildcard characters ? and * are allowed. Regular expressions can also be used with the addition of the ~ character.

Be careful with the directory-path arguments: They have to literally match the filesystem path which is used to access files. Directives applied to a particular <Directory> will not apply to files accessed from that same directory via a different path, such as via different symbolic links. Only fully qualified file paths are allowed.

Example:

<Directory C:/inetpub/>
AllowOverride None
</Directory>

<Directory C:/inetpub/home/>
AllowOverride FileInfo
</Directory>

<Directory ~ "C:/inetpub/wwwroot/.*/[0-9]{3}">
# ... directives here ...
</Directory>

Don't forget to include RewriteEngine on directive in every <VirtualHost> tag or enclosed rules will not be applied.


<DirectoryMatch>

<DirectoryMatch> directive

Description: | Group directives that will be applied to specific file-system directory and sub-directories
Syntax: | <DirectoryMatch regex> ... </DirectoryMatch>
Context: | server config, virtual host

<DirectoryMatch> ... </DirectoryMatch> is used to enclose a group of directives which will apply only to the named file system directory and sub-directories. This directive is the same as <Directory ~> syntax.

Example:

<DirectoryMatch "^/www/(.+/)?[0-9]{3}">
# ... directives here ...
</DirectoryMatch>

Don't forget to include RewriteEngine on directive in every <VirtualHost> tag or enclosed rules will not be applied.


<Files>

<Files> directive

Description: | Enclose directives that apply to matched filenames
Syntax: | <Files filename> ... </Files>
Context: | server config, virtual host, directory, .htaccess

The <Files> directive limits the scope of the enclosed directives by filename. The filename argument should include a filename, supports ? and * wildcards and regular expressions with the addition of the ~ character.

Example:

<Files index.*>
# ... directives here ...
</Files>

<Files ~ "\.(gif|jpe?g|png)$">
# ... directives here ...
</Files>

Don't forget to include RewriteEngine on directive in every <VirtualHost> tag or enclosed rules will not be applied.


<FilesMatch>

<FilesMatch> directive

Description: | Enclose directives that apply to matched filenames
Syntax: | <FilesMatch regex> ... </FilesMatch>
Context: | server config, virtual host, directory, .htaccess

The <FilesMatch> directive is exactly the same as <Files ~> syntax.

<FilesMatch "\.(gif|jpe?g|png)$">

Don't forget to include RewriteEngine on directive in every <VirtualHost> tag or enclosed rules will not be applied.


<Location>

<Location> directive

Description: | Applies the enclosed directives only to matching URL or virtual path
Syntax: | <Location URL-path|URL> ... </Location>
Context: | server config, virtual host

<Location> ... </Location> tag is used to group directives that will apply to specific URL or virtual path. <Location> sections operate completely outside the filesystem thus these directives should not be used to control access to filesystem locations since several different URLs may map to the same filesystem location.

The URL-path is a virtual path of the form /path/. No protocol, hostname, port, or query string may be included. URL-path may include wildcards ? and * or regular expression starting with the ~ character.

Example:

<Location /directory>

# ... rules go here

</Location>

<Location />

# ... more rules go here

</Location>

Don't forget to include RewriteEngine on directive in every <VirtualHost> tag or enclosed rules will not be applied.


<LocationMatch>

<LocationMatch> directive

Description: | Applies the enclosed directives only to regular-expression matching URLs
Syntax: | <LocationMatch regex> ... </LocationMatch>
Context: | server config, virtual host

This directive is exactly the same as <Location ~> regular expression syntax.

Example:

<LocationMatch "/(home|section)/bin">

# ... rules go here

</LocationMatch>

Don't forget to include RewriteEngine on directive in every <VirtualHost> tag or enclosed rules will not be applied.


NotificationType

NotificationType directive

Description: | Location of general errors file
Syntax: | NotificationType=PREPROC_HEADERS
Default: | not set
Context: | server config

This directive swithes ISAPI_Rewrite into Early Request Processing mode, i.e. ISAPI_Rewrite will process request BEFORE all other ISAPI filters, BUT the following features will be unavailable:

  1. %{REQUEST_FILENAME} variable
  2. <Files>, <FilesMatch>, <Directory>, <DirectoryMatch> sections

NotificationType=PREPROC_HEADERS


Examples

Note! All rules in these examples are intended for httpd.conf file. In ISAPI_Rewrite as well as in Apache mod_rewrite base path for rules is different depending on a directory where you put .htaccess file. Initial leading slash only exist if you put rules in httpd.conf, while in .htaccess files virtual path to these files is truncated. Rules that rely on a root path are preceded with RewriteBase / directive to allow them to work in any location within httpd.conf and directory level .htaccess files.

Simple search engine friendly URLs

This example demonstrates how to easily hide query string parameters using loop flag. Suppose you have URL like http://www.mysite.com/foo.asp?a=A&b=B&c=C and you want to access it as http://www.myhost.com/foo.asp/a/A/b/B/c/C

Try the following rule to achieve desired result:

RewriteEngine on
RewriteRule ^(.*?\.asp)/([^/]*)/([^/]*)(/.+)? $1$4?$2=$3 [NC,LP,QSA]

Note that this rule may break page-relative links to CSSs, images, etc. This is happening due to a change of the base path (parent folder of the page) that is being used by a browser to calculate complete resource URI. This problem occurs only if you use directory separator as a replacement character. There are three possible solutions:

  1. Use the rule given below. It does not affect base path because does not use directory separator character '/'.
  2. Directly specify correct base path for a page with the help of <base href="/folder/"> tag.
  3. Change all page-relative links to either root-relative or absolute form.

There also exist many variations of this rule with different separator characters and file extensions. For example, to use URLs like http://www.myhost.com/foo.asp~a~A~b~B~c~C the following rule can be implemented:

RewriteEngine on
RewriteRule ^(.*?\.asp)~([^~]*)~([^~]*)(.*) $1$4?$2=$3 [NC,LP,QSA]

Keyword rich URLs

In previous example we have used general technique to simply hide query string markers. But much more useful solution for search engine optimization would be making your URL keyword rich. Consider following URL example: http://www.mysite.com/productpage.asp?productID=127 This is very usual situation for most web sites. But you can significantly increase rating of your page in search engines by using the following URL format instead: http://www.mysite.com/products/our_super_tool.asp Keywords “our super tool” in this URL will be indexed and improve page rank. But “our_super_tool” cannot be used to retract productID=127 directly. Several solutions to this problem exist.

The first solution that we would recommend if you have short URL format with only few parameters is to include in URL both keywords and numeric identifiers. In this case your URL may look as: http://www.mysite.com/products/our_super_tool_127.asp Only one rule will be needed to achieve this rewrite:

RewriteEngine on
RewriteBase /
RewriteRule ^products/[^?/]*_(\d+)\.asp productpage.asp?productID=$1 [QSA]

Another and more complex solution is to create 1 to 1 map file and use it to map “our_super_tool” to 127. This solution is useful for some long URLs with many parameters and will allow you to hide even numeric identifier. The URL will look as http://www.mysite.com/products/our_super_tool.asp. Please note that “our_super_tool” part should uniquely identify the product and it’s identifier. Here is an example for this solution:

RewriteEngine on
RewriteBase /
RewriteMap mapfile txt:mapfile.txt
RewriteRule ^products/([^?/]+)\.asp /productpage.asp?productID=${mapfile:$1}

And you will need to create mapfile.txt map file with the following content:

one_product 1
another_product 2
our_super_tool 127
more_products 335

Advantage of this method is that you can use it to combine quite complex URL transformations, but this is a bit out of this small examples guide context.

Use IIS as reverse proxy

Assume you have internet server running IIS and several backend servers or applications running other platform or machine. These servers are not directly accessible from the internet but you need to provide access to these servers for others. Here is an example of how to simply map entire content of one web site into the folder on another site running ISAPI_Rewrite:

RewriteEngine on
RewriteBase /
RewriteRule ^mappoint(.+)$ http://sitedomain$1 [NC,P]

Hide file extensions

While it is not possible to completely hide all file extensions on the site we can use ISAPI_Rewrite's file checking feature to hide some known extensions. Here is a rule example to hide .asp file extensions on the site:

RewriteEngine on

#Redirect extension requests to avoid duplicate content
RewriteRule ^([^?]+)\.asp$ $1 [NC,R=301,L]

#Internally add extensions to request
RewriteCond %{REQUEST_FILENAME}.asp -f
RewriteRule (.*) $1.asp

Emulating host-header-based virtual sites

For example you have registered two domains www.site1.com and www.site2.com. Now you can create two different sites using single physical site. Here is a rules example:

RewriteEngine on

#Fix missing trailing slash char on folders
RewriteRule ^([^.?]+[^.?/])$ $1/ [R,L]

#Emulate site1
RewriteCond %{HTTP:Host} ^(?:www\.)?site1\.com$
RewriteRule (.*) /site1$1 [NC,L,NS]

#Emulate site2
RewriteCond %{HTTP:Host} ^(?:www\.)?site2\.com$
RewriteRule (.*) /site2$1 [NC,L,NS]

Now just place your sites in /site1 and /site2 directories. Note that www.site1.com and www.site2.com should be somehow mapped in IIS to this web site to allow ISAPI_Rewrite intercept request.

Or you can use more generic rules to map any request to the folder with the same name as the host name in request:

RewriteEngine on

#Fix missing trailing slash char on folders
RewriteRule ^([^.?]+[^.?/])$ $1/ [R,L]

#Map requests to the folders
RewriteCond %{HTTP:Host} ^(www\.)?(.+)
RewriteRule (.*) /%2$1 [NS]

Directory names for sites should be like /somesite1.com, /somesite2.info, etc.

Blocking inline-images (stop hot linking)

Assume you have some pages with inline GIF graphics under http://www.mysite.com/. Some other sites incorporate this graphics via hyperlinks to their pages. This adds useless traffic to your site and you want to stop this practice.

While you cannot 100% protect the images from inclusion with ISAPI_Rewrite, only HotlinkBlocker product can do this, you can at least restrict the cases when browser sends HTTP Referer header. The following rules will allow only access to the images if referer is from the same host or empty.

RewriteEngine on

RewriteCond %{HTTP:Host}#%{HTTP:Referer} ^([^#]+)#(?!http://\1).+
RewriteRule .*\.(?:gif|jpg|png) /block.gif [NC]

Redirecting non-www version to www

If your web site is accessible through both versions of URL, i.e. http://helicontech.com and http://www.helicontech.com it is a good idea to redirect one version to another to avoid possible duplicate content penalty from search engines. Here is a rule to generally 301 redirect everything non-www to the corresponding www resource.

RewriteEngine on

RewriteCond %{HTTPS} (on)?
RewriteCond %{HTTP:Host} ^(?!www\.)(.+)$ [NC]
RewriteCond %{REQUEST_URI} (.+)
RewriteRule .? http(?%1s)://www.%2%3 [R=301,L]

Force to SSL or non-SSL for certain locations

Here is example how to force SSL for certain folder. Simply put following rules into the .htaccess file in this folder:

RewriteEngine on

#Fix missing trailing slash char on folders
RewriteRule ^([^.?]+[^.?/])$ $1/ [R,L]

#Redirect non-HTTPS to HTTPS
RewriteCond %{HTTP:Host} (.*)
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} (.*)
RewriteRule .? https://%1%2 [R,L]

And here is example how to do the contrary - force non-SSL for certain folder.

RewriteEngine on

#Fix missing trailing slash char on folders
RewriteRule ^([^.?]+[^.?/])$ $1/ [R,L]

#Redirect HTTPS to non-HTTPS
RewriteCond %{HTTP:Host} (.*)
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} (.*)
RewriteRule .? http://%1%2 [R,L]

Moving site location

This is very usual problem when you move web site from one domain name to another, or just another folder. You want to redirect all requests from one web site to another preserving the requested resource name and parameters. This is incredibly useful especially when you want to preserve page ranks of existing pages and external links. The solution is to use ISAPI_Rewrite on the old web server:

RewriteEngine on

#Permanent redirect to update old links
RewriteRule (.+) http://newserver.com$1 [R=301,L]

Browser-dependent content

It is sometimes necessary to provide browser-dependent content at least for important top-level pages, i.e. one has to provide a full-featured version for the Internet Explorer, a minimum-featured version for the Lynx browsers and an average-featured version for all others.

RewriteEngine on

RewriteCond %{HTTP:User-Agent} MSIE
RewriteRule /foo\.htm /foo.IE.htm [L]

RewriteCond %{HTTP:User-Agent} (?:Lynx|Mozilla/[12])
RewriteRule /foo\.htm /foo.20.htm [L]

RewriteRule /foo\.htm /foo.32.htm [L]

Block annoying robots

Here is a useful example to block a number of known robots and retractors by their user agents. Please note this rule is long and we have divided it into lines. In order to work correctly no spaces can be added to the end or beginning of the lines:

RewriteEngine on

#Block spambots
RewriteCond %{HTTP:User-Agent} (?:Alexibot|Art-Online|asterias|BackDoorbot|Black.Hole|\
BlackWidow|BlowFish|botALot|BuiltbotTough|Bullseye|BunnySlippers|Cegbfeieh|Cheesebot|\
CherryPicker|ChinaClaw|CopyRightCheck|cosmos|Crescent|Custo|DISCo|DittoSpyder|DownloadsDemon|\
eCatch|EirGrabber|EmailCollector|EmailSiphon|EmailWolf|EroCrawler|ExpresssWebPictures|ExtractorPro|\
EyeNetIE|FlashGet|Foobot|FrontPage|GetRight|GetWeb!|Go-Ahead-Got-It|Go!Zilla|GrabNet|Grafula|\
Harvest|hloader|HMView|httplib|HTTrack|humanlinks|ImagesStripper|ImagesSucker|IndysLibrary|\
InfonaviRobot|InterGET|Internet\sNinja|Jennybot|JetCar|JOC\sWeb\sSpider|Kenjin.Spider|Keyword.Density|\
larbin|LeechFTP|Lexibot|libWeb/clsHTTP|LinkextractorPro|LinkScan/8.1a.Unix|LinkWalker|lwp-trivial|\
Mass\sDownloader|Mata.Hari|Microsoft.URL|MIDown\stool|MIIxpc|Mister.PiX|Mister\sPiX|moget|\
Mozilla/3.Mozilla/2.01|Mozilla.*NEWT|Navroad|NearSite|NetAnts|NetMechanic|NetSpider|Net\sVampire|\
NetZIP|NICErsPRO|NPbot|Octopus|Offline.Explorer|Offline\sExplorer|Offline\sNavigator|Openfind|\
Pagerabber|Papa\sFoto|pavuk|pcBrowser|Program\sShareware\s1|ProPowerbot/2.14|ProWebWalker|ProWebWalker|\
psbot/0.1|QueryN.Metasearch|ReGet|RepoMonkey|RMA|SiteSnagger|SlySearch|SmartDownload|Spankbot|spanner|\
Superbot|SuperHTTP|Surfbot|suzuran|Szukacz/1.4|tAkeOut|Teleport|Teleport\sPro|Telesoft|The.Intraformant|\
TheNomad|TightTwatbot|Titan|toCrawl/UrlDispatcher|toCrawl/UrlDispatcher|True_Robot|turingos|\
Turnitinbot/1.5|URLy.Warning|VCI|VoidEYE|WebAuto|WebBandit|WebCopier|WebEMailExtrac.*|WebEnhancer|\
WebFetch|WebGo\sIS|Web.Image.Collector|Web\sImage\sCollector|WebLeacher|WebmasterWorldForumbot|\
WebReaper|WebSauger|Website\seXtractor|Website.Quester|Website\sQuester|Webster.Pro|WebStripper|\
Web\sSucker|WebWhacker|WebZip|Wget|Widow|[Ww]eb[Bb]andit|WWW-Collector-E|WWWOFFLE|\
Xaldon\sWebSpider|Xenu's|Zeus) [NC]
RewriteRule .? - [F]

Dynamically generated robots.txt

robots.txt is a file that search engines use to discover URLs that should or should not be indexed. But creation of this file for large sites with lots of dynamic content can be a very complex task. Have you ever thought about robots.txt dynamically generated from a script? Let's write robots.asp script:

<%@ Language=JScript EnableSessionState=False%>
<%

//The script must return plain text
Response.ContentType="text/plain";

/*

Place generation code here

*/

%>

Now make it available as robots.txt using single rule:

RewriteEngine on
RewriteRule robots\.txt robots.asp [NC]

Emulating load balancing

This example emulates some kind of DNS Round-Robin load balancing technique. Suppose you have main site www.mysite.com and a number of web servers which you have registered as www[1-9].mysite.com If you install ISAPI_Rewrite on the main server, you can spread traffic randomly between all servers by redirecting initial client request to some specific server. Once redirected, client will continue using this specific server. While this solution is not ideal, it can really spread your traffic and help to avoid problem with preserving session state.

Use the following rule to redirect clients:

RewriteEngine on

RewriteMap hosts rnd:hosts.txt

RewriteCond %{HTTP:Host} (www)\.mysite.com [NC]
RewriteRule (.*) http://${hosts:%1}.mysite.com$1 [R,L]

And here is hosts.txt file content:

www www1|www2|www3|www4|www5|www6|www7|www8|www9

Please find many other useful examples in Apache documentation here. Most of them can be used with ISAPI_Rewrite 3 without any modification.


Troubleshooting

Here you may find step-by-step instruction on how to troubleshoot your ISAPI_Rewrite installation.

  1. First of all to correctly troubleshoot your problem we require you to run the latest build of ISAPI_Rewrite available. You can always upgrade your ISAPI_Rewrite 3 installation by downloading current build from our web site here http://www.helicontech.com/download-isapi_rewrite3.htm
  2. Most of the problems with running ISAPI_Rewrite lay in NTFS permissions restrictions configured on your server. So please read Permissions required to run ISAPI_Rewrite document first.
  3. Please check Application and System logs for error messages. This may point you to the error source.
  4. Don't forget to put RewriteEngine on directive in every configuration file you are using.
  5. Put the following lines into httpd.conf file:
    RewriteLogLevel 9
    LogLevel debug
    This will create error.log and rewrite.log files by default in the installation directory. If log files are created, this will indicate that ISAPI_Rewrite is running. Read resulting error.log and rewrite.log files, this may give you some clue on a problem source.
  6. If httpd.conf rules are working but no .htaccess files are loaded, please check NTFS permissions on .htaccess files again and make sure you are not using Lite version of ISAPI_Rewrite.
  7. If rules are working in httpd.conf file but not in other sections or .htaccess files, make sure to include RewriteEngine on directive in every section and .htaccess file. Also remember that rewriting base inside .htaccess files by default is different from httpd.conf. ISAPI_Rewrite automatically strips the local directory prefix from the path when in .htaccess or <Directory> section and applies rules only to the remainder. So if your rules start with a '/' character, this should be removed in .htaccess file in the root folder of web site.

If you still having problems with using ISAPI_Rewrite, please write your question on the Support forum or send it to the Support e-mail.

Please include the following information in your support request:

  1. Your ISAPI_Rewrite configuration file, including path and file names.
  2. A link to your web site.
  3. URL that you have used for testing your rules
  4. Copy of error.log and rewrite.log files with failed requests.
  5. Portion of IIS log file that include failed requests.

Remember the more information you provide the easier it will be for us to resolve your problem, thus you will have more chances to get fast resolution.


Release history

ISAPI_Rewrite 3 release history

Release 3.1.0.82
================
[bugfix in filter] %{REQUEST_FILENAME} variable does not properly set on IIS7 for php scripts

Release 3.1.0.81
================

Release 3.1.0.80
================
[bugfix in filter] Possible crash in rare situations

Release 3.1.0.79
================
[bugfix in filter] Infinite loop is possible with LP flag
[bugfix in filter] Possible crash in rare situations

Release 3.1.0.78
================
[bugfix in Filter] Access violation with PREPROC_HEADERS flag turned On and very long urls

Release 3.1.0.77
================
[bugfix in filter] Possible rare crash on Windows 2008 servers

Release 3.1.0.76
================
[bugfix in filter] RewriteProxy rule with query string not working
[feature in filter] NotificationType=PREPROC_HEADERS added

Release 3.1.0.75
================
[bugfix in Installation] 32-bit version of isapi_rewrite.dll is deleted while upgrade. (x64 version only)
[bugfix in Filter] conditional format pattern doesn't support extended ?xx syntax

Release 3.1.0.74
================
[bugfix in Filter] tolower and toupper functions don't work with Unicode symbols

Release 3.1.0.73
================
[bug in Snap-in] Incorrect .htaccess path determination for sites with very long SiteID

Release 3.1.0.71
================
[bug in Installation] Installation error on 2008 and windows7 systems

Release 3.1.0.70
================
[feature in Filter] Extended syntax of back references $$NN and %%NN for sub-matches greater than 9
[bug in Installation] Snapin doesn't register properly on Windows 2008 R2 systems

Release 3.1.0.69
================
[bug in Installation] Bug in installation packages for Itanium systems
[bug in Filter] Incorrect processing of RewriteProxy directives with unicode symbols in the script name

Release 3.1.0.68
================
[feature in Filter] Information about the successful registration is added to the error.log
[bug in Filter] <Helicon> section should be inherited in child's contexts
[bug in Filter] Incorrect processing of headers with non-encoded symbols in foreign locale

Release 3.1.0.67
================
[feature in Filter] Improved dynamic reload of map files
[bug in Proxy helper] Returns not all response if back end doesn't set Content-Length header

Release 3.1.0.66
================
[feature in Filter] Compiled with VC 9 and Boost 1.39
[bug in Proxy helper] Problems with operation of ProxySuppressErrors directive
[bug in Proxy helper] Incorrect processing of response from uTorrent webUI on Windws2003 R2 system
[bug in Filter] Bug in RewriteHeader directive processing

Release 3.1.0.65
================
[bug in Installation] Installer failure on 2008 server with Plesk installed
[bug in Filter] RewriteBase directive should be case insensitive
[bug in Proxy helper] X-Forwarded-Host header should contain non-standard port number
[bug in Filter] RewriteLog mangled. Ugly char at the beginning of log file

Release 3.1.0.64
================
[feature in Filter] Flag [NU] added to RewriteRule, RewriteHeader, RewriteProxy directives
[bug in Filter] Issue with 2008 server and IIS6 metabase compatibility mode

Release 3.1.0.63
================
[bug in Filter] Incorrect parsing of RewriteMap directive with spaces in the path
[bug in Filter] Unicode signature FFFE is missing in log files
[bug in Manager] Incorrect conversion of RewriteHeader directives from v2 syntax

Release 3.1.0.62
================
[feature in Filter] Case-insensitive RewriteMap
[bug in Filter] Application crash occurred when httpd.conf reloaded frequently under heavy load
[bug in Filter] Incorrect convertion from Unicode to UTF-8 symblols in the range 7E - DF
[bug in Snap-in] Incorrect resolving of home directory path for an application (inside mmc snap-in)

Release 3.1.0.61
================
[feature in Filter] Additional Apache compatibility. Comments in the same line with directives disabled

Release 3.1.0.60
================
[feature in Filter] rewrite.log with Unicode support
[feature in Manager] Make .htaccess hidden optionally
[bug in Manager] Incorrect conversion RewriteProxy directives from v2 syntax
[bug in Proxy helper] Incorrect multiple Set-Cookie: headers processing
[bug in Proxy helper] Incorrect PathInfo processing

Release 3.1.0.59
================
[bug in Filter] Relative paths not working inside <Files></Files> section for RewriteMap directive
[bug in Manager] Looking for .htaccess in wrong directory on IIS7 with unusual application mapping

Release 3.1.0.58
================
[bug in Installation] Problem with proxy extension registration upon upgrade
[bug in Filter] Map file defined in httpd.conf cannot be accessed from .htaccess

Release 3.1.0.57
================
[feature in Installation] Enhanced registration of 32 and 64-bit dlls
                          for simultaneous operation of 32 and 64-bit sites on Windows 2008 x64
[bug in Filter] Redirect to unicode url fails
[bug in Filter] Incorrect processing of [NE] flag

Release 3.1.0.56
================
[bug in Proxy helper] Browser does not receive complete response from backend when chunked encoding is used

Release 3.1.0.55
================
[feature in Filter] Optimized ISAPI_Rewrite files change monitoring to decrease resource consumption
[bug in Filter] Fixed problem with metabase that caused inteinfo.exe to crash in some environments

Release 3.1.0.54
================
[feature in Filter] Optimized memory fragmentation for performance improvements
[bug in Filter] <FilesMatch> directive does not work inside .htaccess file

Release 3.1.0.53
================
[bug in Filter] <Location> directive does not work inside <VirtualHost>
[bug in Filter] Impossible to delete folder by short path

Release 3.1.0.51
================
[bug in Filter] Submatch numbering mod_rewrite incompatibility fix

Release 3.1.0.50
================
[feature in Filter] Compiled with Boost 1.35
[bug in Installation] On 64-bit Windows in 32-bit compatibility mode 64-bit version of ISAPI_Rewrite dll is installed

Release 3.1.0.49
================
[bug in Filter] Some WebDAV requests hung IIS worker thread

Release 3.1.0.48
================
[bug in Filter] Incorrect map name parsing
[bug in Snap-in] Regex tester crash issue

Release 3.1.0.47
================
[feature in Filter] Unicode UTF-16 support for URLs

Release 3.1.0.46
================
[bug in Proxy helper] Incorrect chunked response handling in proxy in HTTP 1.0
[bug in Filter] Filter logs superfluous messages in "warn" level
[bug in Filter] ntdll.dll crash problem resolved

Release 3.1.0.45
================
[bug in Filter] Issue with occasional ISAPI_Rewrite stop
[bug in Filter] Additional stability fixes

Release 3.1.0.44
================
[bug in Proxy helper] Error when trying to perform POST request for large files

Release 3.1.0.43
================
[bug in Filter] AllowOverride in global httod.conf context caused 500 server error
[bug in Filter] "Begin watch directory failed" massages flooded error.log

Release 3.1.0.40
================
[feature in Filter] .htaccess processing order changed to reflect exact Apache behavior
[bug in Filter] Sporadical crash issue fixed

Release 3.1.0.39
================
[feature in Filter] Various improvements in configuration monitoring system

Release 3.1.0.38
================
[feature in Proxy helper] Chunked request support.
[bug in Proxy helper] Chunked response incorrect Content-Length bug

Release 3.1.0.36
================
[bug in Filter] %{REQUEST_URI} return uri with query string
[bug in Filter] RewriteMap with forward slashes in path didn't work
[bug in Filter] Unicode did not work with RewriteCond %{REQUEST_FILENAME} !-d (f)
[bug in Filter] U flag appends query string to logged url

Release 3.1.0.34
================
[bug in Filter] Map files are not reloaded when moved from configuration file folder.

Release 3.1.0.32
================
[feature in Filter] Unicode support
[feature in Filter] <IfModule> Directive
[bug in Filter] RewriteHeader adds query string

Release 3.0.0.31
================
[feature in Documentation] Release history in documentation
[bug in Snap-in] Unix line feeds display incorrectly in snap-in
[bug in Filter] RewriteMap directive don't work when inside <VirtualHost> tag.
[bug in Proxy helper] Redirect responses don't support HTTPS  through proxy

Release 3.0.0.30
================
[bug in Snap-in] Config preview in snapin do not refresh
[bug in Snap-in] Error occurs when pressing Ctrl+t not on RewriteRule in Helicon Config Editor.

Release 3.0.0.29
================
[bug in Proxy helper] Proxy fails with unencoded special characters
[bug in Filter] Path to .htaccess file may be logged with QueryString
[bug in Proxy helper] Proxy module share cookies between different users

Release 3.0.0.27
================
[bug in Proxy helper] Error in realization of RewriteProxy directive. No need to set [L] flag.
                      No rules are processed after RewriteProxy fires.
[bug in Filter] The trailing slash in RewriteBase directive is now added automatically if it was not specified.
[bug in Proxy helper] RewriteProxy [FR] flag removed.

Release 3.0.0.26
================
[feature in Proxy helper] RewriteProxy [H] flag added.
[feature in Proxy helper] RewriteProxy [A] flag added.
[feature in Proxy helper] RewriteProxy [C] flag added.
[feature in Installation] Installer automatically grants right on writing into rewrite.log.
[bug in Filter] Error in realization of RewriteCond %{REQUEST_FILENAME} !-l directive.

Release 3.0.0.25
================
[bug in Installation] Incorrect version number in Itanium build.
[bug in Snap-in] Number of trial days left display incorrectly.

Release 3.0.0.24
================
[feature in Filter] Support of variables in parameters [CO=NAME:VALomain[:lifetime[ath]]].
[bug in Proxy helper] Incorrect transmission of X-Forwarded-Host header.

Release 3.0.0.23
================
[feature in Filter] Support of Unix-style line folding \r and \r\n.
[feature in Filter] Support of spaces in RewriteRule.
[bug in Installation] Incorrect snap-in de-registration.

Release 3.0.0.22
================
[feature in Filter] <LogLevel> directive added.
[feature in Filter] <ErrorLog> directive added.
[bug in Filter] IE7 new style HTTP requests (GET http://www.host.com/) not processed correctly.

Release 3.0.0.21
================
[bug in Snap-in] RewriteEngine On snap-in indicator (Enabled/Disabled) removed.
[bug in Filter] ?N in FormatString don't work correctly.

Release 3.0.0.20
================
[feature in Filter] The possibility to specify empty RewriteBase directive added.
[feature in Filter] Prohibit access to .htaccess and *.rwhlp files from the outside.

Release 3.0.0.17
================
[feature in Filter] <Files> directive in .htaccess added.
[bug in Filter] Impossible to write %{ NAME_OF_VARIABLE } inside another, i.e. %{NAME_OF_VARIABLE%{NAME_OF_VARIABLE}}
[bug in Installation] Installation error on Lite x64.

Release 3.0.0.16
================
[feature in Filter] <Directory> directive added.
[feature in Filter] <DirectoryMatch> directive added.
[feature in Filter] <Files> directive added.
[feature in Filter] <Location> directive added.
[feature in Filter] The possibility of line folding ("\") in the configuration was added.
[feature in Proxy helper] [FR] flag added.
[bug in Filter] If directive RewriteCond [OR] was the last in the config, it lead to error.

Release 3.0.0.15
================
[bug in Installation] Manifest files generated incorrectly on x64 platform.

Release 3.0.0.14
================
[feature in Filter] <VirtualHost> directive added.

Release 3.0.0.13
================
[bug in Filter] Non-printing characters not ignored in .htaccess
[bug in Installation] Dependent services don't stop correctly
[bug in Manager] Helicon Manager problem with Lite version.

Release 3.0.0.12
================
[feature in Filter] Windows 2008 server / Vista support
[feature in Filter] AllowOverride directive
[feature in Filter] AccessFileName directive
[bug in Installation] Improvements in installation. Check of existance of ISAPI modules in IIS7.
© Helicon Tech Corp. All rights reserved.


Lite version limitations

Lite version of ISAPI_Rewrite shares the same rewrite engine and features but with the following limitations:

  • No support for distributed .htaccess configurations, directory and web site level configurations. Only one global httpd.conf configuration file will be loaded from Lite version installation folder.
  • No support for <VirtualHost>, <Directory>, <DirectoryMatch>, <Files>, <FilesMatch>, <Location> and <LocationMatch> tags.
  • There is no proxy module in Lite version, thus all proxy related functions like RewriteProxy directive and [P] flag will be ignored.
  • No manual installation package for Lite version to install in a shared hosting environment.

ISAPI_Rewrite Lite is completely free and it is a good solution for development or testing purposes and for small servers that host only a few web sites and don’t require distributed configurations or proxy functions.


Technical information

ISAPI_Rewrite consists of four components – ISAPI filter, helper ISAPI extension, GUI Manager and MMC snap-in extension. ISAPI filter and extension are fast DLL modules written in pure C++. While installing ISAPI_Rewrite MMC snap-in will be registered automatically. ISAPI filter will be installed on a global level and you don't need to register it manually. ISAPI extension will be also installed and registered.

The ISAPI_Rewrite Manager utility can run ISAPI_Rewrite MMC snap-in on systems where MMC is not installed or inaccessible.

ISAPI_Rewrite Manager utility (Helicon Manager.exe) on Windows Vista and Windows Server 2008 systems require administrator priveleges to execute, because users with less priveleges don't have permissions to read from IIS metabase, which is required to display web sites configuration. You will be automatically prompted to login with administrator credentials if restricted user account is used to run ISAPI_Rewrite Manager.

ISAPI_Rewrite filter is fast enough not to worry about performance, unless your server is running under maximum load. Users will not find any difference in response time or CPU load, but the maximum server bandwidth may fall down a bit if large number of rules is used. So keep in mind that performance depends on a configuration settings you are using. It is not recommended to have more than 100 rules per web site. In most cases use of large number of rules can be avoided by utilizing RewriteMap functions.

This program uses Regex++ library.
Regex++ (Version Boost 1.31)
Copyright © 1998-2004, Dr John Maddock


License agreement

License for use and distribution

This license agreement covers all existing versions of ISAPI_Rewrite: ISAPI_Rewrite, ISAPI_Rewrite Full, ISAPI_Rewrite Lite, ISAPI_Rewrite beta from now on referred below as ISAPI_Rewrite unless otherwise specified.

1. All rights not expressly granted here are reserved by Helicon Tech.

2. All copyrights to ISAPI_Rewrite are exclusively owned by the author - Helicon Tech.

3. Helicon Tech grants a free license for use of ISAPI_Rewrite Lite product.

4. Helicon Tech grants permission to use ISAPI_Rewrite during a test period of 30-days. When the trial period is over you should either buy ISAPI_Rewrite or remove the ISAPI_Rewrite product.

5. The unregistered trial version of ISAPI_Rewrite, may be freely distributed, with exceptions noted below, provided the distribution package is not modified. No person or company may charge a fee for the distribution of ISAPI_Rewrite without written permission from the copyright holder. The unregistered trial version of ISAPI_Rewrite may not be bundled or distributed with any other package without written permission of the copyright holder.

6. ISAPI_Rewrite IS DISTRIBUTED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE ISAPI_Rewrite AT YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING OR MISUSING THIS SOFTWARE.

7. You may not use, copy, emulate, clone, rent, lease, sell, modify, decompile, disassemble, otherwise reverse engineer, or transfer the licensed program, or any subset of the licensed program, except as provided for in this agreement. Any such unauthorized use shall result in immediate and automatic termination of this license and may result in criminal and/or civil prosecution.

8. The terms of this license are subjects of changes in future versions of ISAPI_Rewrite.

9. When you buy ISAPI_Rewrite, the "Registration key" is being issued to you. This "Registration key" can only be used by the person (or company) purchased it and only on the single computer. If you buy more than one copy of ISAPI_Rewrite, the “Registration key” issued to you could be used only on the number of computers equal to the number of licenses you bought.

10. You can only use the "Registration key" received from Helicon Tech or the company affiliating or partnering with Helicon Tech and having written permission to distribute "Registration key".

11. Installing and using ISAPI_Rewrite signifies acceptance of these terms and conditions of the license.

12. If you do not agree with the terms of this license or if the terms of this license contradict with your local laws, you must remove ISAPI_Rewrite files from your storage devices and cease to use the product.

13. We adhere to strict privacy guidelines and do NOT collect personally identifiable information unless it is voluntarily provided.

If you have further questions or feedback, please visit us at http://www.helicontech.com/

Thank you for using ISAPI_Rewrite.
Helicon Tech Corporation.


Installing Snap-in extension

In some configurations ISAPI_Rewrite IIS Snap-in extension may not be installed automatically. In this case you will need to install the extension manually.

  1. Under Windows NT 4 select Start >> Programs >> Windows NT 4.0 Option Pack >> Microsoft Internet Information Server >> Internet Services Manager.
  2. Under Windows 2000 and later follow these steps:
    1. Select Start >> Run, enter "mmc" in the text box and hit Run button.
    2. In Microsoft Management Console select "Add/Remove Snap-in" from the Console menu.
    3. In the dialog click Add button, select "Information Services" from the list and hit Add.
  3. Open "Extensions" tab on the "Add/Remove Snap-in" dialog.
  4. Put a check in the box near "ISAPI_Rewrite Snap-in extension" and hit OK.


Quick start

The following is a step by step guide to start using ISAPI_Rewrite.

  1. Install ISAPI_Rewrite. Please read installation instructions to complete this step.
  2. Run “Internet Information Services” console from the “Administrative Tools” menu.
  3. From the list of web sites select a site you wish to optimize with ISAPI_Rewrite. Right click this site node and hit “Properties”.
  4. In the site properties select ISAPI_Rewrite tab. If you can’t find ISAPI_Rewrite tab, please read Installing Snap-in extension chapter.
  5. On the ISAPI_Rewrite tab click Enable button.
  6. In the Directory list select Add new and type in a folder name you wish to apply transformation. Leave '/' if you want to apply transformation to entire web site.
  7. Type substitution characters to replace '?', '&' and '='. Tilda character '~' is known to be most safe from conflicts.
  8. If you want to hide some file extension behind .htm then enter this extension in the box.
  9. You can leave all parameters default and just click Apply button.
  10. Click Apply or OK. Please note no changes on the dialog will take effect until you hit Apply or OK.

Note: You are solely responsible for what you are entering as substitution characters and how you configure other ISAPI_Rewrite settings. ISAPI_Rewrite does not include any kind of protection against improper configuration. Incorrect usage of substitution characters and directory scope may cause conflicts with real files on your site or even break links. Disable ISAPI_Rewrite if you have conflicts with your site structure and things will come back to normal.