3. 範囲リクエスト (Range Requests)
3.1 Range
GET リクエストの "Range" ヘッダフィールドは、メソッドの意味論を変更して、選択された表現データ全体ではなく、その 1 つ以上の部分範囲の転送だけを要求する。
Range = byte-ranges-specifier / other-ranges-specifier
other-ranges-specifier = other-range-unit "=" other-range-set
other-range-set = 1*VCHAR
サーバーは Range ヘッダフィールドを無視してもよい (MAY)。ただし、Range は部分的に失敗した転送からの効率的な回復と、大きな表現の部分的な取得をサポートするため、オリジンサーバーと中間キャッシュは可能な場合にバイト範囲をサポートすべきである。サーバーは、GET 以外のリクエストメソッドとともに受信した Range ヘッダフィールドを無視しなければならない (MUST)。
オリジンサーバーは、自身が理解しない範囲単位を含む Range ヘッダフィールドを無視しなければならない (MUST)。プロキシは、自身が理解しない範囲単位を含む Range ヘッダフィールドを破棄してもよい (MAY)。
範囲リクエストをサポートするサーバーは、2 つを超える重複する範囲からなる Range ヘッダフィールド、または昇順に列挙されていない多数の小さな範囲の集合からなる Range ヘッダフィールドを無視または拒否してもよい (MAY)。どちらも、壊れたクライアントか、意図的なサービス妨害攻撃 (6.1 節) のいずれかを示すものだからである。クライアントは、同じデータを包含する単一の範囲よりも本質的に処理と転送の効率が悪い複数の範囲を要求すべきではない (SHOULD NOT)。
複数の範囲を要求するクライアントは、特定の理由で後の部分を先に要求する必要がある場合を除き、それらの範囲を昇順 (完全な表現で通常受信される順序) に列挙すべきである (SHOULD)。例えば、部分の内部カタログを持つ大きな表現を処理するユーザーエージェントは、後の部分を先に要求する必要があるかもしれない。特に、その表現が逆順に格納されたページから構成されており、ユーザーエージェントが一度に 1 ページずつ転送したい場合などである。
Range ヘッダフィールドは、[RFC7232] で定義された事前条件ヘッダフィールドを評価した後に評価され、かつ Range ヘッダフィールドが存在しない場合の結果が 200 (OK) 応答になる場合にのみ評価される。言い換えると、条件付き GET が 304 (Not Modified) 応答になる場合、Range は無視される。
If-Range ヘッダフィールド (3.2 節) は、Range ヘッダフィールドを適用するかどうかの事前条件として使用できる。
すべての事前条件が真であり、サーバーが対象リソースに対して Range ヘッダフィールドをサポートしており、指定された範囲が有効かつ (2.1 節で定義されているように) 満たすことが可能である場合、サーバーは、要求された満たすことが可能な範囲に対応する 1 つ以上の部分表現を含むペイロードを持つ 206 (Partial Content) 応答を、4 節で定義されているように送信すべきである (SHOULD)。
すべての事前条件が真であり、サーバーが対象リソースに対して Range ヘッダフィールドをサポートしており、指定された範囲が無効または満たすことが不可能である場合、サーバーは 416 (Range Not Satisfiable) 応答を送信すべきである (SHOULD)。
3.2 If-Range
クライアントが表現の部分的なコピーを持っており、表現全体の最新のコピーを望む場合、条件付き GET (If-Unmodified-Since と If-Match のいずれかまたは両方を使用) とともに Range ヘッダフィールドを使用できる。しかし、表現が変更されたために事前条件が失敗した場合、クライアントは現在の表現全体を取得するために 2 回目のリクエストを行わなければならなくなる。
"If-Range" ヘッダフィールドは、クライアントが 2 回目のリクエストを「ショートカット」することを可能にする。非公式に述べれば、その意味は次のとおりである。表現が変更されていなければ、Range で要求している部分を送ってほしい。そうでなければ、表現全体を送ってほしい。
If-Range = entity-tag / HTTP-date
クライアントは、Range ヘッダフィールドを含まないリクエストに If-Range ヘッダフィールドを生成してはならない (MUST NOT)。サーバーは、Range ヘッダフィールドを含まないリクエストで受信した If-Range ヘッダフィールドを無視しなければならない (MUST)。オリジンサーバーは、範囲リクエストをサポートしない対象リソースへのリクエストで受信した If-Range ヘッダフィールドを無視しなければならない (MUST)。
クライアントは、弱い (weak) とマークされたエンティティタグを含む If-Range ヘッダフィールドを生成してはならない (MUST NOT)。クライアントは、対応する表現のエンティティタグを持たず、かつその日付が [RFC7232] の 2.2.2 節で定義された意味での強いバリデーター (strong validator) である場合を除き、HTTP 日付を含む If-Range ヘッダフィールドを生成してはならない (MUST NOT)。
If-Range 事前条件を評価するサーバーは、エンティティタグを比較する際に強比較関数 ([RFC7232] の 2.3.2 節) を使用しなければならず (MUST)、[RFC7232] の 2.2.2 節で定義された意味での強いバリデーターではない HTTP 日付バリデーターが与えられた場合、その条件を偽として評価しなければならない (MUST)。有効なエンティティタグと有効な HTTP 日付は、先頭 2 文字が DQUOTE (二重引用符) であるかどうかを調べることによって区別できる。
If-Range ヘッダフィールドで与えられたバリデーターが、対象リソースの選択された表現の現在のバリデーターと一致する場合、サーバーは要求どおりに Range ヘッダフィールドを処理すべきである (SHOULD)。バリデーターが一致しない場合、サーバーは Range ヘッダフィールドを無視しなければならない (MUST)。この完全一致による比較は、バリデーターが HTTP 日付である場合も含め、If-Unmodified-Since 条件を評価する際に使用される「以前か同時」の比較とは異なることに注意されたい。