Regex for URL rewrite with optional query string parameters - asp.net

I have this rewrite rule:
<rule name="rentals by proptype+state+city+street test" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{UNENCODED_URL}" pattern="^/([a-zA-Z0-9\-+]+)/rent/province/([a-zA-Z\-+]+)/street/([a-zA-Z0-9%\-+]+)/([0-9a-zA-Z%\-+']+)$" />
</conditions>
<action type="Rewrite" url="search_new.aspx?proptype={C:1}&province={C:2}&city={C:3}&street={C:4}" appendQueryString="true" />
</rule>
I also tried:
<rule name="rentals by proptype+state+city+street test" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{UNENCODED_URL}" pattern="^/([a-zA-Z0-9\-+]+)/rent/province/([a-zA-Z\-+]+)/street/([a-zA-Z0-9%\-+]+)/([0-9a-zA-Z%\-+']+)$" />
<add input="{QUERY_STRING}" pattern=".*" />
</conditions>
<action type="Rewrite" url="search_new.aspx?proptype={C:1}&province={C:2}&city={C:3}&street={C:4}" appendQueryString="true" />
</rule>
This URL works: http://www.example.com/apartment/rent/province/texas/street/houston/mystreet
But when I add query string parameters, the URL throws a 404: http://www.example.com/apartment/rent/province/texas/street/houston/mystreet?rooms=3&pricemin=2500
I already checked here:
IIS URL Rewrite not working with query string
https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/url-rewrite-module-configuration-reference
https://msdn.microsoft.com/en-us/library/ms972974.aspx
It seems I have to use a QUERY_STRING server variable.
I actually just want to append the query string parameters, without having to write a special mapping for each parameter. I thought I could solve this through the appendQueryString="true" property, but that apparently doesn't work.
How can I make sure my rewrite rule works also with query string parameters?

When I look at your rule, I understand that you are looking for a complete match (^...$) with URL Path.
However {UNENCODED_URL} may contain query strings too. So this breaks your rule when the URL contains any query string, even if it's just a query separator (?).
To fix this you should look for a match until the beginning of the query string instead, not till the end.
Try the following rule.
<rule name="rentals by proptype+state+city+street test" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{UNENCODED_URL}" pattern="^/([a-zA-Z0-9\-+]+)/rent/province/([a-zA-Z\-+]+)/street/([a-zA-Z0-9%\-+]+)/([0-9a-zA-Z%\-+']+)" />
</conditions>
<action type="Rewrite" url="search_new.aspx?proptype={C:1}&province={C:2}&city={C:3}&street={C:4}" appendQueryString="true" />
</rule>

Related

IIS rewrite URL in asp.net goes to into infinity loop

I just need to create a rule in my web config file to rewrite all URLs to given into rule
ex:
url/services/presentations-evenementielles to
url/Services/Presentations-Evenementielles
This is all made for SEO purposes to avoid duplicates.
<rule name="ProductionRule2" stopProcessing="true" patternSyntax="ExactMatch" >
<match url="^/productions/xyz" ignoreCase="true" />
<action type="Redirect" url="Productions/XYZ" redirectType="Permanent"/>
</rule>
Above code its gives me infinite loop error.
There was some mistakes with your rule
1.You were trying to use "^" in an exact match rule. Please set it to regular expression
2.You are trying to use "/" in match url. The match url part of domain/productions/xyz is
productions/xyz instead of /production/xyz.
3.You are enabling ignore case when you redirect URL to itself.
So please try to modify the rule like this
<rule name="ProductionRule2" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^productions/xyz" ignoreCase="false" />
<action type="Redirect" url="Productions/XYZ" redirectType="Permanent" />
</rule>
Update:
Please modify the rule like this
<rule name="ProductionRule2" enabled="true" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^Productions/XYZ" ignoreCase="false" negate="true" />
<action type="Redirect" url="Productions/XYZ" redirectType="Permanent" />
<conditions>
<add input="{ToLower:{URL}}" pattern="/productions/xyz" />
</conditions>
</rule>
And this is working on my side
Please remember to clean browser cache when you test the rule.And the URL should be prODuctions/Xyz instead of prODuction/Xyz.

URL rewrite for Google analytics

I have searched through many S.O. questions and answers, but haven't seen a good solution for this. I have already created and well-established SEO URLs in my web.config file. I was using a rewriteMap to basically turn my product pages into any URL that I needed.
Here is what I have to do this:
<rule name="Redirect Rule" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{RedirectMapName:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="{C:1}" appendQueryString="false" redirectType="Permanent" />
</rule>
<rule name="Rewrite Rule" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{RewriteMapName:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="{C:1}" />
</rule>
What is being requested now is to add in Google Analytics parameters in order to track campaigns. If I simply add in the parameters, it will of course, give me a 404 error. I am now trying to get these SEO URLs to pick up these parameters, but getting quite frustrated.
If I remove the query string, Google Analytics will not pick it up since it is a client side script. Something like this might be close, but I am not pointing to any specific page.
URL Rewrite with Query String
This is how I remove the querystring:
<rule name="Subject redirect with query" stopProcessing="true">
<match url="^(.*)" />
<conditions trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="^utm_source=([^=&]+)&utm_medium=([^=&]+)&utm_campaign=([^=&]+)&?(.*)$" />
</conditions>
<action type="Redirect" url="{R:1}" appendQueryString="false" redirectType="Permanent" />
</rule>
Summed up, how do I turn this:
https://www.example.com/fancy-url
to this
https://www.example.com/fancy-url?utm_source=Targeted_Email&utm_medium=email&utm_campaign=campaigntag
After much frustration, I was able to figure this out. The query string was okay, but one of the settings was preventing the rest of the rules to be processed. After the rule name, I had stop processing set to true. When I looked at it in IIS, the setting is much more descriptive. It says "Stop processing of subsequent rules". Once I removed that and moved this above my other rules, worked perfectly.
<rule name="Google Query string">
<match url="(.*)$" />
<conditions>
<add input="{QUERY_STRING}" pattern="utm_source=([^=&]+)&utm_medium=([^=&]+)&utm_campaign=([^=&]+)&?(.*)$" />
</conditions>
<action type="Rewrite" url="{R:0}" appendQueryString="false" />
</rule>

IIS Url-Rewrite

I'm trying to use IIS7 Url Rewrite module rewrite
services.mydomain.com/some-file-here to mydomain.webhost.com/folder/some-file-here
The rule is as follows:
Pattern = ^services.mydomain.com/(.*)$
Action = Rewrite
Rewrite URL = http://mydomain.webhost.com/folder/{R:1}
The problem is IIS keeps giving me 404 not found errors. I've been stuck at this for days now. Any ideas?
You have your pattern wrong. It should not include domain name or query string there -- only path without leading slash. See the working rule below:
<rule name="MyRewriteRule" stopProcessing="true">
<match url="^(some-file-here)$" />
<conditions>
<add input="{HTTP_HOST}" pattern="^services\.mydomain\.com$" />
</conditions>
<action type="Redirect" url="http://mydomain.webhost.com/folder/{R:1}" />
</rule>
The above rule will only trigger if host name is services.mydomain.com. If you do not require such additional condition (which is optional) then just remove these 3 lines: <conditions>...</conditions>
Also, the above rule will only do one specific redirect from services.mydomain.com/some-file-here to mydomain.webhost.com/folder/some-file-here. If you need to redirect ANY file like that, then use this one instead:
<rule name="MyRewriteRule" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^services\.mydomain\.com$" />
</conditions>
<action type="Redirect" url="http://mydomain.webhost.com/folder/{R:1}" />
</rule>

Conditional query string redirect

I'm trying to redirect requests that have a query string to a different domain name.
I've got a short url, http://short.url and I want to redirect http://short.url?hello to http://long.url/?hello. So the query string has to be kept by the redirect. To make things more complicated, I would like to rediect http://short.url?hello,hello2 to http://long.url/advanced.aspx/?hello,hello2.
Here is the rule I've got now (only dealing with the first part of my question)
<rewrite>
<rules>
<rule name="test" patternSyntax="ECMAScript" stopProcessing="true">
<match url="~/?\w+" />
<action type="Redirect" url="http://long.url/?{R:0}" redirectType="Found" />
</rule>
</rules>
</rewrite>
However, I am not seeing any redirects. Also, is there a better way to do this? Basically I just want to setup a shortcut to pass queries to a website. These are not meant to be permanent so I'm using redirectType="Found".
In case anyone is looking to do this:
<rules>
<rule name="Basic" patternSyntax="ECMAScript" stopProcessing="true">
<match url="\w*" />
<action type="Redirect" url="http://longurl.com" redirectType="Found" />
<conditions>
<add input="{QUERY_STRING}" pattern="\w+" />
<add input="{QUERY_STRING}" pattern="\," negate="true" />
</conditions>
</rule>
<rule name="Advanced" patternSyntax="ECMAScript" stopProcessing="true">
<match url="\w*" />
<action type="Redirect" url="http://longurl.com/advanced.aspx" redirectType="Found" />
<conditions>
<add input="{QUERY_STRING}" pattern="^\w+(?=\,)" />
</conditions>
</rule>
</rules>

Append Query String to IIS Rewrite Map

I have a ReWrite Map and I would like to append any query parameters in the requested URL to the rewritten URL.
For instance:
/page/abc/ ---> /index.cfm?page=abc (works)
/page/abc/?param1=111 ---> /index.cfm?page=abc&param1=111 (doesn't work)
/page/abc/?param3=333&param4=444 ---> /index.cfm?page=abc&param3=333&param4=444 (doesn't work)
My web.config is:
[...]
<rules>
<clear />
<rule name="Rewrite rule1 for SiteMapEngine">
<match url=".*" />
<conditions>
<add input="{SiteMapEngine:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="{C:1}" appendQueryString="true" />
</rule>
</rules>
[...]
Short answer:
Use PATH_INFO server variable instead of REQUEST_URI, as you do not want to include the query string in the matching.
Full explanation:
This has caught me out before - basically it is a subtlety of using Rewrite Maps in the IIS URL Rewrite Module.
In your case, SiteMapEngine will be a static key-value list of URLs:
<rewrite>
<rewriteMaps>
<rewriteMap name="SiteMapEngine" defaultValue="">
<add key="/page/abc/" value="/index.cfm?page=abc" />
...
</rewriteMap>
</rewriteMaps>
...
</rewrite>
The {SiteMapEngine:{REQUEST_URI}} condition in your rule checks whether there is a key in this rewrite map matching the REQUEST_URI server variable:
{REQUEST_URI} = /page/abc/?param1=111
Notice that this variable includes the query string - it therefore fails to find a matching key.
Instead, use the PATH_INFO server variable, which is the equivalent of REQUEST_URI but without the query string:
{PATH_INFO} = /page/abc/
So the correct rule is:
<rule name="Rewrite rule1 for SiteMapEngine">
<match url=".*" />
<conditions>
<add input="{SiteMapEngine:{PATH_INFO}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="{C:1}" />
</rule>
I'll be damned if I can find a reference for this, but it's my understanding that in some versions of IIS {REQUEST_URI} comes back without it's query string, and will be empty entirely if rewriting is enabled.
You should be able to use {PATH_INFO} instead.
This bug report (against Drupal!) is the issue you're describing, I think: http://drupal.org/node/298016
There's a hotfix from Microsoft, but I haven't tried it: http://support.microsoft.com/kb/954946
Here is my rule. It seems to work as expected:
<rule name="Insert index.cfm" enabled="true" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.cfm/{PATH_INFO}" appendQueryString="true" />
</rule>

Resources