IIS URL Rewrite not working with query string - url

I thought this was pretty straightforward, but it refuses to work. The old URL is
http://www.site.com/?q=node/17
It needs to redirect to http://www.site.com. I don't need to worry about wildcards, this is the only query string parameter I need to worry about. The rule I wrote looks like
<rule name="Node17" patternSyntax="ExactMatch" stopProcessing="true">
<match url="http://www.site.com/?q=node/17" />
<action type="Redirect" url="http://www.site.com" appendQueryString="False" />
</rule>
I can test the pattern inside of IIS and it matches, but when I hit the URL in a browser it doesn't redirect. Any thoughts?

As described in Microsoft's documentation:
It is important to understand how certain parts of the URL string can
be accessed from a rewrite rule.
For an HTTP URL in this form:
http(s)://{host}:{port}/{path}?{querystring}
The {path} is matched against the pattern of the rule. The
{querystring} is available in the server variable called QUERY_STRING
and can be accessed by using a condition within a rule.
Rule conditions allow defining additional logic for rule evaluation...
Rule conditions are evaluated after the rule pattern match is successful.
In the URL you wanted to rewrite as a redirect, your {host} = "www.site.com", {path} = "" and {querystring} = "q=node/17". So the {path} part in the URL you wanted to redirect is actually empty, and the rule you used in your question was matched against it and did not match.
Your solution is indeed valid, so I'll quote it here:
<rule name="Node17" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{QUERY_STRING}" pattern="q=node/17" />
</conditions>
<action type="Redirect" url="http://www.example.com" appendQueryString="False" />
</rule>

Of course I figured it out soon after I posted. This does it, not really sure why the exactmatch wasn't working though.
<rule name="Node17" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{QUERY_STRING}" pattern="q=node/17" />
</conditions>
<action type="Redirect" url="http://www.site.com" appendQueryString="False" />
</rule>

Related

IIS URL Rewrite with wild card

I need to change current URL pattern (hotels/{City}) to more SEO friendly one villa-{city} and I need to add a wild card for cities. Any city name should allow by the site and previous URL pattern need to rewrite as new pattern. I tried the below rewrite and its working for redirection but it effects on other URL patterns like "hotels/{name}/{code}" too. How can I overcome this redirection effecting on other patterns?
Can someone help me with this?
I would like to know how can we determine whether we use {R:0} Or {R:1} for conditions and the purpose of adding "^" to patterns
<rule name="HotelToVilla" stopProcessing="true">
<match url="hotels/(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="localhost:23617" />
</conditions>
<action type="Redirect" url="http://localhost:23617/villa-{R:1}" appendQueryString="false" redirectType="Permanent" />
</rule>

IIS URL redirection - igonre match all for some URLs

I had to change previous URL pattern to something else. Earlier URL pattern was
www.testdomain.com/hotels/"city" and it changed to www.testdomain.com/hotel-"city"
Below is the redirection I have used that for.
<rule name="cityChange" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^hotels/(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="www.testdomain.com" />
</conditions>
<action type="Redirect" url="www.testdomain.com/hotel-{R:1}"appendQueryString="false" redirectType="Temporary" />
</rule>
Now I have another issue which is another URL I have used for the site is also redirecting to different one. That URL is,
www.testdomain.com/hotels/'city'/'name'-'street'-'postalcode'
Since I have used a wildcard for /hotels/'city' to /hotel-'city' it changes above URL as
www.testdomain.com/hotel-'city'/'name'-'street'-'postalcode'
as well. But that URL is not valid in the site and I do not want to replace "/" from "-" there.
How can I exclude this URL pattern from that wild card which I have mentioned above?
Thanks in advance.
Can't be sure about that but did you try to add parentheses, like that ?
<match url="^(hotels)/(.*)" />
We did that for ou specific wildcard redirect :
<rule name="modeles-en" enabled="true" stopProcessing="true">
<match url="^(modeles-en)/(.*)" ignoreCase="true" />
<action type="Redirect" url="/models/{R:2}" redirectType="Permanent" />
</rule>
Hope it helps !

IIS URL Rewrite multiple parameters

I am really confused about the URL rewrite interface. I dont understand what i need to do.
I have an url as:
www.example.com/diretory/subdirectory/index.html?param1=1&param2=2&param3=2&param4=7
I want to hide this url in a <a>-href tag, which displays "Example Tag".
When the url is requested it should rewrite it to
www.example.com/program/location/year/vacancie
I allready tried this:
<system.webServer>
<rewrite>
<rules>
<rule name="ProgramRewrite" patternSyntax="ECMAScript" stopProcessing="true">
<match url="\?([^/]+)&([^/]+)&([^/]+)&([^/]+)" />
<action type="Rewrite" url="www.example.com/program/location/year/vacancie" logRewrittenUrl="true" />
<conditions>
</conditions>
</rule>
</rules>
</rewrite>
</system.webServer>
In the URL Rewrite Interface the Test Pattern said it is working and gets:
?param1=1&param2=2&param3=2&param4=7
param1=1
param2=2
param3=2
param4=7
I checked the log url rewrite as well, but in my logs it is not shown.
2017-03-20 16:29:24 192.168.253.146 GET /diretory/subdirectory/index.html param1=1&param2=2&param3=2&param4=7 88 - 192.168.253.146 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/56.0.2924.87+Safari/537.36 - 304 0 0 4
ps: the urls are not working and only for illustrative purpose.
The match URL only matches the URL and does not take the querystring into account. You will need to add a condition for this. Also do you want to rewrite this (so the server internally executes the new URL) or redirect (so the server will request the browser to go to the new URL and URL changes in address bar). In case you want to rewrite you should not add the domain again, in case you want to redirect add http:// as well. Assuming a rewrite is what you want use below rule:
<rule name="ProgramRewrite" patternSyntax="ECMAScript" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="/program/location/year/vacancie" logRewrittenUrl="true" />
<conditions>
<add input="{QUERY_STRING}" pattern="([^/]+)&([^/]+)&([^/]+)&([^/]+)" />
</conditions>
</rule>

IIS Rewrite module - how to redirect maintaining path and querystring but adding an extra querystring parameter?

I've been banging my head against a brick wall attempting to get some IIS redirect rules to work. I've searched and read stuff here on Stack Overflow and on IIS.net but it just doesn't work at all.
I'm trying it on my local (real) IIS, I have the rewrite 2.0 module installed and have tried doing a repair install on it. I've done an iisreset at an admin cmd line more times than I care to mention.
In my hosts file I have set-up 127.0.0.1 for the URL my.test.com.
What I want to achieve is given a sub-domain URL redirect to the main domain URL with an extra querystring parameter whilst maintaining the existing path and querystring values if they exist.
I setup 3 rules as follows that are in the root folder of the website:
<system.webServer>
<rewrite>
<rules>
<rule name="PathAndQueryString" enabled="true" stopProcessing="true">
<match url="(/\w*)(\?\w*=\w*)([&\w*=\w*]*)" />
<action type="Redirect" url="https://www.test.com{R:1}{R:2}{R:3}&param=value" appendQueryString="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="my.test.com" />
</conditions>
</rule>
<rule name="Querstring" enabled="true" stopProcessing="true">
<match url="(\?\w*=\w*)([&\w*=\w*]*)" />
<action type="Redirect" url="https://www.test.com{R:1}{R:2}&param=value" appendQueryString="false" />
<conditions>
<add input="{HTTP_HOST}" pattern="my.test.com" />
</conditions>
</rule>
<rule name="DomainOnly" enabled="true" stopProcessing="true">
<match url=".*" />
<action type="Redirect" url="https://www.test.com?param=value" appendQueryString="false" />
<conditions>
<add input="{HTTP_HOST}" pattern="my.test.com" />
</conditions>
</rule>
</rules>
</rewrite>
</system.webServer>
Unfortunately despite testing the patterns and confirming the {R:x} captures are correct when I try to test this using Edge, Chrome, Firefox and IE for all of them IIS acts like the rules don't exist.
Tests:
https://my.test.com >> https://www.test.com?param=value
https://my.test.com/SomePath >> https://www.test.com/SomePath
https://my.test.com/SomePath?AParam=AValue >>
https://www.test.com/SomePath?AParam=AValue&param=value
None of the above tests work, they get served without a redirect.
I've also tried putting the condition pattern used as part of the Match URL pattern but it didn't work with that either; in fact I moved it to the condition after reading a Stack Overflow post which said when rules are in the root of the site it doesn't include the host, but still nothing works.
Any help would be much appreciated.
UPDATE 1: For the path and querystring rule tried removing the bolded part from that start of this pattern (/\w*). Didn't have any effect.
UPDATE 2: Tried enabling the extremely temperamental "Failed Request Tracing" functionality and when it is actually working it says that none of the Match URL patterns are matching, except for the 3rd rule which has now started kicking in and redirecting but is not maintaining the path and other querystring params for obvious reasons.
UPDATE 3: On Edge and IE none of the rules work at all. On Chrome and FF the domain only redirect appears to be working - however if I disable the domain only rule and restart IIS it acts as though the rule is still there - FFS give me strength this crap is really starting to boil my blood now - this should not be that damn difficult.
Before I give the answer, a shout out to Yuk Ding at Microsoft who responded to a copy of this post on the iis.net forums and provided most of the answer.
So here we go, if you want rewrite rules that redirects from 1 URL to another maintaining the path and querystring if they exist whilst at the same time adding on a hardcoded URL parameter with the appropriate & or ? then here are the rules you will need.
In the rules you are redirecting from my.test.com to www.test.com, but obviously you would need to replace those 2 URLs in the rules below as well as changed the hardcoded parameter "ExtraParam=SomeValue" to what you need.
<system.webServer>
<rewrite>
<rules>
<rule name="DomainOnly" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="true">
<add input="{HTTP_HOST}" pattern="my.test.com" />
<add input="{REQUEST_URI}" pattern="/.+" negate="true" />
</conditions>
<action type="Redirect" url="http://www.test.com?ExtraParam=SomeValue" redirectType="Temporary" />
</rule>
<rule name="PathOnly" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="true">
<add input="{REQUEST_URI}" pattern="/.+" />
<add input="{REQUEST_URI}" matchType="Pattern" pattern="\?.+" ignoreCase="true" negate="true" />
<add input="{HTTP_HOST}" pattern="my.test.com" />
</conditions>
<action type="Redirect" url="http://www.test.com{C:0}?ExtraParam=SomeValue" redirectType="Temporary" />
</rule>
<rule name="Querstring" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="true">
<add input="{REQUEST_URI}" pattern="/.+" />
<add input="{QUERY_STRING}" pattern=".*" />
<add input="{HTTP_HOST}" pattern="my.test.com" />
</conditions>
<action type="Redirect" url="http://www.test.com{C:0}&ExtraParam=SomeValue" appendQueryString="false" redirectType="Temporary" />
</rule>
</rules>
</rewrite>
In my eyes the URL Rewrite 2.0 module has a bug. The basic crux is that you cannot match anything in the main match pattern you have to do everything with conditions. Thus the fact that you can set a pattern for the match is completely pointless because if you try to match anything other than (.*), i.e. match anything like I originally did it won't do what you want and will effectively cause head-bashing-brick-wall-ness.
The even more annoying thing is that in IIS Manager the UI for this is very unhelpful. You can test your patterns - and I did - and they will work, but all it's really testing is the regEx pattern.
What we really need is a test at the rules level. In other words you enter a URL and it tells you whether any of the rules match and which conditions pass or fail. Yes you can get this information if you enabled the failing request tracing rules but it's all a long winded phaff to enable and works in a haphazard fashion (just try clearing out the old logs and watch as it then stops logged until you turn it off and on again) for something that should be trivial.

How to rewrite part of the URL and then attach the remaining?

For example, rewrite from www.example.com/foo/123 to www.example.com/bar/123
In web.config I have something like:
<rewriteMap name="TestRM">
<add key="/foo/" value="/bar" />
</rewriteMap>
<rule name="TEST" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{TestRM:{PATH_INFO}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="http://www.example.com{C:1}" appendQueryString="false" redirectType="Temporary" />
</rule>
With this is place, www.example.com/foo can be redirected to www.example.com/bar, but no www.example.com/foo/123 to www.example.com/bar/123
Anything I need to add to make the last part attached?
One of the strategy you can use is to use regex and separate the URL Parts.
For example URL: www.example.com/foo/123
Regex: ^(/foo)(/.*)? will separate out /foo and /123 or /123/3434/ or anything after /foo
Then you can craft the redirect URL as Such:
{HTTP-HOST}/bar{R:2}

Resources