web-dev-qa-db-ja.com

System.Net.Http.HttpClientのキャッシュ動作

NuGetのHttpClient0.6.0を使用しています。

私は次のC#コードを持っています:

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

サービス(今回はCouchDB)は、ETag値とステータスコード200OKを返します。値がmust-revalidateの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 NotModifiedを返します。どちらが正しいですか。

ただし、同じCachePolicyで低レベルのHttpWebRequestクラスを使用している場合、リクエストは2回目も行われません。これは、HttpClientも動作させたい方法です。

検証が必要なヘッダー値ですか、それともHttpClientの動作が異なるのはなぜですか?リクエストを1つだけ実行し、残りを条件付きリクエストなしでキャッシュから取得したいと思います。

(また、補足として、デバッグ時に、サービスが304 Not Modifiedを返しても、応答ステータスコードは200 OKとして表示されます)

17
NiklasN

両方のクライアントが正しく動作します。

must-revalidatestale response にのみ適用されます。

キャッシュによって受信された応答にmust-revalidateディレクティブが存在する場合、そのキャッシュはエントリを使用してはなりません古くなった後最初にOriginサーバーで再検証せずに後続の要求に応答します。 (つまり、キャッシュは、オリジンサーバーのExpiresまたはmax-age値のみに基づいて、毎回エンドツーエンドの再検証を実行する必要がありますifキャッシュされた応答は古くなっています =。)

明示的な有効期限を指定しないため、 キャッシュはヒューリスティックを使用して鮮度を判断できます

Last-Modifiedキャッシュを提供しないため ヒューリスティックが使用されたことをクライアントに警告する必要はありません。

Expires、Cache-Control:max-age、またはCache-Control:s- maxage(セクション14.9.3を参照)のいずれも応答に表示されず、応答にキャッシュに関する他の制限が含まれていない場合、the cacheヒューリスティックを使用して鮮度の寿命を計算できます。キャッシュは、すべての応答に警告113を添付する必要があります年齢が24時間を超えるそのような警告がまだ追加されていない場合。

応答 年齢はDateヘッダーに基づいて計算されますAgeが存在しないため。

ヒューリスティックな有効期限に従って応答がまだ新鮮な場合、キャッシュは保存された応答を使用する場合があります。

1つの説明は、HttpWebRequestがヒューリスティックを使用し、ステータスコード200の保存された応答がまだ新鮮であったことです。

25
Hans Malherbe