我们偶尔会接到一些客户电话(不到 0.1% 的用户),抱怨无法访问我公司的网站 - 他们要么看到空白页(如果他们使用 IE),要么看到“内容编码错误”,提示页面使用了无效或不受支持的压缩形式(如果他们使用 FireFox)。
目前的怀疑是,当 HTTP 1.1 浏览器请求通过 HTTP 1.0 代理时,我们会发回压缩的 HTTP 1.1 浏览器请求,而该请求不知何故被 HTTP 1.0 代理破坏了。
该网站是 Tomcat 4.2.2 后端,带有 IIS 6.0 前端,并在 IIS 服务器上启用了 GZIP 和 DEFLATE。
以前有人遇到过这种错误吗?是否有建议的修复方法以避免破坏旧的代理实现?
编辑:我们可以使用 squid-2.5 的默认设置复制该问题,但较新版本的 squid 似乎运行良好。
答案1
好的,我想我们已经明白了……
在客户端,Squid 2.5 及更早版本不理解“传输编码:分块”,因此它将每个块作为整个客户端请求进行传递。由于它只是整个压缩请求的 1 个块,因此它是无效数据,浏览器无法读取。(不确定这是否是其他代理的问题)
在服务器端,IIS 始终发送分块编码进行动态压缩(因为 IIS 不缓存应用程序响应,所以它必须动态压缩每个响应,因此需要分块编码)。
我们能想到的唯一解决办法是完全禁用 HTTP 1.0 客户端的压缩,只对 HTTP 1.1 响应进行压缩。缺点是,任何使用代理发送 1.0 请求的人都不会获得压缩数据,网站对这些用户的加载速度会慢 0.5 到 1 秒。
metabase.xml 文件中所做的更改:
<IIsCompressionSchemes Location ="/LM/W3SVC/Filters/Compression/Parameters"
...
HcDoOnDemandCompression="TRUE"
HcNoCompressionForHttp10="TRUE"
...
</IIsCompressionSchemes>
如果有人有更好的解决方案,请告诉我!
答案2
如果可以重现此问题,那么我将首先检查发送给客户端的响应标头,以确保请求/响应流中某处存在 1.0 代理,如 Via: 响应标头中所示。如果没有,那么你很可能找错了方向。代理必须在请求/响应流的两个方向插入此标头及其使用的协议。