Может ли условие перезаписи 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 ( Source), в данном случае 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
Переменная сервера - "да" или "нет".