メインコンテンツまでスキップ

2. Validators (バリデーター)

この仕様は, リソースの状態を観察し前提条件をテストするために一般的に使用される2つの形式のメタデータを定義しています: 変更日時 (セクション 2.2) と不透明なエンティティタグ (セクション 2.3)。HTTP の様々な拡張, 例えば Web 分散オーサリングとバージョン管理 (WebDAV, [RFC4918]) によって定義されたリソース状態を反映する追加のメタデータもありますが, これらはこの仕様の範囲外です。リソースメタデータ値が前提条件内で使用される場合, "バリデーター" (validator) と呼ばれます。

2.1. Weak versus Strong (弱いと強い)

バリデーターには2つのタイプがあります: 強いバリデーターまたは弱いバリデーターです。弱いバリデーターは生成が容易ですが, 比較においてははるかに有用性が低いです。強いバリデーターは比較に最適ですが, 効率的に生成することが非常に難しい (時には不可能な) 場合があります。HTTP は, すべての形式のリソースが同じ強度のバリデーターに従うことを強制するのではなく, 使用されているバリデーターのタイプを公開し, 弱いバリデーターを前提条件として使用できる場合に制限を課します。

"強いバリデーター" (strong validator) は, GET に対する 200 (OK) 応答のペイロードボディで観察可能な表現データに変更が発生するたびに値が変わる表現メタデータです。

強いバリデーターは, 表現データの変更以外の理由で変更される可能性があります。例えば, 表現メタデータの意味的に重要な部分が変更された場合 (例えば Content-Type) などです。しかし, オリジンサーバーの最善の利益は, リモートキャッシュやオーサリングツールが保持する保存された応答を無効化する必要がある場合にのみ値を変更することです。

キャッシュエントリは, 有効期限に関係なく, 任意の長期間存続する可能性があります。したがって, キャッシュは遠い過去に取得したバリデーターを使用してエントリを検証しようとする場合があります。強いバリデーターは, 時間の経過とともに特定のリソースに関連付けられたすべての表現のすべてのバージョンにわたって一意です。ただし, 異なるリソースの表現間での一意性を意味するものではありません (つまり, 同じ強いバリデーターが同時に複数のリソースの表現に使用される可能性があり, それらの表現が同等であることを意味しません)。

対照的に, "弱いバリデーター" (weak validator) は, 表現データのすべての変更に対して変更されない可能性がある表現メタデータです。この弱点は, 値の計算方法の制限 (クロック解像度など), リソースのすべての可能な表現に対して一意性を保証できないこと, またはリソース所有者がデータの一意なシーケンスではなく自己決定された等価性のセットによって表現をグループ化したいという要望によるものである可能性があります。オリジンサーバーは, 以前の表現が現在の表現の代替として受け入れられないと判断した場合, 弱いエンティティタグを変更すべきです (SHOULD)。言い換えれば, オリジンサーバーがキャッシュに古い応答を無効化させたい場合は常に, 弱いエンティティタグを変更すべきです。

強いバリデーターは, キャッシュ検証, 部分コンテンツ範囲, "失われた更新" 回避を含むすべての条件付きリクエストに使用できます。弱いバリデーターは, クライアントが以前に取得した表現データとの正確な等価性を必要としない場合にのみ使用できます。例えば, キャッシュエントリを検証する場合や Web トラバーサルを最近の変更に制限する場合などです。

2.2. Last-Modified (最終更新)

応答内の Last-Modified ヘッダーフィールドは, オリジンサーバーが選択された表現が最後に変更されたと考える日時を示すタイムスタンプを提供します。これはリクエストの処理終了時に決定されます。

Last-Modified = HTTP-date

使用例:

Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT

2.2.1. Generation (生成)

オリジンサーバーは, 最終変更日を合理的かつ一貫して決定できる選択された表現に対して Last-Modified を送信すべきです (SHOULD)。これは, 条件付きリクエストとキャッシュの鮮度評価 ([RFC7234]) での使用により, インターネット上の HTTP トラフィックを大幅に削減し, サービスのスケーラビリティと信頼性を向上させる重要な要因となる可能性があるためです。

オリジンサーバーは, 応答の Date フィールド値を生成する時刻にできるだけ近い時点で表現の Last-Modified 値を取得すべきです (SHOULD)。これにより, 特に応答が生成される時刻の近くで表現が変更される場合, 受信者が表現の変更時刻を正確に評価できます。

時計を持つオリジンサーバーは, サーバーのメッセージ発信時刻 (Date) よりも後の Last-Modified 日付を送信してはなりません (MUST NOT)。オリジンサーバーの時計によると, 最終変更時刻が実装固有のメタデータから導出され, それが将来のある時刻と評価される場合, オリジンサーバーはその値をメッセージ発信日付で置き換えなければなりません (MUST)。これにより, 将来の変更日付がキャッシュ検証に悪影響を及ぼすことを防ぎます。

2.2.2. Comparison (比較)

リクエスト内でバリデーターとして使用される場合, Last-Modified 時刻は, 仕様で定義された特定のルールを使用して強いと推定できる場合を除き, 暗黙的に弱いバリデーターです。

2.3. ETag (エンティティタグ)

応答内の ETag ヘッダーフィールドは, リクエストの処理終了時に決定される選択された表現の現在のエンティティタグを提供します。エンティティタグは, 同じリソースの複数の表現を区別するための不透明なバリデーターです。これらの複数の表現が時間の経過に伴うリソース状態の変化によるものか, 同時に複数の表現が有効になるコンテンツネゴシエーションによるものか, またはその両方によるものかは関係ありません。

ETag = entity-tag

entity-tag = [ weak ] opaque-tag
weak = %x57.2F ; "W/", 大文字小文字を区別
opaque-tag = DQUOTE *etagc DQUOTE
etagc = %x21 / %x23-7E / obs-text

例:

ETag: "xyzzy"
ETag: W/"xyzzy"
ETag: ""

エンティティタグは弱いバリデーターまたは強いバリデーターのいずれかであり, デフォルトは強いバリデーターです。オリジンサーバーが表現に対してエンティティタグを提供し, そのエンティティタグの生成が強いバリデーターのすべての特性を満たさない場合 (セクション 2.1), オリジンサーバーは不透明な値の前に W/ (大文字小文字を区別) を付けることで, エンティティタグを弱いとしてマークしなければなりません (MUST)。

2.3.1. Generation (生成)

エンティティタグの背後にある原則は, サービス作成者のみがリソースの実装を十分に理解しており, そのリソースに対して最も正確で効率的な検証メカニズムを選択でき, そのようなメカニズムは簡単に比較できる単純なオクテットシーケンスにマッピングできるということです。値は不透明であるため, クライアントが各エンティティタグがどのように構築されているかを知る必要はありません。

オリジンサーバーは, 変更の検出を合理的かつ一貫して判断できる選択された表現に対して ETag を送信すべきです (SHOULD)。エンティティタグを条件付きリクエストとキャッシュの鮮度評価 ([RFC7234]) で使用することにより, HTTP ネットワークトラフィックを大幅に削減でき, サービスのスケーラビリティと信頼性を向上させる重要な要因となる可能性があります。

2.3.2. Comparison (比較)

比較コンテキストが弱いバリデーターの使用を許可するかどうかに応じて, 2つのエンティティタグ比較関数があります:

  • 強い比較 (Strong comparison): 両方とも弱くなく, 不透明タグが文字ごとに一致する場合, 2つのエンティティタグは同等です。
  • 弱い比較 (Weak comparison): どちらかまたは両方が "弱い" とタグ付けされているかどうかに関係なく, 不透明タグが文字ごとに一致する場合, 2つのエンティティタグは同等です。

以下の例は, エンティティタグペアのセットの結果を示しています:

ETag 1ETag 2強い比較弱い比較
W/"1"W/"1"一致しない一致
W/"1"W/"2"一致しない一致しない
W/"1""1"一致しない一致
"1""1"一致一致

2.4. When to Use Entity-Tags and Last-Modified Dates (エンティティタグと最終更新日を使用するタイミング)

GET または HEAD に対する 200 (OK) 応答で, オリジンサーバーは:

  • エンティティタグバリデーターを生成することが不可能でない限り, 送信すべきです (SHOULD)。
  • パフォーマンス上の考慮事項が弱いエンティティタグの使用をサポートする場合, または強いエンティティタグを送信することが不可能な場合, 強いエンティティタグの代わりに弱いエンティティタグを送信してもよい (MAY)。
  • 送信することが可能であれば, Last-Modified 値を送信すべきです (SHOULD)。

言い換えれば, オリジンサーバーの推奨される動作は, 取得リクエストへの成功応答で強いエンティティタグと Last-Modified 値の両方を送信することです。

クライアントは:

  • オリジンサーバーがエンティティタグを提供した場合, 任意のキャッシュ検証リクエスト (If-Match または If-None-Match を使用) でそのエンティティタグを送信しなければなりません (MUST)。
  • オリジンサーバーが Last-Modified 値のみを提供した場合, 非サブレンジキャッシュ検証リクエスト (If-Modified-Since を使用) で Last-Modified 値を送信すべきです (SHOULD)。
  • オリジンサーバーがエンティティタグと Last-Modified 値の両方を提供した場合, キャッシュ検証リクエストで両方のバリデーターを送信すべきです (SHOULD)。これにより, HTTP/1.0 と HTTP/1.1 の両方のキャッシュが適切に応答できます。