Creating rewrite rules for the URL Rewrite Module

This walkthrough will guide you through how to create and test a set of rewrite rules for the URL rewrite module..

Prerequisites

This walkthrough requires the following prerequisites:

  1. IIS 7.0 with ASP.NET role service enabled;
  2. URL rewrite module Go Live release installed.

Setting up a test Web page

To demonstrate how the URL rewrite module works, we will be using a simple test ASP.NET page. This page reads the Web server variables and outputs their values in the browser.

Copy the following ASP.NET code and put it in the %SystemDrive%\inetpub\wwwroot\ folder in a file called article.aspx:

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>URL Rewrite Module Test</title>
</head>
<body>
      <h1>URL Rewrite Module Test Page</h1>
      <table>
            <tr>
                  <th>Server Variable</th>
                  <th>Value</th>
            </tr>
            <tr>
                  <td>Original URL: </td>
                  <td><%= Request.ServerVariables["HTTP_X_ORIGINAL_URL"] %></td>
            </tr>
            <tr>
                  <td>Final URL: </td>
                  <td><%= Request.ServerVariables["SCRIPT_NAME"] + "?" + Request.ServerVariables["QUERY_STRING"] %></td>
            </tr>
      </table>
</body>
</html>

After copying this file, browse to http://localhost/article.aspx and check that the page was rendered correctly in a browser.

Creating a rewrite rule

We will create a simple rewrite rule that rewrites URLs by using the following format:

http://localhost/article/342/some-article-title
will be rewritten as:
http://localhost/article.aspx?id=342&title=some-article-title.

We will create a rewrite rule by using URL Rewrite UI in IIS Manager. To do this follow these steps:

  1. Go to IIS Manager
  2. Select “Default Web Site”
  3. In the Feature View click “URL Rewrite“
  4. In the “Actions” pane on right hand side click on “Add rules…
  5. In the "Add Rules" dialog, select the "Blank Rule" and click "Ok"

Now you must define the actual rewrite rule. In the URL rewrite module, a rewrite rule is defined by specifying four required pieces of information:

  • Name of the rule;
  • Pattern to use for matching the URL string;
  • Optional set of conditions;
  • Action to perform if a pattern is matched and all conditions checks succeed.

Naming a rule

In the “Name” text box enter a name that will uniquely identify the rule, for example: ”Rewrite to article.aspx”.

Defining a pattern

In the “Pattern” text box enter the following string:

^article/([0-9]+)/([_0-9a-z-]+)

This string is a regular expression that specifies that the pattern will match any URL string that meets the following conditions:

  1. Starts with the sequence of characters “article/”.
  2. Contains one or more numeric characters after the first “/”.
  3. Contains one or more alphanumeric or “_” or “-” characters after the second “/”.

Notice that certain parts of the regular expression are within parentheses. These parentheses create capture groups, which can be later referenced in the rule by using back-references.

Defining an action

Since the rule that we are creating is supposed to rewrite the URL, choose the “Rewrite” action type that is listed in the “Action” group box. In the “Rewrite URL:” text box, enter the following string:

article.aspx?id={R:1}&title={R:2}

This string specifies the new value to which the input URL should be rewritten. Notice that for the values of the query string parameters we used {R:1} and {R:2}, which are back-references to the capture groups that were defined in the rule pattern by using parentheses.

Leave default values for all other settings. The "Edit Rule" property page should look like the following page:

 

Save the rule by clicking on “Apply” action on the right hand side.

Viewing the rewrite rule in configuration file

The rewrite rules are stored either in aplicationHost.config file or in web.config files. To check the configuration of the rule that we have just created, open a web.config file located in %SystemDrive%\inetput\wwwroot\. In this file you should see the <rewrite> section that contains this rule definition:

<rewrite>
  <rules>
    <rule name="Rewrite to article.aspx">
      <match url="^article/([0-9]+)/([_0-9a-z-]+)" />
      <action type="Rewrite" url="article.aspx?id={R:1}&amp;title={R:2}" />
    </rule>
  </rules>
</rewrite>

Testing the rule

To test that the rule correctly rewrites URL’s, open a Web browser and request the following URL:

http://localhost/article/234/some-title

You should see that the rewrite rule on web server has changed the original URL to article.aspx and it has passed “234” and “some-title” as values for query string parameters.

Creating a redirect rule

Now we will create a redirect rule that will redirect all URLs in the following format:

http://localhost/blog/some-other-title/543
will be redirected to:
http://localhost/article/543/some-other-title

To do this, open the URL Rewrite feature view UI in IIS Manager and then click "Add Rule…" and select "Blank Rule" template again.
Within the “Edit Rule” page, enter the following:

  • Name: "Redirect from blog" (this is a unique name for the rule)
  • Pattern: "^blog/([_0-9a-z-]+)/([0-9]+)" (This pattern will match the URL string that starts with “blog” and captures the second and third segments of the URL into back-references)
  • Action: "Redirect" (The redirect action will cause a redirect response to be sent back to the browser)
  • Redirect URL: "article/{R:2}/{R:1}" (this substitution string will be used as a redirect URL; notice that it uses back-references to preserve and re-arrange the original URL pieces captured during pattern match)

Leave default values for all other settings. The "Edit rule" property page should look like the following page:

save the rule by clicking on “Apply” action on the right hand side.

Testing the rule

To test that the rule redirects requests correctly, open a Web browser and request the following URL:

http://localhost/blog/some-other-title/323

You should see that the browser was redirected to http://localhost/article/323/some-other-title as a result of redirect rule execution and then the request was rewritten in accordance to the rewrite rule that you have created earlier:

Creating an access block rule

The third rule that we will create is used to block all requests made to Web site if those requests do not have the host header set. This type of rule is useful when you want to prevent hacking attempts that are made by issuing HTTP requests against the IP address of the server instead of using the host name.

We will create this rule without using IIS Manager. Open the Web.config file and locate the <rewrite> section. Insert the following rule:

<rule name="Fail bad requests">
      <match url=".*"/>
      <conditions>
        <add input="{HTTP_HOST}" pattern="localhost" negate="true" />
      </conditions>
      <action type="AbortRequest" />
</rule>

into the <rules> collection, so that it is a first rule in a collection. The <rewrite> section should look like the following code:

<rewrite>
  <rules>
    <rule name="Fail bad requests">
      <match url=".*"/>
      <conditions>
        <add input="{HTTP_HOST}" pattern="localhost" negate="true" />
      </conditions>
      <action type="AbortRequest" />
    </rule>
    <rule name="Redirect from blog">
      <match url="^blog/([_0-9a-z-]+)/([0-9]+)" />
      <action type="Redirect" url="article/{R:2}/{R:1}" redirectType="Found" />
    </rule>
    <rule name="Rewrite to article.aspx">
      <match url="^article/([0-9]+)/([_0-9a-z-]+)" />
      <action type="Rewrite" url="article.aspx?id={R:1}&amp;title={R:2}" />
    </rule>
  </rules>
</rewrite>


Let’s analyze the rule to understand what it does.

  • <match url=".*"/> - This element says that the rule will match any URL string
  • <add input="{HTTP_HOST}" pattern="localhost" negate="true" /> - This element adds a condition to the rule that retrieves the host header value by reading the server variable HTTP_HOST, matches it against the pattern “localhost” and then negates the result of matching. In other words, the condition verifies that the host header does not match “localhost”.
  • <action type="AbortRequest" /> - this element tells the URL rewrite module to end the HTTP request.

Testing the rule

To test this rule, open a Web browser and make a request to http://127.0.0.1/article/234/some-title. What you should see is a browser that does not receive any response from the server. However, if you request http://localhost/article/234/some-title, then the Web server will respond successfully.

Summary

In this walkthrough you have learned how to configure URL rewrite rules by using IIS manager or by manually editing web.config files. The rules that were created in this walkthrough demonstrated some of the important features of URL rewrite module, such as regular expressions support, different types of actions and ability to use http headers and server variables to make rewriting decisions.

Related Content

Comments

I think that the "Edit Rule" capture image of "Creating a redirect rule" section has a incorrect information. "Redirect URL" textbox's value must be "article.aspx?id={R:1}&title={R:2}". Sorry for my poor English composition. :-)

Jun 23 2008 by Song wonseok

The screenshot is correct. The redirect rule is used to redirect from "blog/some-other-title/234" to "article/234/some-other-title". After the redirection is performed, another rewrite rule called "Rewrite to article.aspx" kicks in and rewrites the "article/234/some-other-title" to "article.aspx?id=234&title=some-other-title".

Jun 24 2008 by ruslany

Oh!!! I'm sorry for my mistake. ruslany is correct. Thanks a lot. :-)

But, I have a question yet. I think still remain incorrect capture image. The image of "Testing the rule" within "Creating a redirect rule" section is OK?

I think... the value of "Final URL:" is must be "http://localhost/article/323/some-other-title". I can't understand. Browser's address bar shows "http://localhost/article/323/some-other-title". But the value of "Final URL:" is "article.aspx?id=234&title=some-other-title".

My machine use XP. So I can not test this module now.

Jun 29 2008 by song wonseok

Ok, now I understand what mean this images. First, "Redirect from blog" rule is running, and then now "Rewrite to article.aspx" rull is running again. So the value of "Final URL:" is "article.aspx?id=234&title=some-other-title". It is amazing!!!

Jun 29 2008 by song wonseok

Awesome Article.

there are some other rules I found and Implemented with my applications, works fine.
Microsoft Always pioneer to explain in depth. For more rules combination

http://msdn.microsoft.com/en-us/library/ms972974.aspx
http://www.developerfusion.co.uk/show/5302/

Joggee
http://blog.joggee.com

Jul 10 2008 by dbmaster

I have been waiting for this for ever..

This is one powerful momma!

Thanks

Sep 11 2008 by erikkl2000

Tell me if this is possible: I have a directory that has a "download" page that dynamically creates download links to zip files stored in the same folder. For business reasons I can't move the files out of this directory so I use a simple username/password combination when you access the download page before I generate the file list. The obvious problem is that if you know the name of one of the zip files you can type the full path in the browser and download the file. What I would like to do is deny access to any zip files unless the referrer is the "login" page. make sense? So using this module can I deny access if the URL contains ".zip" unless you just came from "login.asp"? Thanks in advance.

Sep 12 2008 by jjd228

Please submit your questions to the URL Rewrite forum.
http://forums.iis.net/1152.aspx

Sep 15 2008 by steve schofield

I have a group of urls that start with /Citys/ and in my url Rewrite I have:

1. Using Regular Expressions
2. Pattern = ^/Citys/
3. Action = Rewrite
4. Rewrite Url = http://google.com

here is the error i get
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

--------
What in the world am i missing?

Do I have to restart IIS after a rule is created?

Thanks for the help

erik

Nov 27 2008 by erikkl2000

Please remove the forward slash from the pattern, i.e. Pattern= ^Cities/ .

Dec 01 2008 by ruslany

Got it..

When ever I do a rewrite to another document the rewrite is perfect; however, the document will not load any of my styles or master page..

When I do a redirect this document opens perfectly; however, now I have to do a redirect. Some search engines do not like this? Is this right? Or not?

Thanks a lot!
Erik

Jan 12 2009 by erikkl2000

How do you match against a literal "?" question mark? I'm moving from isapirewrite and I can't seem to do this using the new module.

It should allow me to do something like this, but I can't get it to work.

Example:
rewrite\.html\?var1=([^&]*)(.*)

toAnotherURL.html?newvar1={R:1}&{R:2}

I wish microsoft would have copied mod_rewrite syntax. I have been using isapirewrite dot com which is great but I can't get it to install the licensed copy on Vista x64 IIS7 so I have to switch to something else.

Mar 01 2009 by skyflare

How do you match against a literal "?" question mark? >>

With a character class (put brackets around it):

[?] matches 1 question mark
[?]? matches 0 or 1 question marks
[?]* matches 0 or more question marks
[?]+ matches 1 or more question marks

e.g.,

[.]html[?]var1=([^&]*)(.*)

Apr 15 2009 by nekno

I have installed this on Win 7. I dont see the URL Rewrite.. Any help there?

Apr 16 2009 by pyu.agrawal

TO ALL: PLEASE POST YOUR QUESTIONS ABOUT THE MODULE HERE: http://forums.iis.net/1152.aspx. YOU WILL GET MUCH FASTER RESPONSE!

Jun 06 2009 by ruslany

Hi

Excellent article , therefore I m newbie on it and I need some help, so

I have this URL exmaple:

http://mydomain.com/home and it take to http://mydomain.com/index.php?q={R:1} or when it is

http://mydomain.com/blue/1 and it take to http://mydomain.com/index.php?q={R:1}{R:2}

but

I would like when the URL be :

http://mydomain.com/brazil/home it should be :
http://mydomain.com/brazil/index.php?q={R:1}
or
http://mydomain.com/brazil/blue/1 it should be :
http://mydomain.com/brazil/index.php?q={R:1}{R:2}

Because "Brazil" is a subfolder or other application

But the problem is it goto to http://mydomain.com/index.php?q={R:1}

what should be rules here?

my current rule is , which is I think is incorrect:

?xml version="1.0" encoding="UTF-8"?>
configuration>
system.webServer>
rewrite>
rules>
rule name="Clean URLs" stopProcessing="true">
match url="^(.*)$" />
conditions>
add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
/conditions>
action type="Rewrite" url="index.php?q={R:1}" appendQueryString="true" />
/rule>

/rules>
/rewrite>
/system.webServer>
/configuration>

I need help ,
Thanks in advance
Fred.










Sep 17 2009 by bkgmaster

Submit a Comment

You must Log In to comment.

Microsoft Communities