首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >作为反向代理的IIS -压缩来自后端服务器的重写响应

作为反向代理的IIS -压缩来自后端服务器的重写响应
EN

Stack Overflow用户
提问于 2013-04-10 20:44:23
回答 4查看 28.6K关注 0票数 22

我正在实现一个反向代理,用于将请求路由到后端服务器。

在功能上一切正常,但是我担心所有来自后端服务器的响应都在没有压缩的情况下传输到客户端(web浏览器)。

设置如下:

内部域上公共不可访问的

  • 后端服务器。在装有IIS7.5的https://internal.app
  • Front web服务器上托管web应用程序,托管主要公共网站并充当后端服务器的代理。主要网站是https://site.com.

我希望以一种对客户端透明的方式将所有对https://site.com/app/WHATEVER的请求路由到https://internal.app/WHATEVER

我当前的设置基于URL重写2.0和应用程序请求路由IIS扩展。一般方法基于以下文章中的指导方针:

site.com应用程序的web.config的相关部分:

代码语言:javascript
复制
<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报头以完全禁用压缩(不仅在服务器到服务器通信中)。

所以最后,我的问题是:有没有一种方法来压缩这些响应?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-04-11 05:20:20

我自己已经弄明白了。

需要做些什么才能让它正常工作:

在将请求路由到后端服务器之前,必须删除

  • Accept-Encoding标头,以便可以使用outbound rules
  • the标头重写响应。必须通过附加的附带出站规则恢复出站client

标头,以便在响应发送到client之前压缩模块启动时存在该标头

我决定这样做:

  • 在重写规则中添加一个新的服务器变量,以保存客户端发送的原始标头:

(我将它放在清除variable)

  • add HTTP_ACCEPT_ENCODING的行之前,这是一个新的出站规则:

和一个附带的前提条件:

到目前为止,它的效果很不错。

票数 30
EN

Stack Overflow用户

发布于 2016-10-29 05:11:56

要解决原始发帖的问题,同时仍然保留gzip压缩的回复,只需执行以下操作:

  1. 在面向公众的web服务器上更新注册表,如下所示:

a.对于64位网站,请在具有管理员权限的命令控制台中运行以下命令:reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp\Rewrite /v LogRewrittenUrlEnabled /t REG_DWORD /d 0

b.对于32位网站,请在具有管理员权限的命令控制台中运行以下命令:reg add HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432node\Microsoft\Inetstp\Rewrite /v LogRewrittenUrlEnabled /t REG_DWORD /d 0

  • reset IIS

  • 禁用静态压缩

答:为了实现这一点,我插入了以下网页配置:在IIS管理器中重写服务器节点,双击Modules图标,然后在右侧单击“查看有序列表”,并验证静态/动态压缩模块是否朝向顶部,URL重写模块是否朝向底部。

请注意

我在网上看到了很多解决这个问题的方法,其中HTTP_CONTENT_TYPE请求头是作为URL重写规则的一部分被清除的(包括本页上的答案)。需要注意的是,虽然这确实解决了500.52错误的原始问题,但响应中的gzip压缩是REMOVED。这可能是预期的结果,但是如果需要gzip压缩,上面的解决方案就可以解决问题。

票数 3
EN

Stack Overflow用户

发布于 2016-05-18 11:03:33

附言:下面的解决方案只有在你能控制你的应用服务器的情况下才有效。

它基本上是让web服务器做压缩,让应用服务器做应用程序应该做的重任(没有压缩)。

如果您在应用服务器上禁用压缩,则您从应用服务器获得的响应是未压缩的。在web服务器上,您应该启用压缩,以便web服务器在响应客户端(浏览器)时遵守HTTP报头"Accept-Encoding: gzip,deflate“。

此配置将减轻应用程序服务器上的CPU负载,但会增加web服务器和应用程序服务器之间的网络流量。如果您使用的是内部网络,则不会对性能产生太大影响。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15926203

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档