IIS UrlRewrite problem - iis

I've been using the UrlRewrite IIS plugin for about a month on our production site.
I created a single redirect rule using the supplied template/wizard, the resulting config enrty is as follows:
<rewrite>
<rules>
<rule name="CanonicalHostNameRule1" enabled="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.mycompany\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://www.mycompany.com/{R:1}" />
</rule>
</rules>
</rewrite>
It's been running fine until this morning, when the site started erroring with "too many redirects". As far as I know, nothing in the configuration or infrastructure changed.
I disabled the rule, and the site became functional again (though clearly without any redirecting).
I then re-enabled the rule, and now all is running as expected. I didn't make any changes to the rule other than to temporarily disable it.
Any ideas? Is the plugin buggy?

I'd recommend setting this up:
http://learn.iis.net/page.aspx/467/using-failed-request-tracing-to-trace-rewrite-rules/
This may help you track down the problem if you start getting the "too many directs" error again.

Try this other code, i have on my web and run perfect:
<rule name="Canonical Host Name" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^yourdomain\.com$" />
</conditions>
<action type="Redirect" url="http://www.yourdomain.com/{R:0}" redirectType="Permanent" />
</rule>
The explanation is simple:
Match any URL received to process
The condition is that have anydomaintext.extension (your domain and extension) without prefix
Redirect to same domain with full prefix and put all url.
Other tries was R:1 but quit some of the main url and not run.
The sample from Ruslani:
http://blogs.iis.net/ruslany/archive/2009/04/08/10-url-rewriting-tips-and-tricks.aspx
I tried to use adding www but finally use the sample above.

The fix below worked for me. I discovered my rewrite rule was at out-of-date. The other domain had changed their URL policy and were now redirecting all traffic from otherdomain.com to www.otherdomain.com
<action type="Rewrite" url="http://otherdomain.com/abc/{R:1}" />
to
<action type="Rewrite" url="http://www.otherdomain.com/abc/{R:1}" />
Do you see the difference? By adding the 'www' I preempted the other domain redirection. I basically just complied with their new policy.

Related

IIS Rewrite Rule in web.config to redirect HTTPS requests to HTTP

I need to redirect all https requests to http, for example, if someone visits https://www.example.com/another-page/ to http://www.example.com/another-page/
I have the following rewrite rule in my web.config right now, but it's not working correctly. It's redirecting https://www.example.com/another-page/ to https://www.example.com/, so to the root of the site, but instead I want the redirect to stay in the same URL and only rewrite https to http.
<rule name="Redirect to HTTP" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{R:1}" pattern="^onepage/(.*)$" negate="true" />
<add input="{HTTPS}" pattern="^ON$" />
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}/{R:0}" redirectType="Permanent" />
</rule>
Any help on changing the above rule so that it only changes https to http, but keeps the full url visited would be greatly appreciated!
I set up your rule, cleaned up a little, and it worked; so this isn't really answering with much new.
Suggestion: Remove the onepage input condition just for testing, as cheesmacfly suggested in the question comment.
Also, try changing the action to {R:1} instead of {R:0}. It shouldn't matter in this case, but I just like using 1 and up, to match the specific capturing group. R:0 means the entire matched string, which always confuses me just a little.
<rule name="Redirect to HTTP" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^ON$" />
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
One possibility is that your browser has cached a previous attempt of your rules. When the redirectType is Permanent, and you're still developing or testing, the browser often caches a previous rule. Clear your browser cache, and/or remove the Permanent, and/or browse in incognito mode. When done testing, change it to permanent. See number 2 and 3 in this answer: https://stackoverflow.com/a/9204355/292060
Please paste the below code in web.config file.
<rule name="Redirect to http" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="http://{HTTPS_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
</rule>

IIS HTTP to HTTPS web.config rewrite doesn't return entire URL

So I have been trying to rewrite using the following:
<rules>
<rule name="HttpToHttps" stopProcessing="true"/>
<match url="(.*)"/>
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true"/>
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{URL}"/>
</rule>
<rules>
In two environments, this redirects like it should. In a third environment, it doesn't work. It doesn't work in the sense of, looking at a fiddler log, I see the http call with the full url. When it redirects to https, it removes everything after the HTTP_HOST.
So using the following url:
nonsecure://www.mysite.com/page.aspx?var1=1&var2=2
In two environments, it becomes
secure://www.mysite.com/page.aspx?var1=1&var2=2
In the third it becomes:
secure://www.mysite.com
I tried rewriting it as https://{HTTP_HOST}{HTTP_URL} and that doubled the {URL} in the first two environments:
secure://www.mysite.com/page.aspx?var1=1&var2=2&var1=1&var2=2
I'm not very experienced with web.configs, kinda learning as I go, so if anyone has any input as to what's going on here, it would be greatly appreciated. If it has any bearing on anything, the third environment is on two servers that are load balanced.
Ruslany has several IIS URL Rewrite examples on his blog, HTTP to HTTPS is one of them:
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
See http://ruslany.net/2009/04/10-url-rewriting-tips-and-tricks/ for more.

Remove multiple forward slashes

I've noticed that with .NET MVC sites, you're able to hit URLs with multiple forward slashes, for example:
http://www.example.com//category
http://www.example.com//category//product
The URL loads fine and everything works, however, I've been asked to stop this from happening.
I've been trying to use IIS URL Rewrites to get it working:
<rewrite>
<rules>
<rule name="Remove multiple slashes" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{UNENCODED_URL}" matchType="Pattern" pattern="^(.*)//(.*)$" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="{C:1}/{C:2}" />
</rule>
</rules>
</rewrite>
However, the results seem very temperamental. Sometimes the product URL will redirect, sometimes it won't and the same thing happens with the category. It's almost like the URL is being cached by the application.
Does anyone know if I can disable any caching that's in place, or if there is another way to get around this multiple slash issue?
Any help is much appreciated.
In the end, I have resorted to using a code behind redirect to get it working.
The issues I was having using the IIS URL Rewrites was due to the way IIS caches the redirects. When I disabled caching completely, as WouterH suggested, it worked. However, I'm not comfortable disabling caching in this way as it could introduce performance issues.
My fix was to use a code behind redirect in the Global.asax.cs file:
protected void Application_BeginRequest(object sender, EventArgs e)
{
string requestUrl = Request.ServerVariables["REQUEST_URI"];
string rewriteUrl = Request.ServerVariables["UNENCODED_URL"];
if (rewriteUrl.Contains("//") && !requestUrl.Contains("//"))
Response.RedirectPermanent(requestUrl);
}
I would have liked to use IIS URL Rewrite to get this working, unfortunately I didn't have the time to continue down that line.
Interestingly, the below method did work, however, the HTTP_X_REWRITE_URL is added by the Helicon ISAPI Rewrite which I'm running locally, but is not available on our production server.
<rewrite>
<rules>
<rule name="Remove multiple slashes" stopProcessing="true">
<match url=".*" />
<action type="Redirect" url="{REQUEST_URI}" />
<conditions>
<add input="{HTTP_X_REWRITE_URL}" pattern="([^/]*)/{2,}([^/]*)" />
</conditions>
</rule>
</rules>
</rewrite>
URL Rewrite Module
As IIS automatically normalizes url's with double slashes, you can try to redirect to the normalized url like this:
<rewrite>
<rules>
<rule name="Remove multiple slashes" stopProcessing="true">
<match url=".*" />
<action type="Redirect" url="{REQUEST_URI}" />
<conditions>
<add input="{UNENCODED_URL}" pattern="(.*?)[/]{2,}$" />
</conditions>
</rule>
</rules>
</rewrite>
You can also try to disable caching of the URL rewrite module:
Disabling internal caching of rewrite rules
To disable caching of inbound rewrite rules in URL Rewrite Module run
the following command from an elevated command prompt:
reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp\Rewrite /v
RewriteCacheEnabled /t REG_DWORD /d 0
I have a small feeling that you'll have to restart the webserver after this change :)
Other option #1: non-cacheable server variable
This idea just popped into my mind:
use a non-cacheable server variable in the rule, f.e. try with HTTP_USER_AGENT
<rewrite>
<rules>
<rule name="Remove multiple slashes" stopProcessing="true">
<match url=".*" />
<action type="Redirect" url="{REQUEST_URI}" />
<conditions>
<add input="{UNENCODED_URL}" pattern="(.*?)[/]{2,}$" />
<add input="{HTTP_USER_AGENT}" pattern=".*" />
</conditions>
</rule>
</rules>
</rewrite>
You can explore other server variables here
Other option #2: clear browser cache
During web development, make sure you use Ctrl+F5 to refresh your page, or clear your browser cache after making changes like updating rewrite rules etc. Otherwise you can spend hours of watching to the same problem while it was just your browser that needed to refresh its cache.
Other option #3: IIRF
If you really can't get it to work with the IIS URL Rewrite Module, you can give the open-source ISAPI module IIRF a try. It accepts rules similar to mod_rewrite for Apache.
Try following
<rule name="RemoveMultipleSlashes" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*" />
<action type="Redirect" url="{REQUEST_URI}" />
<conditions>
<add input="{UNENCODED_URL}" pattern="([^/]*)/{2,}([^/]*)" />
</conditions>
</rule>

IIS 7 Canonical URL redirect

I would like to make a website always have www in the address, and enforce it via IIS rewrite.
For example, test.com would become www.test.com.
The typical example rewrite rule is:
<rule name="Canonical Host Name" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" negate="true" pattern="^www\.test\.com$" />
</conditions>
<action type="Redirect" url="http://www.test.com/{R:1}" redirectType="Permanent" />
</rule>
However this requires me to enter the full url of my website. It will not work for development and staging environments that have URLs like www.test.dev and www.test.stage.
Is it possible to create an IIS Rewrite rule that will handle all of those cases?
I have another solution for you:
<rule name="Canonical domain name" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" negate="true" pattern="^www\.([.a-zA-Z0-9]+)$" />
</conditions>
<action type="Redirect" url="http://www.{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" />
</rule>
You're right that the full URL needs to be in the web.config. You have options though.
You can use a config transform to make the regular expression match the correct environment.
There doesn't seem to be any harm if you include all three URL rewrite rules in your web.config. It sounds like your environments are isolated so each environment would only ever match one of the rules. That can clutter your web.config, but not horribly.
I'd go with option 1. You can find information on config transforms here: http://msdn.microsoft.com/en-us/library/dd465326.aspx
I would also suggest you another variant for testing in local environment:
Add to c:\Windows\System32\drivers\etc\hosts:
127.0.0.1 www.example.com
In IIS Manager select site and right click -> Edit bindings.. -> Add..
Enter host name: www.example.com
Open cmd and run iisreset
Now you are able to use www.example.com in browser which is mapped to localhost

Configure IIS to use different robot.txt for https requests

How do I use a different robots.txt for https request than the one that is used for http connections in IIS 7?
Thanks.
There are a few options here, depending on how custom you need this to be. Most flexible approach would be to write a handler and map to it for robots request, and handle internally.
However, for most needs, try to URL rewrite module
http://www.iis.net/download/urlrewrite
off top of my head (aka prob doesnt work 100%), its something like :
<rule name="https_robots">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/robots-https.txt" />
</rule>
Got exactly the same problem:
I am setting up https version now, want to look at it and debug it without a rush, meanwhile fending off Google from crawling https, but keeping http "business as usual". Here's the piece of code I used in a config file:
<rule name="https_robots" stopProcessing="true">
<match url="^robots\.txt$" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Rewrite" url="robots_https.txt" />
</rule>
A few notes:
Basically, I've created a file "robots_https.txt" containing "disallow for all" instruction.
I used Rewrite, not Redirect. I am not sure if the spider would get the redirect. I really doubt that. With Rewrite you can't go wrong.
Hope that helps!

Resources