http-redirectiis-7web-configurl-rewritingisapi-rewrite

Domain Rewrite for both HTTP and HTTPS in IIS 7


I want to do a number of 301 redirects in one request and I found this article to be helpful. However, I have a problem where http://example.com redirects to https://www.example.com BUT https://example.com DOES NOT redirect to https://www.example.com

So here are my examples:

  1. SEO - remove default.aspx (works fine but no HTTPS)
    https://www.example.com/app/default.aspx => https://www.example.com/app/

BUT http://www.example.com/app/default.aspx => http://www.example.com/app/

  1. SEO - Remove trailing slash (doesn't work and no HTTPS as above)
    All links get the trailing slash instead
    http://www.example.com/app => http://www.example.com/app/
    https://www.example.com/app => https://www.example.com/app/

  2. SEO - ToLower (works fine but no HTTPS as above)
    http://www.example.com/APP => http://www.example.com/app
    https://www.example.com/APP => https://www.example.com/app

  3. SEO - http canonical redirect (works 100%)
    http://example.com/app => https://www.example.com/app

  4. SEO - https canonical redirect (doesn't work at all)
    https://example.com/app => https://www.example.com/app - FAILS

  5. SEO - non-canonical redirect (Doesn't work 100%. Without this rule the stylesheet fails to load, but also other links that didn't match any of the above are not being )
    https://example.com/app => https://example.com/app/
    http://example.com/app => http://example/com/app/
    https://www.example.com/app => https://www.example.com/app/
    http://www.example.com/app => http://www.example.com/app/

This is what I have implemented and the problem is as above.

<rewrite>
    <rules>
        <clear />
        <rule name="WhiteList - resources" stopProcessing="true">
            <match url="^resources/" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
            <action type="None" />
        </rule>
        <rule name="SEO - remove default.aspx" stopProcessing="false">
            <match url="(.*?)/?default\.aspx$" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{HTTP_METHOD}" pattern="GET" />
            </conditions>
            <action type="Rewrite" url="_{R:1}" />
        </rule>
        <rule name="SEO - Remove trailing slash" stopProcessing="false">
            <match url="(.+)/$" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{HTTP_METHOD}" pattern="GET" />
               <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            </conditions>
            <action type="Rewrite" url="_{R:1}" />
        </rule>
        <rule name="SEO - ToLower" stopProcessing="false">
            <match url="(.*)" ignoreCase="false" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{HTTP_METHOD}" pattern="GET" />
                <add input="{R:1}" pattern="[A-Z]" ignoreCase="false" />
            </conditions>
            <action type="Rewrite" url="_{ToLower:{R:1}}" />
        </rule>
        <rule name="SEO - http canonical redirect" stopProcessing="true">
            <match url="^(_*)(.*)" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{HTTP_HOST}" matchType="Pattern" pattern="^www\.example\.com$" ignoreCase="true" negate="true" />
                <add input="{HTTP_METHOD}" pattern="GET" />
            </conditions>
            <action type="Redirect" url="https://www.example.com/{R:2}" />
        </rule>
        <rule name="SEO - https canonical redirect" stopProcessing="true">
            <match url="^(_*)(.*)" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{HTTP_HOST}" matchType="Pattern" pattern="^www\.example\.com$" ignoreCase="true" negate="true" />
                <add input="{HTTP_METHOD}" pattern="GET" />
                <add input="{HTTPS}" pattern="^ON$" ignoreCase="true" />
            </conditions>
            <action type="Redirect" url="https://www.example.com/{R:2}" />
        </rule>
        <rule name="SEO - non-canonical redirect" stopProcessing="true">
            <match url="^(_+)(.*)" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{HTTP_METHOD}" pattern="GET" />
            </conditions>
            <action type="Redirect" url="{R:2}" />
        </rule>         
    </rules>
</rewrite>

Solution

  • This is not really a solution as I found the actual problem with IIS.

    When you visit https://example.com with the rules above setup (or https canonical redirect) it will first give you a certificate error if you don't have the "naked domain" certification. If the user opt to continue, then the redirect to https://www.example.com will happen.

    I think this may be happening at the "DNS Negotiation" level rather than IIS level.