mod_rewritemod_rewrite overviewmod_rewrite is a powerful regular-expressions-based URL manipulation module for IIS. It allows of performing URL modifications depending on various conditions—HTTP headers, states of server variables etc. Flexible and easily manageable rewriting of loads of URLs is possible due to map files support. URL manipulations are established using plain text configuration files with a bunch of directives inside. Configurations may occur on different levels:
All configuration files are reloaded automatically every time the file is changed. It is allowed to change file content using third party programs and scripts. In most cases ISAPI_Rewrite is used to rewrite requested URL. In addition to rewriting, mod_rewrite can modify, create or remove any HTTP headers of the client REQUEST. Module is capable of doing rewriting, proxying, redirection or blocking of original client request to a server. Rewriting causes 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 the 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 the 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. Redirection results in sending of immediate response with a redirect instruction (HTTP response code 301 or 302) setting substituted URL as a new location. You can use an absolute URL format (as required by RFC 2616) in redirection instruction to redirect the request to a different host, port and protocol. If this information is omitted, mod_rewrite will automatically prepend URL with the current request's protocol, server name and directory location. Rules are applied in order of appearance in configuration files. Directory level configuration files are processed file by file starting from the parents. Rules from global (server) configuration file are applied first. Order of rules is important because substitution result of one rule will become a source for subsequent rules application. mod_rewrite directivesRewriteBase
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. For directory context RewriteBase will be empty by default but for .htaccess configurations it will contain virtual path to requested directory. RewriteCond
RewriteCond 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:
CondPattern specifies a regular expression that will be applied to the instance of TestString. The following special values are also supported:
The following values are unsupported because they are senseless in IIS:
RewriteCond directive may be accompanied by the following flags:
Note! RewriteCond directive affects only ONE subsequent RewriteRule, RewriteHeader or RewriteProxy directive. RewriteEngine
RewriteEngine enables or disables rewriting runtime. Use RewriteEngine off instead of commenting out rewrite rules if you need to disable mod_rewrite module or specific .htaccess file. RewriteHeader
RewriteHeader directive is more general variant of RewriteRule directive and is designed to rewrite not only the URL part of client request, but any HTTP header. Technically RewriteRule directive is equivalent to RewriteHeader URL Pattern Substitution [flags]. This directive can be used to rewrite, create or delete any HTTP headers in the client request before it is processed by other applications on IIS. HeaderName: specifies the name of HTTP header that will be rewritten. Pattern, Substitution and flags are the same as for RewriteRule directive. Note! RewriteHeader directive has no equivalent in Apache (see Compatibility chart). RewriteLog
RewriteLog directive sets the name of the log file where ISAPI_Rewrite will log all its actions. Example:
RewriteLogLevel
RewriteLogLevel 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 mod_rewrite operation. We recommend you to disable logging by setting log level to 0 after debugging of your ruleset has been completed. RewriteMap
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. There are three types of mapping:
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, mod_rewrite will lookup for the key in the map file 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. RewriteMap directive may be accompanied by the following flag:
Here is an example of using maps:
Then you may use this map in RewriteRule as follows:
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:
rnd: Random multiple values lookup. Source is the path to a text file of the following format:
int: Internal function call. Source should be one of the following pre-defined internal functions:
dbd: Database-driven mapping. Below is the example of how to use it to rewrite SEO-friendly URLs to original physical pages. What you need is a database containing two columns: OriginalURL (with real physical URLs) and SEO_URL (with pretty SEO-friendly links). Having created the database you are ready to use this config:
RewriteOptions
RewriteOptions directive can set special options for mod_rewrite. Currently only one option is available: 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. RewriteProxy
RewriteProxy 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. Syntax and operation are the same as for RewriteRule directive, but RewriteProxy supports some additional flags:
Note! RewriteProxy directive has no equivalent in Apache (see Compatibility chart). RewriteRule
RewriteRule directive defines a single URL rewriting operation. It may occur more that once in configuration file with each instance defining a URL rewriting rule. 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. Also current URL differs depending on a level of configuration that is applied, i.e. for directory level configuration current directory name will be omitted from the URL to match. 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:
The following escape sequences are also allowed:
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 connected 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 the rule with any of the flags terminating rules processing. 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 affect rule behavior. Apache-compatible flags are green, unsupported flags are red, and Ape-specific flags are yellow. All unsupported flags will be ignored.
ExamplesNote! All rules in these examples are intended for httpd.conf file. In 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 URLsThis 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 The following rule is destined to perform this transformation:
Note! 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:
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:
Keyword rich URLsIn 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 the following URL: http://www.mysite.com/productpage.asp?productID=127 This is a common 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:
Another, more complex but effective, 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:
And you will need to create mapfile.txt map file with the following content:
Advantage of this method is that you can use it to combine quite complex URL transformations. Use IIS as reverse proxyAssume 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:
Emulating host-header-based virtual sitesFor 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:
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 mod_rewrite intercept the 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:
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 mod_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.
Moving site locationThis 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 following configuration should be used on old web server:
Browser-dependent contentIt 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.
Block annoying robotsHere 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 split it into lines. In order to work correctly no spaces can be added to the end or beginning of the lines:
Dynamically generated robots.txtrobots.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:
Now make it available as robots.txt using single rule:
Emulating load balancingThis 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:
And here is hosts.txt file content:
|