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

6. メッセージ抽象化 (Message Abstraction)

HTTPの各メジャーバージョンは、メッセージを通信するための独自の構文を定義しています。このセクションでは、これらのメッセージ特性、共通構造、およびセマンティクスを伝達する能力の一般化に基づいて、HTTPメッセージの抽象データ型を定義します。この抽象化は、あるバージョンのメッセージが他のバージョンを経由してリレーされても、その意味を変更することなく、HTTPバージョンに依存しない送信者と受信者の要件を定義するために使用されます。

「メッセージ」(message) は以下で構成されます:

  • メッセージを記述およびルーティングするための制御データ
  • その制御データを拡張し、送信者、メッセージ、コンテンツ、またはコンテキストに関する追加情報を伝達するための名前/値ペアのヘッダールックアップテーブル
  • 潜在的に無制限のコンテンツストリーム
  • コンテンツ送信中に取得された情報を伝達するための名前/値ペアのトレーラールックアップテーブル

フレーミングと制御データが最初に送信され、その後ヘッダーテーブル用のフィールドを含むヘッダーセクションが続きます。メッセージにコンテンツが含まれる場合、コンテンツはヘッダーセクションの後に送信され、その後にトレーラーテーブル用のフィールドを含む可能性のあるトレーラーセクションが続く場合があります。

メッセージはストリームとして処理されることが期待されており、そのストリームの目的とその継続的な処理は読み取り中に明らかになります。したがって、制御データは受信者がすぐに知る必要があることを記述し、ヘッダーフィールドはコンテンツを受信する前に知る必要があることを記述し、コンテンツ(存在する場合)はおそらく受信者がメッセージセマンティクスを満たすために望むまたは必要とするものを含み、トレーラーフィールドはコンテンツを送信する前に未知であったオプションのメタデータを提供します。

メッセージは「自己記述的」(self-descriptive) であることが意図されています。受信者がメッセージについて知る必要があるすべてのことは、転送中に圧縮または省略された部分をデコードまたは再構成した後、送信者の現在のアプリケーション状態(以前のメッセージを介して確立された)を理解することなく、メッセージ自体を見ることで判断できます。ただし、クライアントは、対応する応答を解析、解釈、またはキャッシュする際にリクエストの知識を保持しなければなりません (MUST)。たとえば、HEADメソッドへの応答は、GETへの応答の開始部分と同じように見えますが、同じ方法で解析することはできません。

このメッセージ抽象化は、HTTPの多くのバージョンにわたる一般化であり、一部のバージョンには見られない機能を含んでいることに注意してください。たとえば、トレーラーはHTTP/1.1チャンク転送コーディング内で、コンテンツ後のトレーラーセクションとして導入されました。同等の機能は、各ストリームを終了するヘッダーブロック内のHTTP/2およびHTTP/3に存在します。

6.1. フレーミングと完全性 (Framing and Completeness)

メッセージフレーミング (Message framing) は、各メッセージが開始および終了する方法を示し、各メッセージが同じ接続上の他のメッセージまたはノイズと区別できるようにします。HTTPの各メジャーバージョンは、独自のフレーミングメカニズムを定義しています。

HTTP/0.9およびHTTP/1.0の初期の展開では、基礎となる接続のクロージャを使用して応答を終了していました。下位互換性のため、この暗黙的なフレーミングはHTTP/1.1でも許可されています。ただし、接続が早期に閉じられた場合、暗黙的なフレーミングは不完全な応答を区別できない可能性があります。そのため、ほぼすべての最新の実装は、長さで区切られたメッセージデータのシーケンスの形式の明示的なフレーミングを使用しています。

メッセージは、そのフレーミングによって示されるすべてのオクテットが利用可能な場合に「完全」(complete) であると見なされます。明示的なフレーミングが使用されていない場合、基礎となる接続のクローズによって終了する応答メッセージは、トランスポートレベルのエラーがそれが完全でないことを示さない限り、不完全な応答と区別できない可能性があるにもかかわらず、完全であると見なされることに注意してください。

6.2. 制御データ (Control Data)

メッセージは、その主な目的を記述する制御データで始まります。リクエストメッセージの制御データには、リクエストメソッド (request method) (セクション9)、リクエストターゲット (request target) (セクション7.1)、およびプロトコルバージョン (protocol version) (セクション2.5) が含まれます。応答メッセージの制御データには、ステータスコード (status code) (セクション15)、オプションの理由フレーズ (reason phrase)、およびプロトコルバージョンが含まれます。

HTTP/1.1 ([HTTP/1.1]) 以前では、制御データはメッセージの最初の行として送信されます。HTTP/2 ([HTTP/2]) およびHTTP/3 ([HTTP/3]) では、制御データは予約された名前プレフィックス(例:":authority")を持つ疑似ヘッダーフィールドとして送信されます。

すべてのHTTPメッセージにはプロトコルバージョンがあります。使用されているバージョンに応じて、メッセージ内で明示的に識別されるか、メッセージが受信される接続によって推論される可能性があります。受信者は、そのバージョン情報を使用して、その送信者との後続の通信の制限または可能性を判断します。

メッセージが仲介者によって転送される場合、プロトコルバージョンはその仲介者が使用するバージョンを反映するように更新されます。Viaヘッダーフィールド (Section 7.6.3) は、転送されたメッセージ内でアップストリームプロトコル情報を伝達するために使用されます。

クライアントは、クライアントが準拠している最高バージョンで、そのメジャーバージョンがサーバーがサポートする最高バージョンよりも高くない(既知の場合)リクエストバージョンを送信すべきです (SHOULD)。クライアントは、準拠していないバージョンを送信してはなりません (MUST NOT)。

クライアントは、サーバーがHTTP仕様を誤って実装していることが既知である場合、より低いリクエストバージョンを送信してもよい (MAY) ですが、クライアントが少なくとも1つの通常のリクエストを試み、応答ステータスコードまたはヘッダーフィールド(例:Server)からサーバーがより高いリクエストバージョンを不適切に処理していると判断した後にのみ可能です。

サーバーは、サーバーが準拠している最高バージョンで、そのメジャーバージョンがリクエストで受信されたバージョン以下である応答バージョンを送信すべきです (SHOULD)。サーバーは、準拠していないバージョンを送信してはなりません (MUST NOT)。サーバーは、何らかの理由でクライアントのメジャープロトコルバージョンのサービスを拒否したい場合、505 (HTTP Version Not Supported) 応答を送信できます。

実装しているメジャーバージョン番号と実装しているものよりも高いマイナーバージョン番号を持つメッセージを受信する受信者は、そのメッセージを、受信者が準拠しているそのメジャーバージョン内の最高のマイナーバージョンであるかのように処理すべきです (SHOULD)。受信者は、より高いマイナーバージョンを持つメッセージが、そのより高いバージョンのサポートをまだ示していない受信者に送信される場合、同じメジャーバージョンの任意の実装によって安全に処理されるのに十分な下位互換性があると仮定できます。

6.3. ヘッダーフィールド (Header Fields)

コンテンツの前に送信または受信されるフィールド (Section 5) は、「ヘッダーフィールド」(header fields)(または口語的には単に「ヘッダー」(headers))と呼ばれます。

メッセージの「ヘッダーセクション」(header section) は、ヘッダーフィールド行のシーケンスで構成されます。各ヘッダーフィールドは、メッセージセマンティクスを変更または拡張したり、送信者を記述したり、コンテンツを定義したり、追加のコンテキストを提供したりする場合があります。

注記: 名前付きフィールドがヘッダーセクションでのみ送信が許可されている場合、特に「ヘッダーフィールド」と呼びます。

6.4. コンテンツ (Content)

HTTPメッセージは、多くの場合、メッセージ「コンテンツ」(content) として完全または部分的な表現を転送します。これは、メッセージフレーミングによって区切られた、ヘッダーセクションの後に送信されるオクテットのストリームです。

このコンテンツの抽象的な定義は、メッセージフレーミングから抽出された後のデータを反映しています。たとえば、HTTP/1.1メッセージボディ ([HTTP/1.1] のセクション6) は、チャンク転送コーディングでエンコードされたデータのストリーム(データチャンクのシーケンス、1つのゼロ長チャンク、およびトレーラーセクション)で構成される場合がありますが、同じメッセージのコンテンツには、転送コーディングがデコードされた後のデータストリームのみが含まれます。チャンク長、チャンクフレーミング構文、またはトレーラーフィールド (Section 6.5) は含まれません。

注記: 一部のフィールド名には「Content-」プレフィックスがあります。これは非公式の慣例です。これらのフィールドの一部は上記で定義されたメッセージのコンテンツを参照しますが、他のフィールドは選択された表現 (Section 3.2) にスコープされています。曖昧さを解消するには、個々のフィールドの定義を参照してください。

6.4.1. コンテンツセマンティクス (Content Semantics)

リクエストのコンテンツの目的は、メソッドセマンティクス (Section 9) によって定義されます。

たとえば、PUTリクエスト (Section 9.3.4) のコンテンツの表現は、リクエストが正常に適用された後のターゲットリソースの望ましい状態を表しますが、POSTリクエスト (Section 9.3.3) のコンテンツの表現は、ターゲットリソースによって処理される情報を表します。

応答では、コンテンツの目的は、リクエストメソッド、応答ステータスコード (Section 15)、およびそのコンテンツを記述する応答フィールドによって定義されます。たとえば、GET (Section 9.3.1) に対する200 (OK) 応答のコンテンツは、メッセージ発信日時 (Section 6.6.1) の時点で観察されたターゲットリソースの現在の状態を表しますが、POSTへの応答の同じステータスコードのコンテンツは、処理結果またはprocessingを適用した後のターゲットリソースの新しい状態のいずれかを表す場合があります。

GETに対する206 (Partial Content) 応答のコンテンツには、選択された表現の単一の部分、またはSection 15.3.7で説明されているように、その表現の複数の部分を含むマルチパートメッセージボディのいずれかが含まれます。

エラーステータスコードを持つ応答メッセージには、通常、エラー条件を表すコンテンツが含まれます。このコンテンツは、エラー状態と解決のために推奨される手順を記述します。

HEADリクエストメソッド (Section 9.3.2) への応答には、コンテンツは含まれません。関連する応答ヘッダーフィールドは、リクエストメソッドがGET (Section 9.3.1) であった場合にそれらの値がどうであったかを示すだけです。

CONNECTリクエストメソッド (Section 9.3.6) に対する2xx (Successful) 応答は、コンテンツを持つ代わりに、接続をトンネルモードに切り替えます。

すべての1xx (Informational)、204 (No Content)、および304 (Not Modified) 応答には、コンテンツは含まれません。

他のすべての応答にはコンテンツが含まれますが、そのコンテンツは長さゼロの場合があります。

6.4.2. コンテンツの識別 (Identifying Content)

完全または部分的な表現がメッセージコンテンツとして転送される場合、送信者がその特定の表現に対応するリソースの識別子を提供するか、受信者が識別子を決定することが望ましい場合があります。たとえば、「現在の天気予報」のリソースに対してGETリクエストを行うクライアントは、返されたコンテンツに固有の識別子(例:「20210720T1711のラグナビーチの天気予報」)を必要とする場合があります。これは、時間の経過とともに変化する表現を持つことが予想されるリソースからのコンテンツを共有またはブックマークする場合に役立ちます。

リクエストメッセージの場合:

  • リクエストにContent-Locationヘッダーフィールドがある場合、送信者は、コンテンツがContent-Locationフィールド値によって識別されるリソースの表現であることを主張します。ただし、そのような主張は、他の手段(この仕様では定義されていません)によって検証できない限り、信頼できません。この情報は、リビジョン履歴リンクには役立つ場合があります。

  • それ以外の場合、コンテンツはHTTPによって識別されませんが、コンテンツ自体内でより具体的な識別子が提供される場合があります。

応答メッセージの場合、一致が見つかるまで以下のルールが順番に適用されます:

  1. リクエストメソッドがHEADであるか、応答ステータスコードが204 (No Content) または304 (Not Modified) である場合、応答にコンテンツはありません。

  2. リクエストメソッドがGETで、応答ステータスコードが200 (OK) の場合、コンテンツはターゲットリソース (Section 7.1) の表現です。

  3. リクエストメソッドがGETで、応答ステータスコードが203 (Non-Authoritative Information) の場合、コンテンツは仲介者によって提供されたターゲットリソースの潜在的に変更または拡張された表現です。

  4. リクエストメソッドがGETで、応答ステータスコードが206 (Partial Content) の場合、コンテンツはターゲットリソースの表現の1つ以上の部分です。

  5. 応答にContent-Locationヘッダーフィールドがあり、そのフィールド値がターゲットURIと同じURIへの参照である場合、コンテンツはターゲットリソースの表現です。

  6. 応答にContent-Locationヘッダーフィールドがあり、そのフィールド値がターゲットURIとは異なるURIへの参照である場合、送信者は、コンテンツがContent-Locationフィールド値によって識別されるリソースの表現であることを主張します。ただし、そのような主張は、他の手段(この仕様では定義されていません)によって検証できない限り、信頼できません。

  7. それ以外の場合、コンテンツはHTTPによって識別されませんが、コンテンツ自体内でより具体的な識別子が提供される場合があります。

6.5. トレーラーフィールド (Trailer Fields)

「トレーラーセクション」(trailer section) 内に配置されるフィールド (Section 5) は、「トレーラーフィールド」(trailer fields)(または口語的には単に「トレーラー」(trailers))と呼ばれます。トレーラーフィールドは、メッセージ整合性チェック、デジタル署名、配信メトリクス、または後処理ステータス情報を提供するのに役立ちます。

トレーラーフィールドは、ヘッダーセクションが完了した時点で既知のメッセージセマンティクスと矛盾しないように、ヘッダーセクションのフィールドとは別に処理および保存されるべきです。特定のヘッダーフィールドの存在または不在は、トレーラーが受信される前にメッセージ全体のルーティングまたは処理のために行われた選択に影響を与える可能性があります。これらの選択は、後でトレーラーフィールドが発見されても取り消すことはできません。

6.5.1. トレーラー使用の制限 (Limitations on Use of Trailers)

トレーラーセクションは、使用中のHTTPバージョンでサポートされ、明示的なフレーミングメカニズムによって有効化されている場合にのみ可能です。たとえば、HTTP/1.1のチャンク転送コーディングでは、コンテンツの後にトレーラーセクションを送信できます ([HTTP/1.1] のセクション7.1.2)。

多くのフィールドは、メッセージフレーミング、ルーティング、認証、リクエスト修飾子、応答制御、またはコンテンツ形式を記述するフィールドなど、コンテンツを受信する前に評価が必要であるため、ヘッダーセクションの外では処理できません。送信者は、対応するヘッダーフィールド名の定義がトレーラーでフィールドを送信することを許可していることを知っている場合を除き、トレーラーフィールドを生成してはなりません (MUST NOT)。

トレーラーフィールドは、あるプロトコルバージョンから別のプロトコルバージョンにメッセージを転送する仲介者による処理が困難な場合があります。メッセージ全体が転送中にバッファリングできる場合、一部の仲介者は転送する前にトレーラーフィールドをヘッダーセクションに(適切に)マージできます。ただし、ほとんどの場合、トレーラーは単に破棄されます。受信者は、対応するヘッダーフィールド定義を理解し、その定義がトレーラーフィールド値を安全にマージする方法を明示的に許可および定義している場合を除き、トレーラーフィールドをヘッダーセクションにマージしてはなりません (MUST NOT)。

リクエストのTEヘッダーフィールド (Section 10.1.4) にキーワード「trailers」が存在することは、クライアント自身およびすべてのダウンストリームクライアントに代わって、クライアントがトレーラーフィールドを受け入れることを示します。仲介者からのリクエストの場合、これは、すべてのダウンストリームクライアントが転送された応答でトレーラーフィールドを受け入れることを意味します。「trailers」の存在は、クライアントが応答内の特定のトレーラーフィールドを処理することを意味するわけではないことに注意してください。トレーラーセクションがいずれかのクライアントによってドロップされないことだけを意味します。

トレーラーフィールドが転送中に破棄される可能性があるため、サーバーは、ユーザーエージェントが受信する必要があると考えるトレーラーフィールドを生成すべきではありません (SHOULD NOT)。

6.5.2. トレーラーフィールドの処理 (Processing Trailer Fields)

「Trailer」ヘッダーフィールド (Section 6.6.2) は、トレーラーセクションで送信される可能性の高いフィールドを示すために送信でき、受信者がコンテンツを処理する前にそれらの受信に備えることができます。たとえば、フィールド名が、コンテンツが受信されるときに動的チェックサムを計算し、トレーラーフィールド値の受信時にすぐにチェックする必要があることを示す場合、これは役立ちます。

ヘッダーフィールドと同様に、同じ名前のトレーラーフィールドは受信順に処理されます。同じ名前の複数のトレーラーフィールド行は、複数の値をメンバーのリストとして追加するのと同等のセマンティクスを持ちます。メッセージ中に複数回生成される可能性のあるトレーラーフィールドは、各メンバー値が受信したフィールド行ごとに1回だけ処理される場合でも、リストベースのフィールドとして定義されなければなりません (MUST)。

メッセージの終わりに、受信者は、受信したトレーラーフィールドのセットを、ヘッダーフィールドと同様の(ただし別個の)名前/値ペアのデータ構造として扱ってもよい (MAY) です。追加の処理期待がある場合は、トレーラーでの使用を意図したフィールドのフィールド仕様内で定義できます。

6.6. メッセージメタデータ (Message Metadata)

メッセージがいつどのように生成されたかなど、メッセージ自体を記述するフィールドは、リクエストと応答の両方に表示される場合があります。

6.6.1. Date

「Date」ヘッダーフィールドは、メッセージが発信された日時を表し、[RFC5322] のセクション3.6.1で定義されている発信日フィールド (orig-date) と同じセマンティクスを持ちます。フィールド値は、Section 5.6.7で定義されているHTTP-dateです。

Date = HTTP-date

例:

Date: Tue, 15 Nov 1994 08:12:31 GMT

Dateヘッダーフィールドを生成する送信者は、そのフィールド値をメッセージ生成の日時の最良の利用可能な近似値として生成すべきです (SHOULD)。理論的には、日付はメッセージコンテンツを生成する直前の瞬間を表すべきです。実際には、送信者はメッセージ発信中の任意の時点で日付値を生成できます。

時計を持つ (Section 5.6.7で定義) オリジンサーバーは、すべての2xx (Successful)、3xx (Redirection)、および4xx (Client Error) 応答でDateヘッダーフィールドを生成しなければならず (MUST)、1xx (Informational) および5xx (Server Error) 応答でDateヘッダーフィールドを生成してもよい (MAY) です。

時計を持たないオリジンサーバーは、Dateヘッダーフィールドを生成してはなりません (MUST NOT)。

Dateヘッダーフィールドのない応答メッセージを受信する時計を持つ受信者は、それが受信された時刻を記録し、それがキャッシュされるか下流に転送される場合、メッセージのヘッダーセクションに対応するDateヘッダーフィールドを追加しなければなりません (MUST)。

無効なDateヘッダーフィールド値を持つ応答を受信する時計を持つ受信者は、その値を応答が受信された時刻に置き換えてもよい (MAY) です。

ユーザーエージェントは、リクエストでDateヘッダーフィールドを送信してもよい (MAY) ですが、通常、サーバーに有用な情報を伝達すると考えられない限り、そうしません。たとえば、HTTPのカスタムアプリケーションは、サーバーがユーザーエージェントとサーバーの時計の差に基づいてユーザーのリクエストの解釈を調整することが予想される場合、Dateを伝達する可能性があります。

6.6.2. Trailer

「Trailer」ヘッダーフィールドは、送信者がそのメッセージ内でトレーラーフィールドとして送信することを予期しているフィールド名のリストを提供します。これにより、受信者は、コンテンツの処理を開始する前に、示されたメタデータの受信に備えることができます。

Trailer = #field-name

たとえば、送信者は、コンテンツがストリーミングされているときに署名が計算され、最終的な署名がトレーラーフィールドとして提供されることを示す場合があります。これにより、受信者は、コンテンツを受信しながら同じチェックをオンザフライで実行できます。

メッセージ内で1つ以上のトレーラーフィールドを生成する意図がある送信者は、そのメッセージのヘッダーセクションでTrailerヘッダーフィールドを生成して、トレーラーに存在する可能性のあるフィールドを示すべきです (SHOULD)。

仲介者が転送中にトレーラーセクションを破棄した場合、Trailerフィールドは失われたメタデータのヒントを提供できますが、Trailerの送信者が常に名前付きフィールドを送信することによってフォロースルーするという保証はありません。