Может ли условие URL Rewrite сравнивать две серверные переменные?

Может ли условие URL Rewrite сравнивать две серверные переменные?

Я пытаюсь сравнить две переменные сервера как часть условия перезаписи 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 Rewrite), предположительно из-за того, что я использую {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#, который преобразует одну строку в другую. Затем вы можете использовать его аналогично тому, как вы используете 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переменной «да» или «нет».

Связанный контент