Wininet 不缓存压缩内容

Wininet not caching compressed content

我有一个压缩资源,当在 IE 中查看时,它会按预期从缓存中加载。但是,当我的应用程序加载相同的 URL 时,Wininet 会忽略缓存并始终从服务器下载内容。在 IIS 上禁用动态内容压缩后,我的应用程序的行为与 IE 相同(HTTP GET 包含 If-None-Match header。)

如何才能使我的应用程序与 IE 的行为相同?

_httpClient = new HttpClient(new WebRequestHandler
{
    CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Default),
    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
});

using (Task<HttpResponseMessage> tget = _httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, _cancel))
{
    tget.Wait();
    response = tget.Result;
}

用于我的应用程序 GET 的 HTTP header:

GET https://beautykiosktest.coinstar.com/conductor/configuration/files/Promos.xml?kioskid=ENG20130027 HTTP/1.1
Accept: */*
Accept-Language: en-US
User-Agent: ConfigurationService/2.3.0.0
Host: beautykiosktest.coinstar.com
Accept-Encoding: gzip, deflate

HTTP/1.1 200 OK
Cache-Control: max-age=30
Transfer-Encoding: chunked
Content-Type: application/xml; charset=utf-8
Content-Encoding: gzip
ETag: "cHmrX5Fp2Z+ETV/qIXiS2A=="
Vary: Accept-Encoding
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 17 Mar 2015 00:39:18 GMT

IE 的 GET 响应为 304 是我所期望的

GET https://beautykiosktest.coinstar.com/conductor/configuration/files/Promos.xml?kioskid=ENG20130027 HTTP/1.1
Accept: image/jpeg, image/gif, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; InfoPath.3; .NET4.0C; .NET4.0E; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.1.4322)
Accept-Encoding: gzip, deflate
Host: beautykiosktest.coinstar.com
If-None-Match: "cHmrX5Fp2Z+ETV/qIXiS2A=="
DNT: 1
Connection: Keep-Alive

HTTP/1.1 304 Not Modified
Cache-Control: max-age=30
ETag: "cHmrX5Fp2Z+ETV/qIXiS2A=="
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 17 Mar 2015 00:42:13 GMT

我最终向 Microsoft 提交了一张票来解决这个问题,并发现 .NET 4 中存在一个错误导致了这个问题。问题在于,从具有 Vary header 的响应中填充的缓存条目在下一个 GET 中无法正确匹配,因为即使设置了 AutomaticDecompression 属性,.NET 也没有添加 Accept-Encoding header 在进行 WinINET 缓存测试之前进入请求。

workaround/fix是在使用HttpClient实例前添加一个"Accept-Encoding"默认header

_httpClient.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");