3
votes

In the context of URL Rewrite 2.0 in IIS 7.5, I want to be able to enforce canonical domain names for multiple domains for a multi-country site, in as few rules as possible. Something like this:

<rule name="UK Host Name">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{HTTP_HOST}" pattern="^company\.co\.uk$" />
        <add input="{HTTP_HOST}" pattern="^company\.co$" />
        <add input="{HTTP_HOST}" pattern="^company\.org$" />
        <add input="{HTTP_HOST}" pattern="^company\.net$" />
        <add input="{HTTP_HOST}" pattern="^company\.uk\.com$" />
        <add input="{HTTP_HOST}" pattern="^www\.company\.co\.uk$" negate="true" />
    </conditions>
    <action type="Redirect" url="http://www.company.co.uk/{R:1}" />
</rule>
<rule name="France Host Name">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{HTTP_HOST}" pattern="^company\.fr$" />
        <add input="{HTTP_HOST}" pattern="^company-france\.com$" />
        <add input="{HTTP_HOST}" pattern="^www\.company\.fr$" negate="true" />
    </conditions>
    <action type="Redirect" url="http://www.company.fr/{R:1}" />
</rule>

The problem with the above, I believe, is that each of those conditions must be true hence logicalGrouping="MatchAll" but if changed to MatchAny then the last condition (with negate="true") will be ignored, meaning we run the redirect rule even if the user is visiting the correct domain.

The only alternative I can think of is having a separate rewrite rule for every single different domain, but there could be vast numbers of domains and it could get messy. There will be plenty of other rewrite rules and maps as it is.

How can I create more complex sets of conditions, rather than just All or Any?

1

1 Answers

7
votes

The trick is to combine the domains you want to match against into one rule with the or | operator so that you only have one 'positive' rule and one 'negative' rule which should MatchAll. E.g.:

<rule name="UK Host Name">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{HTTP_HOST}" pattern="^company\.(co(\.uk)?|org|net|uk\.com)$" />
        <add input="{HTTP_HOST}" pattern="^www\.company\.co\.uk$" negate="true" />
    </conditions>
    <action type="Redirect" url="http://www.company.co.uk/{R:1}" />
</rule>
<rule name="France Host Name">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{HTTP_HOST}" pattern="^company(-france)?\.(fr|com)$" />
        <add input="{HTTP_HOST}" pattern="^www\.company\.fr$" negate="true" />
    </conditions>
    <action type="Redirect" url="http://www.company.fr/{R:1}" />
</rule>

This might eventually give you a slight chance that your regular expression matches too many domain names. E.g. the pattern pattern="^company(-france)?\.(fr|com)$" also matches company.com which might not be desirable. In that case you have to be more specific and e.g. change the pattern to pattern="^company\.fr|company-france\.com$".