URL 重寫條件可以比較兩個伺服器變數嗎?

URL 重寫條件可以比較兩個伺服器變數嗎?

我正在嘗試比較兩個伺服器變數作為 URL 重寫條件的一部分。但首先,一些背景......

在 IIS 中,如果您要求http://www.example.com/foo並且foo是目錄,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是「yes」還是「no」。

相關內容