I am trying to compare two server variables as part of a URL rewrite condition. But first, some context...
In IIS, if you request http://www.example.com/foo
and foo
is a directory, IIS sends a 302 "Object moved" redirect to http://www.example.com/foo/
as a "courtesy redirect" (Source).
If you are using IIS+ARR as reverse proxy with SSL offloading, the request that the back-end IIS node receives is over http, not https.
Combine these two behaviors, and IIS's courtesy redirects drop SSL. The courtesy redirect uses the same scheme as the request that IIS received (Source), http in this case instead of https.
I'd like to create an outbound rewrite rule that will compare the incoming URL with the outgoing Location header and rewrite it from http to https in this case:
- The response is a redirect:
{RESPONSE_STATUS}
is 302 - The incoming request was over SSL:
{HTTPS}
is "on" - The incoming URL does not end in a slash.
- The outgoing Location header ends in a slash.
All of the above is handled in the precondition. The tricky part is the last bit:
- The path of the outgoing Location header is the same as the incoming URL with a slash appended.
Below is the code I have so far. The precondition and header rewrite both work fine. However, the condition causes a 500 error (URL Rewrite module error), presumably because I'm using {REQUEST_URI}
in the pattern. I've tried separating the condition into two and using capture groups, but that didn't work either. Any ideas?
<rule name="Fix: Courtesy Redirect + SSL Offloading = SSL dropped" preCondition="Courtesy Redirect Drops SSL" enabled="true">
<match serverVariable="RESPONSE_LOCATION" pattern="^http://(.+/)$" />
<conditions>
<add input="{RESPONSE_LOCATION}" pattern="{REQUEST_URI}/" />
</conditions>
<action type="Rewrite" value="https://{R:1}" />
</rule>
<preConditions>
<preCondition name="Courtesy Redirect Drops SSL">
<add input="{RESPONSE_STATUS}" pattern="^302$" />
<add input="{HTTPS}" pattern="^on$" />
<add input="{REQUEST_URI}" pattern=".*[^/]$" />
<add input="{RESPONSE_LOCATION}" pattern="^http://.+/$" />
</preCondition>
</preConditions>