[12] [DFN[[CODE(HTTP)@en[[[Content-Range:]]]]]] [[ヘッダー]]は、
[[資源]]のうちどの部分が含まれているかを表します。

* 仕様書

[REFS[
- [3] '''[CITE@en[RFC 7233 - Hypertext Transfer Protocol (HTTP/1.1): Range Requests]] ([TIME[2014-09-11 09:57:55 +09:00]] 版) <https://tools.ietf.org/html/rfc7233#section-4.2>'''
- [507] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-06-07 01:55:45 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-4.3.4>
]REFS]

* 意味

[4] [CODE(HTTP)@en[[[Content-Range:]]]] [[ヘッダー]]は、 [CODE(HTTP)[[[206]]]]
[[応答]]において当該[[メッセージ]]の [[payload]]、
または当該[[本体部分]]に含まれる[[選択された表現]]の範囲を表します [SRC[>>3]]。

[5] [CODE(HTTP)@en[[[Content-Range:]]]] [[ヘッダー]]は、 [CODE(HTTP)[[[416]]]]
[[応答]]において[[選択された表現]]についての情報を提供します [SRC[>>3]]。

[10] それ以外の[[状態符号]]では、意味を持ちません [SRC[>>3]]。

* 構文

[6] 値は[[範囲単位]]、 [CODE(char)[[[SP]]]]、範囲の記述を並べたものです。
範囲の記述は[[範囲単位]]に依存しますが、0文字以上の列とされています。 [SRC[>>3]]

;; [7] 範囲の記述に使える文字を [[RFC 7233]] は [CODE(ABNF)@en[[[CHAR]]]]
としていますが [SRC[>>3]]、これは [[RFC 723x]] のどこでも定義されていません。
[CODE(HTTP)@en[[[Range:]]]] との整合性を考慮すると [CODE(ABNF)@en[[[VCHAR]]]]
の誤りで、 [CODE(char)[[[U+0021]]]]-[CODE(char)[[[U+007E]]]]
と解釈するべきでしょう。 [[RFC 2616]] [CODE(ABNF)@en[[[CHAR]]]]
だとすると [CODE(char)[[[U+0000]]]]-[CODE(char)[[[U+00FF]]]]
が認められますが、[[改行]]なども含まれていて不適切です。

[FIG(railroad)[
= [[範囲単位]]
= [CODE(charname)@en[[[SP]]]]
= *
== [CODE(char)[[[U+0021]]]]-[CODE(char)[[[U+007E]]]]
]FIG]

;; [8] この構文では [CODE(HTTP)@en[[[Content-Range:]]]] [[ヘッダー]]の値が[[範囲単位]]と
[CODE(charname)@en[[[SP]]]] だけで終わることがありますが、
[[欄値]]の項にある通り、 [[RFC 7230]] にある[[ヘッダー]]一般の構文に反しています。

;; [11] [[範囲単位]]依存の構文については、各[[範囲単位]]の項を参照してください。

* 文脈

[14] [CODE(HTTP)[[[206]]]] [[応答]]の場合については、 [CODE(HTTP)[[[206]]]]
の項を参照してください。

[15] [[バイト範囲]]の[[範囲要求]]に対する [CODE(HTTP)[[[416]]]]
[[応答]]の場合については、[[バイト範囲]]の項を参照してください。

* 処理

[9] [[受信者]]は、 [CODE(HTTP)[[[206]]]] [[応答]]が理解できない[[範囲単位]]の
[CODE(HTTP)@en[[[Content-Range:]]]] [[ヘッダー]]を含んでいる時、
あるいは[[非妥当]]な範囲の値を含んでいる時、
蓄積された[[表現]]にこれを結合しようと試みては[['''なりません''']]。
[[串]]は[[下流]]へ[[転送]]する[['''べきです''']]。 [SRC[>>3]]

[13] [[受信者]]は [CODE(HTTP)@en[[[Content-Range:]]]] が含まない範囲の[[応答]]を無視するべきと思われますが、
仕様上明記されていません。

[521] [[起源鯖]]は、[[対象資源]]に [CODE(HTTP)@en[[[PUT]]]] を認めている場合で、
[[要求]]に [CODE(HTTP)@en[[[Content-Range:]]]] [[ヘッダー]]が含まれる場合、
[[payload]] が一部分しか含まれないのに誤って [CODE(HTTP)@en[[[PUT]]]]
を使っている可能性があるため、 [CODE(HTTP)[[[400]]]] [[応答]]を送信しなければ[['''なりません''']]
[SRC[>>507]]。

;; [20] この規定は [[RFC 723x]] で追加されました。

;; [16] [[範囲要求]]や[[不完全メッセージ]]も参照。

[18] [[Google BigQuery]] [SRC[>>17]] や [[yfrog]] [SRC[>>19]]
はファイルの一部のアップロードのために [CODE(HTTP)@en[[[PUT]]]]
で [CODE(HTTP)@en[[[Content-Range:]]]] を使っています。

[REFS[
- [17] [CITE@ja[Loading Data with a POST Request - Google BigQuery — Google Cloud Platform]] ([TIME[2014-12-18 02:33:03 +09:00]] 版) <https://cloud.google.com/bigquery/loading-data-post-request#resume-upload>
- [19] [CITE[yfrog - API]] ([TIME[2014-12-24 15:59:00 +09:00]] 版) <http://twitter.yfrog.com/page/api#a9>
]REFS]

;; [21] この種の [[Web API]] は世間一般でほとんど使われていない [CODE(HTTP)@en[[[PUT]]]]
[[メソッド]]の数少ない正当な利用例だったのに、梯子を外して不適合にしちゃう
[[RFC 723x]] はまじ鬼畜wwwww

* 歴史

[FIG(quote)[
[FIGCAPTION[
[2] RFC 2068 14.17・RFC 2616 14.16 Content-Range
]FIGCAPTION]

> The Content-Range entity-header is sent with a partial entity-body to
specify where in the full entity-body the partial body should be [INS[applied. Range units are defined in section 3.12.]] [DEL[inserted. It also indicates the total size of the full entity-body. When a server returns a partial response to a client, it must describe both the extent of the range covered by the response, and the length of the entire entity-body.]]

[CODE(HTTP)[Content-Range]] 実体頭欄は、部分 [CODE(ABNF)[[[entity-body]]]]
と共に送信して、その部分本体が完全 [CODE(ABNF)[entity-body]]
のどこに適用されるべきかを指定します。 [INS[範囲単位は 3.12 節で定義しています。]] [DEL[この欄は完全 [CODE(ABNF)[entity-body]] の全体の寸法も示します。サーバーが部分応答をクライアントに返す時は、その応答により覆われる範囲と [CODE(ABNF)[entity-body]] 全体の長さを記述しなければなりません。]]

>
- [CODE(ABNF)[[DFN[Content-Range]]]] = "Content-Range" ":" content-range-spec]]
- [CODE(ABNF)[[DFN[content-range-spec]] = byte-content-range-spec]]
- [DEL[[CODE(ABNF)[[DFN[byte-content-range-spec]] = bytes-unit [[SP]] first-byte-pos "-" last-byte-pos "/" entity-length]]]]
- [INS[[CODE(ABNF)[[DFN[byte-content-range-spec]] = bytes-unit SP byte-range-resp-spec "/" ( instance-length | "*" )]]]]
- [INS[[CODE(ABNF)[[DFN[byte-range-resp-spec]] = (first-byte-pos "-" last-byte-pos) | "*"]]]]
- [CODE(ABNF)[[DFN[[DEL[entity-length]] [INS[instance-length]]]] = 1*[[DIGIT]]]]

[INS[

> The header SHOULD indicate the total length of the full entity-body,
unless this length is unknown or difficult to determine. The asterisk
"*" character means that the instance-length is unknown at the time
when the response was generated.

この頭は完全な [CODE(ABNF)[entity-body]] の全体の長さが未知であるか、
又は決定するのが難しい場合を除いては、この長さを示す'''べきです'''。
星印 [CODE(HTTP)[*]] 文字は、その応答が生成された時点で
[CODE(ABNF)[instance-length]] が未知であることを意味します。
]INS]

> Unlike byte-ranges-specifier values [INS[(see section 14.35.1)]], a [DEL[byte-content-range-spec may]] [INS[byte-range-resp-spec MUST]]
only specify one range, and [DEL[must]] [INS[MUST]] contain absolute byte positions for
both the first and last byte of the range.

[CODE(ABNF)[byte-ranges-specifier]] 値とは異なり、 
[CODE(ABNF)[byte-range-resp-spec]] は一つの範囲だけを指定しなければ'''ならず'''、
範囲の最初と最後のバイトの絶対バイト位置を含まなければ'''なりません'''。

> A byte-content-range-spec [INS[with a byte-range-resp-spec]] whose last-byte-pos value is less than its
first-byte-pos value, or whose [DEL[entity-length]] [INS[instance-length]] value is less than or
equal to its last-byte-pos value, is invalid. The recipient of an
invalid byte-content-range-spec MUST ignore it and any content
transferred along with it.

[CODE(ABNF)[byte-range-resp-spec]] つきの [CODE(ABNF)[byte-content-range-spec]]
であってその [CODE(ABNF)[last-byte-pos]] が
[CODE(ABNF)[first-byte-pos]] 値よりも小さなものや、
[CODE(ABNF)[instance-length]] 値が [CODE(ABNF)[last-byte-pos]]
値以下のものは不当です。不当な [CODE(ABNF)[byte-content-range-spec]]
の受信者は、この [CODE(ABNF)[byte-content-range-spec]]
及びそれと共に転送された内容を全て無視しなければ'''なりません'''。

[INS[

> A server sending a response with status code 416 (Requested range not
satisfiable) SHOULD include a Content-Range field with a byte-range-resp-spec 
of "*". The instance-length specifies the current length of
the selected resource. A response with status code 206 (Partial
Content) MUST NOT include a Content-Range field with a byte-range-resp-spec 
of "*".

状態符号 [CODE(HTTP)[[[416]]]] (要求された範囲は満足されませんでした)
の応答を送信するサーバーは、 [CODE(ABNF)[byte-range-resp-spec]]
が [CODE(HTTP)[*]] の [CODE(HTTP)[Content-Range]]
欄を含める'''べきです'''。 [CODE(ABNF)[instance-length]]
が選択された資源の現在の長さを指定します。
状態符号 [CODE(HTTP)[[[206]]]] (部分内容) の応答は
[CODE(ABNF)[byte-range-resp-spec]]
が [CODE(HTTP)[*]] の [CODE(HTTP)[Content-Range]] 欄を含んでいては'''なりません'''。
]INS]

> Examples of byte-content-range-spec values, assuming that the entity
contains a total of 1234 bytes:

実体が全部で 1234 バイトあるとして、 [CODE(ABNF)[byte-content-range-spec]]
値の例を示します:

>
:[DEL[o]] [INS[.]] The first 500 bytes [INS[最初の500バイト]]:
bytes 0-499/1234
:[DEL[o]] [INS[.]] The second 500 bytes [INS[次の500バイト]]:
bytes 500-999/1234
:[DEL[o]] [INS[.]] All except for the first 500 bytes [INS[最初の500バイト以外全て]]:
bytes 500-1233/1234
:[DEL[o]] [INS[.]] The last 500 bytes [INS[最後の500バイト]]:
bytes 734-1233/1234

> When an HTTP message includes the content of a single range (for
example, a response to a request for a single range, or to a request
for a set of ranges that overlap without any holes), this content is
transmitted with a Content-Range header, and a Content-Length header
showing the number of bytes actually transferred. For example,

単一の範囲の内容を含む HTTP メッセージ (例えば、
単一の範囲の要求への応答又は穴なしに重なり合う範囲の集合の要求への応答)
の場合は、この内容は [CODE(HTTP)[Content-Range]] 頭と共に転送され、
[CODE(HTTP)[[[Content-Length]]]] 頭は実際に転送されるバイト数を示します。
例えば、

>
[PRE[
HTTP/1.1 206 Partial content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Range: bytes 21010-47021/47022
Content-Length: 26012
Content-Type: image/gif
]PRE]
> When an HTTP message includes the content of multiple ranges (for
example, a response to a request for multiple non-overlapping
ranges), these are transmitted as a multipart [DEL[MIME]] message. The
multipart [DEL[MIME content-type]] [INS[media type]] used for this purpose is [DEL[defined in this specification to be "multipart/byteranges"]] [INS["multipart/byteranges" as defined in appendix 19.2]]. See appendix [DEL[19.2 for its definition]] [INS[19.6.3 for a compatibility issue]].

HTTP メッセージが複数の範囲を含む場合 (例えば、
複数の重なり合わない範囲の要求への応答) には、
複数部分メッセージとして転送されます。
この目的で使う複数部分媒体型は附属書 19.2 節で定義している
[CODE(MIME)[[[multipart/byterange]]]] です。互換性の問題については附属書
19.6.3 節を参照してください。

> [INS[A response to a request for a single range MUST NOT be sent using the multipart/byteranges media type.  A response to a request for multiple ranges, whose result is a single range, MAY be sent as a multipart/byteranges media type with one part.]] A client that cannot
decode a [DEL[MIME]] multipart/byteranges message [DEL[should not]] [INS[MUST NOT]] ask for multiple
byte-ranges in a single request.

単一の範囲の要求への応答は [CODE(MIME)[multipart/byterange]]
媒体型を使って送っては'''なりません'''。
複数範囲の要求への応答であってその結果が単一範囲であるものは、
1つの部分の [CODE(MIME)[multipart/byterange]]
媒体型で送っても'''構いません'''。
[CODE(MIME)[multipart/byterange]] メッセージを復号できないクライアントは、
複数の [CODE(ABNF)[byte-range]] を単一の要求で依頼しては'''なりません'''。

> When a client requests multiple byte-ranges in one request, the
server SHOULD return them in the order that they appeared in the
request.

クライアントが複数の [CODE(ABNF)[byte-range]] 
を1つの要求で要求した時は、サーバーは要求中に出現した順でこれを返す'''べきです'''。

> If the server ignores a byte-range-spec because it is [INS[syntactically]] invalid, the
server [DEL[should]] [INS[SHOULD]] treat the request as if the invalid Range header field
did not exist. (Normally, this means return a 200 response containing
the full entity). [DEL[The reason is that the only time a client will make such an invalid request is when the entity is smaller than the entity retrieved by a prior request.]]

[CODE(ABNF)[byte-range-spec]] が構文的に不当であるためにサーバーがこれを無視する場合は、
サーバーは要求に不当な [CODE(HTTP)[[[Range]]]] 頭欄が存在しなかったものとして扱う'''べきです'''。
(通常、これは完全な実体を含んだ [CODE(HTTP)[[[200]]]]
応答を返すことを意味します。) [DEL[理由は、クライアントがそのような不当な要求を作るのは実態が以前の要求で取り出された実体より小さい時だけだからです。]]

[INS[

> If the server receives a request (other than one including an 
If-Range request-header field) with an unsatisfiable Range 
request-header field (that is, all of whose byte-range-spec values have a
first-byte-pos value greater than the current length of the selected
resource), it SHOULD return a response code of 416 (Requested range
not satisfiable) (section 10.4.17).

サーバーが ([CODE(HTTP)[[[If-Range]]]] 要求頭欄を含んでいない) 
満足されない [CODE(HTTP)[Range]] 要求頭欄
(つまり、 [CODE(ABNF)[byte-range-spec]] 値の全てにおいて [CODE(ABNF)[first-byte-pos]] 値が選択された資源の現在の長さよりも大きいもの。) を持った要求を受け取ったときには、
サーバーは応答符号 [CODE(HTTP)[416]] (要求された範囲は満足されませんでした)
を返す'''べきです'''。

> Note: clients cannot depend on servers to send a 416 (Requested
range not satisfiable) response instead of a 200 (OK) response for
an unsatisfiable Range request-header, since not all servers
implement this request-header.

注意 : 全てのサーバーはこの要求頭を実装しているわけではありませんから、
クライアントは満足されない [CODE(HTTP)[Range]] 要求頭欄にサーバーが 
[CODE(HTTP)[200]] (OK) 応答ではなく [CODE(HTTP)[416]]
(要求された範囲は満足されませんでした)
応答が送ることに依存することはできません。
]INS]
]FIG]

[1] 参照しろと書いてある  RFC 2616 19.6.3 (RFC 2068 からの変更点) にはたいして面白いことは書いてありませんでした。

[REFS[
- [2] [CITE@en[draft-wood-dtnrg-http-dtn-delivery-07 - Using HTTP for delivery in Delay/Disruption-Tolerant Networks]]
( ([TIME[2012-02-26 11:11:35 +09:00]] 版))
<http://tools.ietf.org/html/draft-wood-dtnrg-http-dtn-delivery-07#page-6>
- [522] [CITE[api - Content-Range header - allowed units? - Stack Overflow]]
( ([TIME[2014-09-17 03:04:52 +09:00]] 版))
<http://stackoverflow.com/questions/9480193/content-range-header-allowed-units>
- [523] [CITE[''''''[''''''#JENKINS-13125'''''']'''''' HTTP Content-Range Header one byte past file length and missing "bytes" unit - Jenkins JIRA]]
( ([TIME[2014-09-17 03:20:04 +09:00]] 版))
<https://issues.jenkins-ci.org/browse/JENKINS-13125>
]REFS]

[23] [[WebDAV]] の [[MS]] の拡張には
[DFN[[CODE[DAV:contentrange]]]]
があります。
[SRC[>>22]]

[22] [CITE['''['''MS-XWDSEARCH''']'''.pdf]], [TIME[2018-10-13T16:09:45.000Z]], [TIME[2023-12-02T07:12:25.169Z]] <https://download.microsoft.com/download/5/0/1/501ED102-E53F-4CE0-AA6B-B0F93629DDC6/Exchange/%5BMS-XWDSEARCH%5D.pdf#page=10>


