Rewrite rule to WWW except when on localhost - asp.net

For SEO optimization reason, I get all requests to http://Example.com redirected to http://www.Example.com. The problem is that when working on local, requests to localhost get redirected as well.
I tried the suggestion in this Rewrite rule to HTTPS except when on localhost answer with no luck.
Here is my actual redirection rule located in Web.Config (hopefully it can help someone that is looking for Rewrite rule to WWW):
<system.webServer>
<rewrite>
<rules>
<rule name="redirect example.com to www.example.com">
<match url="^(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.example\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
Any help?

You can do a rule as follows
<rule name="redirect example.com to www.example.com">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^www.*" negate="true" />
<add input="{HTTP_HOST}" pattern="localhost" negate="true" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:0}" />
</rule>
</rules>
It combines two conditions with "MatchAll" where the first input is similar to one you already have (you can use yours if you want) and the second one is to check for localhost. Note, that you would probably need to use {R:0} and I also changed match url to .*
You can also use different web.configs (debug and release). Read more here: http://msdn.microsoft.com/en-us/library/vstudio/dd465318(v=vs.100).aspx

Related

IIS Redirect HTTP to HTTPS and WWW to non-WWW

On IIS 10 with URL Rewrite Module 2.0 I need 2 rules
1) HTTP to HTTPS
2) WWW to non-WWW
First one created by Blank rule template.
For second one I use Canonical domain name template.
In my web.config rules likes like this:
<rewrite>
<rules>
<rule name="ForceHttps" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
<rule name="CanonicalHostNameRule1" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^cooltechunder\.com$" negate="true" />
</conditions>
<action type="Redirect" url="https://cooltechunder.com/{R:1}" />
</rule>
</rules>
</rewrite>
All cases works fine expect one starting with: http://www.
See this image for results I have:
https://i.imgur.com/h2l3Yw6.png
You wrote stopProcessing="true".
This means that, if the rule matches, subsequent rules will be skipped.
From the documentation:
A rule may have the StopProcessing flag turned on. When the rule action is performed (i.e. the rule matched) and this flag is turned on, it means that no more subsequent rules will be processed and the request will be passed to the IIS request pipeline. By default, this flag is turned off.
It seems to me that this is the situation you are describing that you did not want.
So, remove it.
Ok, My problem was different and related to bindings.
I have to specify 'Host Name' in bindings, as specific ports used by other websites also
And I forgot to add 'www' versions of bindings also.
Now my bindings looks like this: https://i.imgur.com/Lhdv4nS.jpg
Also I have changed rewrite code to more compact one:
<rewrite>
<rules>
<rule name="Https and non-www">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{HTTP_HOST}" pattern="^cooltechunder\.com$" negate="true" />
</conditions>
<action type="Redirect" url="https://cooltechunder.com/{R:1}" />
</rule>
</rules>
</rewrite>

IIS rewrite rule to redirect https to http not working

There's lots of questions here about redirecting http to https so I figured it would be easy to reverse the process. However, everything I've tried hasn't worked.
I'm trying to combine the rule with my canonical host name rule (it's the first rule, at the top of the rewrite rules):
<rule name="CanonicalHostName" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="^ON$" />
<add input="{HTTP_HOST}" negate="true" pattern="^www\.example\.com|example-staging\.azurewebsites\.net$" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
The site is hosted on Azure and DNS is with CloudFlare if that makes any difference, I'm sure it shouldn't.
Any ideas what I'm doing wrong / might be preventing the https to http part of the rule working? (the host name part works fine)
CloudFlare
It seems the reason you cannot redirect away from SSL is because you are using CloudFlare. CloudFlare at a minimum uses flexible SSL. This means that the end user, browser shows the SSL lock but your server doesn't need SSL. See documentation here: https://www.cloudflare.com/ssl
Without CloudFlare the following example should work.
No CloudFlare
The following rule should work. You could still add your negate in if you want.
<rule name="HTTPS to HTTP redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Redirect" redirectType="Found" url="http://{HTTP_HOST}/{R:1}" />
</rule>
Full rewrite section for my working demo site.
<rewrite>
<rules>
<rule name="CanonicalHostNameRule1">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.ashleymedway\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://www.ashleymedway.com/{R:1}" />
</rule>
<rule name="HTTPS to HTTP redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="on" />
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}/{R:1}" redirectType="Found" />
</rule>
</rules>
</rewrite>
Your redirect is still http:
url="http://www.example.com/{R:1}"
You can follow these instructions: Click Here
Additional information: Here

Redirect Non-WWW to WWW (except one spesific subdomain)

On my Windows 2012 server I have installed the URL Rewrite module in IIS. I have followed this guide to redirect non-www to www in web.config:
http://www.surfingsuccess.com/asp/iis-url-rewrite.html#.VF6GBid0yAU
So far, so good!
The only problem is that we also host the subdomain "api.example.com". This API stops working when I apply the code in web.config.
My question is: What is wrong with the code below? Why does the subdomain stop working when I try to redirect non-www to www, except "api.example.com"?
<rewrite>
<rules>
<rule name="CanonicalHostNameRule1">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.example\.com$" negate="true" />
<add input="{HTTP_HOST}" pattern="^api\.example\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" />
</rule>
</rules>
</rewrite>
I have similar check and I have same rule but have specified differently in pattern.
My suggestion is to enable Failed request tracing to check URL rewrites.
http://www.iis.net/learn/extensions/url-rewrite-module/using-failed-request-tracing-to-trace-rewrite-rules
Edit: Updated rule.
<rewrite>
<rules>
<rule name="non-root" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^(www.example.com)$" negate="true" />
<add input="{HTTP_HOST}" pattern="^(api.example.com)$" negate="true" />
<add input="{HTTP_HOST}" pattern="^(example.com)$" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" />
</rule>
</rules>
</rewrite>
Actually, there was nothing wrong with my rewrite code. The reason why the API stopped working was because it had a referance to the top domain of the site (example.com), this caused a conflict with the rewrite code. After changing the referance to the www -version of the doman (www.example.com) everything worked fine.

ASP.NET - rewriting all https requests to http

My issue is precisely the one presented here, and I've decided to try rewrite all https requests to http. I've searched long and hard but there doesn't seem to be a definitive way to achieve this - see these questions (no solutions): Redirect https to http using rewrite rule in webconfig file ; https://stackoverflow.com/questions/15214717/iis-rewrite-https-to-http-whilst-keeping-existing-https-rules
I've added the rewrite module to IIS, and tried the following in web.config:
<rewrite>
<rules>
<clear />
<rule name="force http" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
But it still allows the user to access a non-https site with https (essentially accessing a different site).
How do I force all https requests to be http requests?
edit: I've also tried every suggested solution here with no luck. The url rewrite module is definitely successfully installed on IIS!
edit2: Tried the following without success:
<system.webServer>
<rewrite>
<rules>
<clear />
<rule name="force http" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
<add input="{HTTP_HOST}" pattern="^(?:www)?\.test.site\.com$"
negate="true" ignoreCase="true" />
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}{REQUEST_URI}"
redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
I restarted IIS and the rewrite rules reflect in inetmgr. Loading https://test.site.com/ still loads with https.
A couple of things. First the rewrite needs to process when HTTPS is on and not off. Second, for the application that needs to run over HTTPS you will need to exclude it from the rewrite. The revised rewrite rule should look something like this:
<rewrite>
<rules>
<clear />
<rule name="force http" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
<add input="{HTTP_HOST}" pattern="^example\.com$"
negate="true" ignoreCase="true" />
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}{REQUEST_URI}"
redirectType="Permanent" />
</rule>
</rules>
</rewrite>
This should keep https://example.com/login on https and all other URL's will get redirected to http. For example, https://test.example.com/login will be redirected to http://test.example.com/login. This rewrite rule needs to be placed on the site with the HTTPS binding for the rewrite to work properly.
Please be aware when using a 301 permanent redirect some browsers won't make the request out to the server on subsequent hits so after changing the rule a browser cache clear is required. The network tab may even lie and say the request is made but an external tool like Fiddler or Wireshark will let you know for sure.

IIS7 URL Rewriting: How not to drop HTTPS protocol from rewritten URL?

I'm working on a website that uses IIS 7's URL rewriting feature to do a permanent redirect from example.com to www.example.com, as well as rewrites from similar domain names to the "main" one, such as from www.examples.com to www.example.com.
This rewrite rule - shown below - has worked well for some time now. However, we recently added HTTPS support and noticed that if users visit one of the URLs to be rewritten to www.example.com then HTTPS is dropped. For instance, if a user visits https://example.com they get redirected to http://www.example.com, whereas we would like them to be sent to https://www.example.com.
Here is the rewrite rule of interest (in Web.config):
<rule name="Canonical Host Name" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^example\.com$" />
<add input="{HTTP_HOST}" pattern="^(www\.)?example\.net$" />
<add input="{HTTP_HOST}" pattern="^(www\.)?example\.info$" />
<add input="{HTTP_HOST}" pattern="^(www\.)?examples\.com$" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
As you can see, the action element's url attribute points directly to http://, so I get why https://example.com is redirected to http://www.example.com. My question is, how do I fix this? I tried (naively) to just drop the http:// part from the url attribute, but that didn't work.
Here's Scott's answer with Hasan's improvements. This should cover mixed SSL/non-SSL sites. The rule basically says "if the url does not have www.example.com", do a permanent redirect to it. Essentially... you are redirecting people who visit you without www or directly to your IP address.
<rewrite>
<rules>
<rule name="Canonical Host Name" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^www\.example\.com$" negate="true" />
</conditions>
<action type="Redirect" url="{MapSSL:{HTTPS}}www.example.com/{R:1}" redirectType="Permanent" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="MapSSL" defaultValue="http://">
<add key="ON" value="https://" />
<add key="OFF" value="http://" />
</rewriteMap>
</rewriteMaps>
</rewrite>
Figured out the answer with some help from my colleagues.
I needed to use multiple rules with a condition on {HTTPS}. Note the {HTTPS} condition in the rules below.
<rule name="Canonical Host Name (HTTP)" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="OFF" />
<add input="{HTTP_HOST}" pattern="^example\.com$" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
<rule name="Canonical Host Name (HTTPS)" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="ON" />
<add input="{HTTP_HOST}" pattern="^example\.com$" />
</conditions>
<action type="Redirect" url="https://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
I then repeated the rule pair above for the alternate domain names.
If you just want to redirect based on the currently used protocol (as per your last sample) then there's a much simpler solution that will halve the amount of rules you will need. The following is what I've learned from a collegue of mine.
As you've seen, the {HTTPS} argument will contain the value ON or OFF. You can map this value to https:// or http:// by feeding this value into a rewritemap.
Here's how this would work:
1- Create a rewritemap section for mapping the {HTTPS} value:
<rewriteMap name="MapProtocol" defaultValue="OFF">
<add key="ON" value="https://" />
<add key="OFF" value="http://" />
</rewriteMap>
It's up to you to decide if you want to only include the protocol, or the semicolon and forward slashes as well. It doesn't matter for the solution, but keep it in mind wherever you refer to it.
2- Refer to this map wherever you need. In this sample it's used in outbound-rules, but it'll also work in your scenario:
<rule name="Outbound-Rule Name" stopProcessing="true" preCondition="ResponseIsHtml">
<match filterByTags="A, Link, Script" pattern="YOUR PATTERN" />
<action type="Rewrite" value="{MapProtocol:{HTTPS}}{HTTP_HOST}/REST OF RELATIVE LINK HERE" />
</rule>
That's it, the URL Rewrite module should now automagically use the correct protocol for your links depending on if you're using https, or, of course, http.
Hope this helps!
Here's a cross-domain solution which works not only on example.com but also on any domain
<rewrite>
<rules>
<rule name="Canonical Host Name" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^www\.([.a-zA-Z0-9]+)$" negate="true" />
</conditions>
<action type="Redirect" url="{MapProtocol:{HTTPS}}www.{HTTP_HOST}/{R:0}" redirectType="Permanent" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="MapProtocol" defaultValue="OFF">
<add key="ON" value="https://" />
<add key="OFF" value="http://" />
</rewriteMap>
</rewriteMaps>
</rewrite>

Resources