System.Net.Http.HttpClient 缓存行为
我正在使用 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修改的。这是正确的。
但是,如果我使用具有相同 CachePolicy 的低级 HttpWebRequest 类,则甚至不会第二次发出请求。这就是我希望 HttpClient 也有行为方式的方式。
它是必须重新验证标头值还是为什么 HttpClient 的行为不同?我只想执行一个请求,然后从缓存中获取其余请求,而无需条件请求。
(此外,作为旁注,在调试时,响应状态代码显示为 200 OK,即使服务返回 304 Not修改的)
I'm using HttpClient 0.6.0 from NuGet.
I have the following C# code:
var client = new HttpClient(new WebRequestHandler() {
CachePolicy =
new HttpRequestCachePolicy(HttpRequestCacheLevel.CacheIfAvailable)
});
client.GetAsync("http://myservice/asdf");
The service (this time CouchDB) returns an ETag value and status code 200 OK. There is returned a Cache-Control header with value must-revalidate
Update, here are the response headers from couchdb (taken from the visual studio debugger):
Server: CouchDB/1.1.1 (Erlang OTP/R14B04)
Etag: "1-27964df653cea4316d0acbab10fd9c04"
Date: Fri, 09 Dec 2011 11:56:07 GMT
Cache-Control: must-revalidate
Next time I do the exact same request, HttpClient does a conditional request and gets back 304 Not Modified. Which is right.
However, if I am using low-level HttpWebRequest class with the same CachePolicy, the request isn't even made the second time. This is the way I would want HttpClient also behave.
Is it the must-revalidate header value or why is HttpClient behaving differently? I would like to do only one request and then have the rest from cache without the conditional request..
(Also, as a side-note, when debugging, the Response status code is shown as 200 OK, even though the service returns 304 Not Modified)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
两个客户端的行为都正确。
必须重新验证
仅适用于过时 回复。由于您没有提供明确的到期时间,允许缓存使用启发式方法来确定新鲜度。
由于您不提供
Last-Modified
缓存不需要警告客户使用了启发式方法。响应年龄是根据
Date
标头计算的因为Age
不存在。如果根据启发式过期响应仍然是新鲜的,则缓存可以使用存储的响应。
一种解释是
HttpWebRequest
使用启发式方法,并且存储了状态代码为 200 的响应,该响应仍然是最新的。Both clients behave correctly.
must-revalidate
only applies to stale responses.Since you do not provide explicit expiration, caches are allowed to use heuristics to determine freshness.
Since you do not provide
Last-Modified
caches do not need to warn the client that heuristics was used.The response age is calculated based on
Date
header sinceAge
is not present.If the response is still fresh according to heuristic expiration, caches may use the stored response.
One explanation is that
HttpWebRequest
uses heuristics and that there was a stored response with status code 200 that was still fresh.回答我自己的问题..
根据 http://www.w3 .org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 我想说的是
没有过期的“Cache-Control:must-revalidate”表示应该对每个请求验证资源。
在这种情况下,这意味着每次创建资源时都应该执行有条件的 GET。因此,在这种情况下,System.Net.Http.HttpClient 的行为正确,而旧版 (Http)WebRequest 的行为无效。
Answering my own question..
According to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 I would say that
a "Cache-Control: must-revalidate" without expiration states that the resource should be validated on every request.
In this case it means a conditional GET should be done every time the resource is made. So in this case System.Net.Http.HttpClient is behaving correctly and the legacy (Http)WebRequest is doing invalid behavior.