Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 241
Owen Blacker Avatar asked Mar 24 '14 14:03

Owen Blacker


1 Answers

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:

  • removed the leading slashes in the keys in the rewrite map
  • used the non-greedy quantifier +? in the rule's match
  • used a back reference to the match {R:1} in the condition input

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

  • http://www.iis.net/learn/extensions/url-rewrite-module/using-rewrite-maps-in-url-rewrite-module
  • http://technet.microsoft.com/en-us/library/ee215190(v=ws.10).aspx
like image 157
Ruud Helderman Avatar answered Oct 19 '22 11:10

Ruud Helderman