Я пытаюсь сравнить две серверные переменные как часть условия перезаписи 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{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>
Вы можете использовать пользовательский поставщик перезаписи. Провайдер - это код 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
переменная сервера - «да» или «нет».