httpclient缓存行为

本文关键字:缓存 httpclient | 更新日期: 2023-09-27 18:17:25

我使用的是NuGet的HttpClient 0.6.0 .

我有以下c#代码:

var client = new HttpClient(new WebRequestHandler() {
    CachePolicy =
        new HttpRequestCachePolicy(HttpRequestCacheLevel.CacheIfAvailable)
});
client.GetAsync("http://myservice/asdf");

服务(这次是CouchDB)返回ETag值和状态码200 OK。返回一个Cache-Control头,值必须重新验证

更新,这里是couchdb的响应头(取自visual studio调试器):

Server: CouchDB/1.1.1 (Erlang OTP/R14B04)
Etag: "1-27964df653cea4316d0acbab10fd9c04"
Date: Fri, 09 Dec 2011 11:56:07 GMT
Cache-Control: must-revalidate

下次我做完全相同的请求,HttpClient做一个条件请求,并得到304未修改。

然而,如果我使用低级HttpWebRequest类与相同的CachePolicy,请求甚至不做第二次。这是我希望HttpClient也表现的方式。

是必须重新验证头值或为什么HttpClient行为不同?我想只做一个请求,然后从缓存中没有条件请求的其余部分。

(另外,作为旁注,在调试时,响应状态码显示为200 OK,即使服务返回304 Not Modified)

httpclient缓存行为

两个客户端行为正确。

must-revalidate仅适用于过期响应。

当必须重新验证指令存在于缓存接收到的响应中时,缓存绝对不能在条目过期后使用来响应a后续请求,而不首先与源服务器重新验证它。(例如,缓存必须每次都进行端到端重新验证,如果仅基于源服务器的Expires或max-age值,则缓存的响应是过期的)

由于您没有提供显式过期,因此允许缓存使用启发式方法来确定新鲜度。

由于您不提供Last-Modified缓存,因此不需要警告客户端使用了启发式。

如果响应中没有Expires, cache - control: max-age或cache - control: s- maxage(参见14.9.3节),并且响应中不包含其他缓存限制,缓存可能会使用启发式计算新鲜度生命周期。缓存必须在超过24小时的响应上附加警告113,如果该警告尚未添加的话。

响应时间根据Date报头计算,因为Age不存在。

如果响应根据启发式过期仍然是新鲜的,缓存可以使用存储的响应。

一种解释是HttpWebRequest使用启发式,并且有一个状态码为200的存储响应仍然是新鲜的。

回答我自己的问题…

根据http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4,我会这么说a "Cache-Control: must-revalidate" without expiration表示每个请求都要验证资源。

在这种情况下,它意味着每次创建资源时都应该执行一个条件GET。所以在这种情况下System.Net.Http.HttpClient行为正确,而遗留的(Http)WebRequest正在做无效的行为。