.NET HttpWebRequest 中的压缩(标头)错误?
我刚刚注意到,使用 .NET HttpWebRequest
,我没有从服务器(运行 nginx 0.8.52)获取 gzip 内容。通过使用curl 进行测试,我验证了gzip 已在服务器端正确设置,然后使用VS 调试器深入研究了该问题。
罪魁祸首是 Accept-Encoding
标头字段的生成方式:如果我设置,
request.AutomaticDecompression = DecompressionMethods.GZip |
DecompressionMethods.Deflate`
我会得到以下标头:
`Accept-Encoding: gzip, deflate,gzip, deflate`.
如果我设置,
request.AutomaticDecompression = DecompressionMethods.GZip;
我会得到
Accept-Encoding: gzip,gzip
我没有检查 HTTP 规范所说的内容,但是 nginx应该可以处理这种情况,但它却返回了 Vary: Accept-Encoding
。另一方面,由 HttpWebRequest
生成的 Accept-Encoding
标头看起来绝对不正确,对我来说似乎是一个错误。
如果我不指定 AutomaticDecompression
并手动设置 Accept-Encoding
标头,我会返回 gzip 内容,但 HttpWebRequest
似乎是非常愚蠢,并且不解码压缩流(我猜它依赖于内部 IsCompressed 标志而不是解析响应标头)。
有什么建议吗?
编辑:
应该注意的是,涉及身份验证;我刚刚发现 HttpWebRequest
最初执行的请求不包含提供的凭据。对于此请求,正确指定了 Accept-Encoding
标头。在获取 401 服务器响应并使用凭据重新执行请求后,会发生重复。
编辑2:
我发布了 Microsoft Connect 错误报告< /a>.
I just noticed that using the .NET HttpWebRequest
, I wasn't getting gzip'd contents back from the server (running nginx 0.8.52). Testing with curl, I verified that gzip was set up properly server-side, then dug into the issue with the VS debugger.
The culprit turns out to be how the Accept-Encoding
header field is generated: if I set
request.AutomaticDecompression = DecompressionMethods.GZip |
DecompressionMethods.Deflate`
I get the following header:
`Accept-Encoding: gzip, deflate,gzip, deflate`.
If I set
request.AutomaticDecompression = DecompressionMethods.GZip;
I get
Accept-Encoding: gzip,gzip
I haven't checked what the HTTP specification says, but nginx ought to handle the situation, but instead it returns Vary: Accept-Encoding
back. On the other hand, the Accept-Encoding
header generated by HttpWebRequest
definitely doesn't look right, and seems like a bug to me.
If I don't specify AutomaticDecompression
and manually set the Accept-Encoding
header, I get gzip'd content back, but HttpWebRequest
seems to be pretty dumb, and doesn't decode the compressed stream (I guess it relies on an internal IsCompressed
flag rather than parsing the response headers).
Any suggestions?
EDIT:
It should be noted that there's authentication involved; I've just found out that HttpWebRequest
initially does a request without including the supplied credentials. For this request, the Accept-Encoding
header is specified correctly. The duplication occurs after getting the 401 server response and re-doing the request with credentials.
EDIT 2:
I posted a Microsoft Connect bug report.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看来是一个错误好吧。可能的解决方法:
Seems to be a bug alright. Possible workarounds:
哈哈,有趣的是你提到了这一点,我在周五就注意到了这一点;P
我没有看到因此造成的任何问题,我的回复仍然很压缩。
我还注意到了几个代理请求。但我一生都无法在 MS ISA 或具有长名称服务器的新 ISA 上进行 GZip 压缩。似乎只是剥离了请求头,而服务器甚至不知道它。明天我将与我们的一位网络管理员开会,看看问题是否与代理相关。
更新:
我应该注意,我在自己和服务器之间放置 Squid 代理没有问题,但这只是使用基本身份验证,而不是 Windows/ISA 使用的花哨的质询响应内容。
更新2:
我忘了提及,当使用浏览器访问该网站时,Accept-Encoding 标头也会“消失”。这就是为什么我认为真正的问题可能不是 .NET 特有的。测试仍在继续。
更新 3:
我使用 FF3.6 通过 ISA 代理进行了捕获,结果几乎相同。通过 ISA,仅对“单个”代理进行身份验证,但最终响应仍然未压缩。
鉴于 MS 产品中遗传性错误的发生率很高,我不得不支持 ISA/FTMG 是罪魁祸首。
<罢工>
更新4(已解决):
刚刚开会,解决了问题(稍后将发布具有适当设置的屏幕截图)。所以预感是正确的(至少就我而言)。
如果托管服务器的网络中使用了 ISA/FTMG 配置,我强烈建议您研究一下。
更新 5(确实已解决):
尝试了另一种设置,结果成功了。在 FTMG 代理上,我们必须为“外部”网络启用 HTTP 压缩,并确保可压缩内容类型正确(必须为 WCF 添加 application/soap+xml)。这允许代理进行压缩,而实际的 Web 服务器则不能,这可能是理想的,也可能不是理想的,但至少它可以工作。 :)
我强烈建议您研究 ISA/FTMG 配置(如果在托管服务器的网络中使用该配置)。
捕获日志:
这是我通过 Wireshark 捕获的 Forefront TMG 代理使用 IE8 访问网站的跟踪记录。如果错误是 .NET 特定的,我预计结果会有所不同,但从我所看到的来看,它的行为是相同的。
初始请求:
使用代理进行身份验证,但失败?:
最终序列:
LOL, funny you mention this, I noted this just on Friday ;P
I have not seen any issues due to this, my response is still compressed.
I have also noted the several proxy requests. But I cannot for the life of me get GZip compression working over MS ISA or the new one with the long name server. It seems to just strip the request header, and the server does not even know about it. I am having a meeting with one of our network admins tomorrow to see if the issue is proxy related.
Update:
I should note that, I have no problem placing a Squid proxy between myself and server, but that was simply using basic authentication, and not the fancy challenge-response stuff Windows/ISA uses.
Update 2:
I forgot to mention, the Accept-Encoding header 'disappears' too when using a browser to access the site. This is why I think the real problem might not be specific to .NET. Testing continues.
Update 3:
I did a capture using FF3.6 going via ISA proxy and pretty much the same result. Going via ISA, only does a 'single' proxy authenticate, but the final response is still not compressed.
Given the high rate of hereditary bugs in MS products, I would have to side with ISA/FTMG being the culprit here.
Update 4 (solved):
Just had the meeting, and solved the issue (will post screenie with the appropriate setting later). So the hunch was correct (in my case at least).
I would strongly advise to look into ISA/FTMG configuration, if that is used in the network hosting the server.
Update 5 (solved, really):
Tried another setting, and that did the 'trick'. On the FTMG proxy, we had to enable HTTP compression for the 'External' network, as well as make sure the compressible content-types were correct (had to add application/soap+xml for WCF). This allows the proxy to do compression, and the actual web server does not, which may or may not be ideal, but at least it works. :)
I would strongly advise to look into ISA/FTMG configuration, if that is used in the network hosting the server.
Capture log:
Here is my trace hitting the site with IE8 via Forefront TMG proxy captured with Wireshark. If the bug is .NET specific, I would expect the result to be different, but from what I can see, it behaves the same.
Initial request:
Authenticate with proxy, but fails?:
Final sequence: