我想比较两个服务器variables作为URL重写条件的一部分。 但首先,一些背景…
在IIS中,如果您请求http://www.example.com/foo并且foo是一个目录,则IIS会将302“Object moved”redirect到http://www.example.com/foo/作为“礼貌redirect“( 来源 )。
如果使用IIS + ARR作为带有SSL卸载的反向代理,则后端IIS节点接收的请求通过http而不是https。
结合这两个行为,以及IIS的礼貌redirect丢弃SSL。 礼貌redirect使用与IIS收到的请求( 源 )相同的scheme,在这种情况下http而不是https。
我想创build一个出站重写规则,将传入的URL与传出的位置标题进行比较,并在此情况下将其从http重写为https:
{RESPONSE_STATUS}是302 {HTTPS}是“开” 以上都是在前提下处理的。 棘手的部分是最后一点:
以下是我到目前为止的代码。 前提条件和头重写都工作正常。 但是,该条件导致500错误(URL重写模块错误),大概是因为我在模式中使用{REQUEST_URI} 。 我已经尝试将条件分成两个并使用捕获组,但是这也不起作用。 有任何想法吗?
<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>
您可以使用自定义的重写提供程序。 提供程序是将一个string转换为另一个string的C#代码。 然后,您可以像使用重写映射一样使用它:
你可以select一个在URL中无效的分隔符。 (也许使用空间或类似的东西,我会使用|所以在这篇文章中可见,但你应该select其他的string。)
您将编写一个规则来设置服务器variablesIsItMatching的值。 服务器variables的值将使用您的自定义url重写提供程序进行设置:
{provider_name:{server_variable_1}|{server_variable_2}}
实现提供程序的C#代码将执行此操作(伪代码,无错误检查):
string Rewrite(string input) { string[] inputVariables = input.split(separator); if (inputVariables[0] == inputVariables[1] + "/") return "yes"; else return "no"; }
然后再编写一个规则来检查IsItMatching服务器variables的值是“yes”还是“no”。