[9] [DFN[[RUBYB[[[トレーラー部]]]@en[trailer part]]]]は、[CODE(HTTP)@en[[[chunked]]]]
[[符号化]]されている[[メッセージ本体]]の末尾の[[ヘッダー]]を記述できる箇所です。

[10] [[トレーラー部]]を使うと、[[メッセージ本体]]の送信時に動的に生成される[[一貫性]]のデータや[[デジタル署名]]などを[[メッセージ]]の末尾に記述することができます
[SRC[>>8]]。

[51] 実際には使われていません。

* 仕様書

[REFS[
- [8] '''[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-4.1.2>'''
- [26] [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-4.3>
- [28] [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-4.4>
- [36] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-08-07 05:54:02 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#page-79>
- [41] [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.2>
- [43] [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.1>
]REFS]

* 構文

[11] [[トレーラー部]]は、0個以上の[[ヘッダー]]で構成されます。
各[[ヘッダー]]の後には、 [[CRLF]] が来ます。 [SRC[>>8]]

[FIG(railroad)[
= *
== [[ヘッダー]]
== [[CRLF]]
]FIG]

[40] [[HTTP/2]] では、 [CODE[[[HEADERS]]]] [[フレーム]]や
[CODE[[[CONTINUATION]]]] [[フレーム]]による [[header block]]
として表されます。

;; [[HTTPメッセージ]]参照。

* 文脈

[23] [[トレーラー部]]は、 [[HTTP/1.1]] [CODE(HTTP)@en[[[chunked]]]] 
[[符号化]]されている場合に[[メッセージ本体]]の末尾近くに、または
[[HTTP/2]] [[メッセージ]]を表す[[フレーム]]の末尾に存在しています。

;; [CODE(HTTP)@en[[[chunked]]]]、[[ヘッダー部]]、[[HTTPメッセージ]]も参照。

[25] [[利用者エージェント]]は[[要求]]の [CODE(HTTP)@en[[[TE:]]]]
[[ヘッダー]]に [DFN[[CODE(HTTP)@en[[[trailers]]]]]] [SRC[>>26]] という値を指定することで、
[[トレーラー部]]に対応していると明示できます。

;; [27] [[中間器]]が[[送信]]する場合、[[下流]]すべてが[[トレーラー部]]に対応しているか、
[[中間器]]が[[バッファリング]]してから[[下流]]に渡すかのいずれかを表します [SRC[>>26]]。

;; [42] [[HTTP/2]] は [CODE(HTTP)@en[[[TE:]]]] [[ヘッダー]]の値として
[CODE(HTTP)@en[[[trailers]]]] のみを認めています [SRC[>>41]]。

[21] [[サーバー]]は、 [CODE(HTTP)@en[[[TE:]]]] に [CODE(HTTP)[[[trailers]]]] が指定されている場合を除き、
[[利用者エージェント]]に必要と考えられる[[ヘッダー]]を[[トレーラー部]]で[[生成]]する[['''べきではありません''']]。
[[鯖]]は、 [CODE(HTTP)@en[[[TE:]]]] に [CODE(HTTP)[[[trailers]]]] が指定されていない場合には、
[[トレーラー部]]の[[ヘッダー]]は[[利用者エージェント]]への経路中で黙って捨てられるかもしれないと考える[RUBYB[べき]@en[ought to]]です。
[SRC[>>8]]

;; [22] [[中間器]]は [CODE(HTTP)@en[[[chunked]]]] [[符号化]]を[[復号]]して
[[HTTP/1.0]] [[受信者]]に[[転送]]するかもしれませんが、
その際に[[応答]]全体をバッファリングする必要はありません [SRC[>>8]]。

;; [24] [CODE(HTTP)@en[[[TE:]] [[trailers]]]] が指定されていなくても、
[[トレーラー部]]の利用が禁止されているわけではないようです。
しかし指定されていない場合には、[[トレーラー部]]が理解される保証は全くありません。

* ヘッダーの種類

[12] [[送信者]]は、次のような[[ヘッダー]]を[[生成]]しては[['''なりません''']]。
[[受信者]]は、これらを無視するか、[[誤り]]とみなすかしなければ[['''なりません''']]。
[SRC[>>8]]
[FIG(list)[
- [13] [[メッセージ]]の[[フレーム付け]]に関するもの ([CODE(HTTP)@en[[[Transfer-Encoding:]]]]、
[CODE(HTTP)@en[[[Content-Length:]]]] など)
- [14] [[経路制御]]に関するもの ([CODE(HTTP)[[[Host:]]]] など)
- [15] [[要求修飾子]]
- [16] [[認証]]
- [17] [[応答制御データ]]
- [18] [[payload]] の処理方法に関するもの ([CODE(HTTP)@en[[[Content-Encoding:]]]]、
[CODE(HTTP)@en[[[Content-Type:]]]]、[CODE(HTTP)@en[[[Content-Range:]]]]、
[CODE(HTTP)@en[[[Trailer:]]]] など)
]FIG]

;; [19] なぜか完全なリストはなく、例示に留まっています。

[44] [[疑似ヘッダー]]を含んでは[['''なりません''']]。含んでいる場合、[[メッセージ]]は[[奇形]]です。 [SRC[>>43]]

[37] [[RFC 7231]] は[[ヘッダー]]の仕様書に対し、 [[トレーラー部]]で使用することを認めるかどうか、
便利かどうかを明記することを検討するよう求めています [SRC[>>36]]。

[20] 禁止されているものを除いた[[ヘッダー]]は、[[頭部]]に現れた場合と同じように処理して構いません。
[SRC[>>8]]

[38] 次の[[ヘッダー]]は[[トレーラー部]]での使用が明示的に認められています。
[FIG(short list)[
- [CODE(HTTP)@en[[[Authentication-Info:]]]] 
- [CODE(HTTP)@en[[[OPES-System:]]]]
- [CODE(HTTP)@en[[[OPES-Via:]]]]
]FIG]

;; [35] [[トレーラー部]]で使って良いもの、使っていけないものに該当すると思われる[[ヘッダー]]の一覧は >>6 に [[JSON]]
形式で収録されています。
[REFS[
- [6] [CITE@en[data-web-defs/headers.txt at master · manakai/data-web-defs]] ([TIME[2014-09-03 10:02:34 +09:00]] 版) <https://github.com/manakai/data-web-defs/blob/master/doc/headers.txt>
]REFS]

[39] [[トレーラー部]]の[[ヘッダー]]は、使用が認められていないものは無視されますし、
それ以外であっても無視される可能性があります。また通常の[[ヘッダー部]]と[[トレーラー部]]の両方に同名の[[ヘッダー]]が含まれていると、どちらを採用するかが実装により異なる可能性もあります。
これは[[相互運用性]]の問題を生じるだけでなく、[[セキュリティー]]上の問題となる危険性もあります。

* 処理

[45] [[トレーラー部]]の[[ヘッダー]]のエラー処理をどうするべきなのか、
あまり明確ではありません。

[46] [[ヘッダー]]の受信完了後、[[payload body]] や[[トレーラー部]]の全体を受信せずとも処理を開始できます。
その後に[[トレーラー部]]を受信した結果エラーが検出された場合、
既に開始されている処理は止められないかもしれません。

[50] 現在のどの [[Webブラウザー]]も、[[トレーラー部]]が含まれていたら正しく扱えますが、
その内容は無視するようです。 [TIME[2015-08-08T07:08:53.300Z]]

* [CODE(HTTP)@en[Trailer:]] ヘッダー (HTTP)

[2] [DFN[[CODE(HTTP)@en[[[Trailer:]]]]]] [[ヘッダー]]は、
[[トレーラー部]]に含まれる[[ヘッダー名]]を表しています。

** 文脈

[30] この[[ヘッダー]]は複数指定できます。

[31] [[送信者]]は[[トレーラー部]]で[[ヘッダー]]を送りたいときは、
[[頭部]]に [CODE(HTTP)@en[[[Trailer:]]]] [[ヘッダー]]を[[生成]]して当該[[ヘッダー名]]を含める[['''べきです''']]
[SRC[>>28]]。

** 構文

[29] [[ヘッダー名]]の1つ以上の[[リスト]] ([CODE(HTTP)[#]]) です [SRC[>>28]]。

[FIG(railroad)[
= [[ヘッダー名]]
= *
== [[FWS]]
== [CODE(HTTP)[[[,]]]]
== [[FWS]]
== [[ヘッダー名]]
]FIG]

** 処理

[32] [[受信者]]に対するヒントとして用いることが想定されているようで、
具体的にどのように処理するかは規定がありません。また、
[[トレーラー部]]を使用する時に指定することが[['''推奨''']]はされていますが、
実態と一致していない可能性は排除されていませんし、
その場合のエラー処理も特に規定されていません。

[59] [[プロキシ]]が[[転送]]前または[[転送]]後の[[プロトコル]]で[[トレーラー部]]を扱えない場合、
削除するべきだと思われます。

* 歴史

[FIG(quote)[
[FIGCAPTION[
[4] RFC 2616 (HTTP/1.1) 14.40 Trailer
]FIGCAPTION]

> The Trailer general field value indicates that the given set of
header fields is present in the trailer of a message encoded with
chunked transfer-coding.

Trailer (尻尾) 全般領域値は、指定された頭領域の集合が
chunked (塊) 転送符号化で符号化されたメッセージの尻尾に
あることを示します。

- [CODE(ABNF)[       Trailer  = "Trailer" ":" 1#field-name]]

> An HTTP/1.1 message SHOULD include a Trailer header field in a
message using chunked transfer-coding with a non-empty trailer. Doing
so allows the recipient to know which header fields to expect in the trailer.

HTTP/1.1 メッセージは、空でない尻尾の塊転送符号化を使うメッセージには、
Trailer 頭領域を含める'''べき'''です。そうすることで、受信者は
どの頭領域が尻尾に巻かれて来ようかを知ることが出来ます。

> If no Trailer header field is present, the trailer SHOULD NOT include
any header fields. See section 3.6.1 for restrictions on the use of
trailer fields in a "chunked" transfer-coding.

Trailer 頭領域が無い場合、尻尾にはどんな頭領域も含める'''べきではありません'''。
「chunked」転送符号化で尻尾領域を使う際の制限については、
3.6.1節を参照して下さい。

> Message header fields listed in the Trailer header field MUST NOT
include the following header fields:

Trailer 頭欄に列せられるメッセージ頭欄には、
次に挙げる頭欄を含めては'''いけません'''。

>
- Transfer-Encoding
- Content-Length
- Trailer
]FIG]

** [CODE(HTTP)@en[[[Trailers:]]]] ヘッダー

[3] [[RFC 2616]] は [CODE(HTTP)[[[Trailer:]]]] [[ヘッダー]]のことを
[DFN[[CODE(HTTP)@en[[[Trailers:]]]]]] としているところがあり、
[[正誤表]]で訂正されています。

[REFS[
- [5] ''HTTP/1.1 Specification Errata'' <http://purl.org/NET/http-errata#trailer-hop>)
]REFS]

* メモ

[1] [CODE(HTTP)[Trailer:]] 欄に挙げてはみたけど、やっぱりや〜めた、ってのはありなのかな? どうなのかな?

[7] [[CGI]] や [[PHP]] のようなサーバー側の処理で[[応答]]を出力する時に、内容を送りつつ最後に確定した追加の欄を送る、という使い方が想定されているのでしょうが、実際のところ、この欄とその機能のちゃんとした実装があるのかすら不明です。
現状では実質使えない機能だと考えても良いでしょう。

更に、計算機や回線の性能はよくなってきていますから、
内容と欄を全て生成してから一気に送るというやり方でもほとんど問題がなくなってきています。
ですからこの欄もこのまま使われずに完全に忘れられるかもしれません。

[33] [CITE@en[HTTP Chunking peculiarities]]
( ([[Martin Holst Swende]] 著, [TIME[2014-04-03 17:07:05 +09:00]] 版))
<http://martin.swende.se/blog/HTTPChunked.html>

[34] [CITE@en[RFC 3507 - Internet Content Adaptation Protocol (ICAP)]]
( ([TIME[2014-06-08 07:17:07 +09:00]] 版))
<http://tools.ietf.org/html/rfc3507#section-4.3.1>

[47] [CITE[GoでHTTP Trailerを扱う - Qiita]]
([TIME[2015-08-08 00:41:25 +09:00]] 版)
<http://qiita.com/ono_matope/items/89ce7f491b791dece38c>

[48] [CITE[Issue 33325 - chromium - Support trailers for HTTP chunked transfer-coding - An open-source project to help move the web forward. - Google Project Hosting]]
([TIME[2015-08-08 00:58:34 +09:00]] 版)
<https://code.google.com/p/chromium/issues/detail?id=33325>

[49] [CITE@en[698313 – Headers in chunked transfer encoding trailers are not size limited]]
([TIME[2015-08-08 01:00:43 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=698313>

[FIG(quote)[
[FIGCAPTION[
[52] [CITE@en[Server Timing]]
([TIME[2015-07-18 02:12:22 +09:00]] 版)
<https://w3c.github.io/server-timing/#processing-model>
]FIGCAPTION]

> The user-agent must process Server-Timing header field communicated via a trailer field (see '''['''RFC7230''']''' section 4.1.2) using the same algorithm.

]FIG]


[53] [CITE@en[Access to the HTTP trailer · Issue #34 · whatwg/fetch]]
([TIME[2016-03-15 17:56:22 +09:00]] 版)
<https://github.com/whatwg/fetch/issues/34>

[54] [CITE@en[Editorial: rename end-of-file to end-of-body]]
([[annevk]]著, [TIME[2016-07-27 21:46:17 +09:00]])
<https://github.com/whatwg/fetch/commit/483ffd8c4984b306a262f3b11711747023c0d395>

[FIG(quote)[
[FIGCAPTION[
[55] [CITE@en[grpc/grpc: The C based gRPC (C++, Node.js, Python, Ruby, Objective-C, PHP, C#)]]
([TIME[2016-08-11 17:55:20 +09:00]])
<https://github.com/grpc/grpc>
]FIGCAPTION]

> Status and Trailing-Metadata are sent as HTTP/2 trailing headers (a.k.a., trailers).

]FIG]


[56] [CITE@en[Add trailer support to network responses]]
([[annevk]]著, [TIME[2016-08-10 15:12:40 +09:00]])
<https://github.com/whatwg/fetch/commit/427255ebd4b07c4912292dbb3a24f97bfa8d1c8a>

[57] [CITE@en[Response's trailer cannot use '''['''SameObject''']''']]
([[annevk]]著, [TIME[2017-02-14 01:08:08 +09:00]])
<https://github.com/whatwg/fetch/commit/7c256a597fb895910d212caf253737c7f5e2c4ae>

[58] [CITE@en[691599 - Add Fetch's Response's trailer attribute - chromium - Monorail]]
( ([TIME[2017-04-28 12:49:28 +09:00]]))
<https://bugs.chromium.org/p/chromium/issues/detail?id=691599>

[60] [CITE@en[Abortable fetch]]
([[jakearchibald]]著, [TIME[2017-09-20 21:59:57 +09:00]])
<https://github.com/whatwg/fetch/commit/0bcd5dfc71ef44319873887f4b83119bd6d0b71d>

[61] [CITE@en[Trailers · Issue #16 · httpwg/http-core]]
([TIME[2018-03-27 15:23:32 +09:00]])
<https://github.com/httpwg/http-core/issues/16>