IIS 10 Rewrite Rule adds extra slash (/) on end of rewrite - iis

I needed to change a folder name on a live site. I need to redirect all requests to that folder (and below it) to the new one.
OLD: https://www.example.com/oldfolder/
OLD: https://www.example.com/oldfolder/subfolder/
OLD: https://www.example.com/oldfolder/subfolder?i=234
to
NEW: https://www.example.com/newfolder/
NEW: https://www.example.com/newfolder/subfolder/
NEW: https://www.example.com/newfolder/subfolder?i=234
The trailing forward slash is desired, but the rewrite is resulting in two trailing slashes:
https://www.example.com/oldfolder redirects to https://www.example.com/newfolder//
The server is IIS 10. Here is the Web.config setting:
<rewrite>
<rules>
<rule name="Add trailing slash" stopProcessing="true">
<match url="(.*[^/])$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_METHOD}" matchType="Pattern" negate="true" ignoreCase="true" pattern="POST" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="{R:1}/" />
</rule>
<rule name="Redirect to /newfolder/ directory" stopProcessing="true">
<match url="^(oldfolder)(.*)" ignoreCase="true" />
<action type="Redirect" url="https://www.example.com/newfolder{R:2}" redirectType="Permanent" appendQueryString="true" />
</rule>
</rules>
</rewrite>
I changed the order of the rules but got the same result. I changed /{R:2} to only {R:2} and still get the same result.
I also don't think my rule is catching /oldfolder/subfolder/ and redirecting to /newfolder/subfolder/
Can anyone see where this extra slash is coming from and how to handle subfolders of the redirected folder?

Related

Rewrite/Redirect rule in IIS causing trailing slash

I am using 3 domain-agnostic rewrite rules in my IIS. First i redirect from HTTP to HTTPS, then i redirect from naked-domain to www and in the end i remove .php from the URL by rewrite.
However, i see that whenever i access a page which is a subfolder and i access the index page in it, a trailing slash is added in the end of the url. Example:
Root -> subfolder called Items with an index.php in it
URL - www.xxx.net/items/
If i access a file other than index.php inside that folder it doesn't have a trailing slash
Root -> subfolder called Items with 2.php in it
URL - www.xxx.net/items/2
Normally, i wouldn't care but i noticed that google and the crawlers consider www.xxx.net/items and www.xxx.net/items/ as different entities which causes issues.
I know it's something easy but can't pinpoint it right now. Can someone show me how to get rid of this behaviour?
Here are the rules:
<rewrite>
<rules>
<rule name="HTTP/S to HTTPS Redirect" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{SERVER_PORT_SECURE}" pattern="^0$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" />
</rule>
<rule name="Redirect naked domain to www" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" negate="true" pattern="^www\." />
</conditions>
<action type="Redirect" url="https://www.{HTTP_HOST}{REQUEST_URI}" appendQueryString="false" redirectType="Permanent" />
</rule>
<rule name="Remove PHP" stopProcessing="true">
<match url="^(.*)$" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}.php" matchType="IsFile" ignoreCase="false" />
</conditions>
<action type="Rewrite" url="{R:1}.php" />
</rule>
</rules>
</rewrite>
After reading a lot about it, it turns out that this is very expected behaviour and you need to factor it in. Basically when you know that you going to get a trailing slash, make sure that your links pointing to this page also include trailing slash in the end so you don't get a redirect.

Web.config Ignore all subdomains while redirecting non www to www

I am using a web.config to redirect all non www to www which is working fine. How do I add a rule to ignore all subdomains so http://example.com redirects to http://www.example.com but any subdomain http://*.example.com or http://one.example.com do not redirect to www. (I cannot add the list of subdomains).
<rule name="Redirect to www">
<match url=".*" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^(www\.)(.*)$" negate="true" />
</conditions>
<action type="Redirect" url="http://www.{HTTP_HOST}" redirectType="Permanent"/>
</rule>
I think Joey's answer only covers the cases where domains are ending in .com and can't handle cases like .co.uk .co.za .com.au etc. You can extend the regular expression a little more but allowing for different types of domains using [a-z] will end up redirecting the subdomains as well, which is what you don't want according to the question.
So in order to achieve this, you'll have to handle the specific cases that you think can arise in your situation.
<rule name="Redirect to www">
<match url=".*" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^([a-z-]+[.](com|co|ca|net)([.](uk|sg|au)){0,1})$" negate="false" />
</conditions>
<action type="Redirect" url="http://www.{HTTP_HOST}" redirectType="Permanent"/>
</rule>
You can modify the regular expression to your liking.
You could try to with the following code:
<rules>
<rule name="Redirect to www">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^example\.com$" negate="true" />
<add input="{HTTP_HOST}" pattern="^one\.example\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://www.{HTTP_HOST}/{R:0}"/>
</rule>
</rules>

How to apply URL Rewrite rules correctly for IIS applications

We have an IIS 8.5 setup where a single website is bound to domain.com and contains a number of IIS applications accessed as domain.com/app1, domain.com/app2 etc.
Each of these applications points to the same physical path, so they all share a web.config. This is a specific CMS configuration.
I have applied the usual URL Rewrite rules (redirect to HTTPS, enforce lowercase, add trailing slash etc.) to the web.config each application shares but have realised these rules are only applied to the URL after the application name. The rules I have are just standard rules added using the URL Rewrite GUI:
<rewrite>
<rules>
<rule name="Enforce lowercase" stopProcessing="true">
<match url="[A-Z]" ignoreCase="false" />
<action type="Redirect" url="{ToLower:{URL}}" redirectType="Permanent" />
</rule>
<rule name="Add trailing slash" stopProcessing="true">
<match url="(.*[^/])$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Redirect" url="{R:1}/" redirectType="Permanent" />
</rule>
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
So, for example, http://domain.com/APP1/PATH redirects to https://domain.com/APP1/path/. Also, https://domain.com/app1 doesn't redirect to https://domain.com/app1/.
The HTTPS rule is fine, but can anyone tell me how I can configure the other 2 rules so that they work with the entire URL, bearing in mind that the specific application name (app1, app2 etc) needs to be handled generically.
UPDATE
I've discovered that I can enforce lowercase URLs using a global rule in IIS (at server level) which is sufficient for my needs. But it doesn't seem to be possible to replicate the website-level rule for adding/removing trailing slash.
You just need to change action URL.
<rule name="Add trailing slash" stopProcessing="true">
<match url="(.*[^/])$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}/" redirectType="Permanent" />
</rule>

IIS Rewrite rule with QueryString in Rewrite

I'm having a problem with an IIS rewrite rule. We have many set up and working in our web.config file. I am trying to modify one of them. Apologies for the level of this question. I'm not experienced in this topic.
The current rule is:
<rule name="my-rule-test" stopProcessing="true">
<match url="^my-page.asp" />
<action type="Rewrite" url="/my-domain/my-actual-page.asp" />
</rule>
This rule works fine. I'm now trying to simply add a QueryString to the Rewrite page as follows:
<rule name="my-rule-test" stopProcessing="true">
<match url="^my-page.asp" />
<action type="Rewrite" url="/my-domain/my-actual-page.asp?aS=h" />
</rule>
This rule fails and trips the server over to the page we have set up in web.config here:
<system.web>
<customErrors defaultRedirect="c:\test.html" mode="On">
</customErrors>
</system.web>
Can somebody please let me know what I'm doing wrong?
Thanks,
J
Your formatting is not correct:Please refer to this.
<rules>
<rule name="Remove trailing slash" stopProcessing="true">
<match url="(.*)/$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="{R:1}" />
</rule>

Use urlrewrite to rewrite all requests to root

I want to use web.config and IIS's urlrewrite to rewrite all requests to a certain directory to the root, for example:
From:
mydomain.com/directory/test.php
To:
mydomain.com/test.php
and
From:
mydomain.com/directory/test/test.php
To:
mydomain.com/test/test.php
All parameters, etc should be passed as well. Any idea how to do this using web.config?
I had a requirement for this a while back and found this:
Using Url rewrite to "delete" a folder
There's a small error in the rule which was corrected later by the poster. Here's a copy with the correction should the link dry up (I also made it a bit more generic for your requirements):
<rewrite>
<rules>
<rule name="RemoveDirectory" stopProcessing="true">
<match url="^directory$|^directory/(.*)$" />
<conditions>
</conditions>
<action type="Redirect" url="{R:1}" />
</rule>
<rule name="RewriteToFile">
<match url="^(?!directory/)(.*)" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="directory/{R:1}" />
</rule>
</rules>
</rewrite>
Just search and replace directory with your directory name.

Resources