[2] [[キャッシュ]]に[[蓄積]]されるデータの単位を[DFN[[RUBYB[[[キャッシュ項目]]]@en[cache entry]]]]といいます。

* 仕様書

[REFS[
- [1] '''[CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-2>'''
- [125] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-3.1>
- [23] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-4>
-- [36] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-4.2.4>
-- [106] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-4.3.2>
-- [107] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-4.3.3>
- [93] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.2>
-- [54] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.2.1.1>
-- [50] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.2.1.2>
-- [53] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.2.1.3>
-- [71] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.2.1.4>
-- [38] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.2.1.7>
-- [101] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.2.2.1>
-- [73] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.2.2.2>
-- [104] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.2.2.7>
-- [95] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.2.2.9>
- [39] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.4>
- [96] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.5>
-- [46] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.5.1>
-- [43] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.5.2>
-- [49] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.5.3>
- [136] [CITE@en[RFC 7230 - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing]] ([TIME[2014-09-11 10:00:03 +09:00]] 版) <https://tools.ietf.org/html/rfc7230#section-2.6>
- [139] [CITE@en[RFC 7230 - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing]] ([TIME[2014-09-11 10:00:03 +09:00]] 版) <https://tools.ietf.org/html/rfc7230#section-3.2.4>
- [85] [CITE@en[RFC 7230 - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing]] ([TIME[2014-09-11 10:00:03 +09:00]] 版) <https://tools.ietf.org/html/rfc7230#section-5.7.2>
- [121] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-09-11 09:52:09 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-6.6.3>
- [131] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-09-11 09:52:09 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-7.1.1.2>
- [127] [CITE@en[RFC 7232 - Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests]] ([TIME[2014-09-11 10:02:44 +09:00]] 版) <https://tools.ietf.org/html/rfc7232#section-2.3>
- [163] [CITE@en[RFC 7232 - Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests]] ([TIME[2014-09-11 10:02:44 +09:00]] 版) <https://tools.ietf.org/html/rfc7232#section-4.1>
- [166] [CITE@en[RFC 5861 - HTTP Cache-Control Extensions for Stale Content]] ([TIME[2014-09-10 03:23:24 +09:00]] 版) <http://tools.ietf.org/html/rfc5861#section-3>
- [168] [CITE@en[RFC 5861 - HTTP Cache-Control Extensions for Stale Content]] ([TIME[2014-09-10 03:23:24 +09:00]] 版) <http://tools.ietf.org/html/rfc5861#section-4>
- [177] [CITE@en[RFC 3229 - Delta encoding in HTTP]] ([TIME[2014-10-26 21:15:25 +09:00]] 版) <http://tools.ietf.org/html/rfc3229#section-10.6>
]REFS]

* 構成

[3] [[キャッシュ項目]]は、[RUBYB[キャッシュキー]@en[cache key]]と、
1つ以上の [[HTTP応答]]との組です [SRC[>>1]]。この[[応答]]のことを[RUBYB[[[蓄積]]された[[応答]]]@en[stored response]]といいます。

;; [9] [[蓄積された応答]]には[[腐敗]]したものと[[新鮮]]なものがあり、また[[満期時刻]]や[[齢]]のような特性もあります。

[6] [[キャッシュ項目]]には、[[完全]]なものと[[不完全]]なものがあります。

;; [7] [[不完全]]かどうかは[[メッセージ]]の性質なので、正確には[[キャッシュ項目]]ではなく[[キャッシュ項目]]に含まれる[[応答]]それぞれの性質だと思うのですが、
仕様上[[キャッシュ項目]]の性質となっています。

[172] [CODE(HTTP)@en[[[Meter]]]] を実装する[[串]]の場合、
[[蓄積された応答]]について計測数に関するいくつかの値を保持する必要があります。

;; [CODE(HTTP)@en[[[Meter]]]] 参照。

[4] キャッシュキーは[[要求メソッド]]と[[対象URL]]です。
しかし一般的な[[HTTPキャッシュ]]は [CODE(HTTP)@en[[[GET]]]] に対する[[応答]]しか[[キャッシュ]]しないので、
その場合は[[対象URL]]だけをキャッシュキーとすることができます。 [SRC[>>1]]

[5] [[対象資源]]で[[内容折衝]]が使われている場合には、
複数の[[HTTP応答]]が蓄積されることになります。 [SRC[>>1]]

[176] [[蓄積された応答]]を利用できるかどうかの判定には、[[蓄積された応答]]のもととなった[[要求]]の情報の一部が必要になります。
[FIG(short list)[
- [[要求メソッド]]
- [[対象資源]]
- [[蓄積された応答]]の [CODE(HTTP)@en[[[Vary:]]]] [[ヘッダー]]で指定された[[要求]]の[[ヘッダー]]
- [CODE(HTTP)@en[[[If-None-Match:]]]] ([CODE(HTTP)[[[226]]]] 参照。)
]FIG]

[184] [CODE[/.well-known/http-opportunistic]] を使う場合、
[[代替サービス]]の認証済み接続で得たものか否かのフラグを保持する必要があります。

* 処理

[8] [[キャッシュ可能性]]、[[検証]]、[[条件付き要求]]、[[部分要求]]も参照。

[10] [[キャッシュ]]からの[[応答]]の決定は、次のように行います。

[FIG(steps)[
= [12] エラーその他の[[応答]]を返す場合、
[[HTTP認証]]によりエラーを返す場合などは、
そちらの方法で処理し、ここで終わります。
= [32] 使う応答を「上流の応答」とします。
= [24] [[キャッシュ項目]]として[[蓄積された応答]]から[[実効要求URL]]が一致するものがあれば [SRC[>>23]]、
== [25] [CODE(HTTP)@en[[[Vary:]]]] [[ヘッダー]]の条件が一致するもの
([CODE(HTTP)@en[[[Vary:]]]] 参照。) のみに限定します [SRC[>>23]]。
== [26] [[蓄積された応答]]の[[要求メソッド]]が現在の[[要求]]の[[要求メソッド]]に再利用できるものに限定します [SRC[>>23]]。
== [126] 現在の[[要求]]が求めている[[範囲]]をカバーできない[[不完全な応答]]や
[CODE(HTTP)[[[206]]]] [[応答]] [SRC[>>125]]、 [CODE(HTTP)[[[266]]]]
[[応答]] [SRC[>>177]] は除外します。
== [178] [CODE(HTTP)[[[266]]]] [[応答]]の場合、その再利用の制限を満たさないものは除外します
[SRC[>>177]]。
== [27] 候補が複数ある場合は、次のいずれかとします [SRC[>>23]]。
==- [29] [CODE(HTTP)@en[[[Date:]]]] が最新のものを選びます。
==- [28] 使う応答を「無キャッシュの上流の応答」とします。
== [30] ここで、候補が1つの場合は、
=== [89] 候補の複製を応答とします。
=== [90] 使う応答を「キャッシュ応答」とします。
= [31] 使う応答が「キャッシュ応答」の場合、
== [69] [[時計]]がない場合、[[検証]]必要フラグを設定します [SRC[>>23]]。
== [13] それ以外の場合、
=== [19] [[齢]]を計算し、その結果を[[応答]]に [CODE(HTTP)@en[[[Age:]]]]
[[ヘッダー]]として追加 (既にあれば置換) します ([[齢]]参照)。
=== [14] [[明示的満期時刻]]がある場合、これを使って[[新鮮寿命]]を決定します。
=== [15] そうでない場合、
==== [16] [[発見的満期時刻]]を使って[[新鮮寿命]]を決定します。
==== [17] [[新鮮寿命]]が24時間を超えていて、[[応答]]に[[警告符号]] [CODE(HTTP)[[[113]]]] の
[CODE(HTTP)@en[[[Warning:]]]] [[ヘッダー]]がなければ、追加します
([[新鮮寿命]]参照)。
=== [20] 次のいずれかを満たす場合には、[[検証]]必要フラグを設定します。
===- [60] [[齢]]が[[新鮮寿命]][[以上]]の場合。
===- [61] [[要求]]に [CODE(HTTP)@en[[[Cache-Control:]] [[max-age]]]] が指定されていれば、
その[[秒]]数より[[齢]]が大きい場合 [SRC[>>54]]。
===- [62] [[要求]]に [CODE(HTTP)@en[[[Cache-Control:]] [[min-fresh]]]] が指定されていれば、
その[[秒]]数と[[齢]]の[[和]]の方が[[新鮮寿命]]より大きい場合 [SRC[>>53]]。
===- [72] [[要求]]に [CODE(HTTP)@en[[[Cache-Control:]] [[no-cache]]]] がある場合 [SRC[>>71]]。
===- [78] [[要求]]に [CODE(HTTP)@en[[[Cache-Control:]]]] [[ヘッダー]]がなく、
[CODE(HTTP)@en[[[Pragma:]] [[no-cache]]]] がある場合 [SRC[>>71, >>39]]。
===- [74] [[応答]]に [CODE(HTTP)@en[[[Cache-Control:]] [[no-cache]]]] がある場合で、
[[ヘッダー名]]が指定されていない場合 [SRC[>>73]]。
===- [63] [[応答]]に [CODE(HTTP)@en[[[Cache-Control:]] [[must-revalidate]]]] 
がある場合 [SRC[>>101]]。
===- [80] [[応答]]に [CODE(HTTP)@en[[[Pragma:]] [[no-cache]]]]
がある場合 ([CODE(HTTP)@en[[[no-cache]]]] 参照)。
===- [64] [[共有キャッシュ]]であって、[[応答]]に
[CODE(HTTP)@en[[[Cache-Control:]] [[proxy-revalidate]]]] がある場合 [SRC[>>104, >>101]]。
===- [175] [[共有キャッシュ]]であって、[[応答]]の [VAR[MU]] や [VAR[MR]]
の制限に抵触する場合 ([CODE(HTTP)@en[[[Meter]]]] 参照)
= [47] [[検証]]必要フラグが設定されている場合、
== [97] [[要求]]に [CODE(HTTP)@en[[[Cache-Control:]] [[only-if-cached]]]]
があれば、使う応答を「エラー応答」とします [SRC[>>93, >>38]]。
== [91] それ以外の場合、
=== [108] [[要求]]の複製を転送要求とします。
=== [142] [[要求]]の[[プロトコルの版]]を自身が対応する最高の版に書き換えます [SRC[>>136]]。
版の変更による書き換えが必要なら、適宜行います。
=== [145] [[ヘッダー名]]と [CODE(HTTP)[[[:]]]] の間に[[空白]]があれば、除去します
[SRC[>>139]]。
=== [146] [CODE(ABNF)@en[[[obs-fold]]]] があれば置換します [SRC[>>139]]。
=== [160] [CODE(HTTP)@en[[[Transfer-Encoding:]]]], [CODE(HTTP)@en[[[Content-Length:]]]],
[CODE(HTTP)@en[[[Connection:]]]], [CODE(HTTP)@en[[[Via:]]]], [CODE(HTTP)@en[[[X-Forwarded-*:]]]], [CODE(HTTP)@en[[[Forwarded:]]]], [CODE(HTTP)@en[[[Host:]]]],
[CODE(HTTP)@en[[[Proxy-Authorization:]]]], [CODE(HTTP)@en[[[TE:]]]], [CODE(HTTP)@en[[[Max-Forwards:]]]], [CODE(HTTP)@en[[[Meter:]]]], [[RFC 2774]]
各[[ヘッダー]]や[[要求対象]]の[[ホスト]]部分に関する書き換えを適宜行います (それぞれの項を参照)。
=== [128] [[応答]]に [CODE(HTTP)@en[[[ETag:]]]] が含まれていれば、
[CODE(HTTP)@en[[[If-None-Match:]]]] か [CODE(HTTP)@en[[[If-Match:]]]]
にその[[実体タグ]]を指定します [SRC[>>127]]。
===- [114] このとき、[[要求]]に既に [CODE(HTTP)@en[[[If-None-Match:]]]]
が指定されているなら、[[要求]]が求めている[[範囲]]が[[応答]]に含まれている場合のみ、
[[応答]]の[[実体タグ]]を [CODE(HTTP)@en[[[If-None-Match:]]]]
に付け加えて構いません [SRC[>>106]]。
=== [109] [[応答]]に [CODE(HTTP)@en[[[Last-Modified:]]]] が含まれていれば、
==== [130] [[範囲要求]]で[[応答]]が [[HTTP/1.0]] なら、 
[CODE(HTTP)@en[[[If-Unmodified-Since:]]]]
に [CODE(HTTP)@en[[[Last-Modified:]]]] の値を設定します [SRC[>>106]]。
==== [129] それ以外なら、 [CODE(HTTP)@en[[[If-Modified-Since:]]]]
に [CODE(HTTP)@en[[[Last-Modified:]]]] の値を設定します [SRC[>>106]]。
=== [115] 転送要求を[[上流]]に[[転送]]します。
=== [167] [[応答]]に [CODE(HTTP)@en[[[Cache-Control:]] [[stale-while-revalidate]]]]
があってその[[秒]]数と[[新鮮寿命]]の[[和]]より[[齢]]が大きくないなら、
[[上流]]からの[[応答]]がなかったものとして先に進むと共に、
[[並列]]に[[上流]]からの最終的な[[応答]]を待ち、受信した時の処理(のみ)を行います [SRC[>>166]]。
=== [98] [[上流]]からの最終的な[[応答]]を受信したら、
==== [122] 不正な[[応答]]なら、[[応答]]を得られなかったとします。
==== [116] [CODE(HTTP)[[[304]]]] [[応答]]なら、
===== [164] [[蓄積された応答]]を更新します [SRC[>>106]] ([[条件付き要求]]参照)。
===== [165] 元の[[要求]]が[[条件付き要求]]だった場合を除き [SRC[>>163]]、
更新結果を上流からの[[応答]]とします [SRC[>>106, >>107]]。
==== [117] [CODE(HTTP)[[[5xx]]]] [[応答]]なら、[[応答]]を得られなかったとして構いません
[SRC[>>107]]。
=== [118] [[上流]]からの[[応答]]がある場合、
==== [132] [[時計]]があり、[[上流]]からの[[応答]]に [CODE(HTTP)@en[[[Date:]]]] がないなら、
[CODE(HTTP)@en[[[Date:]]]] [[ヘッダー]]を追加します [SRC[>>131]]。
==== [119] [[上流]]からの[[応答]]が[[キャッシュ可能]]で[[要求]]によって禁止されていないなら、
[[蓄積された応答]]を[[上流]]からの[[応答]]により置換して構いません [SRC[>>107]]。
==== [120] [[上流]]からの[[応答]]を[[応答]]とします [SRC[>>107]]。
==== [100] 使う応答を「検証済み応答」に設定します。
==== [105] [[応答]]に[[警告符号]]が [CODE(HTTP)[[[1xx]]]] の [CODE(HTTP)@en[[[Warning:]]]]
[[ヘッダー]]があれば、削除します [SRC[>>96]]。
=== [21] それ以外の場合、
==== [58] 次のいずれかを満たす場合には、使う応答を「エラー応答」に設定します。
====- [102] [[応答]]に
[CODE(HTTP)@en[[[Cache-Control:]] [[must-revalidate]]]] がある場合 [SRC[>>101]]。
====- [103] [[共有キャッシュ]]であって、[[応答]]に
[CODE(HTTP)@en[[[Cache-Control:]] [[proxy-revalidate]]]] がある場合 [SRC[>>104, >>101]]。
====- [22] [[共有キャッシュ]]であって、[[応答]]に [CODE(HTTP)@en[[[Cache-Control:]] [[s-maxage]]]] 
がある場合 [SRC[>>95]]。
====- [83] [[要求]]に [CODE(HTTP)@en[[[Cache-Control:]] [[no-cache]]]] がある場合 [SRC[>>23]]。
====- [84] [[要求]]に [CODE(HTTP)@en[[[Cache-Control:]]]] [[ヘッダー]]がなく、
[CODE(HTTP)@en[[[Pragma:]] [[no-cache]]]] がある場合 [SRC[>>23, >>39]]。
====- [75] [[応答]]に [CODE(HTTP)@en[[[Cache-Control:]] [[no-cache]]]] 
がある場合 [SRC[>>73, >>23]]。
====- [81] [[応答]]に [CODE(HTTP)@en[[[Pragma:]] [[no-cache]]]]
がある場合 ([CODE(HTTP)@en[[[no-cache]]]] 参照)。
====- [82] [[要求]]に [CODE(HTTP)@en[[[Cache-Control:]] [[no-store]]]] がある場合 [SRC[>>23]]。
====- [174] [[共有キャッシュ]]であって、[[応答]]の [VAR[MU]] や [VAR[MR]]
の制限に抵触する場合 ([CODE(HTTP)@en[[[Meter]]]] 参照)
==== [40] それ以外で、[[要求]]に [CODE(HTTP)@en[[[Cache-Control:]] [[max-stale]]]]
が指定されている場合、
===== [42] 値が指定されている場合、[[齢]]と[[新鮮寿命]]の[[差]]が指定された値[[以下]]なら、
使う応答を「腐敗応答」に設定します [SRC[>>50]]。
それ以外なら、使う応答を「エラー応答」に設定します。
===== [44] 値が指定されていない場合、使う応答を「腐敗応答」に設定します [SRC[>>50]]。
==== [41] そうでない場合、
===== [55] [[要求]]に [CODE(HTTP)@en[[[Cache-Control:]] [[max-age]]]] が指定されていない場合
[SRC[>>54]]、
====== [169] 使う応答を「腐敗応答」に設定します。
===== [170] それ以外なら、
====== [171] [[要求]]または[[応答]]またはその両方に
[CODE(HTTP)@en[[[Cache-Control:]] [[state-if-error]]]] があり、
いずれもその[[秒]]数と[[新鮮寿命]]の[[和]]より[[齢]]が大きくないなら、
使う応答を「腐敗応答」に設定します [SRC[>>168]]。
====== [173] それ以外なら、使う応答を「エラー応答」に設定します。
===== [51] それ以外の場合、使う応答を「腐敗応答」に設定します。
= [67] 使う応答が「上流の応答」または「無キャッシュ上流の応答」の場合、
== [92] [[要求]]に [CODE(HTTP)@en[[[Cache-Control:]] [[only-if-cached]]]]
があれば、使う応答を「エラー応答」とします [SRC[>>93, >>38]]。
== [94] それ以外の場合、
=== [68] 転送要求を要求の複製とします。
=== [147] [[要求]]の[[プロトコルの版]]を自身が対応する最高の版に書き換えます [SRC[>>136]]。
版の変更による書き換えが必要なら、適宜行います。
=== [148] [[ヘッダー名]]と [CODE(HTTP)[[[:]]]] の間に[[空白]]があれば、除去します
[SRC[>>139]]。
=== [149] [CODE(ABNF)@en[[[obs-fold]]]] があれば置換します [SRC[>>139]]。
=== [150] [CODE(HTTP)@en[[[Transfer-Encoding:]]]], [CODE(HTTP)@en[[[Content-Length:]]]],
[CODE(HTTP)@en[[[Connection:]]]], [CODE(HTTP)@en[[[Via:]]]], [CODE(HTTP)@en[[[Host:]]]],
[CODE(HTTP)@en[[[Proxy-Authorization:]]]], [CODE(HTTP)@en[[[TE:]]]], [CODE(HTTP)@en[[[Max-Forwards:]]]], [CODE(HTTP)@en[[[X-Forwarded-*:]]]], [CODE(HTTP)@en[[[Forwarded:]]]], [CODE(HTTP)@en[[[Meter:]]]], [[RFC 2774]]
各[[ヘッダー]]や[[要求対象]]の[[ホスト]]部分に関する書き換えを適宜行います (それぞれの項を参照)。
=== [88] 使う応答が「無キャッシュ上流の応答」なら、転送要求に 
[CODE(HTTP)@en[[[Cache-Control:]] [[max-age]]=0]]
または [CODE(HTTP)@en[[[Cache-Control:]] [[no-cache]]]] を追加します [SRC[>>23]]。
=== [65] 転送要求を[[要求]]として[[上流]]に送信します。
=== [153] [CODE(HTTP)[[[1xx]]]] [[応答]]を受信したら、それぞれについて、
==== [154] 不正な[[応答]]の場合、使う応答を「エラー応答」に設定します。
==== [155] それ以外の場合、
===== [156] [[時計]]があり、[[上流]]からの[[応答]]に [CODE(HTTP)@en[[[Date:]]]] がないなら、
[CODE(HTTP)@en[[[Date:]]]] [[ヘッダー]]を追加します [SRC[>>131]]。
===== [157] [[要求]]の[[プロトコルの版]]を自身が対応する最高の版に書き換えます [SRC[>>136]]。
版の変更による書き換えが必要なら、適宜行います。
===== [158] [[ヘッダー名]]と [CODE(HTTP)[[[:]]]] の間に[[空白]]があれば、除去します
[SRC[>>139]]。
===== [159] [CODE(ABNF)@en[[[obs-fold]]]] があれば置換します [SRC[>>139]]。
===== [161] [CODE(HTTP)@en[[[Transfer-Encoding:]]]], [CODE(HTTP)@en[[[Content-Length:]]]],
[CODE(HTTP)@en[[[Connection:]]]], [CODE(HTTP)@en[[[Via:]]]], [CODE(HTTP)@en[[[Meter:]]]], [[RFC 2774]]
各[[ヘッダー]]に関する書き換えを適宜行います (それぞれの項を参照)。
===== [162] [[下流]]に送信します。
=== [66] [[上流]]からの最終的な応答を受信したら、
==== [123] 不正な[[応答]]の場合、使う応答を「エラー応答」に設定します。
==== [124] それ以外の場合、
===== [135] [[時計]]があり、[[上流]]からの[[応答]]に [CODE(HTTP)@en[[[Date:]]]] がないなら、
[CODE(HTTP)@en[[[Date:]]]] [[ヘッダー]]を追加します [SRC[>>131]]。
===== [134] [[上流]]からの[[応答]]が[[キャッシュ可能]]で[[要求]]によって禁止されていないなら、
[[蓄積された応答]]を更新したり、新規に[[蓄積]]したりして構いません。
===== [133] [[上流]]からの応答を[[応答]]に設定します。
=== [33] 受信できなかった場合は、使う応答を「エラー応答」に設定します。
= [34] 使う応答が「上流の応答」か「検証済み応答」の場合、
== [137] [[応答]]の[[プロトコルの版]]を、[[要求]]と自身が対応する最高の版に書き換えます
[SRC[>>136]]。
版の変更による書き換えが必要なら、適宜行います。
== [140] [[ヘッダー名]]と [CODE(HTTP)[[[:]]]] の間に[[空白]]があれば、除去します
[SRC[>>139]]。
== [143] [CODE(ABNF)@en[[[obs-fold]]]] があれば置換します [SRC[>>139]]。
== [151] [CODE(HTTP)@en[[[Transfer-Encoding:]]]], [CODE(HTTP)@en[[[Content-Length:]]]],
[CODE(HTTP)@en[[[Connection:]]]], [CODE(HTTP)@en[[[Via:]]]], [CODE(HTTP)@en[[[Meter:]]]], [[RFC 2774]]
各[[ヘッダー]]に関する書き換えを適宜行います (それぞれの項を参照)。
= [79] 使う応答が「キャッシュ応答」または「腐敗応答」の場合、
== [138] [[応答]]の[[プロトコルの版]]を、[[要求]]と自身が対応する最高の版に書き換えます
[SRC[>>136]]。
版の変更による書き換えが必要なら、適宜行います。
== [141] [[ヘッダー名]]と [CODE(HTTP)[[[:]]]] の間に[[空白]]があれば、除去します
[SRC[>>139]]。
== [144] [CODE(ABNF)@en[[[obs-fold]]]] があれば置換します [SRC[>>139]]。
== [152] [CODE(HTTP)@en[[[Transfer-Encoding:]]]], [CODE(HTTP)@en[[[Content-Length:]]]],
[CODE(HTTP)@en[[[Connection:]]]], [CODE(HTTP)@en[[[Via:]]]], [CODE(HTTP)@en[[[Meter:]]]], [[RFC 2774]]
各[[ヘッダー]]に関する書き換えを適宜行います (それぞれの項を参照)。
== [76] [[応答]]に [CODE(HTTP)@en[[[Cache-Control:]] [[no-cache]]]] があって、
[[ヘッダー名]]が指定されている場合、
=== [77] [[応答]]から指定されている[[ヘッダー]]をすべて削除します [SRC[>>73]]。
== [56] 使う応答が「腐敗応答」の場合、
=== [45] [[応答]]に[[警告符号]] [CODE(HTTP)[[[110]]]] の 
[CODE(HTTP)@en[[[Warning:]]]] [[ヘッダー]]を追加します [SRC[>>46, >>36]]。
=== [52] 意図的に切断されていた場合には、
[[応答]]に[[警告符号]] [CODE(HTTP)[[[112]]]] の 
[CODE(HTTP)@en[[[Warning:]]]] [[ヘッダー]]を追加します [SRC[>>49, >>36]]。
=== [57] [[上流]]への接続に失敗した場合には、
[[応答]]に[[警告符号]] [CODE(HTTP)[[[111]]]] の 
[CODE(HTTP)@en[[[Warning:]]]] [[ヘッダー]]を追加します [SRC[>>43, >>36]]。
= [59] 使う応答が「エラー応答」の場合、
== [70] [[上流]]から不正な[[応答]]を受信して「エラー応答」に設定された場合、
新しい [CODE(HTTP)[[[502]]]] [[応答]]を[[応答]]とします [SRC[>>121]]。
== [18] それ以外の場合、新しい [CODE(HTTP)[[[504]]]] [[応答]]を[[応答]]とします [SRC[>>104, >>101]]。
= [37] [[要求]]または[[応答]]に [CODE(HTTP)@en[[[Cache-Control:]] [[no-transform]]]]
が含まれない場合で、[[変形]]を適用したい場合、
== [86] [[変形]]を適用します [SRC[>>85]]。
== [35] [[警告符号]] [CODE(HTTP)[[[214]]]] の [CODE(HTTP)@en[[[Warning:]]]]
[[ヘッダー]]を (なければ) 追加します [SRC[>>85]]。
== [87] [[状態符号]]が [CODE(HTTP)[[[200]]]] なら、 [CODE(HTTP)[[[203]]]]
に変更しても構いません [SRC[>>85]]。
= [99] エラーの[[応答]]や[[リダイレクト]]の[[応答]]の場合、
それを返してここで終わります。 [SRC[>>18]]
= [11] 使う応答が「キャッシュ応答」または「腐敗応答」なら、
[[要求]]に[[事前条件]]があれば適用します。真なら、あるいは事前条件がなければ、
[[応答]]を返します。詳しくは[[条件付き要求]]を参照。
]FIG]

;; [48] この[[アルゴリズム]]は [[HTTP]] [[仕様書]]に含まれる要件をできるだけ矛盾なく満たそうと試みたものです。
[[HTTP]] 仕様書には曖昧な記述や境界での動作が不明瞭なケース、
機能同士の相互作用が明確に規定されていないケースが多く、
細部においてこの[[アルゴリズム]]が正しいか (あるいは仕様上必ずしも要求されていないことまで求めていないか) 判断することは困難です。
また仕様上なぜか推奨や[[事実の文]]に留まっていて要件となっていない箇所などもあります。
詳しくは関連各項も参照してください。

* キャッシュの非妥当化

[187] [[非妥当化]]参照。

* キャッシュ項目の削除

[179] [[キャッシュ項目]]を削除するタイミングについて、仕様上は規定はありません。
[[腐敗]]した[[キャッシュ項目]]はただちに[[応答]]として再利用することはできなくなりますが、
[[再検証]]すれば再利用できますから、必ずしも削除しなくても構いません。

[180] [[キャッシュ]]は、[[ストレージ容量]]その他の都合で任意のタイミングで[[キャッシュ項目]]を削除できます。

[183] [[キャッシュ]]は、同じ[[対象資源]]や [CODE(HTTP)@en[[[Vary:]]]]
の新しい[[応答]]を[[蓄積]]するときに、前の[[キャッシュ項目]]を削除したり、置き換えたりできます。

[182] [[応答]]の [CODE(HTTP)@en[[[Cache-Control:]] [[retain]]]] [[キャッシュ指令]]での[[デルタ秒]]の指定は、
指定された[[秒]]数が経過した後[[キャッシュ項目]]を削除できます。

;; [CODE(HTTP)@en[[[retain]]]] は[[ヒント]]であり、それより前に削除しても構いませんし、
それより後まで削除しなくても構いません。

[181] [[キャッシュ項目]]全体、または[[キャッシュ項目]]に関連付けられた計測数を削除する場合には、
計測数を報告しなければならないことがあります。

;; [CODE(HTTP)@en[[[Meter]]]] 参照。