[47] [[HTTPメッセージ]]の[DFN[[RUBYB[ヘッダー部]@en[header section]]]]は、
[[HTTPヘッダー]]を記述できる部分です。

* 仕様書

[REFS[
- [6] [CITE@en[RFC 7230 - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing]] ([TIME[2014-06-07 01:59:35 +09:00]] 版) <https://tools.ietf.org/html/rfc7230#section-3>
- [73] '''[CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-4.3>'''
- [82] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-5.5>
- [24] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-6.2>
- [84] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-6.5.2>
- [26] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-6.6>
- [27] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-6.8>
- [29] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-6.10>
- [92] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-8.1.2>
- [104] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-10.5>
- [4] [CITE@en[RFC 7541 - HPACK: Header Compression for HTTP/2]] ([TIME[2015-05-15 10:13:02 +09:00]] 版) <https://tools.ietf.org/html/rfc7541#section-1.3>
- [3] [CITE@en-US[Fetch Standard]] ([TIME[2015-05-07 18:42:14 +09:00]] 版) <https://fetch.spec.whatwg.org/#concept-header-list>
]REFS]

* ヘッダー部

[7] [[HTTPメッセージ]]のうち0個以上の[[頭欄]]の部分のことを、
[DFN[[RUBYB[頭部]@en[header section]]]]や[DFN[[RUBYB[ヘッダー群]@en[headers]]]]といいます [SRC[>>6]]。

[8] >>7 の定義によると[[開始行]]は[[頭部]]には含まれていません。
[[トレーラー部]]も[[ヘッダー部]]の一部では無さそうです。

[9] [[頭部]]のそれぞれの項目のことを仕様上は[[頭欄]]、一般的には[[ヘッダー]]と呼んでいます。
[[頭部]]のことを[[ヘッダー群]]と言うのはこの[[ヘッダー]]という呼称に由来します。
[[HTTP]] に影響を与えた [[RFC 822]] の本来の用語では、
[[頭部]]全体のことを[RUBYB[[[ヘッダー]]]@en[header]]と呼んでいました。

* ヘッダーリスト

[5] [[Fetch]] [SRC[>>3]] と [[HTTP/2]] [SRC[>>73]] や [[HPACK]] [SRC[>>4]] は、
0個以上の[[ヘッダー]]の順序付きのリストを[DFN[[RUBYB[ヘッダーリスト]@en[header list]]]]と呼んでいます。

[10] [[HTTP/2]] や [[HPACK]] では、[[トレーラー部]]も (独立した) [[ヘッダーリスト]]です。

* HTTP/1.x ヘッダー部

[31] 仕様上の長さ制限はありません。

[30] [[Chrome]] は[[ヘッダー部]]の末尾の [[CRLF]] までが 2[SUP[18]]-1 [[バイト]]
(= 256KB-1B) [[以下]]に収まっていなければならないようです。そうでなければ[[非文書表示]]でエラーとなります。
[[IE]] や [[Firefox]] は数[[MB]]より大きくても大丈夫なようです。制限があるのかは不明です。
[TIME[2015-06-17T08:36:58.500Z]]

[39] [[サーバー]]は、大きすぎる時 [CODE[[[431]]]] [[応答]]を返すことができます。

[35] 個別の[[ヘッダー]]については、[[HTTPヘッダー]]を参照。

[37] 構文解析については、[[HTTPメッセージ]]や[[HTTPの構文解析]]を参照。

* HTTP/2 ヘッダー

[12] [[HTTP/2]] では、[[HTTPメッセージ]]の先頭となる1つ[[以上]]の[[フレーム]]により、
[[ヘッダーリスト]]が転送されます。

[13] 加えて、[[HTTPメッセージ]]の末尾となる1つ[[以上]]の[[フレーム]]により、
[[トレーラー部]]の[[ヘッダーリスト]]が転送されます。

[99] [[HTTP/2]] の[[ヘッダー]]には、 [[HTTP/1.1]] と共通の通常の [[HTTPヘッダー]]の他に、
[[HTTP/1.1]] の[[開始行]]に相当する[[疑似ヘッダー]]があります。

[14] [[疑似ヘッダー]]は、通常の[[ヘッダー]]より前になければなりません [SRC[>>92]]。

[15] [[疑似ヘッダー]]は[[trailer]]では使えません [SRC[>>92]]。

;; [16] [[ヘッダー名]]、[[ヘッダー値]]も参照。

** 構文

[77] [[ヘッダー]]を表す[[フレーム]]群は、 [CODE[[[HEADERS]]]] または
[CODE[[[PUSH_PROMISE]]]] で始まり、0個[[以上]]の [CODE[[[CONTINUATION]]]]
が続きます [SRC[>>73, >>29]]。

[25] 最後の[[フレーム]]では [DFN[[CODE[[[END_HEADERS]]]]]] 
([CODE(HTTP)[[[0x4]]]] = 第2ビット)
[[フラグ]]が設定され、それ以外の[[フレーム]]では設定されません [SRC[>>73, >>24, >>26, >>29]]。 

[FIG(railroad)[
= |
== [CODE[[[HEADERS]]]] ([CODE[[[END_HEADERS]]]])
== [CODE[[[PUSH_PROMISE]]]] ([CODE[[[END_HEADERS]]]])
== =
=== |
==== [CODE[[[HEADERS]]]] (¬[CODE[[[END_HEADERS]]]])
==== [CODE[[[PUSH_PROMISE]]]] (¬[CODE[[[END_HEADERS]]]])
=== *
==== [CODE[[[CONTINUATION]]]] (¬[CODE[[[END_HEADERS]]]])
=== [CODE[[[CONTINUATION]]]] ([CODE[[[END_HEADERS]]]])
]FIG]

[17] 通常の [[HTTPメッセージ]]の[[ヘッダー部]]や[[トレーラー部]]では、
[CODE(HTTP)@en[[[HEADERS]]]] [[フレーム]]を使います。
[[サーバープッシュ]]の[[要求]]の[[ヘッダー部]]では、
[CODE(HTTP)@en[[[PUSH_PROMISE]]]] [[フレーム]]を使います。

[80] [[ヘッダーブロック]]は連続した[[フレーム]]として転送しなければ[['''なりません''']]。
他の[[フレーム型]]の[[フレーム]]や他の[[ストリーム]]の[[フレーム]]を挟んではなりません。 [SRC[>>73, >>24, >>26, >>29]]

[83] 未知の[[フレーム型]]の[[フレーム]]も挟めません [SRC[>>82]]。

;; [22] 多重化もできないなら、なぜ複数の[[フレーム]]に分割できるようになっているのかは謎です。

[19] [[ヘッダーリスト]]は、 [[HPACK]] によって[[圧縮]]します。
その[[符号化]]と[[復号]]に使う[[動的表]]は、[[接続]]単位で[[符号化]]用、
[[復号]]用に1つずつ存在します [SRC[>>73]]。

;; [[HPACK]] を参照。

;; [20] 同じ [[HTTP接続]]を使う[[HTTPメッセージ]]は、[[要求]]と[[応答]]の組以外は互いに意味的に無関係です。
しかしそれを表現する[[フレーム]]列は、[[動的表]]を介して依存関係にあります。

** 符号化

[75] [[ヘッダーリスト]]は、 [[HTTPヘッダー圧縮]]により[RUBYB[[[ヘッダーブロック]]]@en[header block]]として[[直列化]]されます [SRC[>>73]]。

[76] [[直列化]]された[[ヘッダーブロック]]は、1つ[[以上]]の[DFN[[RUBYB[[[ヘッダーブロック素片]]]@en[header block fragment]]]]に分割されて
[CODE[[[HEADERS]]]], [CODE[[[PUSH_PROMISE]]]], [CODE[[[CONTINUATION]]]]
の[[フレーム]]の [[payload]] (の[RUBYB[[[ヘッダーブロック素片]]]@en[Header Block Fragment]]欄 [SRC[>>24, >>26, >>29]]) で転送されます [SRC[>>73]]。

[11] どのように分割するかは、[[送信者]]に委ねられています。

;; [23] 意味的には分割してもしなくても同じです [SRC[>>73]]。

** 復号

[18] [CODE(HTTP)@en[[[CONTINUATION]]]] [[フレーム]]ではなく未知の[[フレーム型]]の[[フレーム]]が現れた場合、[[接続エラー]] [CODE[[[PROTOCOL_ERROR]]]] としなければ[['''なりません''']] [SRC[>>82]]。

[79] [[ヘッダーブロック]]の[[復号エラー]]は、[[接続エラー]]
[CODE[[[COMPRESSION_ERROR]]]] としなければ[['''なりません''']] [SRC[>>73]]。

[81] [[受信者]]は、[[フレーム]]群が捨てられる場合であっても、
その[[フレーム]]群から[[ヘッダーブロック]]を結合し展開する必要があります。
[[受信者]]が持つ[[圧縮文脈]]を変更する可能性があります。 [SRC[>>73, >>104, >>27]]
[[展開]]しない場合は、[[接続エラー]]
[CODE[[[COMPRESSION_ERROR]]]] としなければ[['''なりません''']] [SRC[>>73]]。

;; [28] [[closed]] 状態などで[[フレーム]]を受信して無視する場合で[[接続エラー]]にはならない場合
([[ストリーム]]の項を参照。) や、[CODE(HTTP)@en[[[GOAWAY]]]] [[フレーム]]送信後に受信して無視する場合、
[[ヘッダーブロック]]が長すぎて無視する場合があります。

[21] [[ヘッダー名]]や[[ヘッダー値]]も、エラーを含む場合があります。

;; それぞれの項を参照。

** サイズ制限

[86] [[設定]] [DFN[[CODE[[[SETTINGS_MAX_HEADER_LIST_SIZE]]]]]] ([CODE[[[0x6]]]]) は、
[[送信者]]が受け付ける準備のできている [[header list]] の最大長を知らせる[[ヒント]]です。
この値は、圧縮前の状態で、[[header field]] ごとに名前と値の長さとオーバーヘッドとして 32
を足した合計値を[[バイト]]単位にしたものです。 [SRC[>>84]]

[89] 各[[要求]]で、この値よりも小さな制限を課しても構いません [SRC[>>84]]。

[88] 初期値は、無制限です [SRC[>>84]]。

[105] [[header block]] が大きいと、大量のデータを保持する必要が生じ、
不都合が生じるかもしれません。 [[header block]] の大きさに厳密な上限は設けていませんが、
[[設定]] [CODE[[[SETTINGS_MAX_HEADER_LIST_SIZE]]]]
によって [[header block]] の大きさの制限を [[peer]] に[[ヒント]]として伝えられます。
[[peer]] はそれより大きな [[header block]] を送っても構いませんが、
[[奇形]]とみなされるリスクが有ります。 [SRC[>>104]]

[106] [[設定]] [CODE[[[SETTINGS_MAX_HEADER_LIST_SIZE]]]]
は[[接続]]に対するもので、[[中間器]]を介した別の[[ホップ]]はより厳しい制限を持つかもしれません。
[[中間器]]は[[設定]]を[[転送]]することで問題を避けられますが、
そうする義務はありません。 [SRC[>>104]]

[107] [[サーバー]]は、 [[header block]] が大きすぎて処理したくないときは
[CODE(HTTP)[[[431]]]] [[応答]]を送ることができます。 [SRC[>>104]]

[108] [[クライアント]]は、 [[header block]] が大きすぎて処理したくないときは、
捨てることができます。
[SRC[>>104]]

;; [109] 捨てるとしても、[[ヘッダー圧縮]]の展開処理は実行するか、
[[接続エラー]]として[[接続]]を破棄しないといけません (>>81)。

[38] [[Chrome]] は 2[SUP[15]] [[以下]]ならエラーとしないようです。
超えると[[接続エラー]] [CODE[[[COMPRESSION_ERROR]]]] とするようです。
[[Firefox]] はそれよりずっと大きくてもエラーとしないようです。 [TIME[2015-10-11T08:12:14.200Z]]

* 処理

[32] [[HTTP/1.x]] でも [[HTTP/2]] でも、[[エンドポイント]]は受信中の[[ヘッダー部]]の全体を読み込んで処理を続けるか、
[[ヘッダー部]]を含む[[メッセージ]]全体 (と[[ストリーム]]や[[接続]]) をエラーとみなして処理を中断するかのいずれかとする必要があります。

[33] [CODE(HTTP)@en[[[Content-Length:]]]] [[ヘッダー]]や[[疑似ヘッダー]]など、
[[メッセージ]]全体の解釈に関わったり、場合によってエラーや[[奇形]]としなければならなかったりする[[ヘッダー]]が含まれている可能性がありますから、
[[ヘッダー部]]全体を読み終わるまで、[[エンドポイント]]は[[アプリケーション]]側の処理を実行させることができません。
[[エンドポイント]]の [[HTTP]] 実装は (エラーとして処理を中断するのでなければ)
すべての[[ヘッダー]]を読み終わるまで、必要な[[ヘッダー]]を保持し続ける必要があります。

[34] 個々の[[ヘッダー]]の処理については、[[HTTPヘッダー]]を参照。

* 関連

[46] 
[[HTTPメッセージ]]は [[RFC 822メッセージ]]から派生したものであり、
[[ヘッダー部]]も似たような構造を持っています。
[[ヘッダー部 (インターネットメール)]] も参照。

* 歴史

[45] 
[[ヘッダー部 (インターネットメール)]] も参照。

[1] [CITE[Add sketch for headers · 50b8147 · whatwg/fetch]]
( ([TIME[2014-05-31 02:34:28 +09:00]] 版))
<https://github.com/whatwg/fetch/commit/50b8147869f3d8d9fc2e29e09445176ac07391a6>

[2] [CITE[Define Headers object · 37526e4 · whatwg/fetch]]
( ([TIME[2014-06-12 03:55:34 +09:00]] 版))
<https://github.com/whatwg/fetch/commit/37526e41d1da81e8b19a9d089ff16727eeda9dc8>

[36] [CITE[Issue 244260 - chromium - Security: TLS Truncation attack on HTTP headers, including cookie flags - An open-source project to help move the web forward. - Google Project Hosting]]
([TIME[2015-07-04 16:56:33 +09:00]] 版)
<https://code.google.com/p/chromium/issues/detail?id=244260>

[40] [CITE@en[Editorial: remove structured cloning section]]
([[annevk]]著, [TIME[2016-08-10 22:50:02 +09:00]])
<https://github.com/whatwg/fetch/commit/3dc1612fce7ab38673854d0bf26a4e118e52f077>

[41] [CITE@en[Simplify HeadersInit]]
([[annevk]]著, [TIME[2016-11-30 14:54:44 +09:00]])
<https://github.com/whatwg/fetch/commit/00fce0d96e799f5bc8bc53b30fcec56c4e0b948c>

[42] [CITE@en[Use IDL records for the Headers class]]
([[TimothyGu]]著, [TIME[2016-11-23 23:21:28 +09:00]])
<https://github.com/whatwg/fetch/commit/579e3637d0d82097baa1ee99b9d29e5f11aaa228>

[156] [CITE@en[1197847 – dont allow line folding in h2 headers]]
([TIME[2015-10-10 22:43:21 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=1197847>

[158] [CITE@en[Fix #154: clarify what a header list is · whatwg/fetch@3d7382b]]
([TIME[2015-11-08 16:38:59 +09:00]] 版)
<https://github.com/whatwg/fetch/commit/3d7382b14b01f813e4023b4404422d377232e0c4>

[43] [CITE@en[Stop lowercasing header names]] ([[annevk]]著, [TIME[2017-02-22 20:01:22 +09:00]]) <https://github.com/whatwg/fetch/commit/5869c43a27fff06c6dfc228fe1288018f7f2168d>

[44] [CITE@en[RFC 7975 - Request Routing Redirection Interface for Content Delivery Network (CDN) Interconnection]]
([TIME[2017-03-06 03:04:43 +09:00]])
<https://tools.ietf.org/html/rfc7975#section-4.5>

[48] [CITE@en[Deprecations and Removals in Chrome 60  |  Web  |  Google Developers]]
([TIME[2017-06-15 00:01:43 +09:00]])
<https://developers.google.com/web/updates/2017/06/chrome-60-deprecations>

[49] [CITE@en[Constructing a Headers from another Headers is lossy · Issue #481 · whatwg/fetch]]
([TIME[2017-09-05 14:13:41 +09:00]])
<https://github.com/whatwg/fetch/issues/481>

[50] [CITE@en[Constructing a Headers from another Headers is lossy · Issue #481 · whatwg/fetch]]
([TIME[2017-09-05 14:13:47 +09:00]])
<https://github.com/whatwg/fetch/issues/481>

[51] [CITE@en[Define Content-Type manipulation in terms of MIME Sniffing by annevk · Pull Request #176 · whatwg/xhr]]
([TIME[2018-04-17 23:12:47 +09:00]])
<https://github.com/whatwg/xhr/pull/176>

[52] [CITE@en[Editorial: use Infra to define header list]]
([[annevk]]著, [TIME[2018-04-24 19:25:40 +09:00]])
<https://github.com/whatwg/fetch/commit/13504696e01852b3fc1bef242d8f3b649a397adb>

[53] [CITE@en[Use Infra for header list · Issue #711 · whatwg/fetch]]
([TIME[2018-04-25 10:48:41 +09:00]])
<https://github.com/whatwg/fetch/issues/711>

[54] [CITE@en[Editorial: use Infra to define header list by annevk · Pull Request #713 · whatwg/fetch]]
([TIME[2018-04-25 10:48:58 +09:00]])
<https://github.com/whatwg/fetch/pull/713>

[55] [CITE@en[Clarify how Headers does not support Set-Cookie]]
([[annevk]]著, [TIME[2018-04-19 23:25:32 +09:00]])
<https://github.com/whatwg/fetch/commit/7ab665e05e894f81d8ca741f7e7c19a334d88c08>

[56] [CITE@en[The comma-delimited combined value definition does not support Set-Cookie headers · Issue #345 · whatwg/fetch]]
([TIME[2018-07-25 23:57:30 +09:00]])
<https://github.com/whatwg/fetch/issues/345>

[57] [CITE@en[Clarify how Headers does not support Set-Cookie by annevk · Pull Request #714 · whatwg/fetch]]
([TIME[2018-07-25 23:57:57 +09:00]])
<https://github.com/whatwg/fetch/pull/714>

[58] [CITE@en[Editorial: use "append" to modify the header list]]
([[ryzokuken]]著, [TIME[2018-09-10 21:41:01 +09:00]])
<https://github.com/whatwg/fetch/commit/daca6a824c0c6c5e22b7f7eb70001f36c1732cb1>

[59] [CITE@en[Stop using "combined value"]]
([[annevk]]著, [TIME[2018-11-27 23:18:25 +09:00]])
<https://github.com/whatwg/xhr/commit/0d4253c784d2b71ca5bf6648c67f95b82bb8b239>

[60] [CITE@en[Remove "combined value" concept]]
([[yutakahirano]]著, [TIME[2018-11-30 01:58:47 +09:00]])
<https://github.com/whatwg/fetch/commit/8324d0a8192ce4b48de512d714726fe06fb92851>

[61] [CITE@en[Fix appending to Headers with "request-no-cors" guard]]
([[yutakahirano]]著, [TIME[2018-11-28 17:00:25 +09:00]])
<https://github.com/whatwg/fetch/commit/80d26b6d7a9089dbd18bb7de2ed2a60849824b02>

[62] [CITE@en[Fix: Appending a header to headers with "request-no-cors" guard by yutakahirano · Pull Request #840 · whatwg/fetch]]
([TIME[2019-06-20 10:22:45 +09:00]])
<https://github.com/whatwg/fetch/pull/840>

[63] [CITE@en[CORS request-header Content-Type check should be on a combined value · Issue #748 · whatwg/fetch]]
([TIME[2019-06-21 12:40:45 +09:00]])
<https://github.com/whatwg/fetch/issues/748>

[64] [CITE@en[Align with IDL constructor changes]]
([[autokagami]]著, [TIME[2019-09-24 22:59:53 +09:00]])
<https://github.com/whatwg/fetch/commit/eff7659a2cb15aed801a9dbfc00c58e22efbbd42>