功能上一切正常,但是我担心后端服务器的所有响应都不会压缩到客户端(Web浏览器)。
设置如下:
>后端服务器,不能公开访问内部域。在https://internal.app上托管网络应用程序
>具有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,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错误500.52 – URL重写模块错误。
当HTTP响应的内容被编码(“gzip”)时,不能应用出站重写规则。
我知道this thread,我已经遵循了这些说明。我已经设置了dynamicCompressionBeforeCache =“false”,如上所述,我已经添加了必要的注册表项,我确信这些模块在IIS中的顺序是正确的。
但是,只有在一个网络应用程序中进行重写时,这只能起作用。如果我删除上述规则并添加一个简单的规则(和相应的出站规则)来重写例如。 / x / WHATEVER到just / WHATEVER,所有这些都完美无缺,而不需要清除HTTP_ACCEPT_ENCODING – 为重写的请求启用规则工作和压缩。
但是,一旦我重新添加我的规则,将响应重写为不同的Web应用程序,并且我不清除HTTP_ACCEPT_ENCODING标题,则会再次出现相同的错误。
从我所理解的,如果重写涉及另一个网络应用程序,则可以做的更多的约束。例如。 URL重写器必须从后端服务器接收未压缩的响应,以便能够使用出站规则进行重写。我想在这种情况下清除HTTP_ACCEPT_ENCODING是必须的,因为这样。
但是,由于压缩模块列在模块列表的顶部,所以最终重写的响应应该被压缩,无论其来源于何处。似乎IIS做了一些快捷方式,并将响应返回给客户端绕过压缩模块。或者HTTP_ACCEPT_ENCODING标头被尽快删除,以完全禁用压缩(不仅在服务器到服务器通信中)。
所以最后我的问题是:有压缩这些回应的方法吗?
解决方法
需要做些什么来使其工作:
在将请求路由到后端服务器之前,必须删除Accept-Encoding头,以便可以使用出站规则重写响应
>标题必须通过附加的附加出站规则进行恢复,以便在压缩模块在响应发送到客户端之前启动时才会出现
我决定这样做:
>将新的服务器变量添加到重写规则,以保持客户端发送的原始头文件:
<set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" />
(我把它放在清除HTTP_ACCEPT_ENCODING变量的行之前)
>添加新的出站规则:
<rule name="RestoreAcceptEncoding" preCondition="NeedsRestoringAcceptEncoding"> <match serverVariable="HTTP_ACCEPT_ENCODING" pattern="^(.*)" /> <action type="Rewrite" value="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" /> </rule>
和附带的前提条件:
<preCondition name="NeedsRestoringAcceptEncoding"> <add input="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" pattern=".+" /> </preCondition>
到目前为止,就像魅力一样。