Post

The Very Common Mistakes When Using IIS URL Rewrite Module

A post about the very common mistakes when using IIS URL Rewrite Module and how to avoid them.

The Very Common Mistakes When Using IIS URL Rewrite Module

IIS URL Rewrite module has been a very important addition to the platform, and gives all kinds of possibilities on how you can take full control of the URLs. When proper rules are created and hosted there, many scenarios that were difficult to achieve are no longer miracles.

But flexibility comes at a price, and people can make mistakes if they blindly move on to create rules, without even playing with the examples published by Microsoft on their excellent documentation site.

Here I show a few common mistakes that many make, and hope by reading such you can easily figure out yours.

Tip

Do read all related articles published by Microsoft and test the sample rules on your machine to get familiar with the different parts of this module, like basic rule structure, conditions, rewrite maps, and outbound rules. Later when you start to author your own rules, such knowledge will guide you on the right track.

Mistake 1: Wrong Value Set to url Attribute of <match> Tag

Someone can easily rush to his/her feet to write a rewrite rule as below,

1
2
3
4
5
6
7
8
<rewrite>
  <rules>
    <rule name="Rewrite to some page">
      <match url="http://some.site/some.page" />
      <action type="Redirect" url="http://other.site/other.page" />
    </rule>
  </rules>
</rewrite>

It won’t work at all, and the reason is that when a request on http://some.site/some.page arrives, IIS uses some.page to match the url attribute of the <match> tag. Clearly this rule needs to be modified to work with IIS’s behavior.

Tip

Remove domain name from the url tag and add a condition to check domain name instead.

1
2
3
4
5
6
7
8
9
10
11
12
13
<system.webServer>
  <rewrite>
    <rules>
      <rule name="Rewrite to some page">
        <match url="some.page" />
        <conditions>
          <add input="{HTTP_HOST}" pattern="^some.site$" />
        </conditions>
        <action type="Redirect" url="http://other.site/other.page" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

Tip

Also note that the URL in <match> tag does not have / at the beginning. If you put / there, then IIS won’t be able to match the page.

Mistake 2: Use Rewrite When Actually Redirect Is Needed

Often you want to do HTTP to HTTPS redirection and find a rule from the internet. However, instead of copying it you would like to modify it a bit,

1
2
3
4
5
6
7
8
9
10
11
<rewrite>
  <rules>
    <rule name="Redirect to http" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
      <match url="*" negate="false" />
      <conditions logicalGrouping="MatchAny">
        <add input="{HTTPS}" pattern="off" />
      </conditions>
      <action type="Rewrite" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Found" />
    </rule>
  </rules>
</rewrite>

Why doesn’t it work? Because HTTP and HTTPS use different TCP ports, and if not under proxy mode IIS won’t be able to serve the content properly.

Tip

Do use Redirect as action type, and that asks the browser to connect to your HTTPS link.

Mistake 3: Write Proxy Rules Without ARR Proxy

Microsoft decided to split most of the reverse proxy feature into another module called Application Request Routing, so many times when you design a certain type of rules you need to install ARR and enable proxy mode.

1
2
3
4
5
6
7
8
9
10
<system.webServer>
  <rewrite>
    <rules>
      <rule name="Reverse Proxy to webmail" stopProcessing="true">
        <match url="^webmail/(.*)" />
        <action type="Rewrite" url="http://localhost:8081/{R:1}" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

If you don’t enable ARR proxy mode in such cases, IIS should respond with 404 errors.

To proper configure ARR as a reverse proxy, you should read the official documentation. And usually you need the following,

1
2
3
<system.webServer>
  <proxy enabled="true" preserveHostHeader="true" />
</system.webServer>

Stay tuned, as more common mistakes will be added soon.

Side Notes

Microsoft should make redirectType="Found" the default value for rewrite actions, because such 302 redirection is not cached by browsers. You should manually add this to your <action> tags during rule development, so that you don’t have to manually clear browser caches or resort to the private browsing mode.

It is very important to learn how to troubleshoot URL rewriting rules. Usually failed request tracing should be enabled during your experiments, so that you know why sometimes a rule fails.

You also need to use IIS Manager smartly, to test out the regular expressions.

© Lex Li. All rights reserved. The code included is licensed under CC BY 4.0 unless otherwise noted.
Advertisement