regexiis-7url-rewrite-modulerewritemap

Rewrite maps in IIS7 — how to make the match optionally include a trailing slash?


I have read the top 30 Google hits for several combinations of IIS rewrite map condition and so on, but I can't find any decent documentation, either on a microsoft.com site or elsewhere.

I have a bunch of rewrite maps in IIS7 that I would like to process irrespective of whether or not they are followed by a trailing slash. So www.foo.com/bar and www.foo.com/bar/ should both match the rule.

<rewrite>
    <rewriteMaps>
        <rewriteMap name="ShortURLs">
            <add key="/terms" value="/en-us/terms-and-conditions/"/>
            <add key="/privacy" value="/en-us/privacy-and-cookies/"/>
            <add key="/buy" value="/en-us/where-to-buy/"/>
        </rewriteMap>
    </rewriteMaps>
    <rules>
        <rule name="Short URL redirects">
            <match url="^/?(.+)/?$" />
            <conditions>
                <add input="{ShortURLs:{REQUEST_URI}}" pattern="(.+)"/>
            </conditions>
            <action type="Redirect" url="{C:1}" appendQueryString="true"/>
        </rule>
    </rules>
</rewrite>

Now this works perfectly well, except that the only way I can find to make /terms/ match the first key in the rewrite map is to duplicate the map, so that it reads:

<rewriteMap name="ShortURLs">
    <add key="/terms" value="/en-us/terms-and-conditions/"/>
    <add key="/privacy" value="/en-us/privacy-and-cookies/"/>
    <add key="/buy" value="/en-us/where-to-buy/"/>

    <add key="/terms/" value="/en-us/terms-and-conditions/"/>
    <add key="/privacy/" value="/en-us/privacy-and-cookies/"/>
    <add key="/buy/" value="/en-us/where-to-buy/"/>
</rewriteMap>

This seems ridiculously inelegant, given that I'm using regular expressions to match them in the first place. Adding /? to the condition input or the condition pattern doesn't seem to work.

I have seen the answer to IIS7 Rewrite Map Regex? that mentions regular expressions cannot be used (quoting from Using Rewrite Maps in URL Rewrite Module) but, as I have commented there, this seems to relate to the specific examples being given before that text, rather than a wholesale "this can never work".

What am I missing? There must be some means of doing this; am I missing something obvious?


Solution

  • This should do it:

    <rewrite>
        <rewriteMaps>
            <rewriteMap name="ShortURLs">
                <add key="terms" value="/en-us/terms-and-conditions/"/>
                <add key="privacy" value="/en-us/privacy-and-cookies/"/>
                <add key="buy" value="/en-us/where-to-buy/"/>
            </rewriteMap>
        </rewriteMaps>
        <rules>
            <rule name="Short URL redirects">
                <match url="^(.+?)/?$" />
                <conditions>
                    <add input="{ShortURLs:{R:1}}" pattern="(.+)" />
                </conditions>
                <action type="Redirect" url="{C:1}" appendQueryString="true"/>
            </rule>
        </rules>
    </rewrite>
    

    You were quite close; I only needed to make three small changes:

    I share your experience in having trouble finding decent documentation; I had to experiment my way through, with help from the following articles: