URL 重写条件可以比较两个服务器变量吗?

URL 重写条件可以比较两个服务器变量吗?

我正在尝试比较两个服务器变量作为 URL 重写条件的一部分。但首先,先了解一些背景信息...

在 IIS 中,如果您请求的http://www.example.com/foofoo目录,IIS 会将 302“对象已移动”重定向发送http://www.example.com/foo/至“礼貌重定向”(来源)。

如果您使用 IIS+ARR 作为具有 SSL 卸载的反向代理,则后端 IIS 节点接收的请求是通过 http 而不是 https。

结合这两种行为,IIS 的礼貌重定向会丢弃 SSL。礼貌重定向使用与 IIS 收到的请求相同的方案(来源),在这种情况下是 http 而不是 https。

我想创建一个出站重写规则,将传入的 URL 与传出的 Location 标头进行比较,并在本例中将其从 http 重写为 https:

  • 响应是重定向:{RESPONSE_STATUS}是 302
  • 传入请求通过 SSL:{HTTPS}处于“开​​启”状态
  • 传入的 URL 没有以斜杠结尾。
  • 传出的 Location 标头以斜线结尾。

以上所有内容都是在前提条件中处理的。棘手的部分是最后一点:

  • 传出 Location 标头的路径与传入 URL 相同,但附加了斜杠。

以下是我目前的代码。前提条件和标头重写都工作正常。但是,条件会导致 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>

答案1

您可以使用自定义重写提供程序。提供程序是将一个字符串转换为另一个字符串的 C# 代码。然后,您可以按照与使用重写映射类似的方式使用它:

您可以选择在 URL 中完全无效的分隔符。(也许使用空格或类似的东西。我将使用它,|以便它在这篇文章中可见,但您应该选择其他字符串。)

您将编写一条规则来设置服务器变量的值IsItMatching。 服务器变量的值将使用您的自定义 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是“是”还是“否”。

相关内容