Я реализую обратный прокси для запросов на маршрутизацию на серверный сервер.IIS как обратный прокси - сжатие перезаписанного ответа с сервера backend
Функционально все работает правильно, однако я обеспокоен тем, что все ответы с сервера backend передаются клиенту (веб-браузеру) без сжатия.
Установка выглядит следующим образом:
- Backend сервер не доступен для общественности, на внутренней области. Принимает веб-приложение на
https://internal.app
- Передний веб-сервер с IIS 7.5, размещающий основной общедоступный веб-сайт и выступающий в качестве прокси-сервера для серверного сервера. Основной сайт -
https://site.com
.
Я хочу направить все запросы на https://site.com/app/WHATEVER
к https://internal.app/WHATEVER
таким способом, который является прозрачным для клиентов.
Моя текущая установка основана на URL Rewrite 2.0 и Application Request Routing расширения IIS. Общий подход базируется на следующих положениях из следующих статей:
- Setting up a Reverse Proxy using IIS, URL Rewrite and ARR
- Reverse Proxy with URL Rewrite v2 and Application Request Routing
Соответствующий раздел web.config
из site.com
приложения:
<system.webServer>
<rewrite>
<rules>
<rule name="Route the requests for backend app" stopProcessing="true">
<match url="^app/(.*)" />
<conditions>
<add input="{CACHE_URL}" pattern="^(https?)://" />
</conditions>
<action type="Rewrite" url="{C:1}://internal.app/{R:1}" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="RewriteBackendAbsoluteUrlsInResponse" preCondition="ResponseIsHtml1">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^http(s)?://internal.app(\:80)?/(.*)" />
<action type="Rewrite" value="/app/{R:3}" />
</rule>
<rule name="RewriteBackendAbsoluteUrlsInRedirects" preCondition="ResponseIsHtml1">
<match serverVariable="RESPONSE_LOCATION" pattern="^http(s)?://internal.app(\:80)?/(.*)" />
<action type="Rewrite" value="/app/{R:3}" />
</rule>
<rule name="RewriteBackendRelativeUrlsInResponse" preCondition="ResponseIsHtml1">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^/(.*)" negate="false" />
<conditions>
<add input="{URL}" pattern="^/app/.*" />
</conditions>
<action type="Rewrite" value="/app/{R:1}" />
</rule>
<rule name="RewriteBackendRelativeUrlsInRedirects" preCondition="ResponseIsHtml1">
<match serverVariable="RESPONSE_LOCATION" pattern="^/(.*)" negate="false" />
<conditions>
<add input="{URL}" pattern="^/app/.*" />
</conditions>
<action type="Rewrite" value="/app/{R:1}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<urlCompression dynamicCompressionBeforeCache="false" />
</system.webServer>
Проблема заключается в том, что как только я перестаю очищать переменную сервера HTTP_ACCEPT_ENCODING
, каждый запрос, который соответствует приведенное выше правило заканчивается следующей ошибкой: HTTP Error 500.52 - URL Rewrite Module Error. Outbound rewrite rules cannot be applied when the content of the HTTP response is encoded ("gzip").
Я знаю this thread, и я выполнил эти инструкции. Я установил dynamicCompressionBeforeCache="false"
, как видно выше, я добавил необходимую запись в реестр, и я заверил, что модули находятся в правильном порядке в IIS.
Однако, похоже, это работает только в том случае, если переписывание происходит в одном веб-приложении. Если я удалю вышеуказанные правила и добавлю простой (и соответствующие правила исходящего), чтобы переписать, например. /x/WHATEVER
только /WHATEVER
, все работает отлично, без необходимости очистки HTTP_ACCEPT_ENCODING
- правило работает, и сжатие включено для перезаписанных запросов.
Но как только я снова добавлю свое правило, которое переписывает ответ на другое веб-приложение, и я не очищаю заголовок HTTP_ACCEPT_ENCODING
, эта же ошибка появляется снова.
Из того, что я понимаю, если переписывание связано с другим веб-приложением, существует больше ограничений на то, что можно сделать. Например. Переписывающий URL-адрес должен получить несжатый ответ с сервера базы данных, чтобы иметь возможность переписать его с помощью исходящих правил. Я думаю, что очистка HTTP_ACCEPT_ENCODING
в этом сценарии является обязательным условием из-за этого.
Однако я бы ожидал, что, поскольку модуль сжатия указан сверху списка модулей, окончательный перезаписанный ответ должен быть сжат независимо от того, откуда он произошел. Кажется, что IIS делает несколько ярлыков и возвращает ответ клиенту в обход модуля сжатия.Или заголовок HTTP_ACCEPT_ENCODING
будет удален достаточно быстро, чтобы полностью отключить сжатие (не только в связи между сервером).
Итак, мой вопрос: есть ли способ сжать эти ответы?
Спасибо, я написал о вашем ответе здесь: http://anjdreas.blogspot.no/2016/01/iis-aspnet- exposing-localhost-to-world.html – angularsen
Рад, что вы нашли это полезным и спасибо за ссылку сюда! –
Хм, я чувствую, что мне не хватает части вашей формулы. У меня все это на месте, но я все еще не вижу сжатия для прокси-контента. Каков порядок ваших модулей IIS? Имеет ли значение, где «HttpCacheModule» и «RewriteModule» относятся к «DynamicCompressionModule» и «StaticCompressionModule»? –