URL 書き換え条件は 2 つのサーバー変数を比較できますか?

URL 書き換え条件は 2 つのサーバー変数を比較できますか?

URL 書き換え条件の一部として 2 つのサーバー変数を比較しようとしています。まず、コンテキストについて説明します...

IISでは、リクエストhttp://www.example.com/foofooディレクトリである場合、IISはhttp://www.example.com/foo/「礼儀正しいリダイレクト」として302「オブジェクトが移動されました」リダイレクトを送信します(ソース)。

SSL オフロードを使用して IIS + ARR をリバース プロキシとして使用している場合、バックエンド IIS ノードが受信する要求は https ではなく http 経由になります。

これら 2 つの動作を組み合わせると、IIS の礼儀リダイレクトは SSL をドロップします。礼儀リダイレクトは、IIS が受信したリクエストと同じスキームを使用します (ソース)、この場合は https ではなく http を使用します。

この場合、受信 URL と送信 Location ヘッダーを比較し、http から https に書き換える送信書き換えルールを作成したいと思います。

  • 応答はリダイレクト{RESPONSE_STATUS}です: 302
  • 受信リクエストは SSL 経由です: {HTTPS}「オン」
  • 受信 URL がスラッシュで終わっていません。
  • 発信 Location ヘッダーはスラッシュで終わります。

上記のすべては前提条件で処理されます。難しいのは最後の部分です。

  • 送信 Location ヘッダーのパスは、スラッシュが追加された受信 URL と同じです。

以下は、これまでのコードです。前提条件とヘッダーの書き換えはどちらも正常に動作します。ただし、{REQUEST_URI}パターンで を使用しているため、条件によって 500 エラー (URL 書き換えモジュール エラー) が発生します。条件を 2 つに分割してキャプチャ グループを使用してみましたが、それでもうまくいきませんでした。何かアイデアはありますか?

<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# コードです。これを、rewrite map と同じように使用できます。

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」かをチェックするもう 1 つのルールを記述します。

関連情報