IIS 8.5 - 301 redirect and ampersand - iis

I am struggling get 301 redirects to work when the url includes an ampersand in iis. The code I am using is below :
<rewrite>
<rules>
<rule name="Redirect rule1 for 301-maps">
<match url=".*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{301-maps:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="{C:1}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
<rewriteMaps>
<rewriteMap name="301-maps">
<add key="/mobile/product.htm?id=139" value="/" /> << works
<add key="/mobile/product.htm?id=139&subid=1" value="/" /> << fails syntax

All what you need, is to use & in place of &. Your url in rewrite map should be:
<add key="/mobile/product.htm?id=139&subid=1" value="/" />
In XML you need to escape this 5 symbols:
" "
' &apos;
< <
> >
& &

Related

IIS Rewrite Maps with Wildcard for Querystring

Trying to figure out how to do wildcards for querystrings. Right now this works, but it has to be an exact match.
I have this rewrite rule.
<rule name="Redirect rule1 for Redirects ReSv">
<match url=".*" />
<conditions>
<add input="{Redirects:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="{C:1}" appendQueryString="true" />
</rule>
My rewrite maps are like:
<rewriteMaps>
<rewriteMap name="Redirects">
<add key="/contact-us.aspx" value="/contact/" />
<add key="/contact-us/request-information.aspx" value="/contact/" />
</rewriteMap>
</rewriteMaps>
Trying to get something like this:
/contact-us.aspx?q=t&1=2
To redirect to:
/contact/
And include the querystring? so..
/contact/?q=t&1=2
Please us {URL} variable instead of {REQUEST_URI}. Then Rewritemap will be able to wildcard the query string.
<rule name="Redirect rule1 for Redirects ReSv" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{Redirects:{URL}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="{C:1}" appendQueryString="true" redirectType="Permanent" />
</rule>

Limit IIS rewrite map for particular domain

My requirement is to need redirect url for particular domain.So i decided
to use rewrite map but what ever i tried below that will apply for all domain i have. Its not apply to particular domain.
Let me example more deeply. Suppose i have 3 domains on same IIS instance
www.abc.com
www.xyz.com
www.eee.com
In domain www.abc.com the url www.abc.com/legal should be redirected to www.abc.com/privacy.
Like above i have plenty of redirects url need to implement for the same domain.
Below listed things i had tried
<!--Test snippet 1-->
<rewrite>
<rules>
<rule name="Redirect rule1 for Redirects" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_HOST}" pattern=".*www.abc.com.*" />
<add input="{ABCRedirects:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="{C:1}" appendQueryString="false" />
</rule>
</rules>
<rewriteMaps configSource="abc-rewritemaps.config" />
</rewrite>
<!--Test snippet 2-->
<rewrite>
<rules>
<rule name="Redirect rule1 for Redirects" enabled="true" stopProcessing="true">
<match url=".*www.abc.com.*" />
<conditions>
<add input="{HTTP_HOST}" pattern=".*www.abc.com.*" />
<add input="{ABCRedirects:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="{C:1}" appendQueryString="false" />
</rule>
</rules>
<rewriteMaps configSource="abc-rewritemaps.config" />
</rewrite>
<!--Test snippet 3-->
<rewrite>
<rules>
<rule name="Redirect rule1 for Redirects" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{ABCRedirects:{REQUEST_URI}}" pattern=".*www.abc.com.*" />
</conditions>
<action type="Redirect" url="{C:1}" appendQueryString="false" />
</rule>
</rules>
<rewriteMaps configSource="abc-rewritemaps.config" />
</rewrite>
<!--My Rewrite map-->
<rewriteMaps>
<rewriteMap name="ABCRedirects">
<add key="/legal" value="/privacy" />
<add key="/good" value="/bad" />
<add key="/hi" value="/bye" />
<add key="/no" value="/not" />
<add key="/123" value="/321" />
</rewriteMap>
</rewriteMaps>
Above all code i tried is applied for all domain, I cant able to limit its for only www.abc.com alone.
How to limit rewrite maps for particular domain?

Rewriting rule for & in url

How can I setup a rule to replace & with & in url?
This works: www.../home.asp?h=1&w=2
This fails: www.../home.asp?h=1&w=2
For starters, it should be noted that you can access the messed up w parameter as follows:
Request.QueryString("amp;w");
However, I expect you would like something a little more eloquent :)
Assuming that you have access to the IIS URL Rewrite module, (IIS 7 and above), you can add some rules to web.config as follows:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="One Bad Ampersand" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{QUERY_STRING}" pattern="^([^&]+)&amp;([^&]+)$" />
</conditions>
<action type="Rewrite" url="{R:1}?{C:1}&{C:2}" appendQueryString="false" />
</rule>
<rule name="Two Bad Ampersand" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{QUERY_STRING}" pattern="^([^&]+)&amp;([^&]+)&amp;([^&]+)$" />
</conditions>
<action type="Rewrite" url="{R:1}?{C:1}&{C:2}&{C:3}" appendQueryString="false" />
</rule>
<rule name="Three Bad Ampersand" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{QUERY_STRING}" pattern="^([^&]+)&amp;([^&]+)&amp;([^&]+)&amp;([^&]+)$" />
</conditions>
<action type="Rewrite" url="{R:1}?{C:1}&{C:2}&{C:3}&{C:4}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
What these rules do is check for an incoming & in the query string and replace it with &. I do not think it is possible to come up with a generic rule to handle an arbitrary number of occurrences. But, I have established a pattern for up to 3 occurrences that you should be able to follow to add as many as needed.
It should be noted that if you wish to redirect the user's browser, you may do so by changing the type attribute in each action from Rewrite to Redirect.

Combination of IIS rewrite rules - redirect to changed domain name, remove hostname prefix redirect to ssl

My IIS website is currently accessed as http://mywebsite.com and I have 3 objectives related to url rewriting:
Redirect to the website's new name, mynewwebsite.com
Remove www prefix if it exists (eg www.mywebsite.com -> mywebsite.com or www.mynewwebsite.com --> mynewwebsite.com
Redirect to SSL
So in summary I want to redirect all inbound requests to https://mynewwebsite.com/anything*.
The input cases that must be accounted for are
http://mynewwebsite.com/anything*
http://www.mynewwebsite.com/anything*
http://mywebsite.com/anything*
http://www.mywebsite.com/anything*
https://mywebsite.com/anything*
https://www.mywebsite.com/anything*
https://www.mynewwebsite.com/anything*
My rewrite rules look as follows:
<rewrite>
<rules>
<rule name="Do stuff" enabled="true">
<match url="(.*)" ignoreCase="false" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="off" />
<add input="{HTTP_HOST}" pattern="mywebsite.com" />
<add input="{HTTPS}" pattern="^www.mynewwebsite\.com$" />
</conditions>
<action type="Redirect" url="https://mynewwebsite.com/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
With this rule set the following input case is failing (the www isn't stripped): https://www.mynewwebsite.com/anything*
I've banged my head against this sufficiently that I question my fundamental understanding of how rule definitions work.
anything could be present or not exist at all
I arrived at the following rules which work, but I am afraid it is by coincidence rather than me really understanding what's happening. Comments welcome.
<rewrite>
<rules>
<rule name =" Force HTTPS" enabled="true">
<match url =" (.*)" ignoreCase= "false " />
<conditions logicalGrouping =" MatchAny" >
<add input =" {HTTP_HOST}" negate="true" pattern =" ^mynewwebsite\.com$" />
<add input =" {HTTPS}" pattern= "^www.mynewwebsite\.com$ " />
</conditions>
<action type =" Redirect" url= "https://mynewwebsite.fm/{R:1} " appendQueryString="true" redirectType =" Permanent" />
</rule>
</rules>
</rewrite>

IIS URL Rewrite Module : Redirect Based On QueryString

I Have some problems with redirecting to another URL based on the query string parameters. I want to redirect users which enter www.domain.com/signup.aspx?p=1 to:
www.domain.com/signup
<rule name="Signup Redirect 1" stopProcessing="true">
<match url="signup\.aspx\?p=1" />
<conditions logicalGrouping="MatchAll" />
<action type="Redirect" url="signup" redirectType="Temporary" />
</rule>
Now when they enter www.domain.com/signup.aspx?p=2 they must go to:
www.domain.com/signup/promocode
<rule name="Signup Redirect 2" stopProcessing="true">
<match url="signup\.aspx\?p=2" />
<conditions logicalGrouping="MatchAll" />
<action type="Redirect" url="signup/promocode" redirectType="Temporary" />
</rule>
The above rules don't work. What is the right way to do this? Thanks in Advance.
Gr
Martijn
A more robust method of using a value to select a destination is to use Rewrite Maps. The map is essentially a lookup table. This doesn't require a new rule (and an additional evaluation of the URL against a pattern on every request) for every new path.
<rules>
<rule name="Signup Redirect Map" stopProcessing="true">
<match url="^signup\.aspx$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="p=([^&]+)" />
<add input="{Signups:{C:1}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="{C:2}" redirectType="Temporary" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="Signups">
<add key="1" value="signup" />
<add key="2" value="signup/promocode" />
<add key="3" value="signup/newcode" />
<add key="n" value="signup/futureproof" />
</rewriteMap>
</rewriteMaps>
Definitions:
{C:1} is a backreference to the first condition match: the query string value.
{Signups:{C:1}} is an instruction to look up {C:1} in the Signups map.
{C:2} is a backreference to the second condition match: the value from the Signups map.
See if this works a bit better:
<rule name="Signup Redirect 1" stopProcessing="true">
<match url="signup\.aspx$" />
<conditions>
<add input="{QUERY_STRING}" pattern="p=1" />
</conditions>
<action type="Redirect" url="signup" redirectType="Temporary" />
</rule>
<rule name="Signup Redirect 2" stopProcessing="true">
<match url="signup\.aspx$" />
<conditions>
<add input="{QUERY_STRING}" pattern="p=2" />
</conditions>
<action type="Redirect" url="signup/promocode" redirectType="Temporary" />
</rule>

Resources