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

6. メッセージ本文 (Message Body)

HTTP/1.1 メッセージのメッセージ本文 (存在する場合) は、リクエストまたはレスポンスのコンテンツ ([HTTP] の第 6.4 節) を運ぶために使用されます。メッセージ本文は、第 6.1 節で説明されているように転送コーディングが適用されていない限り、コンテンツと同一です。

message-body = *OCTET

メッセージ本文が HTTP/1.1 メッセージに存在するかどうかを判断する規則は、リクエストとレスポンスで異なります。

リクエストでのメッセージ本文の存在は、Content-Length または Transfer-Encoding ヘッダーフィールドによって通知されます。リクエストメッセージのフレーミングは、メソッドのセマンティクスから独立しています。

レスポンスでのメッセージ本文の存在は、第 6.3 節で詳述されているように、応答しているリクエストメソッドとレスポンスステータスコードの両方に依存します。これは、HTTP セマンティクス ([HTTP] の第 6.4.1 節) によってレスポンスコンテンツが許可される場合に対応します。

6.1. Transfer-Encoding

Transfer-Encoding ヘッダーフィールドは、メッセージ本文を形成するためにコンテンツに適用された (または適用される) 転送コーディングのシーケンスに対応する転送コーディング名をリストします。転送コーディングは第 7 節で定義されています。

Transfer-Encoding = #transfer-coding
; [HTTP]、第 10.1.4 節で定義

Transfer-Encoding は、7 ビット転送サービス上でバイナリデータの安全な転送を可能にするために設計された MIME の Content-Transfer-Encoding フィールド ([RFC2045]、第 6 節) に類似しています。ただし、安全な転送は 8 ビットクリーン転送プロトコルに対して異なる焦点を持っています。HTTP の場合、Transfer-Encoding は主に、動的に生成されるコンテンツを正確に区切ることを目的としています。また、転送中にのみ適用されるエンコーディングと、選択された表現の特性であるエンコーディングを区別する役割も果たします。

受信者は、チャンク転送コーディング (第 7.1 節) を解析できなければなりません (MUST)。これは、コンテンツサイズが事前にわからない場合のメッセージのフレーミングにおいて重要な役割を果たすためです。送信者は、メッセージ本文にチャンク転送コーディングを複数回適用してはなりません (MUST NOT) (つまり、すでにチャンクされたメッセージを再度チャンクすることは許可されていません)。チャンク以外の転送コーディングがリクエストのコンテンツに適用される場合、送信者は、メッセージが適切にフレーム化されることを保証するために、最終的な転送コーディングとしてチャンクを適用しなければなりません (MUST)。チャンク以外の転送コーディングがレスポンスのコンテンツに適用される場合、送信者は、最終的な転送コーディングとしてチャンクを適用するか、接続を閉じることでメッセージを終了しなければなりません (MUST)。

例:

Transfer-Encoding: gzip, chunked

これは、コンテンツが gzip コーディングを使用して圧縮され、次にメッセージ本文を形成する際にチャンクコーディングを使用してチャンク化されたことを示します。

Content-Encoding ([HTTP] の第 8.4.1 節) とは異なり、Transfer-Encoding は表現ではなくメッセージのプロパティです。リクエスト/レスポンスチェーンに沿った任意の受信者は、Transfer-Encoding フィールド値に対応する変更が行われると仮定して、受信した転送コーディングをデコードまたはメッセージ本文に追加の転送コーディングを適用してもかまいません (MAY)。エンコーディングパラメータに関する追加情報は、本仕様書で定義されていない他のヘッダーフィールドによって提供される場合があります。

Transfer-Encoding は、HEAD リクエストへのレスポンスまたは GET リクエストへの 304 (Not Modified) レスポンス ([HTTP] の第 15.4.5 節) で送信されてもかまいません (MAY)。どちらもメッセージ本文を含みませんが、リクエストが無条件の GET であった場合にオリジンサーバーがメッセージ本文に転送コーディングを適用したであろうことを示します。ただし、この指示は必須ではありません。レスポンスチェーン上の任意の受信者 (オリジンサーバーを含む) が、転送コーディングが不要な場合に削除できるためです。

サーバーは、1xx (Informational) または 204 (No Content) のステータスコードを持つ任意のレスポンスで Transfer-Encoding ヘッダーフィールドを送信してはなりません (MUST NOT)。サーバーは、CONNECT リクエストへの任意の 2xx (Successful) レスポンスで Transfer-Encoding ヘッダーフィールドを送信してはなりません (MUST NOT) ([HTTP] の第 9.3.6 節)。

理解できない転送コーディングを含むリクエストメッセージを受信するサーバーは、501 (Not Implemented) で応答すべきです (SHOULD)。

Transfer-Encoding は HTTP/1.1 で追加されました。HTTP/1.0 サポートのみを通知する実装は、転送エンコードされたコンテンツの処理方法を理解していないと一般的に想定されており、Transfer-Encoding を含む HTTP/1.0 メッセージは、転送中にチャンク転送コーディングが適切に処理されずに転送された可能性があります。

クライアントは、サーバーが HTTP/1.1 リクエスト (またはそれ以降のマイナーリビジョン) を処理することがわかっていない限り、Transfer-Encoding を含むリクエストを送信してはなりません (MUST NOT)。そのような知識は、特定のユーザー構成の形式、または以前に受信したレスポンスのバージョンを記憶することによるものです。サーバーは、対応するリクエストが HTTP/1.1 (またはそれ以降のマイナーリビジョン) を示していない限り、Transfer-Encoding を含むレスポンスを送信してはなりません (MUST NOT)。

Transfer-Encoding の初期の実装は、メッセージフレーミングのためにチャンク転送コーディングと、プログレスバーで使用するための推定 Content-Length ヘッダーフィールドの両方を送信することがありました。これが、Transfer-Encoding が相互に互換性がないのではなく、Content-Length を上書きするものとして定義されている理由です。残念ながら、そのようなメッセージを転送すると、下流の受信者が本仕様書に従ってメッセージを解析できない場合、特に下流の受信者が HTTP/1.0 のみを実装している場合、リクエストスマグリング (第 11.2 節) またはレスポンス分割 (第 11.1 節) 攻撃に関する脆弱性につながる可能性があります。

サーバーは、Content-Length と Transfer-Encoding の両方を含むリクエストを拒否するか、Transfer-Encoding のみに従ってそのようなリクエストを処理してもかまいません (MAY)。いずれにしても、サーバーは、潜在的な攻撃を回避するために、そのようなリクエストに応答した後に接続を閉じなければなりません (MUST)。

Transfer-Encoding ヘッダーフィールドを含む HTTP/1.0 メッセージを受信するサーバーまたはクライアントは、Content-Length が存在する場合でも、フレーミングに欠陥があるかのようにメッセージを処理し、メッセージの処理後に接続を閉じなければなりません (MUST)。メッセージ送信者は、メッセージの一部をバッファーに保持している可能性があり、接続のさらなる使用によって誤解される可能性があるためです。

6.2. Content-Length

メッセージに Transfer-Encoding ヘッダーフィールドがない場合、Content-Length ヘッダーフィールド ([HTTP] の第 8.6 節) は、潜在的なコンテンツの予想されるサイズを 10 進数のオクテット数として提供できます。コンテンツを含むメッセージの場合、Content-Length フィールド値は、データ (およびメッセージ) がどこで終了するかを決定するために必要なフレーミング情報を提供します。コンテンツを含まないメッセージの場合、Content-Length は選択された表現のサイズを示します ([HTTP] の第 8.6 節)。

送信者は、Transfer-Encoding ヘッダーフィールドを含む任意のメッセージで Content-Length ヘッダーフィールドを送信してはなりません (MUST NOT)。

注: メッセージフレーミングのための HTTP の Content-Length の使用は、同じフィールドの MIME での使用とは大きく異なります。MIME では、これは "message/external-body" メディアタイプ内でのみ使用されるオプションフィールドです。

6.3. メッセージ本文の長さ (Message Body Length)

メッセージ本文の長さは、次のいずれか (優先順位順) によって決定されます:

  1. HEAD リクエストへの任意のレスポンス、および 1xx (Informational)、204 (No Content)、または 304 (Not Modified) ステータスコードを持つ任意のレスポンスは、メッセージに存在するヘッダーフィールドに関係なく、常にヘッダーフィールドの後の最初の空行で終了するため、メッセージ本文またはトレーラーセクションを含むことはできません。

  2. CONNECT リクエストへの任意の 2xx (Successful) レスポンスは、ヘッダーフィールドを終了する空行の直後に接続がトンネルになることを意味します。クライアントは、そのようなメッセージで受信した任意の Content-Length または Transfer-Encoding ヘッダーフィールドを無視しなければなりません (MUST)。

  3. Transfer-Encoding と Content-Length ヘッダーフィールドの両方を含むメッセージが受信された場合、Transfer-Encoding が Content-Length を上書きします。そのようなメッセージは、リクエストスマグリング (第 11.2 節) またはレスポンス分割 (第 11.1 節) の試みを示している可能性があり、エラーとして処理されるべきです。メッセージの転送を選択する中継装置は、メッセージを下流に転送する前に、受信した Content-Length フィールドを削除し、Transfer-Encoding を (以下で説明するように) 処理しなければなりません (MUST)。

  4. Transfer-Encoding ヘッダーフィールドが存在し、チャンク転送コーディング (第 7.1 節) が最終エンコーディングである場合、メッセージ本文の長さは、転送コーディングがデータが完了したことを示すまで、チャンクされたデータを読み取ってデコードすることによって決定されます。

    Transfer-Encoding ヘッダーフィールドがレスポンスに存在し、チャンク転送コーディングが最終エンコーディングでない場合、メッセージ本文の長さは、サーバーによって接続が閉じられるまで接続を読み取ることによって決定されます。

    Transfer-Encoding ヘッダーフィールドがリクエストに存在し、チャンク転送コーディングが最終エンコーディングでない場合、メッセージ本文の長さを確実に決定することはできません。サーバーは 400 (Bad Request) ステータスコードで応答し、次に接続を閉じなければなりません (MUST)。

  5. メッセージが Transfer-Encoding なしで受信され、無効な Content-Length ヘッダーフィールドを持つ場合、メッセージフレーミングは無効であり、受信者は回復不可能なエラーとして処理しなければなりません (MUST)。ただし、フィールド値がカンマ区切りリスト ([HTTP] の第 5.6.1 節) として正常に解析でき、リスト内のすべての値が有効で、リスト内のすべての値が同じである場合を除きます (この場合、メッセージはその単一の値を Content-Length フィールド値として使用して処理されます)。回復不可能なエラーがリクエストメッセージにある場合、サーバーは 400 (Bad Request) ステータスコードで応答し、次に接続を閉じなければなりません (MUST)。プロキシが受信したレスポンスメッセージにある場合、プロキシはサーバーへの接続を閉じ、受信したレスポンスを破棄し、クライアントに 502 (Bad Gateway) レスポンスを送信しなければなりません (MUST)。ユーザーエージェントが受信したレスポンスメッセージにある場合、ユーザーエージェントはサーバーへの接続を閉じ、受信したレスポンスを破棄しなければなりません (MUST)。

  6. 有効な Content-Length ヘッダーフィールドが Transfer-Encoding なしで存在する場合、その 10 進値は、オクテット単位で期待されるメッセージ本文の長さを定義します。送信者が接続を閉じるか、受信者が指定されたオクテット数を受信する前にタイムアウトする場合、受信者はメッセージを不完全と見なし、接続を閉じなければなりません (MUST)。

  7. これがリクエストメッセージであり、上記のいずれも当てはまらない場合、メッセージ本文の長さは 0 です (メッセージ本文は存在しません)。

  8. それ以外の場合、これは宣言されたメッセージ本文の長さを持たないレスポンスメッセージであるため、メッセージ本文の長さは、サーバーが接続を閉じる前に受信したオクテット数によって決定されます。

正常に完了したクローズ区切りレスポンスメッセージと、ネットワーク障害によって中断された部分的に受信したメッセージを区別する方法がないため、サーバーは可能な限りエンコーディングまたは長さ区切りメッセージを生成すべきです (SHOULD)。クローズ区切り機能は、主に HTTP/1.0 との下位互換性のために存在します。

注: リクエストメッセージは、長さまたは転送コーディングによって常に明示的にフレーム化されるため、クローズ区切りされることはありません。両方が存在しない場合、リクエストがヘッダーセクションの直後に終了することを意味します。

サーバーは、メッセージ本文を含むが Content-Length を持たないリクエストを、411 (Length Required) で応答して拒否してもかまいません (MAY)。

チャンク以外の転送コーディングが適用されていない限り、メッセージ本文を含むリクエストを送信するクライアントは、メッセージ本文の長さが事前にわかっている場合、チャンク転送コーディングではなく、有効な Content-Length ヘッダーフィールドを使用すべきです (SHOULD)。一部の既存のサービスは、チャンク転送コーディングを理解しているにもかかわらず、チャンクに対して 411 (Length Required) ステータスコードで応答するためです。これは通常、そのようなサービスが、呼び出される前にコンテンツの長さを必要とするゲートウェイ経由で実装されており、サーバーが処理前にリクエスト全体をバッファリングできないか、望まないためです。

メッセージ本文を含むリクエストを送信するユーザーエージェントは、有効な Content-Length ヘッダーフィールドを送信するか、チャンク転送コーディングを使用しなければなりません (MUST)。クライアントは、サーバーが HTTP/1.1 (またはそれ以降) のリクエストを処理することがわかっていない限り、チャンク転送コーディングを使用してはなりません (MUST NOT)。そのような知識は、特定のユーザー構成の形式、または以前に受信したレスポンスのバージョンを記憶することによるものです。

接続上の最後のリクエストに対する最終レスポンスが完全に受信され、読み取る追加データが残っている場合、ユーザーエージェントは残りのデータを破棄するか、そのデータが以前のメッセージ本文の一部として属するかどうかを判断しようとしてもかまいません (MAY)。これは、以前のメッセージの Content-Length 値が正しくない場合に当てはまる可能性があります。クライアントは、そのような余分なデータを別のレスポンスとして処理、キャッシュ、または転送してはなりません (MUST NOT)。そのような動作はキャッシュポイズニングに脆弱であるためです。