[8] [DFN[[CODE(HTTP)@en[[[Age:]]]]]] [[ヘッダー]]は[[応答]]の[[齢]]を表します。
[DFN[[RUBY[[[齢]]][よわい]@en[age]]]]は、[[応答]]が[[起源鯖]]で[[生成]]されてからの[[時間]]です。

* 仕様書

[REFS[
- [19] '''[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.1>'''
- [22] [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>
-- [7] [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>
--- [11] [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.3>
- [24] [CITE@en[RFC 2295 - Transparent Content Negotiation in HTTP]] ([TIME[2014-08-31 19:36:42 +09:00]] 版) <http://tools.ietf.org/html/rfc2295#section-10.2>
- [27] [CITE@en[RFC 2295 - Transparent Content Negotiation in HTTP]] ([TIME[2014-08-31 19:36:42 +09:00]] 版) <http://tools.ietf.org/html/rfc2295#section-10.4>
]REFS]

* 意味

[12] [CODE(HTTP)@en[[[Age:]]]] [[ヘッダー]]は、
[[応答]]が[[生成]]または成功裏に[[検証]]されてからの時間を[[送信者]]が見積もった値を示します
[SRC[>>19, >>11]]。

[21] [CODE(HTTP)@en[[[Age:]]]] [[ヘッダー]]は[[起源鯖]]で[[生成]]された[[応答]]には付与されず、
[[キャッシュ]]が返した[[応答]]には付与されます。 [CODE(HTTP)@en[[[Age:]]]]
[[ヘッダー]]の存在は、当該[[要求]]が[[起源鯖]]によって[[生成]]されたものではなく、
[[起源鯖]]が[[検証]]したものでもないことを表しています [SRC[>>19]]。
しかし [[HTTP/1.0]] [[キャッシュ]]は [CODE(HTTP)@en[[[Age:]]]]
[[ヘッダー]]に対応していないことがありますから、 [CODE(HTTP)@en[[[Age:]]]]
がないからといって[[起源鯖]]が[[生成]]・[[検証]]したものとは限りません [SRC[>>19]]。

* 齢

[10] [[応答]]の[DFN[[RUBY[[[齢]]][よわい]@en[age]]]]は、
[[起源鯖]]で[[生成]]されたか、[[検証]]が[[成功]]したかのいずれかからの経過時間です [SRC[>>7]]。
[[齢]] [CODE(math)[current_age]] は次の通り計算します。

[13] [DFN[[[apparent_age]]]] は、手元の[[時計][時計 (Web)]]が十分よく[[起源鯖]]の[[時計][時計 (Web)]]と同期されている場合、
[FIG(list)[
- [CODE(math)[date_value]] は [CODE(HTTP)@en[[[Date:]]]] [[ヘッダー]]の値
- [CODE(math)[apparent_age := max (response_time - date_value, 0)]] 
]FIG]
... と定義されます [SRC[>>11]]。

[14] [DFN[[[corrected_age_value]]]] は、[[応答]]の経路上の[[キャッシュ]]がすべて [[HTTP/1.1]]
を実装する場合に
[FIG(list)[
- [CODE(math)[age_value]] は [CODE(HTTP)@en[[[Age:]]]] [[ヘッダー]]の値か、なければ 0
- [CODE(math)[request_time]] は[[蓄積]]された[[応答]]の元の[[要求]]を行った際の[[時計]]の現在値
- [CODE(math)[response_time]] は[[応答]]を受信した際の[[時計]]の現在値
- [CODE(math)[response_delay := response_time - request_time]]
- [CODE(math)[corrected_age_value := age_value + response_delay]]
]FIG]
... と定義されます。なおこの値は[[応答]]の受信の[[時刻]]ではなく、
[[要求]]が開始された[[時刻]]からの相対値と解釈します。 [SRC[>>11]]

[15] [DFN[[[corrected_initial_age]]]] は、原則として
[FIG(list)[
- [CODE(math)[corrected_initial_age := max (apparent_age, corrected_age_value)]]
]FIG]
... と定義されます。ただし [CODE(HTTP)@en[[[Via:]]]] [[ヘッダー]]に [[HTTP/1.0]]
[[ホップ]]が含まれないなど [CODE(HTTP)@en[[[Age:]]]] [[ヘッダー]]の値が信頼できると思われる場合は、
[FIG(list)[
- [CODE(math)[corrected_initial_age := corrected_age_value]]
]FIG]
... としても構いません。 [SRC[>>11]]

[16] [DFN[[[current_age]]]] は
[FIG(list)[
- [CODE(math)[now]] は[[時計][時計 (Web)]]の[[現在値][現在時刻]]
- [CODE(math)[resident_time := now - response_time]]
- [CODE(math)[current_age := corrected_initial_age + resident_time]]
]FIG]
... と定義されます [SRC[>>11]]。

;; [17] [[齢]]の計算には[[時計][時計 (Web)]]が必要です。[[キャッシュ]]は[[蓄積]]した[[応答]]を[[検証]]なしに再利用する場合の前提として[[時計][時計 (Web)]]を持たなければなりません。
[[時計]]を持たない[[キャッシュ]]は、毎回[[検証]]しなければなりません。
([[キャッシュ可能性]]参照。)

[26] [CODE(HTTP)@en[[[Alternates:]]]] [[ヘッダー]]の[[齢]]は、
それが含まれていた[[応答]]の[[齢]]です [SRC[>>27]]。

[25] [[選択応答]]では、[[最善の異体]]の[[齢]]と [CODE(HTTP)@en[[[Alternates:]]]]
[[ヘッダー]]の[[齢]]の大きな方を [CODE(HTTP)@en[[[Age:]]]] [[ヘッダー]]の値としなければ[['''なりません''']] [SRC[>>24]]。

* 構文

[20] [CODE(HTTP)@en[[[Age:]]]] [[ヘッダー]]の値は、
[[デルタ秒]]で、[[時間]]を[[秒]]単位で表した[[非負整数]]です [SRC[>>19]]。

[FIG(railroad)[
= [[デルタ秒]]
]FIG]

* 文脈

[23] [[キャッシュ]]は、[[蓄積された応答]]を[[検証]]なしに[[再利用]]した場合は、
[CODE(HTTP)@en[[[Age:]]]] [[ヘッダー]]を[[生成]] (既にあれば置換)
しなければ[['''なりません''']]。その値は [[current_age]]
としなければ[['''なりません''']]。 [SRC[>>22]]

* 処理モデル

[18] [[齢]]の値は、[[発見的満期時刻]]を使った場合の [CODE(HTTP)@en[[[Warning:]]]]
[[ヘッダー]]の[[生成]]に関わります。

;; [[新鮮寿命]]を参照。

* 歴史

[FIG(quote)[
[FIGCAPTION[
[2] [[HTTP]] ([[RFC 2068]] 1.3, [[RFC 2616]] 1.3)
]FIGCAPTION]
>
:age: The age of a response is the time since it was sent by, or
successfully validated with, the origin server.

:[RUBY[齢] [よわい]]:応答の齢は、[[起源サーバー]]から応答が送られてから、
又は起源サーバーにより成功裏に[[検証]]されてからの時間です。
]FIG]

[REFS[
- [3] [DEL[[[RFC 2068]]]] ([[廃止]]済み), [[RFC 2616]]
-- [5] [CSECTION@en[1.3]]
-- [4] '''[CSECTION@en[13.2.3 Age Calculations]]''' <http://tools.ietf.org/html/rfc2616#section-13.2.3>
-- [6] '''[CSECTION@en[14.6 Age]]'''
]REFS]

[FIG(quote)[
[FIGCAPTION[
[9] RFC 2068・2616 (HTTP/1.1) 14.6 Age
]FIGCAPTION]

>The Age response-header field conveys the sender's estimate of the
amount of time since the response (or its revalidation) was generated
at the origin server. A cached response is "fresh" if its age does
not exceed its freshness lifetime. Age values are calculated as
specified in section 13.2.3.

[CODE(HTTP)[Age]] 応答頭欄は、応答が[[起源サーバー]]で生成されてから
(またはその再検証から) の時間を送信者が見積もったものを伝達します。
[[キャッシュ]]応答は、その年齢が新鮮生存時間をこえなければ
「新鮮」です。年齢値は13.2.3 節に示したように計算します。

>
-            Age = "Age" ":" age-value
-            age-value = delta-seconds

> Age values are non-negative decimal integers, representing time in
seconds.

年齢値は非負十進整数で、秒数で時間を表現します。

> If a cache receives a value larger than the largest positive
integer it can represent, or if any of its age calculations
overflows, it MUST transmit an Age header with a value of
2147483648 (2^31). [DEL[HTTP/1.1 caches MUST send an Age header in every response.]] [INS[An HTTP/1.1 server that includes a cache MUST include an Age header field in every response generated from its own cache.]]
Caches SHOULD use an arithmetic type of at least 31
bits of range.

キャッシュがその表現できる最大の正整数より大きい値を受け取った場合、
またはその年齢計算のいずれかが桁あふれした場合、値
[CODE(HTTP)[2147483648]] (2[SUP[31]]) の [CODE(HTTP)[Age]]
頭を転送しなければ'''なりません'''。 [DEL[HTTP/1.1 キャッシュは各応答で [CODE(HTTP)[Age]] 頭を送信しなければ'''なりません'''。]] [INS[キャッシュを含む HTTP/1.1 サーバーは、その自身のキャッシュから生成した各応答に [CODE(HTTP)[Age]] 頭欄を含めなければ'''なりません'''。]]
キャッシュは、最低31ビットの範囲の計算型を使用する'''べきです'''。
]FIG]

[28] 
[CITE@ja-jp[freenginxでAgeヘッダーの扱いが改善されました · hnakamur's blog]], [TIME[2024-07-22T09:47:34.000Z]], [TIME[2024-07-24T05:31:01.427Z]] <https://hnakamur.github.io/blog/2024/07/22/freenginx-proxy-cache-age/>


* メモ

[1] [[age]]るための欄ではありません。お間違えなきよう。