3

I have a simple IIS rule to redirect HTTPS to HTTP:

<rule name="HTTPS" enabled="true" stopProcessing="true">
    <match url=".*\.(asp)$" ignoreCase="false" />
    <conditions>
        <add input="{HTTPS}" pattern="on" />
        <add input="{REQUEST_URI}" negate="true" pattern="^/ecards/user*" ignoreCase="true" />
    </conditions>
    <action type="Redirect" url="http://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>

The matching url will only work on .asp files, but how can I also get it to work for root directories?

E.g.

example.com
example.com/
example.com/test
example.com/test/

I don't want to just have the match URL as:

<match url="(.*)" />

Because then other non .asp files get rewritten.

Tasos K.
  • 7,979
  • 7
  • 39
  • 63
4532066
  • 2,042
  • 5
  • 21
  • 48

1 Answers1

1

One way to include directories in your rule is to exclude everything else.

Assuming that everything else has a file extension (e.g. .php, .css. .js, etc.) you can negate all input that has the . in the path.

I changed your code a bit to make a working demo locally (I don't have HTTPS locally to test so instead of redirecting to HTTP I set it to redirect to About.aspx) and the two rules are:

<rule name="HTTPS" enabled="true" stopProcessing="true">
    <match url=".*\.(asp)$" ignoreCase="false" />
    <action type="Redirect" url="/About.aspx" appendQueryString="true" redirectType="Permanent" />
</rule>
<rule name="NEWRULE" enabled="true" stopProcessing="true">
    <match url="(.*)" />
    <conditions>
        <add input="{REQUEST_URI}" negate="true" pattern=".*\.(.)$" ignoreCase="true" />
        <add input="{REQUEST_URI}" negate="true" pattern="^/About*" ignoreCase="true" />
    </conditions>
    <action type="Redirect" url="/About.aspx" appendQueryString="true" redirectType="Permanent" />
</rule> 

So, based on your original code sample, a new rule that will work for you would be similar to this:

<rule name="IncludeDirectories" enabled="true" stopProcessing="true">
    <match url="(.*)" />
    <conditions>
        <add input="{REQUEST_URI}" negate="true" pattern=".*\.(.)$" ignoreCase="true" />
        <add input="{HTTPS}" pattern="on" />
        <add input="{REQUEST_URI}" negate="true" pattern="^/ecards/user*" ignoreCase="true" />
    </conditions>
    <action type="Redirect" url="http://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>  

Note: The above approach is rather aggressive. You could replace this condition:

<add input="{REQUEST_URI}" negate="true" pattern=".*\.(.)$" ignoreCase="true" />

with the following:

<add input="{REQUEST_URI}" negate="true" pattern=".*\.(php|css|js|jpg|gif|png)$" ignoreCase="true" />

Where you exclude specific extensions. You add as many as you want.

Edit: If you want to have specific pages still with HTTPS maybe the following rule will be helpful (haven't tested it though). The previous rule sends to HTTP all URLs except those that have /ecards/user where this one sends to HTTPS those that have /ecards/user. I believe there will be no conflict.

<rule name="HTTPS2Admins" enabled="true" stopProcessing="true">
    <match url="/ecards/user(.*)" />
    <conditions>
        <add input="{HTTP}" pattern="on" />
    </conditions>
    <action type="Redirect" url="https://{HTTP_HOST}/ecards/user{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>
Tasos K.
  • 7,979
  • 7
  • 39
  • 63
  • Out of interest @Tasos K., I am trying to add another rule to force e.g. http://example.com/ecards/user* to https, but I keep getting stuck in a redirect loop. Is that possible? The rule you supplied will force all HTTPS except ecards/user* to HTTP, but I also need to force http://example.com/ecards/user* to HTTPS. – 4532066 Nov 07 '15 at 14:12
  • The condition `` should prevent this, right? I added in my demo this rule and the URLs `http://localhost:51801/ecards/user/ddd` and `http://localhost:51801/ecards/user-something` are not redirected. Maybe another rule in your web.config is causing this issue. – Tasos K. Nov 07 '15 at 14:34
  • Thanks @Tasos K. The issue I have is that my whole site got indexed by google as HTTPS before I got my redirect working properly. Now I need to redirect all HTTPS to HTTP except ecard/user*, which is now working fine using your rule. But if a user goes to HTTP..ecard/user* I need that to redirect to HTTPS, but only those pages, and not anything else. e.g. this http://jimpix.co.uk/ecards/user-sign-up.asp needs to redirect to the https version, via a different rule, while leaving your HTTPS to HTTP rule in place. – 4532066 Nov 07 '15 at 15:20
  • Regarding Google and its indexing consider using the meta `` and put the HTTP link there (see [here](https://moz.com/blog/canonical-url-tag-the-most-important-advancement-in-seo-practices-since-sitemaps)). After a few weeks Google index will use the links you provide. Also for CSS and JS files use the `//` prefix instead of `http://` or `https://` (see [here](http://stackoverflow.com/questions/11881054/is-a-url-starting-with-valid)). Those tips are not for the IIS rewriting rules but they might help you resolve your issue with fewer rewriting rules. – Tasos K. Nov 07 '15 at 15:29
  • Thanks I'll check out the canonical option for the index issue. Regarding a rewrite rule, is there any way 2 rules can co-exist, one for HTTPS to HTTP, as you've written, and another to force redirects from HTTP to HTTPS for a while directory at the same time, as there are other folders on my site I would like to force to use HTTPS, e.g. admin folders and so on, such as jimpix.co.uk/admin/ – 4532066 Nov 07 '15 at 15:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/94491/discussion-between-stac-pollaidh-and-tasos-k). – 4532066 Nov 07 '15 at 15:53