[15] [DFN[[CODE(HTTP)[[[206]]]]]] は、[[応答]]に含まれるのが[[要求]]された[[資源]]の一部であることを表す[[状態符号]]です。

* 仕様書

[REFS[
- [1] '''[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.1>'''
- [5] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-3.1>
]REFS]

* 意味

[3] [CODE(HTTP)[[[206]]]] は、[[要求]]の [CODE(HTTP)@en[[[Range:]]]] 
[[ヘッダー]]で指定された各[[範囲]]について、
[[選択された表現]]に関して[[満足可能]]なものに対応する各部分を転送することにより、
[[対象資源]]の[[範囲要求]]を満足することに成功していることを表す[[状態符号]]です [SRC[>>1]]。

* 構文

[11] [CODE(HTTP)[[[206]]]] [[応答]]では、 [CODE(HTTP)[[[200]]]]
[[応答]]だったら送っていたであろう次の[[ヘッダー]]を[[生成]]しなければ[['''なりません''']]
[SRC[>>1]]。
[FIG(short list)[
- [CODE(HTTP)@en[[[Date:]]]]
- [CODE(HTTP)@en[[[Cache-Control:]]]]
- [CODE(HTTP)@en[[[ETag:]]]]
- [CODE(HTTP)@en[[[Expires:]]]]
- [CODE(HTTP)@en[[[Content-Location:]]]]
- [CODE(HTTP)@en[[[Vary:]]]]
]FIG]

;; [16] [CODE(HTTP)[[[200]]]] の時送らないものは、送る必要はありません。

;; [17] [CODE(HTTP)[[[304]]]] でも同様の規定があります。

[12] [[要求]]に [CODE(HTTP)@en[[[If-Range:]]]] [[ヘッダー]]が指定されていた場合には、
[[鯖]]は他の[[表現ヘッダー]]を[[生成]]する[['''べきではありません''']]。
[[クライアント]]は既に以前の[[要求]]で受け取っているはずだからです。
[CODE(HTTP)@en[[[If-Range:]]]] [[ヘッダー]]が指定されていない場合には、
[CODE(HTTP)[[[200]]]] [[応答]]だったら送っていたであろう[[表現ヘッダー]]をすべて[[生成]]しなければ[['''なりません''']]。
[SRC[>>1]]

;; [13] [[表現ヘッダー]] (「[[representation header fields]]」) は [[HTTP]]
仕様書で定義されていない用語なので、何を指しているのか不明です。
[[表現メタデータ]]が近そうですが...

;; [18] [CODE(HTTP)[[[304]]]] は[[キャッシュ]]に関して有用な[[ヘッダー]]であれば指定しても良いとしていますが、
[CODE(HTTP)@en[[[If-Range:]]]] は[[キャッシュ]]の更新のためのものではありませんから、
相当する規定がないものと思われます。

[4] [CODE(HTTP)[[[206]]]] [[応答]]の構築時の構文的制約については、
[[範囲要求]]の項も参照してください。

[8] [CODE(HTTP)[[[206]]]] [[応答]]の [[payload body]] は元のデータの一部分ですから、
[CODE(HTTP)@en[[[Content-Type:]]]] に記述された[[MIME型]]の仕様に従ったデータになっているとは限りません。
単独では意味を成さないデータかもしれません。

* 文脈

[9] [CODE(HTTP)[[[206]]]] [[応答]]は[[範囲要求]]に対する[[応答]]で使われます。

;; [[範囲要求]]では他に [CODE(HTTP)[[[200]]]] が使われる場合もあります。

;; [19] [[範囲]]選択の後に他の[[実現値操作]]が適用される場合には、
[CODE(HTTP)[[[226]]]] が使われます。

[20] [[キャッシュ]]は、 [CODE(HTTP)[[[226]]]] [[応答]]から
[CODE(HTTP)[[[206]]]] [[応答]]を作ることも認められています。

;; [CODE(HTTP)[[[226]]]] の項を参照。

* 処理モデル

[10] [[クライアント]]は、 [CODE(MIME)@en[[[multipart/byteranges]]]] 
の[[本体部分]]が [CODE(HTTP)@en[[[Range:]]]] に指定した範囲の順序であると仮定できません。
[[クライアント]]は各[[本体部分]]の [CODE(HTTP)@en[[[Content-Range:]]]]
[[ヘッダー]]を調べなければ[['''なりません''']] [SRC[>>1]]。

[14] [CODE(HTTP)[[[206]]]] [[応答]]は、[[キャッシュ可能]]です [SRC[>>1]]。

[6] [[キャッシュ]]は、 [CODE(HTTP)@en[[[Range:]]]] と [CODE(HTTP)@en[[[Content-Range:]]]]
と[[範囲単位]]に対応しているなら、 [CODE(HTTP)[[[206]]]] [[応答]]を[[蓄積]]して構いません。
また[[不完全]]な [CODE(HTTP)[[[200]]]] [[応答]]を [CODE(HTTP)[[[206]]]] [[応答]]として[[蓄積]]して構いません。 [SRC[>>5]]

;; [7] [[範囲要求]]も参照。

* 歴史

[FIG(quote)[
[FIGCAPTION[
[2] RFC 2068・2616 (HTTP/1.1) 10.2.7 206 Partial Content
]FIGCAPTION]

>  The server has fulfilled the partial GET request for the resource.
The request [DEL[must]] [INS[MUST]] have included a Range header field (section [DEL[14.36]] [INS[14.35]])
indicating the desired range[INS[, and MAY have included an If-Range header field (section 14.27) to make the request conditional]].

サーバーはその資源についての部分 [CODE(HTTP)[[[GET]]]]
を満たしました。要求は望ましい範囲を示した [CODE(HTTP)[[[Range]]]]
頭欄を含んでいなければ'''なりません'''[INS[で、要求を条件的にする [CODE(HTTP)[[[If-Range]]]] 頭欄を含んでいても'''かまいません''']]。

> The response MUST include [INS[the following header fields:]]
- [DEL[either]] [INS[Either]]
a Content-Range header field (section [DEL[14.17]] [INS[14.16]]) indicating
the range included with this response, or a multipart/byteranges
Content-Type including Content-Range fields for each part. If [DEL[multipart/byteranges is not used, the]] [INS[a]] Content-Length header field [INS[is present]] in the response[INS[, its value]]
MUST match the actual number of OCTETs transmitted in the message-body.

応答は次の頭欄を含んでいなければ'''なりません''':
- この資源に含まれている範囲を示す [CODE(HTTP)[[[Content-Range]]]]
頭欄又は [CODE(MIME)[[[multipart/byterange]]]] [CODE(HTTP)[[[Content-Type]]]]
であって各部分が [CODE(HTTP)[Content-Range]] 欄を含んでいるもののいずれか。
[CODE(HTTP)[[[Content-Length]]]] 頭欄が応答に含まれるなら、
その値は [CODE(ABNF)[[[message-body]]]] 中の転送される [CODE(ABNF)[[[OCTET]]]]
の実際の数と一致しなければ'''なりません'''。

[INS[
>
- Date
- ETag and/or Content-Location, if the header would have been sent
in a 200 response to the same request
- Expires, Cache-Control, and/or Vary, if the field-value might
differ from that sent in any previous response for the same variant

- [CODE(HTTP)[[[Date]]]]
- 同じ要求についての [CODE(HTTP)[[[200]]]] 応答で送られるであろうなら、
[CODE(HTTP)[[[ETag]]]] [[及び/又は]] [CODE(HTTP)[[[Content-Location]]]]
- 同じ変種についての以前の応答で送られたものと異なるかもしれない [CODE(ABNF)[[[field-value]]]]
であれば、 [CODE(HTTP)[[[Expires]]]], [CODE(HTTP)[[[Cache-Control]]]]
及び/又は [CODE(HTTP)[[[Vary]]]]

> If the 206 response is the result of an If-Range request that used a
strong cache validator (see section 13.3.3), the response SHOULD NOT
include other entity-headers. If the response is the result of an
If-Range request that used a weak validator, the response MUST NOT
include other entity-headers; this prevents inconsistencies between
cached entity-bodies and updated headers. Otherwise, the response
MUST include all of the entity-headers that would have been returned
with a 200 (OK) response to the same request.

[CODE(HTTP)[206]] 応答が[[強いキャッシュ検証]]を使った 
[CODE(HTTP)[If-Range]] 要求の結果であるなら、応答は他の実体頭を含む'''べきではありません'''。
応答が弱い検証を使った結果であるなら、応答は他の実体頭を含んでは'''なりません'''。
これによってキャッシュされている実態本体と更新された頭の不一致を防ぐことができます。
これ以外の場合には、応答は同じ要求に対する [CODE(HTTP)[200]]
応答が返すであろう実体頭を全て含まなければ'''なりません'''。

> A cache MUST NOT combine a 206 response with other previously cached
content if the ETag or Last-Modified headers do not match exactly, see 13.5.4.

キャッシュは、 [CODE(HTTP)[ETag]] 頭又は [CODE(HTTP)[[[Last-Modified]]]]
頭が正確に一致しない限り、以前にキャッシュしたほかの内容と
[CODE(HTTP)[206]] 応答を結合しては'''なりません'''。
]INS]

> A cache that does not support the Range and Content-Range headers
MUST NOT cache 206 (Partial) responses.

[CODE(HTTP)[Range]] 頭や [CODE(HTTP)[Content-Range]]
頭に対応していないキャッシュは [CODE(HTTP)[206]] (部分) 応答をキャッシュしては'''なりません'''。
]FIG]

[305] [CITE@en[RFC 4037 - Open Pluggable Edge Services (OPES) Callout Protocol (OCP) Core]]
( ([TIME[2014-10-26 15:20:25 +09:00]] 版))
<https://tools.ietf.org/html/rfc4037#section-10.10>

[21] [CITE@en[CORB: protecting certain nosniff and 206 responses]]
([[anforowicz]]著, [TIME[2018-05-17 16:24:03 +09:00]])
<https://github.com/whatwg/fetch/commit/794dd5452705564538440cc5b2c1f13d909e2f9a>

[22] [CITE@en[CORB: blocking of nosniff and 206 responses by anforowicz · Pull Request #686 · whatwg/fetch]]
([TIME[2018-05-19 12:13:31 +09:00]])
<https://github.com/whatwg/fetch/pull/686>

[23] [CITE@en[Allow Range header to be set by APIs]]
([[jakearchibald]]著, [TIME[2018-05-30 02:00:06 +09:00]])
<https://github.com/whatwg/fetch/commit/819d8c9d6617986a831ecd9cf21c34ba9589a890>

[24] [CITE@en[Handling Partial Content / 206 · Issue #144 · whatwg/fetch]]
([TIME[2018-06-01 21:52:09 +09:00]])
<https://github.com/whatwg/fetch/issues/144>

[25] [CITE@en[Allow range header to be set by APIs by jakearchibald · Pull Request #560 · whatwg/fetch]]
([TIME[2018-06-01 22:04:37 +09:00]])
<https://github.com/whatwg/fetch/pull/560>

[26] [CITE@en[CORB: blocking of nosniff and 206 responses by anforowicz · Pull Request #686 · whatwg/fetch]]
([TIME[2019-02-18 17:13:15 +09:00]])
<https://github.com/whatwg/fetch/pull/686>