web-dev-qa-db-ja.com

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

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

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

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>
5
MALfunction84

カスタム書き換えプロバイダーを使用できます。 プロバイダーは、ある文字列を別の文字列に変換する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";
}

次に、もう1つのルールを記述して、IsItMatchingサーバー変数の値が「yes」か「no」かを確認します。

3
Palo