Scope IIS Rewrite Outbound Rule by request URL - iis

Is there any way to scope IIS' outbound rewrite rule to only apply if the requested URL matches a pattern? I suspect that's not possible because the request URL isn't visible in the response, but I thought I'd ask in hopes that it is possible.
Here is my current outbound rule:
<rewrite>
<outboundRules>
<rule name="Change Absolute Paths" preCondition="ResponseIsHtml1">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^http(s)?://blog.mycompany.com/blog(.*)$" />
<action type="Rewrite" value="https://www.mycompany.com/blog{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
It would be great if I can add a condition in there so that the outbound rule only applies if the request URL matches a pattern.

It turns out to be easy. You just need to add a condition on {REQUEST_URI}.
<rewrite>
<outboundRules>
<rule name="Change Absolute Paths" preCondition="ResponseIsHtml1">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^http(s)?://blog.mycompany.com/blog(.*)$" />
<conditions>
<add input="{REQUEST_URI}" pattern="^/foobar" />
</conditions>
<action type="Rewrite" value="https://www.mycompany.com/blog{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>

Related

IIS reverse proxy outbound rule doesn't work

I have a web site under IIS 10.0 v1809. A specific link https://domain.name/report/ should be proxied to the local service http://localhost:7577/dashboard/. So I need to change the word dashboard to report in the server answer. To do this I set up ReverseProxy rule:
<rule name="MyReverseProxy" enabled="true" stopProcessing="true">
<match url="report(/)?(.*)" />
<action type="Rewrite" url="http://localhost:7577/dashboard/{R:2}" appendQueryString="true" />
</rule>
And the OutBound rule:
<outboundRules>
<rule name="MyReverseProxy" enabled="true" stopProcessing="false">
<match filterByTags="None" pattern="dashboard(/)?(.*)" />
<action type="Rewrite" value="report/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
but for some reason, the outbound rule does not work for me. I get a 404 error and https://domain.name/dashboard/ appears in the browser's address bar.
What am I doing wrong? My pattern test works correctly, but why does the browser switch to dashboard?

IIS Outbound Rewrite Rule for srcset only rewrite once

I have one problem with one outboundRule created on IIs to change text in html. The problem is inside img tag in srcset attribute when it only change last match.
I've tried this:
<outboundRules>
<rule name="ReverseProxyOutboundRuleHTML" preCondition="ResponseIsHTML" enabled="true" patternSyntax="ECMAScript" stopProcessing="false">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script, CustomTags" customTags="customTags" pattern="(.*)9999.99.99.99:8080(.*)" />
<action type="Rewrite" value="{R:1}example.com{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
<customTags>
<tags name="customTags">
<tag name="img" attribute="srcset" />
<tag name="meta" attribute="content" />
</tags>
</customTags>
</outboundRules>
Seems to be correct, but my result is:
<img
src="http://example.com/wp-content/uploads/2019/02/Mercedes_ClasseV-1024x540.png"
srcset="http://9999.99.99.99:8080/wp-content/uploads/2019/02/Mercedes_ClasseV-1024x540.png 1024w, http://9999.99.99.99:8080/wp-content/uploads/2019/02/Mercedes_ClasseV-300x158.png 300w, http://9999.99.99.99:8080/wp-content/uploads/2019/02/Mercedes_ClasseV-768x405.png 768w, http://example.com/wp-content/uploads/2019/02/Mercedes_ClasseV.png 1100w"
sizes="(max-width: 750px) 100vw, 750px">
Any help, to change all values in srcset attribute?
You could use below Rewrite rule:
<outboundRules>
<rule name="ReverseProxyOutboundRuleHTML" preCondition="ResponseIsHTML" enabled="true" patternSyntax="ECMAScript" stopProcessing="false">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script, CustomTags" customTags="customTags" pattern="(.*)9999.99.99.99:8080(.*),(.*)9999.99.99.99:8080(.*)\,(.*)9999.99.99.99:8080(.*)" />
<action type="Rewrite" value="{R:1}example.com{R:2},{R:3}example.com{R:4},{R:5}example.com{R:6}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
<customTags>
<tags name="customTags">
<tag name="img" attribute="srcset" />
<tag name="meta" attribute="content" />
</tags>
</customTags>
</outboundRules>
Regards,
Jalpa.

IIS Rewrite rule, url modify himself

I have write a rewrite rule to redirect an incoming request to the correct server.
Here my web.config :
<rules>
<rule name="ToMonceau">
<match url="test/(.*)" />
<action type="Rewrite" url="http://10.5.5.83/{R:1}" />
<serverVariables>
<set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" />
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="AddPrefix" preCondition="IsText" enabled="true">
<match filterByTags="A, Img, Link, Script" pattern="(http://10.5.5.83/mantis/)?(/mantis/)?(.*)" />
<conditions>
<add input="{URL}" pattern="(test/mantis)/(.*)" />
</conditions>
<action type="Rewrite" value="./{R:3}" />
</rule>
<rule name="RestoreAcceptEncofing" preCondition="NeedsRestoringAcceptEncoding">
<match serverVariable="HTTP_ACCEPT_ENCODING" pattern="^(.*)" />
<action type="Rewrite" value="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" />
</rule>
<preConditions>
<preCondition name="IsText">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/(.+)" />
</preCondition>
<preCondition name="NeedsRestoringAcceptEncoding">
<add input="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" pattern=".*" />
</preCondition>
</preConditions>
</outboundRules>
My problem when I go to http://localhost/test/mantis (my server hosts a mantis here), the url change automatically to http://localhost/mantis/, I have to put again the "test/" and it change to http://localhost/mantis/login_page.php. I reput again "test/" and this time the login's page of mantis shown.
The problem continue when I try to log in, the url changes continously by removing the "test/" part.
If I go directly to my mantis without the redirect (http://10.5.5.83/mantis) everything is working like a charm.
What am I missing in my rule to do it correctly ?
I take the exemple here with mantis but I have the same problem on every sites host by different server.
Thanks in advance and sorry if my english is not perfect.
Go to IIS manager and click on URL rewrite:
Keep pattern .*
Action type should be Rewrite
Rewrite URL: http://yourdesiredurl/{R:0}

IIS Reverse Proxy Apply outbound rule on specific path

I have the following inbound and outbound rules defined to get my reverse proxy working.
<rewrite>
<rules>
<rule name="Route the requests for backend app" stopProcessing="true">
<match url="^foldera/folderb/(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="www.site1.com" />
</conditions>
<action type="Rewrite" url="http://www.site2.com/{R:1}" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="RewriteRelativePaths" preCondition="ResponseIsHtml" enabled="true" stopProcessing="false">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^/(.*)" />
<action type="Rewrite" value="/foldera/folderb/{R:1}" />
<conditions>
<add input="{URL}" pattern="^/foldera/folderb/.*" />
</conditions>
</rule>
<preConditions>
<preCondition name="ResponseIsHtml">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
Now, the site "http://www.site2.com/" is correclty loaded in "http://www.site1.com/foldera/folderb/" and the outbound rule is making sure that every resource from site2 is rewritten to http://www.site1.com/foldera/folderb/{resourcefromsite1}
Unfortunately, the outbound rule is also crashing the rest of my site. Probably because he's trying to rewrite every native resource to this same "http://www.site1.com/foldera/folderb/" folderstructure.
How can I make the outbound rule only to respond to resources that are requested/loaded through path http://www.site1.com/foldera/folderb/ and for instance not through http://www.site1.com/foldera
Cheers
Jeroen
You were very close to solution. To solve this you must add {URL} as input inside your preCondition. Your rewrite rules should look like this finally:
<rewrite>
<rules>
<rule name="Route the requests for backend app" stopProcessing="true">
<match url="^foldera/folderb/(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="www.site1.com" />
</conditions>
<action type="Rewrite" url="http://www.site2.com/{R:1}" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="RewriteRelativePaths" preCondition="ResponseIsHtml" enabled="true" stopProcessing="false">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^/(.*)" />
<action type="Rewrite" value="/foldera/folderb/{R:1}" />
<!-- Removed condition from here -->
</rule>
<preConditions>
<preCondition name="ResponseIsHtml">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
<add input="{URL}" pattern="^/foldera/folderb/.*" /> <!-- Added your condition here -->
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
This way Outbound Rule will be applied only when Response is HTML and current URL got specified pattern.

IIS - setting cache-control header per file type

I'd like to set different cache-control header values for my js,css and html files.
I know about the option to set it on a per-folder basis but my app has html and js files in the same folder.
Is it even possible in IIS ?
This is possible in IIS 7+ using IIS outbound rewrite rules. Eg. if you want to invalidate all .html pages, create the following outbound rule (after installing the IIS rewrite module) in the outboundRules section of the web.config:
<outboundRules>
<rule name="AdjustCacheForHTMLPages" preCondition="IsHTMLFile">
<match serverVariable="RESPONSE_Cache-Control" pattern=".*" />
<action type="Rewrite" value="no-cache, no-store, must-revalidate" />
</rule>
<preConditions>
<preCondition name="IsHTMLFile">
<add input="{REQUEST_FILENAME}" pattern=".*\.html" />
</preCondition>
</preConditions>
</outboundRules>
The answer by #jotap will only work for file requests that end in ".html". I needed it to work for the content type, too:
<outboundRules>
<rule name="AdjustCacheForHTMLPages" preCondition="IsHTML">
<match serverVariable="RESPONSE_CACHE-CONTROL" pattern=".*" />
<action type="Rewrite" value="no-cache, no-store, must-revalidate" />
</rule>
<preConditions>
<preCondition name="IsHTML" logicalGrouping="MatchAny">
<add input="{REQUEST_FILENAME}" pattern="\.html$" />
<add input="{RESPONSE_CONTENT-TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>

Resources