【发布时间】:2013-04-10 12:44:22
【问题描述】:
我正在实现一个反向代理,用于将请求路由到后端服务器。
功能上一切正常,但是我担心来自后端服务器的所有响应都会在没有压缩的情况下传输到客户端(网络浏览器)。
设置如下:
- 内部域上的后端服务器,公众无法访问。在
https://internal.app上托管一个 Web 应用程序 - 带有 IIS 7.5 的前端 Web 服务器,托管主要公共网站并充当后端服务器的代理。主站点位于
https://site.com。
我想以对客户端透明的方式将所有请求路由到 https://site.com/app/WHATEVER 到 https://internal.app/WHATEVER。
我当前的设置基于 URL Rewrite 2.0 和应用程序请求路由 IIS 扩展。一般方法基于以下文章中的指南:
- Setting up a Reverse Proxy using IIS, URL Rewrite and ARR
- Reverse Proxy with URL Rewrite v2 and Application Request Routing
site.com 应用程序的web.config 的相关部分:
<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 中的顺序正确。
但是,这似乎只有在重写发生在一个 Web 应用程序中时才有效。如果我删除上述规则并添加一个简单的规则(以及相应的出站规则)来重写,例如/x/WHATEVER 到 /WHATEVER,无需清除 HTTP_ACCEPT_ENCODING 即可完美运行 - 规则有效,并且为重写的请求启用了压缩。
但是,一旦我重新添加将响应重写到不同 Web 应用程序的规则,并且我没有清除 HTTP_ACCEPT_ENCODING 标头,就会再次出现相同的错误。
据我了解,如果重写涉及另一个 Web 应用程序,那么可以做什么会受到更多限制。例如。 URL 重写器必须从后端服务器接收未压缩的响应,以便能够使用出站规则对其进行重写。我想在这种情况下清除 HTTP_ACCEPT_ENCODING 是必须的。
但是,我希望由于压缩模块列在模块列表的顶部,因此无论来自何处,都应该压缩最终重写的响应。似乎 IIS 做了一些快捷方式,并绕过压缩模块将响应返回给客户端。或者HTTP_ACCEPT_ENCODING 标头很快就会被删除以完全禁用压缩(不仅在服务器到服务器的通信中)。
最后,我的问题是:有没有办法压缩这些响应?
【问题讨论】:
标签: asp.net iis reverse-proxy http-compression arr