I have a site I'm reverse proxying using IIS UrlRewrite. So far I've had a fairly easy time of it thanks to Paul Cociuba's three articles on Microsoft Tech Community.
My current challenge is with a group of urls in a <picture><source srcset which are, heavily abbreviated,
<source srcset="/a/b/c/d/e/en/g/h/thumb%20classes%202020_SX_MX.component.crop-3x2-5.ts=1592419103694.jpg/a/c/d/oceania/au/en/g/jcr:a/root/z_1_col/z_4_col/image_1558468008 1400w,
/a/b/c/d/e/en/g/h/thumb%20classes%202020_SX_MX.component.crop-3x2-6.ts=1592419103694.jpg/a/c/d/oceania/au/en/g/jcr:a/root/z_1_col/z_4_col/image_1558468008 2000w,
/a/b/c/d/e/en/g/h/thumb%20classes%202020_SX_MX.component.crop-3x2-7.ts=1592419103694.jpg/a/c/d/oceania/au/en/g/jcr:a/root/z_1_col/z_4_col/image_1558468008 2800w,
/a/b/c/d/e/en/g/h/thumb%20classes%202020_SX_MX.component.crop-3x2-1.ts=1592419103694.jpg/a/c/d/oceania/au/en/g/jcr:a/root/z_1_col/z_4_col/image_1558468008 350w,
/a/b/c/d/e/en/g/h/thumb%20classes%202020_SX_MX.component.crop-3x2-2.ts=1592419103694.jpg/a/c/d/oceania/au/en/g/jcr:a/root/z_1_col/z_4_col/image_1558468008 460w,
/a/b/c/d/e/en/g/h/thumb%20classes%202020_SX_MX.component.crop-3x2-3.ts=1592419103694.jpg/a/c/d/oceania/au/en/g/jcr:a/root/z_1_col/z_4_col/image_1558468008 700w,
/a/b/c/d/e/en/g/h/thumb%20classes%202020_SX_MX.component.crop-3x2-4.ts=1592419103694.jpg/a/c/d/oceania/au/en/g/jcr:a/root/z_1_col/z_4_col/image_1558468008 920w"
media="(max-width: 768px)"
sizes="(max-width: 768px) 100vw">
How do I convert all of the paths that begin with /a/b/c to https://othersite/a/b/c? At worst I could perhaps write a regular expression that captures a fixed number of paths (say 7) and then rewrites them with {R:1} through {R:7} but I'm not sure at this point whether the number of items in each srcset is fixed.
Also, do I need to create a custom tag so as to match the <source srcset=?
This worked and I'm rather surprised. I'm still not getting the response I'm expecting from the page (some of the images still aren't drawing), but at least the HTML appears to be correct.
First up, I've declared a custom tag
<customTags>
<tags name="sourceSrcset">
<tag name="source" attribute="srcset" />
</tags>
</customTags>
Then I've written an outbound rule to use it
<rule name="source srcset" preCondition="ResponseIsTextHtml">
<match filterByTags="CustomTags" customTags="sourceSrcset" pattern=",?\/(a\/b\/\S+\s\d+w)" />
<action type="Rewrite" value="https://othersite/{R:1}" />
</rule>
In case you're wondering, ResponseIsTextHtml has a brother called ResponseIsTextAnything and these are declared as
<preCondition name="ResponseIsTextHtml">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
<preCondition name="ResponseIsTextAnything">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/(.+)" />
</preCondition>
Related
I do my best to scan the forum for help to make a web.config to do a Rewrite of this kind of url
domain.com/default.asp?id=3&language=2
My hope is that this can be
domain.com/en/service
where language=2 is "en"
and id=3 is page "Service" (this name exist in a mySQL)
I can only find example that do it vice versa...
Like this
<rewrite>
<rules>
<rule name="enquiry" stopProcessing="true">
<match url="^enquiry$" />
<action type="Rewrite" url="/page.asp" />
</rule>
</rules>
</rewrite>
I would like it to be something like this... I know this isn't correct, but maybe explains my problem.
<rewrite>
<rules>
<rule name="enquiry" stopProcessing="true">
<match url="^default.asp?id=3&language=2$" />
<action type="Rewrite" url="/en/serice" />
</rule>
</rules>
</rewrite>
If you want to use regular expressions you could do something like this
<rule name="RewriteUserFriendlyURL1" stopProcessing="true">
<match url="^([^/]+)/([^/]+)/?$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="default.asp?language={R:1}&id={R:2}" />
</rule>
This would rewrite "domain.com/en/service" as "domain.com/default.asp?language=en&id=Service", or "domain.com/2/3" as "domain.com/default.asp?language=2&id=3"
To change the 2 to en and the 3 to service, along with all the other options though I think you would need a separate rule for each permutation, or have some sort of logic within your asp pages to read your querystring variables and send the corresponding values to your SQL queries. Note also that the parameters in the friendly url appear in the same order and the querystring variables in the rewritten URL, although this shouldn't really be an issue. If someone tries to access the page with the original "unfriendly" url they will find what they are looking for, whichever way round they enter the querystring variables.
Please note, I didn't actually hand code the rule above, I generated it with the URL Rewrite module in IIS manager - it makes life a lot easier
Also note, as discussed with my namesake in the other answer, this only applies to IIS7 and above
I have done this in Classic ASP using custom error pages and this seems to be the best way unless you use some sort of third party component installed on the server.
To do this, in IIS (or web.config) you need to set up 404 errors to go to a specific custom error Classic ASP page (eg. 404.asp).
In this custom error page you first need to check to see if the URL is valid. If it is you can Server.Transfer to the correct page, return a 200 response code, and parse the URL there to convert the URL to the values needed for the database lookup, etc. If it's not a valid URL then you show a custom error page and return a 404 response code.
The code to check for a valid URL and to retrieve the URL parameters will vary greatly depending on your URL structure. But to find the URL requested on the custom 404 error page you have to look at the querystring, which will be something like "404;http://domain.com:80/en/service/".
Here's some sample code that gets the parameters from the requested URL:
Dim strUrl, intPos, strPath, strRoutes
strUrl = Request.ServerVariables("QUERY_STRING")
If Left(strUrl, 4) = "404;" Then
intPos = InStr(strUrl, "://")
strPath = Mid(strUrl, InStr(intPos, strUrl, "/") + 1)
If strPath <> "" Then
If Right(strPath, 1) = "/" Then strPath = Left(strPath, Len(strPath) - 1)
End If
strRoutes = Split(strPath, "/")
'Here you can check what parameters were passed in the url
'eg. strRoutes(0) will be "en", and strRoutes(1) will be "service"
End If
And here's how you can setup custom error pages in the web.config (rather than in IIS):
<?xml version="1.0"?>
<configuration>
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" subStatusCode="-1" responseMode="ExecuteURL" path="/404.asp" />
</httpErrors>
</system.webServer>
</configuration>
So I'm having an issue and not sure if it's even possible.
Here's the scenario. We utilize an F5 loadbalancer with an i-Rule set to send us a header (HTTP_IV-USER) value based on an access token.
We want to query that header, see if it matches a value we have setup in a rewritemap and then change it accordingly.
I haven't seen anyone doing this with servervariables. It makes sense on how to do it in regards to changing an URL... but we'd like to change a header variable.
Basically we're taking the value from the Token, which is a number, and then matching that number to a username in active directory.
Thanks for the help!
Of course, we can use rewritemap to check and replace the value. You could modify the rule below to achieve your requirement.
<rewriteMaps>
<rewriteMap name="StaticMap">
<add key="aaaaaaaaa" value="bbbbbbbb" />
</rewriteMap>
</rewriteMaps>
<outboundRules>
<rule name="rewritemaprule">
<match serverVariable="HTTP_IV-USER" pattern="(.*)" />
<conditions>
<add input="{StaticMap:{HTTP_IV-USER}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" value="{C:1}" />
</rule>
</outboundRules>
Trying to use URLRewrite to set up some redirection but retain some (and only some of the query string parameters from the source UR, but running into some problems.
Essentially I need to keep the Google Analytics UTM parameters and move them to the Action URL. Here's the config section or one of my redirects:
<rule name="Anything Else" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAny" trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="utm_source=(\w+)" />
<add input="{QUERY_STRING}" pattern="utm_medium=(\w+)" />
<add input="{QUERY_STRING}" pattern="utm_campaign=(\w+)" />
<add input="{QUERY_STRING}" pattern="utm_term=(\w+)" />
<add input="{QUERY_STRING}" pattern="utm_content=(\w+)" />
<add input="{QUERY_STRING}" pattern=".*" />
</conditions>
<action type="Redirect" url="https://www.google.com?utm_source={C:1}&utm_medium={C:2}" appendQueryString="false" redirectType="Temporary" />
</rule>
The query string may contain none, one, or all of the UTM parameters, but I need these rules fir in any case, as long as the original URL matches. To this end, we have the LogicalGrouping set to MatchAny, and the final condition being a complete wildcard. Testing the conditions individually gives me the back references {C:1} through {C:5} for the UTM parameters, and while there are no matching parameters in the source URL, or no more than one, the rules work.
The problem appears when I have multiple matching conditions in the source URL. IIS throws a 500 error "The expression "https://www.google.com? {C:2}" cannot be expanded."
Am I barking up the wrong tree? Is this even possible? I have the option of coding an HTTPHandler and handing the conversion there, but I was hoping to do this without introducing custom code to the server.
Within a rule action, you can use the back-references to the last matched condition of that rule. Also within a condition input string, you can use the back-references to the previously matched condition.
With that in mind, a possible way to do what you are trying to do is to use the back-reference from previous condition in the next condition's input:
<conditions>
<add input="{QUERY_STRING}" pattern="(?:^|&)var1=([1-9]\d+)(?:&|$)" />
<add input="%{C:1}%_{QUERY_STRING}" pattern="%(.+)%_.*var2=([1-9]\d+)(?:&|$)" />
</conditions>
Then the action of the rule will look like this:
<action type="Redirect" url="newpage.aspx/{C:1}/{C:2}" appendQueryString="false" redirectType="Permanent" />
I'm redirecting my website URLs to mobile with the following conditions:
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_USER_AGENT}" pattern="midp|mobile|phone" />
<add input="{HTTP_X-Device-User-Agent}" pattern="midp|mobile|phone" />
<add input="{HTTP_X-OperaMini-Phone-UA}" pattern="midp|mobile|phone" />
<add input="{StaticRedirects:{R:1}}" pattern="(.+)" />
</conditions>
I want to group these first three conditions together and the last one separately.
Redirect rule must be applied if:
HTTP_USER_AGENT or HTTP_X-Device-User-Agent or HTTP_X-OperaMini-Phone-UA matches the pattern
and {StaticRedirects:{R:1}} matches the pattern
Is there any way for grouping these conditions?
PS: I have nearly 10 rules. Do I have to write first three conditions for each of my rules or is there any tag for all rules?
You can achieve your goal using the distributive law:
(A + B)C = AC + BC
Use a concatenation of variables in the condition input. Use a separator that is not expected in any of variable values. In the example below, the /// sequence is used as a separator:
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_USER_AGENT}///{StaticRedirects:{R:1}}"
pattern="(midp|mobile|phone)///(.+)" />
<add input="{HTTP_X-Device-User-Agent}///{StaticRedirects:{R:1}}"
pattern="(midp|mobile|phone)///(.+)" />
<add input="{HTTP_X-OperaMini-Phone-UA}///{StaticRedirects:{R:1}}"
pattern="(midp|mobile|phone)///(.+)" />
</conditions>
I have a url rewrite rule for my IIS 7 server which is following:
<rewrite>
<rules>
<rule name="topcontent">
<match url=".*">
<action type="rewrite" url="mysite.com/{R:0}"/>
</match>
</rule>
</rules>
</rewrite>
Now I have to provide an exception to this rule, for a particular location, which is 'http://tempurl94.goto.com/?q=x&m=y' where 'http://tempurl94.goto.com' will always be there
in the url, and query parameter q and m may vary. So we have to write different rule for
this url. How to write a different (match url=?).
May be I can write a rule before the 'topcontent' rule and say stopProcessing='true'.
But I need to know what should I write inside <match url=' ? '> and what should I write in <action> tag.
You need to add conditions element to the new rule. Put the new rule before the current one and set stopProcessing to true as you mentioned.
<conditions>
<add input="{HTTP_HOST}" pattern="^tempurl94\.goto\.com$" />
</conditions>