[20] [DFN[[CODE(HTTP)@en[[[retain]]]]]] は、[[差分符号化]]に対応した[[キャッシュ]]が当該[[応答]]を[[蓄積]]するべきことを表す[[キャッシュ指令]]です。
この[[キャッシュ指令]]は[[応答]]の [CODE(HTTP)@en[[[Cache-Control:]]]] [[ヘッダー]]で使うことができます。

* 仕様書

[REFS[
- [4] [CITE@en[RFC 3229 - Delta encoding in HTTP]] ([TIME[2014-10-26 21:15:25 +09:00]] 版) <http://tools.ietf.org/html/rfc3229#section-7>
-- [6] [CITE@en[RFC 3229 - Delta encoding in HTTP]] ([TIME[2014-10-26 21:15:25 +09:00]] 版) <http://tools.ietf.org/html/rfc3229#section-7.2>
- [2] '''[CITE@en[RFC 3229 - Delta encoding in HTTP]] ([TIME[2012-02-19 00:18:18 +09:00]] 版) <http://tools.ietf.org/html/rfc3229#section-10.8.1>'''
]REFS]

* 意味

[12] [CODE(HTTP)@en[[[retain]]]] は、[[差分符号化]]に対応した[[クライアント]]は本[[応答]]の[[実現値]]を[[キャッシュ]]に残す[RUBYB[べき]@en[ought to]]であること、
以後[[差分符号化]]された[[応答]]を[[要求]]したいときに本[[応答]]の[[実体タグ]]を
([[基底実現値]]の指定のために) 使う[RUBYB[べき]@en[ought to]]ことを示します [SRC[>>2]]。

[11] [CODE(HTTP)@en[[[retain]]]] は[[ヒント]]であり、[[受信者]]に特定の動作を強制するものではありません [SRC[>>2]]。

[5] [[鯖]]が[[実現値]]の更新後に差分を[[クライアント]]の送信するためには、
過去の[[実現値]]について何らかの情報を保持しておく必要があります。
必ずしも過去の[[実現値]]をすべて保存する必要はなく、[[差分]]だけ保持しておいたり、
[[LRU]] で間引いたり工夫することができます。 [SRC[>>4]]

[7] [[鯖]]が[[実現値]]の一部(のみ)を残しておく場合、
[[クライアント]]はどれを残すか知ることができればどれをいつまで[[キャッシュ]]に保存するか決める際に[[ヒント]]にできます。
[CODE(HTTP)@en[[[retain]]]] [[キャッシュ指令]]はそのためのものです。 [SRC[>>6]]

* 構文

[10] [CODE(HTTP)@en[[[retain]]]] [[キャッシュ指令]]は、名前のみ指定するか、
名前に対して[[デルタ秒]]を値として指定します [SRC[>>2]]。

[FIG(railroad)[
= [[デルタ秒]]
]FIG]

* 文脈

[8] [CODE(HTTP)@en[[[retain]]]] は通常の[[応答]]にも[[差分]]の[[応答]]にも含められます [SRC[>>6]]。

[18] 転送量削減のため、[[クライアント]]が[[差分符号化]]を求めた場合以外
[CODE(HTTP)@en[[[retain]]=0]] を送信する[RUBYB[べき]@en[ought]]ではありません。 [SRC[>>6, >>2]]

* デルタ秒

[13] 値として[[デルタ秒]]が指定されている場合、
その[[秒]]数が経過した後、[[鯖]]が当該[[実現値]]を[[差分符号化]]の[[基底実現値]]として利用しなくなるであろうことを表します。 [SRC[>>2]]

[15] [[デルタ秒]]は、[[応答]]の[[生成]]からの[[秒]]数を表します [SRC[>>2]]。

;; [16] [[応答]]が[[キャッシュ]]から返されている場合もあるので、
[[応答]]の[[齢]]を考慮する必要があります。

[14] [[クライアント]]は、指定された[[秒]]数の経過後は、当該[[応答]]の[[実体タグ]]を[[差分符号化]]の[[基底実現値]]として指定する[RUBYB[べき]@en[ought to]]ではありません。

[9] [[鯖]]は[[差分符号化]]に対応しているものの当該[[実現値]]については対応しない場合、
[CODE(HTTP)@en[[[retain]]=0]] によってこれを示すことができます。 [SRC[>>6]]

[17] [[クライアント]]は、値として0が指定された時は、
当該[[応答]]の[[実体タグ]]を[[差分符号化]]の[[基底実現値]]として指定する[['''べきではありません''']] [SRC[>>2]]。

* 歴史

[FIG(quote)[
[FIGCAPTION[
[1] RFC 3229 (差分符号化) 10.8.1 Retain directive
]FIGCAPTION]

> The set of cache-response-directive values is augmented to include
the retain directive.

[CODE(ABNF)[cache-response-directive]] (キャッシュ応答指令)
値の集合を改訂して、 [CODE(HTTP)[retain]] 指令を含めます。

>
- cache-response-directive = ... | "retain" [ "=" delta-seconds ]

> A retain directive is always a "hint" from a server to a client; it
never specifies a mandatory action for the recipient.

[CODE(HTTP)[retain]] 指令は常に鯖からクライアントへの「ヒント」です。
受信者に動作を強制することは決してありません。

> The presence of a retain directive indicates that a delta-capable
client ought to retain the instance in the response in its cache,
space permitting, and ought to use the corresponding entity tag in a
future request for a delta-encoded response.  I.e., the server is
likely to provide delta-encoded responses using the corresponding
instance as a base instance.  By implication, if a client has
retrieved and cached several instances of a resource, some of which
are marked with "retain" and some not, then there is no point in
caching the instances not marked with "retain".

[CODE(HTTP)[retain]] 指令の存在は、差分能力を有するクライアントがその応答中の実現値を空間が許せばキャッシュに残すべきであり、
差分符号化応答用の将来の要求で対応する[[実体札]]を使用するべきであることを示します。
すなわち、鯖は対応する実現値を[[基底実現値]]として使用した差分符号化応答を提供しようとしています。
暗示により、クライアントが[[資源]]の幾つかの実現値を取り出してキャッシュしていて、そのうちの幾つかは
[CODE(HTTP)[retain]] と印付けられていていくつかはそうでないなら、
キャッシュ付けにおいてその実現値が [CODE(HTTP)[retain]]
と印付けされていない点はありません。

> If the retain directive includes a delta-seconds value, then the
server is likely to stop using the corresponding instance as a base
instance after the specified number of seconds.  A client ought not
use the corresponding entity tag in a future request for a delta-encoded response after that interval ends.  The interval is measured
from the time that the response is generated, so a client ought to
include the response's Age in its calculations.

[CODE(HTTP)[retain]] 指令が [CODE(ABNF)[delta-seconds]] (差分秒)
値を含んでいるなら、鯖は指定された秒数の後に対応する実現値を基底実現値として使用するのを止めるつもりです。
クライアントはその時間が経過した後は差分符号化応答用の将来の要求で対応する実体札を使用するべきではありません。
時間は応答を得た時刻から計測しますから、
クライアントはその計算に応答の[[齢]]を含めるべきです。

> If the retain directive includes a delta-seconds value of zero, a
client SHOULD NOT use the corresponding entity tag in a future
request for a delta-encoded response.

[CODE(HTTP)[retain]] 指令が零の差分秒値を含んでいるなら、
クライアントは対応する実体札を将来の差分符号化応答用要求で使用する'''べきではありません'''。

> Note: We recommend that server implementors consider the bandwidth
implications of sending the "retain=0" directive to clients or
proxies that might not have the ability to make use of it.

注意: 鯖実装者は [CODE(HTTP)[retain=0]] 指令を利用する能力を有しないかもしれないクライアントや串にこの指令を送信するために必要な帯域を考慮することを推奨します。
]FIG]

[3] [[RFC 7234]] で[[キャッシュ指令]]の[[IANA登録簿]]が新設されましたが、
[CODE(HTTP)@en[[[retain]]]] はなぜか登録されていません。 [TIME[2014-10-09T13:32:54.600Z]]