14. Range Requests (範囲リクエスト)
クライアントは、転送の中断に遭遇したり、大きな表現の一部だけを取得する必要がある場合がよくあります。範囲リクエストは、クライアントが表現全体ではなく、選択された表現の1つ以上の部分範囲を要求できるオプション機能です。
範囲リクエスト機構は、いくつかの異なるシナリオで有用です:
- 大きなファイルの部分ダウンロードを複数の同時リクエストに分割することで、全体の取得速度を向上させることができます
- 中断された転送を最初からやり直すのではなく、中断点から再開できます
- 一部のメディアタイプは増分レンダリングまたは再生を許可し、ユーザーエージェントは受信時にデータの処理を開始できます
サーバーは範囲リクエストをサポートする必要はありません。ただし、オリジンサーバーは範囲リクエストをサポートすべきです(SHOULD)。範囲リクエストはネットワーク使用量を削減し、サービスの応答性を向上させることができるためです。
14.1. Range Units (範囲単位)
表現は異なる方法で部分範囲に分割できます。範囲単位は、表現データがどのように分割されるかを定義します。
range-unit = token
すべての範囲単位名は大文字小文字を区別せず、HTTP Range Unit Registryに登録されるべきです(SHOULD)。
14.1.1. Range Specifiers (範囲指定子)
範囲指定子は、表現データの1つ以上の部分範囲を定義します。
range-spec = range-unit "=" range-set
range-set = 1#range-spec-value
range-spec-value = int-range / suffix-range / other-range
範囲単位により、クライアントは要求している範囲の種類を示すことができます。
14.1.2. Byte Ranges (バイト範囲)
「bytes」範囲単位はHTTPで定義されており、オクテットシーケンスの部分範囲(つまり、バイト範囲)を表します。
byte-ranges-specifier = bytes-unit "=" byte-range-set
byte-range-set = 1#byte-range-spec
byte-range-spec = first-byte-pos "-" [ last-byte-pos ]
/ suffix-byte-range-spec
suffix-byte-range-spec = "-" suffix-length
first-byte-pos = 1*DIGIT
last-byte-pos = 1*DIGIT
suffix-length = 1*DIGIT
bytes-unit = "bytes"
first-byte-pos値は、範囲内の最初のバイトのバイトオフセットを示します。last-byte-pos値は、範囲内の最後のバイトのバイトオフセットを示します。つまり、指定されたバイト位置は包含的です。バイトオフセットはゼロから始まります。
例:
bytes=0-499最初の500バイトを表しますbytes=500-9992番目の500バイトを表しますbytes=-500最後の500バイトを表しますbytes=500-バイト500以降のすべてのバイトを表しますbytes=0-0,-1最初と最後のバイトを表します
14.2. Range
「Range」ヘッダーフィールドは、表現データの1つ以上の部分範囲を要求するために使用されます。
Range = range-unit "=" range-set
サーバーはRangeヘッダーフィールドを無視できます(MAY)。ただし、オリジンサーバーと中間キャッシュは、可能な場合にバイト範囲をサポートすべきです(SHOULD)。範囲サポートにより、部分的に失敗した転送からの効率的な回復と大きな表現の部分取得が可能になるためです。
サーバーは、GET以外のリクエストメソッドで受信したRangeヘッダーフィールドを無視しなければなりません(MUST)。
Rangeヘッダーフィールドをサポートするオリジンサーバーは、すべての事前条件が真である場合、次のことを行わなければなりません(MUST):
- サポートしていない範囲単位が含まれている場合、Rangeヘッダーフィールドを無視する
- Rangeヘッダーフィールドが構文的に無効な場合、416(Range Not Satisfiable)ステータスコードを返す
- Rangeヘッダーフィールドに満たすことができるバイト範囲のセットが含まれている場合、1つ以上の部分表現を含む206(Partial Content)レスポンスを返す
リクエストの例:
GET /document HTTP/1.1
Host: www.example.com
Range: bytes=0-1023
14.3. Accept-Ranges
「Accept-Ranges」ヘッダーフィールドにより、サーバーはターゲットリソースに対する範囲リクエストをサポートしていることを示すことができます。
Accept-Ranges = acceptable-ranges
acceptable-ranges = 1#range-unit / "none"
特定のターゲットリソースに対する範囲リクエストを受け入れるオリジンサーバーは、どの範囲単位がサポートされているかを示すためにAccept-Rangesヘッダーフィールドを送信すべきです(SHOULD)。クライアントは、このヘッダーフィールドを受信せずに範囲リクエストを生成できます(MAY)。
例:
Accept-Ranges: bytes
Accept-Ranges: none
「none」値は、範囲単位が受け入れられないことを示し、サーバーがそのリソースに対する範囲リクエストをサポートしていないことを意味します。
14.4. Content-Range
「Content-Range」ヘッダーフィールドは、単一パート206(Partial Content)レスポンスで送信され、含まれている部分表現のバイト範囲を示すか、416(Range Not Satisfiable)レスポンスで送信され、選択された表現に関する情報を提供します。
Content-Range = range-unit SP
( range-resp / unsatisfied-range )
range-resp = byte-content-range
/ other-range-resp
byte-content-range = bytes-unit SP
( byte-range-resp / unsatisfied-range )
byte-range-resp = first-byte-pos "-" last-byte-pos
"/" ( complete-length / "*" )
complete-length = 1*DIGIT
unsatisfied-range = "*/" complete-length
other-range-resp = *CHAR
例:
Content-Range: bytes 0-1023/5000
Content-Range: bytes 1024-2047/5000
Content-Range: bytes */5000
最初の例は、完全な表現(長さ5000バイト)の最初の1024バイトが転送されていることを示します。3番目の例は、選択された表現の完全な長さが5000バイトであるため、範囲リクエストを満たすことができなかったことを示します。
14.5. Partial PUT (部分PUT)
部分PUTリクエストは範囲リクエストではありませんが、転送されるコンテンツを記述するために範囲リクエストと同じメカニズムを使用します。クライアントは、PUTリクエストにContent-Rangeヘッダーフィールドを含めることで部分PUTを送信できます。
ただし、部分PUTは実際にはほとんど使用されません。その理由は次のとおりです:
- クライアントがリソースの現在の状態を知っている必要がある
- 競合状態に対して脆弱である
- ほとんどのオリジンサーバーがそれをサポートしていない
したがって、クライアントは、ターゲットサーバーがそれをサポートしていることを確認しない限り、部分PUTを使用すべきではありません(SHOULD NOT)。
14.6. Media Type multipart/byteranges (メディアタイプ multipart/byteranges)
複数の範囲を送信する場合、サーバーはmultipart/byterangesメディアタイプを使用すべきです(SHOULD)。
multipart/byteranges
このメディアタイプの各ボディパートには、次を含める必要があります(MUST):
- そのボディパートに含まれる表現のメディアタイプを示すContent-Typeヘッダーフィールド
- 含まれている範囲を示すContent-Rangeヘッダーフィールド
レスポンスの例:
HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-Type: text/html
Content-Range: bytes 0-100/1234
[最初の101バイト]
--THIS_STRING_SEPARATES
Content-Type: text/html
Content-Range: bytes 500-999/1234
[バイト500-999]
--THIS_STRING_SEPARATES--
クライアントが複数の不連続な範囲を要求する場合、サーバーは次の場合にのみマルチパートレスポンスを返すべきです(SHOULD):
- 範囲が重複していない
- 範囲の順序が表現内での出現順序と同じである
それ以外の場合、サーバーは表現全体を返すか、重複する範囲を結合すべきです(SHOULD)。