.NET HttpWebRequest中的压缩(标题)错误?

时间:2010-11-23 11:23:56

标签: .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。另一方面,Accept-Encoding生成的HttpWebRequest标题肯定看起来不对,对我来说似乎是个错误。

如果我没有指定AutomaticDecompression并手动设置Accept-Encoding标头,我会重新获得gzip内容,但HttpWebRequest似乎非常愚蠢,并且无法解码压缩流(我猜它依赖于内部IsCompressed标志,而不是解析响应头。)

有什么建议吗?

编辑:

应该注意的是,涉及到身份验证;我刚刚发现HttpWebRequest最初在没有的情况下执行请求,包括提供的凭据。对于此请求,正确指定了Accept-Encoding标头。获取401服务器响应并使用凭据重新执行请求后发生重复。

编辑2:

我发布了Microsoft Connect bug report

2 个答案:

答案 0 :(得分:4)

似乎是个错误。可能的解决方法:

  1. 不要使用AutomaticDecompression,手动设置“Accept-Encoding”标头字段,如果设置了“Content-Encoding”属性,则手动处理响应流的解压缩。
  2. 不要使用Credentials属性,而是手动构建HTTP Authorization标头。这消除了不必要的服务器往返并修复了头字段重复错误。

答案 1 :(得分:0)

大笑,很有趣,你提到这个,我在星期五就注意到了这一点; P

由于这个原因,我没有看到任何问题,我的回复仍然是压缩的。

我还注意到了几个代理请求。但我不能为我的生活让GZip压缩工作在MS ISA或新的长名称服务器。它似乎只是剥离请求标头,服务器甚至不知道它。我明天正在与我们的一位网络管理员会面,看看问题是否与代理相关。

<强>更新

我应该注意到,我在自己和服务器之间放置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访问网站的跟踪。如果bug是特定于.NET的,我希望结果是不同的,但从我所看到的,它的行为是相同的。

初始请求:

GET http://www.foo.com/ClientInstall HTTP/1.1
Accept: image/gif, image/jpeg, ...
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; ...
Accept-Encoding: gzip, deflate
Proxy-Connection: Keep-Alive
Host: www.foo.com

HTTP/1.1 407 Proxy Authentication Required 
  ( Forefront TMG requires authorization to fulfill the request. 
  Access to the Web Proxy filter is denied.  )
Via: 1.1 PROXP01
Proxy-Authenticate: Negotiate
Proxy-Authenticate: Kerberos
Proxy-Authenticate: NTLM
Proxy-Authenticate: Basic realm="PROXP01.bar.com"
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Pragma: no-cache
Cache-Control: no-cache
Content-Type: text/html
Content-Length: 4140  

使用代理进行身份验证,但失败了?:

GET http://www.foo.com/ClientInstall HTTP/1.1
Accept: image/gif, image/jpeg, ...
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; ...
Accept-Encoding: gzip, deflate
Proxy-Connection: Keep-Alive
Host: www.foo.com
Proxy-Authorization: Negotiate TlRMTVNTUAABAAAA...

HTTP/1.1 407 Proxy Authentication Required ( Access is denied.  )
Via: 1.1 PROXP01
Proxy-Authenticate: Negotiate TlRMTVNTUAACAAAAB...
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Pragma: no-cache
Cache-Control: no-cache
Content-Type: text/html
Content-Length: 0     

最后的序列:

GET http://www.foo.com/ClientInstall HTTP/1.1
Accept: image/gif, image/jpeg, ...
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; ...
Accept-Encoding: gzip, deflate
Proxy-Connection: Keep-Alive
Proxy-Authorization: Negotiate TlRMTVNTUAADAAAAGAAYAH4AAAA...
Host: www.foo.com

HTTP/1.1 301 OK
Via: 1.1 PROXP01
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Content-Length: 160
Date: Wed, 24 Nov 2010 04:34:31 GMT
Age: 308
Location: http://www.foo.com/ClientInstall/
Content-Type: text/html; charset=UTF-8
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET

GET http://www.foo.com/ClientInstall/ HTTP/1.1
Accept: image/gif, image/jpeg, ...
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; ...
Accept-Encoding: gzip, deflate
Proxy-Connection: Keep-Alive
Host: www.foo.com

HTTP/1.1 200 OK
Via: 1.1 PROXP01
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Content-Length: 4621
Date: Wed, 24 Nov 2010 04:39:39 GMT
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.0
Cache-Control: private
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET