3. Precondition Header Fields (前提条件ヘッダーフィールド)
このセクションでは, リクエストに前提条件を適用するための HTTP/1.1 ヘッダーフィールドの構文とセマンティクスを定義します。セクション 5 は前提条件が適用されるタイミングを定義します。セクション 6 は複数の前提条件が存在する場合の評価順序を定義します。
3.1. If-Match
If-Match ヘッダーフィールドは, フィールド値が "*" の場合は受信者のオリジンサーバーがターゲットリソースの少なくとも1つの現在の表現を持っているか, またはフィールド値で提供されたエンティティタグのリストのメンバーと一致するエンティティタグを持つターゲットリソースの現在の表現を持っていることを条件として, リクエストメソッドを条件付きにします。
オリジンサーバーは If-Match のエンティティタグを比較する際に強い比較関数を使用しなければなりません (MUST) (セクション 2.3.2)。これは, クライアントが表現データに変更があった場合にメソッドが適用されるのを防ぐためにこの前提条件を意図しているためです。
If-Match = "*" / 1#entity-tag
例:
If-Match: "xyzzy"
If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-Match: *
If-Match は, 複数のユーザーエージェントが同じリソースに対して並行して動作している可能性がある場合に偶発的な上書きを防ぐために, 状態変更メソッド (例: POST, PUT, DELETE) で最もよく使用されます (つまり "失われた更新" 問題を防ぐため)。また, 選択された表現が以前のリクエストから既に保存されている (または部分的に保存されている) ものと一致しない場合にリクエストを中止するために, 安全なメソッドでも使用できます。
If-Match ヘッダーフィールドを受信したオリジンサーバーは, メソッドを実行する前に条件を評価しなければなりません (MUST) (セクション 5)。フィールド値が "*" の場合, オリジンサーバーがターゲットリソースの現在の表現を持っていない場合, 条件は false です。フィールド値がエンティティタグのリストの場合, リストされたタグのいずれも選択された表現のエンティティタグと一致しない場合, 条件は false です。
受信した If-Match 条件が false と評価された場合, オリジンサーバーはリクエストされたメソッドを実行してはなりません (MUST NOT)。代わりに, オリジンサーバーは a) 412 (Precondition Failed) ステータスコード, または b) オリジンサーバーが状態変更が要求されていることを確認し, 最終状態がターゲットリソースの現在の状態に既に反映されている場合は 2xx (Successful) ステータスコードのいずれかで応答しなければなりません (MUST)。
If-Match ヘッダーフィールドは, 保存された応答には適用されないため, キャッシュと中間サーバーによって無視される可能性があります。
3.2. If-None-Match
If-None-Match ヘッダーフィールドは, フィールド値が "*" の場合は受信者のキャッシュまたはオリジンサーバーがターゲットリソースの現在の表現を持っていないか, またはフィールド値にリストされているタグのいずれとも一致しないエンティティタグを持つ選択された表現を持っていることを条件として, リクエストメソッドを条件付きにします。
受信者は If-None-Match のエンティティタグを比較する際に弱い比較関数を使用しなければなりません (MUST) (セクション 2.3.2)。これは, 表現データに変更があった場合でも, 弱いエンティティタグをキャッシュ検証に使用できるためです。
If-None-Match = "*" / 1#entity-tag
例:
If-None-Match: "xyzzy"
If-None-Match: W/"xyzzy"
If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
If-None-Match: *
If-None-Match は主に条件付き GET リクエストで使用され, 最小限のトランザクションオーバーヘッドでキャッシュ情報の効率的な更新を可能にします。クライアントがエンティティタグを持つ1つ以上の保存された応答を更新したい場合, クライアントは GET リクエストを行う際にこれらのエンティティタグのリストを含む If-None-Match ヘッダーフィールドを生成すべきです (SHOULD)。これにより, 受信者サーバーはこれらの保存された応答の1つが選択された表現と一致する場合に 304 (Not Modified) 応答を送信できます。
If-None-Match は値 "*" と共に使用して, クライアントがリソースに現在の表現がないと考えている場合に, 安全でないリクエストメソッド (例: PUT) がターゲットリソースの既存の表現を誤って変更するのを防ぐこともできます。
If-None-Match ヘッダーフィールドを受信したオリジンサーバーは, メソッドを実行する前に条件を評価しなければなりません (MUST) (セクション 5)。フィールド値が "*" の場合, オリジンサーバーがターゲットリソースの現在の表現を持っている場合, 条件は false です。フィールド値がエンティティタグのリストの場合, リストされたタグのいずれかが選択された表現のエンティティタグと一致する場合, 条件は false です。
条件が false と評価された場合, オリジンサーバーはリクエストされたメソッドを実行してはなりません (MUST NOT)。代わりに, オリジンサーバーは a) リクエストメソッドが GET または HEAD の場合は 304 (Not Modified) ステータスコード, または b) 他のすべてのリクエストメソッドの場合は 412 (Precondition Failed) ステータスコードのいずれかで応答しなければなりません (MUST)。
3.3. If-Modified-Since
If-Modified-Since ヘッダーフィールドは, 選択された表現の変更日がフィールド値で提供された日付よりも新しいことを条件として, GET または HEAD リクエストメソッドを条件付きにします。そのデータが変更されていない場合, 選択された表現のデータの転送は回避されます。
If-Modified-Since = HTTP-date
フィールドの例:
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
リクエストに If-None-Match ヘッダーフィールドが含まれている場合, 受信者は If-Modified-Since を無視しなければなりません (MUST)。If-None-Match の条件は If-Modified-Since の条件のより正確な代替と見なされ, 2つは If-None-Match を実装していない可能性のある古い中間サーバーとの相互運用のためにのみ組み合わされます。
受信したフィールド値が有効な HTTP-date でない場合, またはリクエストメソッドが GET でも HEAD でもない場合, 受信者は If-Modified-Since ヘッダーフィールドを無視しなければなりません (MUST)。
If-Modified-Since は通常2つの異なる目的で使用されます: 1) エンティティタグを持たないキャッシュされた表現の効率的な更新を可能にする, 2) Web トラバーサルの範囲を最近変更されたリソースに制限する。
If-Modified-Since ヘッダーフィールドを受信したオリジンサーバーは, メソッドを実行する前に条件を評価すべきです (SHOULD) (セクション 5)。選択された表現の最終変更日がフィールド値で提供された日付よりも前または同じ場合, オリジンサーバーはリクエストされたメソッドを実行すべきではありません (SHOULD NOT)。代わりに, オリジンサーバーは 304 (Not Modified) 応答を生成すべきです (SHOULD)。これには, 以前にキャッシュされた応答を識別または更新するのに役立つメタデータのみを含めます。
3.4. If-Unmodified-Since
If-Unmodified-Since ヘッダーフィールドは, 選択された表現の最終変更日がフィールド値で提供された日付よりも前または同じであることを条件として, リクエストメソッドを条件付きにします。このフィールドは, ユーザーエージェントが表現のエンティティタグを持っていない場合に If-Match と同じ目的を達成します。
If-Unmodified-Since = HTTP-date
フィールドの例:
If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
リクエストに If-Match ヘッダーフィールドが含まれている場合, 受信者は If-Unmodified-Since を無視しなければなりません (MUST)。If-Match の条件は If-Unmodified-Since の条件のより正確な代替と見なされ, 2つは If-Match を実装していない可能性のある古い中間サーバーとの相互運用のためにのみ組み合わされます。
受信したフィールド値が有効な HTTP-date でない場合, 受信者は If-Unmodified-Since ヘッダーフィールドを無視しなければなりません (MUST)。
If-Unmodified-Since は, 複数のユーザーエージェントがその表現にエンティティタグを提供しないリソースに対して並行して動作している可能性がある場合に偶発的な上書きを防ぐために, 状態変更メソッド (例: POST, PUT, DELETE) で最もよく使用されます (つまり "失われた更新" 問題を防ぐため)。
If-Unmodified-Since ヘッダーフィールドを受信したオリジンサーバーは, メソッドを実行する前に条件を評価しなければなりません (MUST) (セクション 5)。選択された表現の最終変更日がフィールド値で提供された日付よりも新しい場合, オリジンサーバーはリクエストされたメソッドを実行してはなりません (MUST NOT)。代わりに, オリジンサーバーは a) 412 (Precondition Failed) ステータスコード, または b) オリジンサーバーが状態変更が要求されていることを確認し, 最終状態がターゲットリソースの現在の状態に既に反映されている場合は 2xx (Successful) ステータスコードのいずれかで応答しなければなりません (MUST)。
If-Unmodified-Since ヘッダーフィールドは, 保存された応答には適用されないため, キャッシュと中間サーバーによって無視される可能性があります。
3.5. If-Range
If-Range ヘッダーフィールドは, If-Match および If-Unmodified-Since ヘッダーフィールドに類似した特別な条件付きリクエストメカニズムを提供しますが, バリデーターが一致しない場合は Range ヘッダーフィールドを無視するよう受信者に指示し, 412 (Precondition Failed) 応答ではなく新しく選択された表現の転送をもたらします。If-Range は [RFC7233] のセクション 3.2 で定義されています。