メインコンテンツまでスキップ

4. 転送コーディング

転送コーディング名は、ネットワークを通じた "安全な転送" を保証するためにペイロード本文に適用された、適用できる、または適用する必要がある可能性のあるエンコーディング変換を示すために使用されます。これは、転送コーディングが、転送されている表現の特性ではなくメッセージの特性であるという点で、コンテンツコーディングとは異なります。

transfer-coding    = "chunked" ; Section 4.1
/ "compress" ; Section 4.2.1
/ "deflate" ; Section 4.2.2
/ "gzip" ; Section 4.2.3
/ transfer-extension
transfer-extension = token *( OWS ";" OWS transfer-parameter )

パラメータは、name または name=value の組の形式です。

transfer-parameter = token BWS "=" BWS ( token / quoted-string )

すべての転送コーディング名は大文字と小文字を区別せず、セクション 8.4 で定義されているように、HTTP Transfer Coding レジストリに登録されるべきです。それらは、TE (セクション 4.3) および Transfer-Encoding (セクション 3.3.1) ヘッダーフィールドで使用されます。

4.1. チャンク転送コーディング​

chunked 転送コーディングは、ペイロード本文を、それぞれが独自のサイズ指標を持つ一連のチャンクとして転送するために、ペイロード本文をラップし、その後にヘッダーフィールドを含む任意 (OPTIONAL) のトレーラーが続きます。chunked は、サイズが不明なコンテンツストリームを長さで区切られたバッファの列として転送することを可能にし、それにより、送信者は接続の持続性を維持でき、受信者はメッセージ全体を受信したときを知ることができます。

chunked-body   = *chunk
last-chunk
trailer-part
CRLF

chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
chunk-size = 1*HEXDIG
last-chunk = 1*("0") [ chunk-ext ] CRLF

chunk-data = 1*OCTET ; a sequence of chunk-size octets

chunk-size フィールドは、chunk-data のサイズをオクテット単位で示す 16 進数の文字列です。chunked 転送コーディングは、chunk-size が 0 のチャンクが受信され (その後にトレーラーが続く場合があります)、最後に空行で終端されたときに完了します。

受信者は、chunked 転送コーディングを解析およびデコードできなければなりません (MUST)。

4.1.1. チャンク拡張​

chunked エンコーディングでは、各チャンクが、chunk-size の直後に 0 個以上のチャンク拡張を含むことができ、チャンクごとのメタデータ (署名やハッシュなど)、メッセージ途中の制御情報、またはメッセージ本文サイズのランダム化を提供するために使用されます。

chunk-ext      = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )

chunk-ext-name = token
chunk-ext-val = token / quoted-string

chunked エンコーディングは各接続に固有であり、より高レベルのアプリケーションが拡張を検査する機会を得る前に、各受信者 (仲介者を含む) によって除去または再コーディングされる可能性が高いです。したがって、チャンク拡張の使用は、一般に ("long polling" のようにクライアントとサーバーがチャンク拡張の使用について共通の期待を持ち得る) 特殊な HTTP サービス、またはエンドツーエンドで保護された接続内でのパディングに限定されます。

受信者は、認識しないチャンク拡張を無視しなければなりません (MUST)。サーバーは、リクエストで受信したチャンク拡張の合計長を、提供するサービスにとって妥当な量に制限すべきであり (メッセージの他の部分に長さ制限とタイムアウトを適用するのと同じように)、その量を超えた場合は適切な 4xx (Client Error) レスポンスを生成すべきです。

4.1.2. チャンクトレーラー部​

トレーラーにより、送信者は、メッセージ本文の送信中に動的に生成される可能性のあるメタデータ (メッセージ整合性チェック、デジタル署名、または後処理ステータスなど) を提供するために、チャンク化されたメッセージの末尾に追加のフィールドを含めることができます。トレーラーフィールドは、メッセージのヘッダーセクションではなくチャンク化されたトレーラーで送信される点を除き、ヘッダーフィールドと同一です。

trailer-part   = *( header-field CRLF )

送信者は、メッセージのフレーミング (例えば Transfer-Encoding および Content-Length)、ルーティング (例えば Host)、リクエスト修飾子 ([RFC7231] のセクション 5 の制御および条件など)、認証 (例えば [RFC7235] および [RFC6265] を参照してください)、レスポンス制御データ (例えば [RFC7231] のセクション 7.1 を参照してください)、またはペイロードの処理方法の決定 (例えば Content-Encoding、Content-Type、Content-Range、および Trailer) に必要なフィールドを含むトレーラーを生成してはなりません (MUST NOT)。

空でないトレーラーを含むチャンク化されたメッセージを受信した場合、受信者は、(上記で禁止されているものを除く) それらのフィールドを、メッセージのヘッダーセクションに追加されたものであるかのように処理してもかまいません (MAY)。受信者は、トレーラーで送信することが禁止されているフィールドを無視しなければなりません (MUST) (またはエラーと見なさなければなりません)。それらをヘッダーセクションに存在していたかのように処理すると、外部のセキュリティフィルターを迂回する可能性があるためです。

セクション 4.3 で説明されているように、リクエストが "trailers" が許容されることを示す TE ヘッダーフィールドを含まない限り、サーバーは、ユーザーエージェントが受信する必要があると考えるトレーラーフィールドを生成すべきではありません (SHOULD NOT)。"trailers" を含む TE がなければ、サーバーは、トレーラーフィールドがユーザーエージェントへの経路上で黙って破棄される可能性があると想定すべきです。この要件により、仲介者は、レスポンス全体をバッファリングすることなく、デチャンクされたメッセージを HTTP/1.0 の受信者に転送できます。

4.1.3. チャンクのデコード​

chunked 転送コーディングをデコードするプロセスは、擬似コードで次のように表せます:

length := 0
read chunk-size, chunk-ext (if any), and CRLF
while (chunk-size > 0) {
read chunk-data and CRLF
append chunk-data to decoded-body
length := length + chunk-size
read chunk-size, chunk-ext (if any), and CRLF
}
read trailer field
while (trailer field is not empty) {
if (trailer field is allowed to be sent in a trailer) {
append trailer field to existing header fields
}
read trailer-field
}
Content-Length := length
Remove "chunked" from Transfer-Encoding
Remove Trailer from existing header fields

4.2. 圧縮コーディング​

以下で定義するコーディングは、メッセージのペイロードを圧縮するために使用できます。

4.2.1. Compress コーディング​

"compress" コーディングは、UNIX のファイル圧縮プログラム "compress" によって一般的に生成される、適応型 Lempel-Ziv-Welch (LZW) コーディング [Welch] です。受信者は、"x-compress" を "compress" と等価と見なすべきです (SHOULD)。

4.2.2. Deflate コーディング​

"deflate" コーディングは、Lempel-Ziv (LZ77) 圧縮アルゴリズムと Huffman コーディングの組み合わせを使用する "deflate" 圧縮データストリーム [RFC1951] を含む "zlib" データ形式 [RFC1950] です。

注: 一部の非準拠の実装は、zlib ラッパーなしで "deflate" 圧縮データを送信します。

4.2.3. Gzip コーディング​

"gzip" コーディングは、gzip ファイル圧縮プログラム [RFC1952] によって一般的に生成される、32 ビット巡回冗長検査 (CRC) を伴う LZ77 コーディングです。受信者は、"x-gzip" を "gzip" と等価と見なすべきです (SHOULD)。

4.3. TE​

リクエスト内の "TE" ヘッダーフィールドは、chunked 以外にクライアントがレスポンスで受け入れる意思のある転送コーディング、およびクライアントが chunked 転送コーディングでトレーラーフィールドを受け入れる意思があるかどうかを示します。

TE のフィールド値は、転送コーディング名 (それぞれが任意のパラメータを許可します (セクション 4 で説明)) および/またはキーワード "trailers" のコンマ区切りリストで構成されます。クライアントは TE で chunked 転送コーディング名を送信してはなりません (MUST NOT)。chunked は HTTP/1.1 の受信者にとって常に許容されます。

TE        = #t-codings
t-codings = "trailers" / ( transfer-coding [ t-ranking ] )
t-ranking = OWS ";" OWS "q=" rank
rank = ( "0" [ "." 0*3DIGIT ] )
/ ( "1" [ "." 0*3("0") ] )

以下に、TE の使用例を 3 つ示します。

TE: deflate
TE:
TE: trailers, deflate;q=0.5

キーワード "trailers" の存在は、クライアントが、自身および任意の下流のクライアントを代表して、セクション 4.1.2 で定義されている chunked 転送コーディングでトレーラーフィールドを受け入れる意思があることを示します。仲介者からのリクエストの場合、これは次のいずれかを意味します: (a) すべての下流のクライアントが、転送されたレスポンスでトレーラーフィールドを受け入れる意思がある、または (b) 仲介者が下流の受信者の代わりにレスポンスをバッファリングしようと試みる。HTTP/1.1 は、仲介者がレスポンス全体をバッファリングできることを保証されるように、chunked レスポンスのサイズを制限する手段を何ら定義していないことに注意してください。

複数の転送コーディングが許容される場合、クライアントは、大文字と小文字を区別しない "q" パラメータ (コンテンツネゴシエーションフィールドで使用される qvalue に類似、[RFC7231] のセクション 5.3.1) を用いてコーディングを優先度順に順位付けしてもかまいません (MAY)。順位値は 0 から 1 の範囲の実数で、0.001 が最も優先度が低く、1 が最も優先度が高くなります。値 0 は "許容されない" を意味します。

TE のフィールド値が空であるか、TE フィールドが存在しない場合、唯一許容される転送コーディングは chunked です。転送コーディングのないメッセージは常に許容されます。

TE ヘッダーフィールドは直接の接続にのみ適用されるため、TE の送信者は、そのセマンティクスをサポートしない仲介者によって TE フィールドが転送されるのを防ぐために、Connection ヘッダーフィールド (セクション 6.1) 内で "TE" 接続オプションも送信しなければなりません (MUST)。

4.4. Trailer​

メッセージが chunked 転送コーディングでエンコードされたメッセージ本文を含み、送信者がメッセージの末尾にトレーラーフィールドの形式でメタデータを送信したい場合、送信者は、トレーラーにどのフィールドが存在するかを示すために、メッセージ本文の前に Trailer ヘッダーフィールドを生成すべきです (SHOULD)。これにより、受信者は本文の処理を開始する前にそのメタデータの受信に備えることができ、メッセージがストリーミングされていて受信者がオンザフライで整合性チェックを確認したい場合に有用です。

Trailer = 1#field-name