System.Net.Http.HttpClient缓存行为

时间:2011-12-09 12:53:29

标签: c# wcf couchdb wcf-web-api

我正在使用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 Not Modified。哪个是对的。

但是,如果我使用具有相同CachePolicy的低级HttpWebRequest类,则第二次甚至不会发出请求。这就是我希望HttpClient的行为方式。

它是必须重新验证的标头值还是为什么HttpClient表现不同?我想只做一个请求,然后在没有条件请求的情况下从缓存中获取其余的请求。

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

2 个答案:

答案 0 :(得分:24)

两个客户端都表现正常。

must-revalidate only applies to stale responses

  

当缓存接收到的响应中存在must-revalidate指令时,该缓存在变为陈旧之后不得使用条目来响应   后续请求,而不首先使用原始服务器重新验证它。 (即,缓存必须每次都进行端到端的重新验证, if ,仅基于源服务器的Expires或max-age值,缓存的响应是陈旧的。)

由于您未提供明确的到期日期,caches are allowed to use heuristics to determine freshness

由于您未提供Last-Modified缓存do not need to warn the client that heuristics was used.

  

如果响应中没有Expires,Cache-Control:max-age或Cache-Control:s-maxage(请参阅第14.9.3节),并且响应不包含其他缓存限制,缓存可以使用启发式计算新鲜度生命周期。如果尚未添加此类警告,缓存必须将警告113附加到年龄超过24小时的任何响应

Age以来的回复age is calculated based on Date header不存在。

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

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

答案 1 :(得分:-2)

回答我自己的问题..

根据http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4我会说 没有过期的“Cache-Control:must-revalidate”表示应该在每个请求上验证资源。

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