2

I am using IIS URL Rewrite 2.0 module to create a URL that always points to the latest version of my app. I have configured it as follows:

<rule name="Latest" stopProcessing="true">
    <match url="^latest(.*)" />
    <action type="Rewrite" url="1.1{R:1}" />
</rule>

The intention is that if something goes to /latest/* then all of the URLs are rewritten as /1.1/*. For example /latest/index.html should become /1.1/index.html.

This is working when I request a file, for example:

/latest/index.html - works
/latest/js/app.js - works

However this does not work:

/latest

Since index.html is the default document, I would expect this to rewrite to /1.1/index.html, but in fact it seems to do a redirect. For example, if I type the following in the browser address bar:

http://<domain>/latest

and press ENTER, it changes to:

http://<domain>/1.1

as if redirected. It still works, but I don't want the URL to change (hence why I'm using Rewrite rather than Redirect). Any idea why? Is there something wrong my rule?

Salman A
  • 262,204
  • 82
  • 430
  • 521
Barguast
  • 5,926
  • 9
  • 43
  • 73

2 Answers2

3

When you request the URL /latest your rules rewrites it to /1.1. Since /1.1 matches an existing directory instead of a file, IIS responds with a courtesy redirect as described here. IIS uses the rewritten URL since it cannot see the original URL.


Instead of serving same content through two URLs (/latest and /latest/) I would suggest that you emulate the same behavior through your rules. If the requested URL is /latest it should first redirect to /latest/ then rewritten:

<rule name="Latest: force trailing slash" stopProcessing="true">
    <match url="^latest$" />
    <action type="Redirect" url="latest/" redirectType="Found" />
</rule>
<rule name="Latest: rewrite" stopProcessing="true">
    <match url="^latest/(.*)" />
    <action type="Rewrite" url="1.1/{R:1}" />
</rule>
Salman A
  • 262,204
  • 82
  • 430
  • 521
  • Yes, you're right. I've included this along with Kev's answer and it's now behaving how I'd like. Thanks! – Barguast Apr 29 '15 at 18:00
1

This is likely the problem you're experiencing:

IIS generates courtesy redirect when folder without trailing slash is requested

(Although that article is about IIS6, IIS7+ behaves in the same way and it seems you can't disabled this behaviour.)

Add a rule before your existing one that matches just /latest (no trailing slash):

<rewrite>
    <rules>
        <rule name="Latest1" stopProcessing="true">
            <match url="^latest$" />
            <action type="Rewrite" url="1.1/" />
        </rule>
        <rule name="Latest2" stopProcessing="true">
            <match url="^latest(.*)" />
            <action type="Rewrite" url="1.1{R:1}" />
        </rule>
    </rules>
</rewrite>

There's probably a more elegant way, that does what it says on the tin.

You may need to do a hard reload of the page because your browser may cache the redirect, you can always test in "incognito mode" which never saves permanent redirects between sessions.

Kev
  • 118,037
  • 53
  • 300
  • 385
  • Thanks, it appears to work to a degree, except all of the resources referenced in the index.html appear to be loaded from the wrong URL. For example, if I go to /latest then a – Barguast Apr 29 '15 at 17:48
  • Disregard the previous comment - I think Salman A explained and resolved this too. – Barguast Apr 29 '15 at 18:00