Extracting arguments in IIS rewrite - where am I going wrong? - iis

How can I redirect '/path?foo=abc&bar=def' to '/path/abc/def'?
I've tried the following:
<rule name="My rule" stopProcessing="false">
<match url="^path" />
<conditions>
<add input="{QUERY_STRING}" pattern="foo=/[^&]*/" />
<add input="{QUERY_STRING}" pattern="bar=(.*)" />
</conditions>
<action type="Redirect" url="/path/{C:0}/{C:1}" appendQueryString="false" />
</rule>
But this doesn't even process my match. Where am I going wrong?

I don't have access to a computer to verify this, but I think the following could simplify:
<rule name="Redirect old FAQ view" stopProcessing="false">
<match url="^path.*" />
<conditions>
<add input="{QUERY_STRING}" pattern="^foo=([^&]*).*?bar=(.*)" />
</conditions>
<action type="Redirect" url="/path/{C:0}/{C:1}" appendQueryString="false" />
</rule>
You don't need the second input line as you can use multiple capturing groups in one. I'm not sure if the whole line will come back as a match or not so you may need to adjust to {C:1}/{C:2}. Finally, I'm not sure if the match url was problematic. It would contain the query string as well, so that may have been causing it to miss. Look here for more details on the various components of the URL rewrite process.

Related

URL Rewrite-rule in IIS 8 not triggering

I have a problem with my URL rewrite and I don't know what I'm doing wrong so, maybe you can point me in the right direction. We had a intranet-site, which had a pattern like this: intranet.old-site.com. Now we got a new domain and I want to forward my outdated links to the front-page of our new intranet, which looks like: intranet.new-site.com.
I installed the URL Rewrite module in IIS and in my point of view, the setup is correct:
Match URL
Request URL: matches pattern.
Using: Wildcards
Pattern: *intranet.old-site*
Ignore case: true
Conditions
none
Server Variables
none
Action
Action Type: Rewrite
Action Properties: Rewrite-URL: http://intranet.new-site.com/
Append query string: true
Log rewritten URL: false
Stop processing of subsequent rules: false
I'm also open for any idea what might work, so if there is a rule for the web.config, I could try that as well.
Update 1:
the web-config looks like this now:
<rewrite>
<rules>
<rule name="RewriteSG2DE" patternSyntax="ECMAScript" stopProcessing="true">
<match url="(.*).sgbdd.saint-gobain(.*)" />
<action type="Redirect" url="intranet.stark-deutschland.net" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="(.*)sgbdd.saint-gobain(.*)" />
<add input="{HTTP_HOST}" pattern="intranet.sgbdd.saint-gobain.com" />
</conditions>
</rule>
</rules>
</rewrite>
I want any site, which is basically anything like intranet.sgbdd.saint-gobain.com/start.asp?something_more" to be forwarded / redirected to intranet.stark-deutschland.net/start.asp?something_more
For instance:
intranet.sgbdd.saint-gobain.com/start.asp?something_more --> intranet.stark-deutschland.net/start.asp?something_more
somesite.intranet.saint-gobain.com/my/new/site --> somesite.intranet.stark-deutschland.net/my/new/site
I also added conditions as suggested:
Thanks for you input
Using two URL rewrite rules is much easier to handle this.
If you want to redirect
intranet.sgbdd.saint-gobain.com/start.asp?something_more --> intranet.stark-deutschland.net/start.asp?something_more
somesite.intranet.saint-gobain.com/my/new/site --> somesite.intranet.stark-deutschland.net/my/new/site
Then rule can be like this.
<rule name="rule1" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="true">
<add input="{HTTP_HOST}" pattern="^(.*)saint-gobain.com$" />
<add input="{HTTP_HOST}" pattern="intranet.sgbdd.saint-gobain.com" negate="true" />
</conditions>
<action type="Redirect" url="http://{C:1}stark-deutschland.net/{R:1}" redirectType="Temporary" />
</rule>
<rule name="rule2" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^intranet.sgbdd.saint-gobain.com$" />
</conditions>
<action type="Redirect" url="http://intranet.stark-deutschland.net/{R:1}" redirectType="Temporary" />
</rule>
I tried to combine two rules to one rule but there's something wrong with expression ?! so it is recommended to split into two rules.
If you means
intranet.sgbdd.saint-gobain.com/start.asp?something_more --> intranet.stark-deutschland.net/start.asp?something_more
somesite.intranet.sgbdd.saint-gobain.com/my/new/site --> somesite.intranet.stark-deutschland.net/my/new/site
Then the rule can be like this.
<rule name="RewriteSG2DE" patternSyntax="ECMAScript" stopProcessing="true">
<match url="(.*)" />
<action type="Redirect" url="http://{C:1}stark-deutschland.net/{R:1}" redirectType="Temporary" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="(.*)sgbdd.saint-gobain.com" />
</conditions>
</rule>

IIS Rewrite: redirect with one of the query string parameters as part or the URL

What I would like to do is if I have link:
http://www.test.com/photo.asp?hash=hfz6rhfgz&offset=10
to rewrite as:
http://www.test.com/photo/hfz6rhfgz/?offset=10
There can be other query parameters and hash may be on some other place than the first...
The problem is it would work, but as offset is the second parameter with my rule I get:
http://www.test.com/photo/hfz6rhfgz/&offset=10
That of course causes an error as I would need ? instead of &. In the redirected URL the offset is like second parameter and in the original link it is the second.
Here is my redirect rule:
<rule name="test-redirect" stopProcessing="true">
<match url="^photo.asp$" ignoreCase="true" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{QUERY_STRING}" pattern="^(.*)hash=([\w]{8})(.*)$" />
</conditions>
<action type="Redirect" url="/photo/{C:2}/{C:1}{C:3}" redirectType="Permanent" appendQueryString="false" />
</rule>
I kind of find a solution by myself, but if there is something like
http://www.test.com/photo.asp?test=10&hash=jcekg876
It produces:
http://www.test.com/photo/jcekg876/?test=10&
so the last amp is too much, in other situations it works ok. If anybody knows how to get rid of this & it would be nice, because I need a clean URL redirect...
<rule name="test-redirect" stopProcessing="true">
<match url="^photo.asp$" ignoreCase="true" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{QUERY_STRING}" pattern="(.*)hash=([\w]{16})[&]?(.*)" />
</conditions>
<action type="Redirect" url="/photo/{C:2}/?{C:1}{C:3}" redirectType="Found" appendQueryString="false" />
</rule>

IIS 7.5 URL Rewrite Module - Rewrite Maps with variables

I have several pages on my site that have long and unreadable URLs that I'd like to be able shorten. The problem I'm having is appending query strings with variable values.
For example:
"www.example.com/dir1/dir2/filename.php" shortens to "www.example.com/file".
"www.example.com/dir1/dir2/filename.php?id=2" would be "www.example.com/file/2".
"www.example.com/dir1/dir2/filename.php?id=2&alt=6" would be "www.example.com/file/2/6".
The values of 'id' and 'alt' are then used by our page to access information in our database, which determines the contents of the page. These values can change, and there is no set amount.
Right now I've got the first example working fine using the following rewrite rules:
<rewrite>
<outboundRules>
<remove name="OutboundRewriteUserFriendlyURL1" />
</outboundRules>
<rewriteMaps>
<rewriteMap name="StaticRewrites">
<add key="/file" value="/dir1/dir2/filename.php" />
</rewriteMap>
</rewriteMaps>
<rules>
<rule name="Rewrite Rule">
<match url=".*" />
<conditions>
<add input="{StaticRewrites:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="{C:1}" />
</rule>
</rules>
</rewrite>
But I haven't been able to find anything that would allow the URLs to contain variables. Everything I've seen has used static rewrites like my current solution is using, and I can't find anything about allowing arbitrary parameters.
EDIT:
Found a better solution that doesn't use a Rewrite Map. I had attempted a simliar rule previously, but due to the IIS setup on our testing environment it wasn't working as expected. This version should work for most people.
<rule name="Curricula View" stopProcessing="true">
<match url="/file(?:/(\d+)(?:/(\d+))?)?" />
<action type="Rewrite" url="/dir1/dir2/filename.php?id={R:1}&alt={R:2}" appendQueryString="true" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
</rule>
Using this rule I was able to avoid using a rewrite map altogether. I had attempted to use something like this originally, but due to the setup of our test environment it wouldn't work without some weird tweaks. This version should work in all normal environments.
<rule name="Curricula View" stopProcessing="true">
<match url="/file(?:/(\d+)(?:/(\d+))?)?" />
<action type="Rewrite" url="/dir1/dir2/filename.php?id={R:1}&alt={R:2}" appendQueryString="true" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
</rule>
EDIT:
I was also able to get the original version with a rewrite map working for anyone interested.
<rule name="Rewrite Map with Variables" enabled="true">
<match url="^(.+?)/?/(.*)$" />
<conditions logicalGrouping="MatchAny" trackAllCaptures="false">
<add input="{ProductMap:{R:1}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="/dir1/dir2/filename.php?id={C:0}&other={R:2}" appendQueryString="true" />
</rule>

IIS Rewrite to remove certain querystring parameters and redirect to the original requested host

I need to write a redirect to strip off parameters when a certain one exists, but I would like the redirect to be the same as the incoming url, just without the parameters. This is what I had and it doesn't work. I thought if I put the request URI in there without appending the querystring, then it would work but it results in a loop. Has anyone done this before?
<rule name="Remove parameters" stopProcessing="true">
<match url="(.*)" ignoreCase="true" />
<conditions trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="page=([0-9]+)" />
</conditions>
<action type="Redirect" url="{REQUEST_URI}" appendQueryString="false" />
The problem with jallen's answer is that the whole query string will be removed, which may not be ideal if you want to maintain certain parts of it. An alternative would be as follows:
<rule name="Remove paging parameters" stopProcessing="true">
<match url="(.*)?$" />
<conditions trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="(.*)(page=.+)(.*)" />
</conditions>
<action type="Redirect" url="{C:1}{C:3}" appendQueryString="false" />
</rule>
C:1 = Everything before the matching page parameter
C:2 = Is the
match itself, and what we want to exclude
C:3 = Everything after the
matching page parameter
Hence, we use the redirect {C:1}{C:3} to exclude only the page query string.
Got it with the following:
<rule name="Remove paging parameters" stopProcessing="true">
<match url="(.*)?$" />
<conditions trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="page=([0-9]+)" />
</conditions>
<action type="Redirect" url="{R:1}" appendQueryString="false" />

Rewrite Rule using map AND stripping certain parameters

I'm pretty new to all this so please be basic in your explanations.
The place I work just changed store software so I have a series of URLS that need massaging as Google, people, etc continue to use the old links.
The old links look like:
http://mydoman/usedateb.aspx?User_ID=38482&Category_ID=127
I know how to do a rewrite map to change
http://mydomain/usedateb.aspx?Category_ID=127
to
http://mydomain/hoopy-new-tour-name.aspx
And I know how to do a rewrite rule to remove the User_ID=xxx& from the Url.
My problem is in getting them both to work together. I need to take out the User_ID (since it's arbitrarily assigned) AND send it through the map to change to the hoopy-new-tour-name.
I have set up the rewrite rule to remove User at the top of the list and the rewrite map rule lower in the list but I end up at http://mydomain/usedateb.aspx?User_ID=38482&Category_ID=127
If it helps, my web.config has lines like
<add key="UseDateB.aspx?Category_ID=127" value="/success.htm" />
for the map and
<rule name="Remove extra parameters - UserID">
<match url="(.*)User_ID=([0-9]+&)(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="{R:1}{R:3}" appendQueryString="false" />
</rule>
to strip the unwanted parameter.
The reason I need the map is that Cat 127 may be the hoopy tour but 128 may be the frood tour. There's a list of about 500 of these that need remapping but we gotta get the extra parameter off the incoming URLs for it to work.
All help appreciated! If I'm going about it completely wrong please let me know that too.
Look at this:
<rules>
<clear />
<rule name="RedirectToCategory" stopProcessing="true">
<match url="UseDateB.aspx" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{QUERY_STRING}" pattern="Category_ID=127" />
</conditions>
<action type="Redirect" url="http://mydomain/hoopy-new-tour-name.aspx" />
</rule>
<rule name="RemoveUserID" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{QUERY_STRING}" pattern="(.*)(User_ID=[0-9]*)(.*)" />
</conditions>
<action type="Redirect" url="{R:0}?{C:1}{C:3}" appendQueryString="false" />
</rule>
</rules>
The first rule redirects based on category, and the second removes the User_ID. Try it and if you would like to do something else, state what is it.

Resources