System.Net.Http.HttpClient 缓存行为

发布于 2024-12-20 09:49:46 字数 877 浏览 2 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

阿楠 2024-12-27 09:49:46

两个客户端的行为都正确。

必须重新验证仅适用于过时 回复

当缓存收到的响应中存在必须重新验证指令时,该缓存不得使用该条目在它变得陈旧后响应
后续请求无需先与源服务器重新验证。 (即,缓存必须每次都进行端到端重新验证,如果仅基于源服务器的 Expires 或 max-age 值,缓存的响应已过时 >.)

由于您没有提供明确的到期时间,允许缓存使用启发式方法来确定新鲜度

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

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

响应年龄是根据Date标头计算的因为 Age 不存在。

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

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

Both clients behave correctly.

must-revalidate only applies to stale responses.

When the must-revalidate directive is present in a response received by a cache, that cache MUST NOT use the entry after it becomes stale to respond to a
subsequent request without first revalidating it with the origin server. (I.e., the cache MUST do an end-to-end revalidation every time, if, based solely on the origin server's Expires or max-age value, the cached response is stale.)

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.

If none of Expires, Cache-Control: max-age, or Cache-Control: s- maxage (see section 14.9.3) appears in the response, and the response does not include other restrictions on caching, the cache MAY compute a freshness lifetime using a heuristic. The cache MUST attach Warning 113 to any response whose age is more than 24 hours if such warning has not already been added.

The response age is calculated based on Date header since Age 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.

半夏半凉 2024-12-27 09:49:46

回答我自己的问题..

根据 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文