インターネット技術タスクフォース (IETF) R. Fielding, 編集者
Request for Comments: 9112 Adobe
廃止: 7230 M. Nottingham, 編集者
STD: 99 Fastly
カテゴリ: 標準トラック J. Reschke, 編集者
ISSN: 2070-1721 greenbytes
2022年6月

HTTP/1.1


概要

ハイパーテキスト転送プロトコル (HTTP) は、分散型で協調的なハイパーテキスト情報システムのためのステートレスなアプリケーションレベルプロトコルです。本書は HTTP/1.1 のメッセージ構文、メッセージ解析、接続管理、および関連するセキュリティ上の懸念事項を規定します。

本書は RFC 7230 の一部を廃止します。

このメモの状態

これはインターネット標準トラック文書です。

本書はインターネット技術タスクフォース (IETF) の成果物です。IETF コミュニティのコンセンサスを表しています。本書は公開レビューを受け、インターネット技術審議グループ (IESG) により出版が承認されています。インターネット標準に関する詳細は RFC 7841 のセクション 2 を参照してください。

本書の現状、訂正情報 (errata)、およびフィードバックの提供方法については https://www.rfc-editor.org/info/rfc9112 を参照してください。

Copyright Notice

Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.

This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English.

1. 導入

ハイパーテキスト転送プロトコル (HTTP) は、拡張可能なセマンティクスと自己記述的なメッセージを用いて、ネットワーク上のハイパーテキスト情報システムと柔軟にやり取りするためのステートレスなアプリケーション層のリクエスト/レスポンスプロトコルです。HTTP/1.1 は以下によって定義されます。

本書は、HTTP セマンティクスが HTTP/1.1 のメッセージ構文、フレーミング、および接続管理メカニズムを用いてどのように伝達されるかを規定します。その目的は、HTTP/1.1 メッセージパーサーおよびメッセージ転送中継(メッセージ転送を行う仲介者)に対する完全な要件セットを定義することです。

本書は、HTTP/1.1 のメッセージングおよび接続管理に関連する RFC 7230 の部分を廃止します。変更点は 付録 C.3 に要約されています。RFC 7230 の他の部分は "HTTP Semantics" [HTTP] によって廃止されます。

1.1. 要件表記

本書中のキーワード "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", および "OPTIONAL" は、すべて大文字で表記されている場合に限り、BCP 14 の定義([RFC2119][RFC8174])に従って解釈されます。

適合性基準およびエラー処理に関する考察は、Section 2[HTTP] に定義されています。

1.2. 構文表記

本仕様では、拡張バッカス・ナウア記法(ABNF)を [RFC5234] に従って使用し、文字列の大文字小文字敏感性表記は [RFC7405] で定義された表記を拡張して使用します。

また、リスト拡張("#" 演算子を用いたコンマ区切りリストの簡潔な定義を可能にするもの)を Section 5.6.1 の定義に従って使用します。付録 A は、すべてのリスト演算子を標準 ABNF 表記に展開した収集済み文法を示します。

慣例として、"obs-" 接頭辞の付いた ABNF ルール名は歴史的理由により残されている廃止済みの文法ルールを示します。

次のコアルールは、[RFC5234]Appendix B.1 に定義されているとおり参照によって含まれます:ALPHA(文字)、CR(復帰)、CRLF(CR LF)、CTL(制御文字)、DIGIT(10進数 0-9)、DQUOTE(ダブルクォート)、HEXDIG(16 進数 0-9/A-F/a-f)、HTAB(水平タブ)、LF(改行)、OCTET(任意の 8 ビットデータ列)、SP(スペース)、および VCHAR(表示可能な [USASCII] 文字)。

以下のルールは [HTTP] に定義されています:

  BWS           = <BWS, see [HTTP], Section 5.6.3>
  OWS           = <OWS, see [HTTP], Section 5.6.3>
  RWS           = <RWS, see [HTTP], Section 5.6.3>
  absolute-path = <absolute-path, see [HTTP], Section 4.1>
  field-name    = <field-name, see [HTTP], Section 5.1>
  field-value   = <field-value, see [HTTP], Section 5.5>
  obs-text      = <obs-text, see [HTTP], Section 5.6.4>
  quoted-string = <quoted-string, see [HTTP], Section 5.6.4>
  token         = <token, see [HTTP], Section 5.6.2>
  transfer-coding =
                  <transfer-coding, see [HTTP], Section 10.1.4>

以下のルールは [URI] に定義されています:

  absolute-URI  = <absolute-URI, see [URI], Section 4.3>
  authority     = <authority, see [URI], Section 3.2>
  uri-host      = <host, see [URI], Section 3.2.2>
  port          = <port, see [URI], Section 3.2.3>
  query         = <query, see [URI], Section 3.4>

2. メッセージ

HTTP/1.1 クライアントとサーバはメッセージを送受信して通信します。一般的な用語とコア概念については、Section 3[HTTP] を参照してください。

2.1. メッセージ形式

HTTP/1.1 メッセージは、start-line に続いて CRLF、その後にインターネットメッセージ形式 [RFC5322] に類似した形式のオクテット列が続く構成です:0 個以上のヘッダーフィールド行(まとまって「ヘッダ」または「ヘッダセクション」と呼ばれる)、ヘッダセクションの終わりを示す空行、および任意のメッセージ本文。

メッセージはクライアントからサーバへのリクエスト、またはサーバからクライアントへのレスポンスのいずれかです。構文的には、両者は start-line(リクエストの場合は request-line、レスポンスの場合は status-line)と、メッセージ本文の長さを決定するアルゴリズム(Section 6)のみが異なります。

理論的には、クライアントがリクエストを受信し、サーバがレスポンスを受信することもあり得ますが、実際にはサーバはリクエストのみを期待するよう実装され(レスポンスは不明または無効なリクエストメソッドとして解釈される)、クライアントはレスポンスのみを期待するよう実装されています。

HTTP はマルチパーパスインターネットメール拡張(MIME)に似たプロトコル要素を利用します。詳細な差異については 付録 B を参照してください。

2.2. メッセージ解析

HTTP メッセージを解析する通常の手順は、start-line を構造体に読み込み、各ヘッダーフィールド行をフィールド名ごとにハッシュテーブルに読み込み(空行まで)、その解析結果を使ってメッセージ本文が期待されるかを判断することです。メッセージ本文が示されている場合、指定されたメッセージ本文長に等しいオクテット数が読み取られるか、接続が閉じられるまでストリームとして読み取ります。

受信者は、HTTP メッセージを US-ASCII のスーパーセットであるエンコーディングのオクテット列として解析しなければなりません。エンコーディングを無視して Unicode 文字列のストリームとして解析すると、LF (%x0A) を含む無効なマルチバイト文字列の処理がライブラリごとに異なるためセキュリティ脆弱性を生じます。文字列ベースのパーサは、メッセージ解析によって個々のフィールド行が取り出された後など、プロトコル要素がメッセージから抽出された後でのみ安全に使用できます。

start-line およびフィールドの行終端は CRLF ですが、受信者は単一の LF を行終端として認識し、直前の CR を無視してもよい場合があります。

送信者は、コンテンツ以外のプロトコル要素内で(直ちに LF に続かない)裸の CR を生成してはなりません。裸の CR を受け取った受信者は、その要素を無効と見なすか、処理または転送の前に各裸の CR を SP に置き換えなければなりません。

古い HTTP/1.0 ユーザーエージェントの実装は、一部の初期サーバアプリケーションが行終端で終わらないメッセージ本文を読み取れなかったため、POST リクエストの後に追加の CRLF を送信していたことがあります。HTTP/1.1 ユーザーエージェントは、リクエストの前後に追加の CRLF を付加してはなりません。リクエストメッセージ本文を行終端で終了させたい場合、その終端 CRLF オクテットはメッセージ本文長の一部としてカウントしなければなりません。

堅牢性の観点から、リクエストラインを受信して解析することを期待するサーバは、少なくとも 1 行の空行(CRLF)が request-line の前に受信された場合、それを無視すべきです。

送信者は、start-line と最初のヘッダーフィールドの間に空白を送信してはなりません。

受信者が start-line と最初のヘッダーフィールドの間に空白を受け取った場合、受信者はそのメッセージを無効として拒否するか、または各空白で始まる行をさらなる処理なしに消費(すなわち、その行全体と、その後に続く空白で始まる行を、適切に形成されたヘッダーフィールドが受信されるかヘッダセクションが終了するまで無視)しなければなりません。無効な空白で始まる行を拒否または削除することは、リクエストスマグリング(Section 11.2)やレスポンス分割(Section 11.1)攻撃に対して脆弱な下流の受信者による誤解釈を防ぐために必要です。

サーバが HTTP リクエストメッセージのみを待ち受けている場合、または start-line から見て HTTP リクエストメッセージのように見えるものを処理している場合に、HTTP-message 文法と一致しないオクテット列を(上記の堅牢性例外を除いて)受信した場合、サーバは 400 (Bad Request) を返して接続を閉じるべきです。

2.3. HTTP バージョン

HTTP は "<major>.<minor>" の番号付けスキームを用いてプロトコルのバージョンを示します。本仕様はバージョン "1.1" を定義します。Section 2.5[HTTP] は HTTP バージョン番号のセマンティクスを規定します。

HTTP/1.x メッセージのバージョンは、start-line 内の HTTP-version フィールドによって示されます。HTTP-version は大文字小文字を区別します。

  HTTP-version  = HTTP-name "/" DIGIT "." DIGIT
  HTTP-name     = %s"HTTP"

HTTP/1.1 メッセージが HTTP/1.0 受信者またはバージョン不明の受信者に送信される場合、HTTP/1.1 メッセージは新しい機能をすべて無視しても有効な HTTP/1.0 メッセージとして解釈できるように構築されます。本仕様は、一部の新機能に対して受信者バージョンの要件を課すため、適合する送信者は設定や受信したメッセージにより受信者が HTTP/1.1 をサポートすることが判明するまで、互換性のある機能だけを使用します。

HTTP メッセージを処理する仲介者(トンネルとして動作する仲介者を除く)は、転送するメッセージにおいて自分自身の HTTP バージョンを送信しなければなりません(上流の問題に対する回避策として意図的にダウングレードする場合を除く)。つまり、仲介者は、受信および送信の両方についてその仲介者が準拠しているバージョンとメッセージ内のプロトコルバージョンが一致することを確認せずに start-line を盲目的に転送してはなりません。HTTP-version を書き換えずにメッセージを転送すると、下流の受信者が送信者のバージョンをもとに後続の通信で使用して安全な機能を決定する場合に通信エラーが生じる可能性があります。

サーバは、クライアントが仕様を誤実装しており後続のバージョンのレスポンスを正しく処理できないと知られているか疑われる場合に、HTTP/1.1 リクエストに対して HTTP/1.0 レスポンスを送信してもよいです。ただし、そのようなプロトコルのダウングレードは、クライアントのバージョン番号を正しく解析できない場合や、仲介者がプロトコルのマイナーバージョンに準拠していないにもかかわらず HTTP-version を盲目的に転送することが知られている場合など、特定のクライアント属性によって引き起こされない限り、実施すべきではありません。

3. リクエスト行

リクエスト行は method トークンで始まり、単一の空白 (SP)、request-target、さらに単一の空白 (SP) が続き、プロトコルのバージョンで終わります。

request-line の文法規則は各構成要素が単一の SP オクテットで区切られることを要求しますが、受信者は代わりに空白で区切られた語境界で解析し、CRLF 終端を除き任意の形式の空白を SP 区切りとして扱い、前後の空白を無視することが MAY です。このような空白には次の一つ以上のオクテットが含まれます: SP, HTAB, VT (%x0B), FF (%x0C), または裸の CR。ただし、寛容な解析は、メッセージの受信者が複数存在し、それぞれが独自の堅牢性解釈を持つ場合にリクエストスマグリングの脆弱性を引き起こす可能性があります(Section 11.2参照)。

HTTP は request-line の長さにあらかじめ定められた上限を設けていません(Section 2.3 の説明を参照)。受信した method が実装しているどの method よりも長い場合、サーバは SHOULD 501 (Not Implemented) を返すべきです。受信した request-target がサーバが解析したい URI の最大長を超える場合、サーバは MUST 414 (URI Too Long) を返すべきです(詳細は Section 15.5.15 を参照)。

実務上、request-line 長に対する様々な場当たり的な制限が存在します。すべての HTTP 送受信者が少なくとも 8000 オクテットの request-line 長をサポートすることが RECOMMENDED されます。

3.1. Method

method トークンは対象リソースに対して実行されるリクエストメソッドを示します。リクエストメソッドは大文字小文字を区別します。

この仕様で定義されるリクエストメソッドは、Section 9 に記載されています。そこには HTTP メソッドレジストリや、新しいメソッドを定義する際の考慮事項も示されています。

3.2. リクエストターゲット

request-target はリクエストを適用する対象リソースを識別します。クライアントは目的のターゲット URI から request-target を導出します。request-target の形式は、要求されるメソッドとプロキシ宛てかどうかによって4つに分かれます。

request-target 内には空白を含めてはなりません。残念ながら一部のユーザーエージェントはハイパーテキスト参照中の空白を正しくエンコードまたは除去できず、それらの不許可文字が malformed な request-line として送信されることがあります。

無効な request-line を受け取った受信者は、400 (Bad Request) エラー、または request-target を適切にエンコードした 301 (Moved Permanently) のリダイレクトで応答することが SHOULD です。受信者は自動修正してリダイレクトなしにリクエストを処理しようとすべきではありません。なぜなら、無効な request-line はリクエストチェーン上のセキュリティフィルタを回避する目的で故意に作成されている可能性があるためです。

クライアントはすべての HTTP/1.1 リクエストメッセージで Host ヘッダーフィールドを送信することが MUST です(詳細は Section 7.2 を参照)。ターゲット URI に authority 成分が含まれる場合、クライアントは Host のフィールド値としてその authority 成分と同一の値を送信しなければなりません(userinfo サブコンポーネントとその "@" 区切りは除く)。ターゲット URI に authority 成分がないか未定義である場合、クライアントは空のフィールド値を持つ Host ヘッダーフィールドを送信しなければなりません。

サーバは Host ヘッダーフィールドが欠けている HTTP/1.1 リクエストメッセージ、もしくは Host ヘッダーフィールドが 2 行以上含まれるリクエスト、あるいは Host のフィールド値が無効なリクエストに対して MUST 400 (Bad Request) を返すべきです。

3.2.1. origin-form

最も一般的な request-target の形式は origin-form です。

CONNECT やサーバ全体に対する OPTIONS リクエストを除き、オリジンサーバへ直接リクエストを送る場合、クライアントはターゲット URI の絶対パスとクエリの成分のみを request-target として送ることが MUST です。ターゲット URI のパス成分が空の場合、クライアントは origin-form のパスとして "/" を送信しなければなりません。Host ヘッダーフィールドも送信されます(詳細は Section 7.2 を参照)。

例えば、クライアントが次のリソースの表現を取得したい場合:

http://www.example.org/where?q=now

オリジンサーバから直接取得するには、ホスト "www.example.org" のポート 80 へ TCP 接続を開き(または再利用し)、次の行を送信します:

GET /where?q=now HTTP/1.1
Host: www.example.org

その後、リクエストメッセージの残りが続きます。

3.2.2. absolute-form

CONNECT やサーバ全体に対する OPTIONS リクエストを除き、プロキシ宛てのリクエストを行う場合、クライアントは request-target として absolute-form でターゲット URI を送信することが MUST です。

プロキシは可能であれば有効なキャッシュからその要求を処理するか、クライアントに代わって次のインバウンドプロキシあるいはオリジンサーバへ同じリクエストを行うよう要求されます。こうしたメッセージの「転送」に関する要件は Section 7.6 に定義されています。

absolute-form の request-line の例は次のようになります:

GET http://www.example.org/pub/WWW/TheProject.html HTTP/1.1

request-target が absolute-form であっても、古い HTTP/1.0 プロキシを通過させるためにクライアントは HTTP/1.1 リクエストで Host ヘッダーフィールドを送信すること MUST です。

プロキシが absolute-form の request-target を受け取った場合、受信した Host ヘッダーフィールド(存在する場合)は無視し、代わりに request-target のホスト情報で置き換えることが MUST です。そのようなリクエストを転送するプロキシは、受信した Host フィールド値をそのまま転送せず、受信した request-target に基づいて新しい Host フィールド値を生成すること MUST です。

オリジンサーバが absolute-form の request-target を受け取った場合、受信した Host ヘッダーフィールド(存在する場合)は無視し、代わりに request-target のホスト情報を使用すること MUST です。なお、request-target に authority 成分がない場合は、この場合に空の Host ヘッダーフィールドが送信されます。

ほとんどの HTTP/1.1 クライアントは absolute-form をプロキシ宛てにしか送らないにもかかわらず、サーバはリクエストに対して absolute-form を受け入れること MUST です。

3.2.3. authority-form

authority-form の request-target は CONNECT リクエスト専用です(Section 9.3.6参照)。これはトンネル先の uri-host と port 番号のみで構成され、コロン (":") で区切られます。

プロキシを通じてトンネルを確立するための CONNECT リクエストを行う場合、クライアントはトンネル先のホストとポートのみを request-target として送信すること MUST です。クライアントはターゲット URI の authority 成分からホストとポートを取得しますが、ターゲット URI がポートを省略している場合はスキームのデフォルトポートを送信します。例えば、"http://www.example.com" への CONNECT リクエストは次のようになります:

CONNECT www.example.com:80 HTTP/1.1
Host: www.example.com

3.2.4. asterisk-form

asterisk-form の request-target はサーバ全体に対する OPTIONS リクエスト専用です(Section 9.3.7参照)。

クライアントがサーバ全体に対して OPTIONS を要求する場合、特定の名前付きリソースではなくサーバ全体を対象とするので、クライアントは request-target として "*" (%x2A) のみを送信すること MUST です。例:

OPTIONS * HTTP/1.1

もしプロキシがパスが空でクエリ成分を持たない absolute-form の OPTIONS リクエストを受け取った場合、リクエストチェーンの最後のプロキシは origin server に転送する際に request-target を "*" にしなければなりません。

例えば、次のリクエストは

OPTIONS http://www.example.org:8001 HTTP/1.1

最終プロキシによって次のように転送されます:

OPTIONS * HTTP/1.1
Host: www.example.org:8001

その後、ホスト "www.example.org" のポート 8001 に接続されます。

3.3. ターゲット URI の再構築

request-target が absolute-form の場合、ターゲット URI はその request-target です。その場合、サーバはさらに評価するために URI を一般的な構成要素に解析します。

それ以外の場合、サーバは接続コンテキストやリクエストメッセージのさまざまな部分からターゲット URI を再構築して対象リソースを特定します(詳細は Section 7.1 を参照):

  • サーバの設定で固定の URI スキームが提供されているか、信頼されたアウトバウンドゲートウェイによってスキームが提供されている場合、そのスキームがターゲット URI に使用されます。これは大規模な展開で一般的で、ゲートウェイサーバがクライアントの接続コンテキストを受け取り、それを自分自身の接続に置き換えてインバウンドサーバへ転送するためです。そうでない場合、リクエストが保護された接続で受信されたならターゲット URI のスキームは "https"、そうでなければ "http" になります。
  • request-target が authority-form の場合、ターゲット URI の authority 成分は request-target です。そうでない場合、ターゲット URI の authority 成分は Host ヘッダーフィールドのフィールド値です。Host ヘッダーフィールドが存在しないか、そのフィールド値が空または無効な場合、ターゲット URI の authority 成分は空になります。
  • request-target が authority-form または asterisk-form の場合、ターゲット URI の結合された pathquery 成分は空です。そうでない場合、ターゲット URI の結合された path と query 成分は request-target になります。
  • 上記で決定された再構築されたターゲット URI の構成要素は、スキーム、"://"、authority、および結合された path と query 成分を連結することで absolute-URI 形式に再結合できます。

例 1: 以下のメッセージがセキュアな接続上で受信された場合

GET /pub/WWW/TheProject.html HTTP/1.1
Host: www.example.org

のターゲット URI は次のとおりです

https://www.example.org/pub/WWW/TheProject.html

例 2: 以下のメッセージが保護されていない接続上で受信された場合

OPTIONS * HTTP/1.1
Host: www.example.org:8080

のターゲット URI は次のとおりです

http://www.example.org:8080

ターゲット URI の authority 成分が空で、その URI スキームが非空の authority を要求する場合("http" や "https" の場合など)、サーバはリクエストを拒否するか、着信接続のコンテキストと整合する構成済みのデフォルトが適用可能かどうかを判断できます。コンテキストにはアドレスやポート、適用されたセキュリティ、サーバ固有のローカル設定情報などが含まれます。空の authority はさらに処理を行う前に構成済みのデフォルトで置き換えられます。

セキュアな接続のコンテキスト内で authority のデフォルト名を提供することは、ユーザーエージェントの意図した authority がデフォルトと異なる可能性がある場合に本質的に安全ではありません。リクエストコンテキストから一意に authority を識別できるサーバは、その識別子をデフォルトとして使用してもこのリスクはありません。あるいは、新しいクライアントを取得する方法を説明する安全なリソースへリダイレクトする方が望ましい場合もあります。

クライアントのターゲット URI を再構築することは、ターゲットリソースを識別するプロセスの半分に過ぎない点に注意してください。もう半分は、そのターゲット URI がサーバが応答を返すことを許容し得るリソースを識別するかどうかを判断することです(詳細は Section 7.4 を参照)。

4. ステータス行

レスポンスメッセージの最初の行は status-line で、プロトコルのバージョン、空白 (SP)、ステータスコード、さらに空白が続き、ステータスコードを説明する(OPTIONAL な)テキスト句で終わります。

status-line の文法規則は各構成要素が単一の SP オクテットで区切られることを要求しますが、受信者は代わりに空白で区切られた語境界で解析し、行終端を除き任意の形式の空白を SP 区切りとして扱い前後の空白を無視することが MAY です。このような空白には SP, HTAB, VT (%x0B), FF (%x0C), または裸の CR の一つ以上が含まれます。ただし、寛容な解析はレスポンス分割の脆弱性を引き起こす可能性があります(Section 11.1参照)。

status-code 要素はサーバがクライアントの対応するリクエストを理解し満たそうとした結果を説明する 3 桁の整数コードです。受信者は、そのステータスコードが認識される場合はそのセマンティクスに基づいて、また特定のコードが認識されない場合はそのクラスに応じてレスポンスメッセージの残りを解析・解釈します。

HTTP のコアステータスコードは Section 15 に定義されており、ステータスコードのクラス、新しいステータスコード定義に関する考慮事項、およびそのような定義を収集する IANA レジストリについても記載されています。

reason-phrase 要素は数値ステータスコードに関連するテキスト説明を提供するためだけに存在します。これは主に対話型のテキストクライアントで以前のインターネットアプリケーションプロトコルに配慮した遺風です。

クライアントは reason-phrase の内容を信頼できる情報チャネルとして扱うべきではないため、無視すること SHOULD です(ローカライズされたり仲介者によって上書きされたり他バージョンの HTTP 経由で転送時に破棄される可能性があるため)。サーバは reason-phrase が存在しない場合でも status-code と reason-phrase を区切る空白を送信しなければなりません(つまり status-line はその空白で終わります)。

5. フィールドの構文

各フィールド行は、大文字小文字を区別しないフィールド名、コロン (":"), 任意の先頭空白、フィールド行の値、そして任意の末尾空白で構成されます。

フィールド値内の解析ルールは Section 5.5 に定義されています。本節は HTTP/1.1 メッセージ内でのヘッダーフィールドの一般的な構文と、その包含および抽出の方法を扱います。

5.1. フィールド行の解析

メッセージは個々のフィールド名に依存しない汎用アルゴリズムで解析されます。特定のフィールド行値内の内容は、メッセージのフィールドセクション全体が処理された後の段階で解析されます。

フィールド名とコロンの間に空白を入れてはなりません。過去にその取り扱いの違いがリクエストルーティングやレスポンス処理におけるセキュリティ脆弱性につながったことがあります。サーバは、フィールド名とコロンの間に空白がある受信リクエストメッセージを受け取った場合、MUST 400 (Bad Request) を返して拒否しなければなりません。プロキシは、レスポンスメッセージを下流に転送する前にそのような空白を削除しなければなりません。

フィールド行値の前後には任意の空白 (OWS) が存在していてもよく、可読性のためにフィールド行値の直前に単一の SP を置くことが推奨されます。フィールド行値はその先頭および末尾の空白を含みません。つまり、フィールド行値の最初の非空白オクテットの前、または最後の非空白オクテットの後に現れる OWS は、フィールド行からフィールド行値を抽出する際にパーサにより除外されます。

5.2. 廃止された行折り返し

歴史的に、HTTP/1.x のフィールド値は追加行の先頭に少なくとも 1 つの空白または水平タブを付けることで複数行に拡張できました(obs-fold)。本仕様は "message/http" メディアタイプ内を除き、そのような行折り返しを非推奨とします(Section 10.1参照)。

  obs-fold     = OWS CRLF RWS
               ; obsolete line folding

送信者は、"message/http" コンテナ向けでないメッセージに折り返しを含めるメッセージ(すなわちフィールド行値が obs-fold ルールに一致するもの)を生成してはなりません(MUST NOT)。

"message/http" コンテナ内でないリクエストメッセージで obs-fold を受け取ったサーバは、そのメッセージを拒否して 400 (Bad Request) を返すか、受信した各 obs-fold を解釈または下流転送の前に一つ以上の SP オクテットに置き換えなければなりません。

レスポンスメッセージで "message/http" コンテナ内でない obs-fold を受け取ったプロキシまたはゲートウェイは、メッセージを破棄して 502 (Bad Gateway) を返すか、受信した各 obs-fold を解釈または下流へ転送する前に一つ以上の SP オクテットに置き換えなければなりません。

レスポンスメッセージで "message/http" コンテナ内でない obs-fold を受け取ったユーザーエージェントは、受信した各 obs-fold を解釈前に一つ以上の SP オクテットに置き換えなければなりません。

6. メッセージ本文

HTTP/1.1 メッセージのメッセージ本文(存在する場合)は、リクエストまたはレスポンスのコンテンツ(Section 6.4 of [HTTP])を運ぶために用いられます。メッセージ本文は、Section 6.1 に記述されているように transfer coding が適用されていない限り、そのままコンテンツと同一です。

  message-body = *OCTET

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

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

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

6.1. Transfer-Encoding

Transfer-Encoding ヘッダーフィールドは、メッセージ本文を形成するためにコンテンツに適用された(または適用される予定の)transfer coding の順序に対応する transfer coding 名の一覧を列挙します。transfer coding は Section 7 で定義されています。

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

受信者は、コンテンツサイズが事前に判らない場合のメッセージのフレーミングにおいて重要な役割を果たすため、chunked transfer coding (Section 7.1) を解析できなければなりません。送信者はメッセージ本文に対して chunked を複数回適用してはなりません(すなわち、既に chunked 化されたメッセージをさらに chunked にすることは許されません)。もしリクエストのコンテンツに chunked 以外の transfer coding が適用される場合、送信者はメッセージが適切にフレームされるように最終的な transfer coding として chunked を適用しなければなりません。レスポンスのコンテンツに chunked 以外の transfer coding が適用される場合、送信者は最終的な transfer coding として chunked を適用するか、あるいは接続を閉じることでメッセージを終了させなければなりません。

例えば、

Transfer-Encoding: gzip, chunked

は、コンテンツが gzip で圧縮された後に chunked としてメッセージ本文が形成されたことを示します。

Content-EncodingSection 8.4.1 of [HTTP])とは異なり、Transfer-Encoding はメッセージの性質であり表現の性質ではありません。リクエスト/レスポンスチェーン上の任意の受信者は、受信した transfer coding をデコードすることも、Transfer-Encoding フィールド値に対応する変更を行うことを条件にメッセージ本文に追加の transfer coding を適用することもできます。エンコーディングパラメータに関する追加情報は、本仕様で定義されていない他のヘッダーフィールドによって提供されることがあります。

Transfer-Encoding は、メッセージ本文を含まない HEAD リクエストへのレスポンスや、GET リクエストに対する 304 (Not Modified) レスポンス(いずれもメッセージ本文を含まない)で送信されることが MAY あります。これは、条件付きでない GET だった場合にオリジンサーバがメッセージ本文に transfer coding を適用したであろうことを示すためです。ただし、この示唆は必須ではなく、レスポンスチェーン上の任意の受信者(オリジンサーバを含む)は、必要ない場合に transfer coding を取り除くことができます。

サーバは、1xx (Informational) または 204 (No Content) のステータスコードを持つレスポンスに対して Transfer-Encoding ヘッダーフィールドを送信してはなりません。サーバはまた、CONNECT リクエストへの 2xx (Successful) レスポンスに Transfer-Encoding ヘッダーフィールドを送信してはなりません(詳細は Section 9.3.6)。

サーバが理解できない transfer coding を含むリクエストメッセージを受け取った場合、サーバは SHOULD 501 (Not Implemented) で応答すべきです。

Transfer-Encoding は HTTP/1.1 で導入されました。HTTP/1.0 のみをサポートすると表明する実装は transfer-encoded コンテンツを処理する方法を理解していないと一般に想定され、Transfer-Encoding を含む HTTP/1.0 メッセージは transit 中に chunked transfer coding を適切に処理せずに転送された可能性が高いと見なされます。

クライアントは、サーバが HTTP/1.1(またはそれ以降のマイナーリビジョン)リクエストを処理することを知っている場合を除き、Transfer-Encoding を含むリクエストを送信してはなりません。そのような知識は、特定のユーザ設定や以前に受信したレスポンスのバージョンを記憶することによって得られる場合があります。サーバは、対応するリクエストが HTTP/1.1(またはそれ以降のマイナーリビジョン)を示さない限り、Transfer-Encoding を含むレスポンスを送信してはなりません。

Transfer-Encoding の初期実装は、メッセージのフレーミングのために chunked transfer coding を送信しつつ、進行状況表示のために推定の Content-Length ヘッダーフィールドも送信することがありました。したがって Transfer-Encoding は Content-Length を上書きするものとして定義されており、相互に排他的ではありません。残念ながら、そのようなメッセージを転送すると、下流の受信者が本仕様に従ってメッセージを解析しない場合、特に下流の受信者が HTTP/1.0 のみを実装している場合に、リクエストスマグリング(Section 11.2)やレスポンス分割(Section 11.1)に関する脆弱性を引き起こす可能性があります。

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

HTTP/1.0 メッセージに Transfer-Encoding ヘッダーフィールドが含まれているのを受け取ったサーバまたはクライアントは、たとえ Content-Length が存在していても、そのメッセージのフレーミングが不正であるものとして扱い、メッセージ処理後に接続を閉じなければなりません。送信者がメッセージの一部をバッファに保持している可能性があり、それが接続のさらなる利用によって誤解釈される恐れがあります。

6.2. Content-Length

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

送信者は、Transfer-Encoding ヘッダーフィールドを含むメッセージに対して Content-Length ヘッダーフィールドを送信してはなりません。

6.3. メッセージ本文の長さ

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

  1. HEAD リクエストへのあらゆるレスポンスおよび 1xx (Informational), 204 (No Content), または 304 (Not Modified) のステータスコードを持つ任意のレスポンスは、ヘッダーフィールドの後の最初の空行で常に終了します。したがって、ヘッダーフィールドに何が含まれていてもメッセージ本文やトレーラセクションを含むことはできません。

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

  3. メッセージが Transfer-EncodingContent-Length の両方を持っている場合、Transfer-Encoding が Content-Length より優先されます。そのようなメッセージはリクエストスマグリング(Section 11.2)やレスポンス分割(Section 11.1)を試みるものを示している可能性があり、エラーとして扱うべきです。転送を選択した仲介者は、メッセージを下流へ転送する前にまず受信した Content-Length フィールドを削除し、Transfer-Encoding を処理しなければなりません。

  4. もし Transfer-Encoding ヘッダーフィールドが存在し、かつ chunked transfer coding (Section 7.1) が最終的なエンコーディングである場合は、メッセージ本文の長さは chunked データを読み、デコードして transfer coding がデータが完了したことを示すまでの間で決定されます。

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

    もし Transfer-Encoding ヘッダーフィールドがリクエストに存在し、chunked が最終的なエンコーディングでない場合、メッセージ本文の長さは信頼できず、サーバは MUST 400 (Bad Request) で応答し、接続を閉じなければなりません。

  5. もし Transfer-Encoding を持たず、かつ Content-Length が無効な値であるメッセージを受け取った場合、そのメッセージのフレーミングは無効であり、受信者はそれを回復不能なエラーとして扱わなければなりません。ただし、そのフィールド値がカンマ区切りリストとして正しく解析でき、リスト内の全ての値が有効でかつすべて同一であるならば(その場合はその単一の値を Content-Length として使用して処理する)、例外となります。リクエストメッセージ内で回復不能なエラーが発生した場合、サーバは MUST 400 (Bad Request) で応答し、接続を閉じなければなりません。プロキシがレスポンスメッセージ内でそれを受け取った場合、プロキシはサーバへの接続を閉じて受信したレスポンスを破棄し、クライアントに MUST 502 (Bad Gateway) を返さなければなりません。ユーザーエージェントがレスポンスでそれを受け取った場合、ユーザーエージェントはサーバへの接続を閉じて受信したレスポンスを破棄しなければなりません。

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

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

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

正常に完了した close-delimited レスポンスとネットワーク障害で中断された部分的に受信されたメッセージを区別する方法がないため、サーバは可能な限りエンコーディングまたは長さで区切られるメッセージを生成することが SHOULD 推奨されます。接続を閉じることでの区切り機能は主に HTTP/1.0 との後方互換性のために存在します。

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

chunked 以外の transfer coding が適用されていない限り、メッセージ本文の長さが事前に判っている場合にリクエストにメッセージ本文を含めるクライアントは、chunked transfer coding よりも有効な Content-Length ヘッダーフィールドを使用することが SHOULD 推奨されます。いくつかの既存サービスは chunked を理解していても 411 を返すことがあります。これは通常、そのようなサービスがゲートウェイ経由で実装され、ゲートウェイが呼び出される前にコンテンツ長を要求し、サーバが要求全体をバッファリングできないか、あるいはバッファリングしたくないためです。

メッセージ本文を含むリクエストを送るユーザーエージェントは、MUST 有効な Content-Length ヘッダーフィールドを送るか、あるいは chunked transfer coding を使用しなければなりません。クライアントはサーバが HTTP/1.1(またはその後の)リクエストを処理することを知らない限り chunked transfer coding を使用してはなりません。そのような知識は特定のユーザ設定や以前受信したレスポンスのバージョンの記憶などで得られます。

接続上の最後のリクエストに対する最終レスポンスが完全に受信され、その後に追加データが残っている場合、ユーザーエージェントは残りのデータを破棄するか、それが前のメッセージ本文に属するかどうかを判定しようと試みることが MAY できます。これは前のメッセージの Content-Length 値が誤っている場合に該当する可能性があります。クライアントはそのような余分なデータを別個のレスポンスとして処理、キャッシュ、または転送してはなりません。なぜなら、そのような振る舞いはキャッシュ汚染に対して脆弱になるからです。

7. 転送コーディング

Transfer coding 名は、ネットワークを通じた「安全な輸送」を確保するために、メッセージのコンテンツに対して既に適用された、または適用されうるエンコード変換を示すために使用されます。これはコンテンツコーディングと異なり、transfer coding は転送される表現の性質ではなくメッセージの性質です。

すべての transfer-coding 名は大文字小文字を区別せず、Section 7.3 で定義された HTTP Transfer Coding レジストリに登録されるべきです。これらは Transfer-EncodingSection 6.1)および TE ヘッダーフィールドで使用されます(後者は "transfer-coding" 文法も定義します)。

7.1. Chunked Transfer Coding

chunked transfer coding はコンテンツをチャンク列として転送するためにラップします。各チャンクはそれ自体のサイズ指示子を持ち、さらに OPTIONAL なトレーラセクション(トレーラーフィールドを含む)に続きます。chunked によりサイズ不明のコンテンツストリームを長さ区切りのバッファ列として転送できるため、送信者は接続の持続性を保ち、受信者はメッセージの完全受信を知ることができます。

chunk-size フィールドはチャンクデータのバイト数を示す 16 進数字列です。chunked transfer coding は、chunk-size がゼロのチャンクを受信したとき(その後にトレーラセクションが続くことがあり、最後に空行で終了する)に完了します。

受信者は chunked transfer coding を解析・デコードできなければなりません。

HTTP/1.1 は、仲介者が全レスポンスを確実にバッファできるようにチャンク応答のサイズを制限する手段を定義していません。さらに非常に大きなチャンクサイズは、受信実装で正確に表現されない場合にオーバーフローや精度喪失を引き起こす可能性があります。したがって、受信者は潜在的に大きな 16 進数表現に備え、整数変換のオーバーフローや整数表現による精度損失による解析エラーを防止しなければなりません。

chunked コーディングはパラメータを定義しません。パラメータが存在する場合はエラーと扱うことが SHOULD されます。

7.1.1. Chunk Extensions

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

chunked コーディングは各接続に特有であり、各受信者(仲介者を含む)によってメッセージ上位レベルで検査される前に除去または再符号化される可能性が高いです。したがって、チャンク拡張の使用は、チャンク拡張の使用に関するクライアントとサーバ間で共通の期待がある「ロングポーリング」のような特殊な HTTP サービスや、終端間で保護された接続内でのパディングに限定されることが一般的です。

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

7.1.2. Chunked Trailer Section

トレーラセクションは、送信者がチャンク化メッセージの末尾に追加フィールドを含めることを可能にし、送信中に動的に生成されるかもしれないメタデータ(メッセージ整合性チェック、デジタル署名、後処理ステータスなど)を提供します。トレーラフィールドの適切な使用と制限は、Section 6.5 of [HTTP] に定義されています。

チャンク化を削除する受信者は、受信したトレーラフィールドを選択的に保持または破棄することが MAY あります。受信したトレーラフィールドを保持する受信者は、トレーラフィールドを受信したヘッダーフィールドとは別に保存/転送するか、あるいは受信したトレーラフィールドをヘッダセクションに統合しなければなりません。受信者は、対応するヘッダーフィールド定義が明示的に許可し、トレーラフィールド値の安全な統合方法を指示していない限り、受信したトレーラフィールドをヘッダセクションに統合してはなりません。

7.1.3. Decoding Chunked

chunked transfer coding をデコードする処理は擬似コードで次のように表現できます:

  length := 0
  read chunk-size, chunk-ext (if any), and CRLF
  while (chunk-size > 0) {
     read chunk-data and CRLF
     append chunk-data to content
     length := length + chunk-size
     read chunk-size, chunk-ext (if any), and CRLF
  }
  read trailer field
  while (trailer field is not empty) {
     if (trailer fields are stored/forwarded separately) {
         append trailer field to existing trailer fields
     }
     else if (trailer field is understood and defined as mergeable) {
         merge trailer field with existing header fields
     }
     else {
         discard trailer field
     }
     read trailer field
  }
  Content-Length := length
  Remove "chunked" from Transfer-Encoding

7.2. 圧縮のための転送コーディング

以下の圧縮用 transfer coding 名は、それらに対応する content coding と同じアルゴリズムによって定義されます:

compress (and x-compress)
詳細は Section 8.4.1.1 of [HTTP] を参照してください。
deflate
詳細は Section 8.4.1.2 of [HTTP] を参照してください。
gzip (and x-gzip)
詳細は Section 8.4.1.3 of [HTTP] を参照してください。

これらの圧縮コーディングはパラメータを定義しません。これらの圧縮コーディングにパラメータが存在する場合はエラーと扱うことが SHOULD されます。

7.3. 転送コーディング登録簿

"HTTP Transfer Coding Registry" は transfer coding 名の名前空間を定義します。これは https://www.iana.org/assignments/http-parameters で管理されています。

登録には次のフィールドが MUST 含まれていなければなりません:

  • Name
  • Description
  • Pointer to specification text

transfer coding の名前は、それが同一のエンコーディング変換でない限り、content coding の名前と重複してはなりません(これは Section 7.2 で定義された圧縮コーディングのケースのように変換が同一である場合を除きます)。

TE ヘッダーフィールド(Section 10.1.4 of [HTTP])は、複数の transfer coding が許容される場合にランク値として "q" と名付けられた疑似パラメータを使用します。将来の transfer coding 登録は曖昧さを避けるために(大文字小文字を区別せず)"q" と呼ばれるパラメータを定義すべきではないと SHOULD NOT されています。

この名前空間に追加される値は IETF レビューを必要とし(Section 4.8 of [RFC8126] を参照)、本仕様で定義された transfer coding の目的に適合しなければなりません。

エンコーディング形式の識別にプログラム名を使用することは望ましくなく、将来のエンコーディングに対しては推奨されません。

7.4. 転送コーディングの交渉

Section 10.1.4 of [HTTP] にあるように、TE フィールドは HTTP/1.1 でクライアントがレスポンスにおいて chunked のほかに受け入れ可能な transfer coding と、クライアントがチャンク化された transfer coding におけるトレーラーフィールドを保持する意思があるかを示すために使用されます。

クライアントは TE に chunked transfer coding 名を送ってはなりません;chunked は HTTP/1.1 受信者にとって常に受け入れ可能です。

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

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

複数の transfer coding が許容される場合、クライアントは大文字小文字を区別しない "q" パラメータを使って優先度を付けること MAY あります(これはコンテンツネゴシエーションフィールドで使用される q 値に類似します;詳細は Section 12.4.2 of [HTTP] を参照)。ランク値は 0 から 1 の範囲の実数で、0.001 が最も低い優先度、1 が最も高い優先度を示します;0 の値は「受け入れ不可」を意味します。

TE フィールド値が空であるか TE フィールド自体が存在しない場合、唯一受け入れ可能な transfer coding は chunked です。transfer coding を持たないメッセージは常に受け入れ可能です。

キーワード "trailers" は、送信者がトレーラーフィールドを破棄しないことを示します(詳細は Section 6.5 of [HTTP] を参照)。

TE ヘッダーフィールドは即時接続にのみ適用されるため、TE を送信する送信者は、TE ヘッダーフィールドがそのセマンティクスをサポートしない仲介者によって転送されないように、Connection ヘッダーフィールド内でも "TE" 接続オプションを送信しなければなりません(Section 7.6.1 of [HTTP] を参照)。

8. 不完全なメッセージの処理

通常はリクエストのキャンセルやタイムアウト例外の発生が原因で不完全なリクエストメッセージを受信したサーバは、接続を閉じる前にエラー応答を送信してもよい(MAY)。

接続が早期に閉じられた場合や、チャンク化されたはずの transfer coding のデコードに失敗した場合に発生し得る不完全なレスポンスメッセージを受信したクライアントは、そのメッセージを不完全として記録しなければならない(MUST)。不完全なレスポンスのキャッシュ要件は、Section 3.3 of [CACHING] に定義されています。

ヘッダセクションの途中(空行を受信する前)でレスポンスが終了し、ステータスコードがレスポンスの完全な意味をヘッダーフィールドに依存している可能性がある場合、クライアントはその意味が伝達されたとは仮定できません。次に取るべき処置を決定するために、クライアントはリクエストを再送する必要があるかもしれません。

チャンク化 transfer coding を用いるメッセージ本文は、エンコーディングを終了するゼロ長チャンクが受信されていない場合に不完全とみなされます。有効な Content-Length を使用するメッセージは、受信したメッセージ本文のサイズ(オクテット)が Content-Length によって与えられた値より小さい場合に不完全です。チャンク化も Content-Length もないレスポンスは接続のクローズによって終了され、ヘッダセクションが完全に受信されていれば、基盤となる接続でエラーが示されない限り完全とみなされます(例えば TLS における「不完全なクローズ」はレスポンスを不完全に残すことがあり、これは Section 9.8 に記載されています)。

9. 接続管理

HTTP のメッセージングは、下位のトランスポート層やセッション層の接続プロトコルから独立しています。HTTP は、リクエストの順序通りの配信と対応するレスポンスの順序通りの配信を備えた信頼できるトランスポートを想定するだけです。HTTP リクエストおよびレスポンス構造を下位トランスポートプロトコルのデータ単位にどのようにマップするかは本仕様の範囲外です。

Section 7.3 of [HTTP] に記載されているように、HTTP インタラクションで使用される具体的な接続プロトコルはクライアントの設定および target URI により決定されます。例えば "http" URI スキーム(Section 4.2.1 of [HTTP])は、デフォルトで IP 上の TCP(デフォルトポート 80)を示しますが、クライアントは別の接続、ポート、プロトコル経由でプロキシを使うように設定されている場合があります。

HTTP 実装は接続管理に従事することが期待されます。これには現在の接続の状態維持、新しい接続の確立または既存接続の再利用、接続上で受信したメッセージの処理、接続障害の検出、および各接続のクローズが含まれます。ほとんどのクライアントは複数の接続を並列で維持し、サーバー・エンドポイントごとに複数の接続を持つこともあります。ほとんどのサーバは同時接続を何千も維持するよう設計されており、リクエストキューを制御して公正な利用を可能にし、DoS 攻撃を検出します。

9.1. 確立

さまざまなトランスポートやセッション層プロトコルを介して接続がどのように確立されるかを記述することは本仕様の範囲を超えます。各 HTTP 接続は 1 つの下位トランスポート接続にマップされます。

9.2. レスポンスとリクエストの関連付け

HTTP/1.1 には、あるリクエストメッセージを対応する 1 個以上のレスポンスメッセージと関連付けるためのリクエスト識別子は含まれていません。したがって、同じ接続上で行われたリクエストの順序とレスポンス到着の順序が正確に一致することに依存します。1 リクエストに対して複数のレスポンスが生じるのは、1 個以上の情報的レスポンス(1xx; 詳細は Section 15.2 of [HTTP])が同一リクエストに対する最終レスポンスに先行する場合のみです。

接続上で未処理のリクエストが複数あるクライアントは、送信した順序で未処理のリクエストの一覧を維持し、当該接続上で受信した各レスポンスメッセージをまだ最終(非 1xx)レスポンスを受け取っていない最初の未処理リクエストに関連付けなければならない(MUST)。

もしクライアントが未処理のリクエストを持たない接続でデータを受信した場合、クライアントはそのデータを有効なレスポンスとは見なしてはならず、メッセージの区切りが曖昧になっているため接続を閉じるべきである(MUST NOT とせずとも SHOULD の扱い)。ただし、そのデータが CRLF のみ(1 個以上)で構成される場合は、Section 2.2 に従って破棄してよい。

9.3. 持続性

HTTP/1.1 は 持続接続(persistent connections) の使用をデフォルトとし、1 つの接続で複数のリクエストとレスポンスを運ぶことを許可します。HTTP 実装は持続接続をサポートすることが SHOULD 推奨されます。

受信者は、直近に受信したメッセージ(存在する場合)のプロトコルバージョンおよび Connection ヘッダーフィールド(Section 7.6.1 of [HTTP])に基づいて、接続が持続するかどうかを判断します:

  • もし "close" 接続オプションが存在する場合(Section 9.6)、現在のレスポンス後に接続は持続しません。さもなければ、
  • 受信したプロトコルが HTTP/1.1(またはそれ以降)であれば、現在のレスポンス後に接続は持続します。さもなければ、
  • 受信したプロトコルが HTTP/1.0 で、"keep-alive" 接続オプションが存在し、受信者がプロキシでないかメッセージがレスポンスであり、受信者が HTTP/1.0 の "keep-alive" メカニズムを尊重することを望む場合、現在のレスポンス後に接続は持続します。さもなければ、
  • 現在のレスポンス後に接続は閉じられます。

持続接続をサポートしないクライアントは、すべてのリクエストメッセージで "close" 接続オプションを送信しなければならない(MUST)。

持続接続をサポートしないサーバは、持続接続 をサポートしない場合、1xx(情報的)ステータスコードでない各レスポンスメッセージで "close" 接続オプションを送信しなければならない(MUST)。

クライアントは "close" 接続オプションを送信するか、HTTP/1.0 レスポンスで "keep-alive" 接続オプションを受信するまで、持続接続上で追加リクエストを送信してもよい(MAY)。

持続させるためには、接続上のすべてのメッセージは自己定義されたメッセージ長(すなわち接続のクローズで定義されない長さ)を持つ必要があります(Section 6 参照)。サーバはメッセージ本文を完全に読み取るか、応答を送信した後に接続を閉じなければならない(MUST)。そうしないと、持続接続上に残ったデータが次のリクエストとして誤解されるおそれがあります。同様に、クライアントは同じ接続を再利用する意図があるならば、レスポンス本文を完全に読み取らなければならない(MUST)。

プロキシサーバは HTTP/1.0 クライアントと持続接続を維持してはならない(MUST NOT)。詳細は 付録 C.2.2 を参照。

HTTP/1.0 クライアントとの互換性の詳細は 付録 C.2.2 を参照してください。

9.3.1. リクエストの再試行

接続はいつでも意図的にまたは非意図的に閉じられる可能性があり、実装は非同期的なクローズイベントからの回復が必要となることを想定すべきです。クライアントが未処理のリクエストのシーケンスを自動的に再試行できる条件は、Section 9.2.2 of [HTTP] に定義されています。

9.3.2. パイプライン

持続接続をサポートするクライアントはリクエストをパイプライン化(各レスポンスを待たずに複数のリクエストを送信)してもよい(MAY)。サーバは、すべてが safe なメソッドである場合に限り、パイプライン化されたリクエストのシーケンスを並列に処理してもよい(MAY)が、対応するレスポンスはリクエストを受信した順序と同じ順序で送信しなければならない(MUST)。

パイプライン化するクライアントは、接続がすべての対応するレスポンスを受信する前に閉じられた場合、未応答のリクエストを再試行することが望ましい(SHOULD)。接続障害(サーバが最後の完全なレスポンスで明示的に接続を閉じていない場合)後にパイプライン化されたリクエストを再試行する際、クライアントは接続確立直後に直ちにパイプラインを行ってはならない(MUST NOT)。これは、前のパイプラインの最初の未完了リクエストがエラー応答を引き起こし、それが早期クローズされた接続上で複数回送信されると再び失われる可能性があるためである(TCP リセット問題の説明は Section 9.6 を参照)。

冪等(idempotent)メソッドはパイプラインにおいて重要です。なぜなら、接続障害後に自動的に再試行できるからです。ユーザーエージェントは、非冪等メソッドの後に、そのメソッドの最終レスポンスステータスコードを受信するまでリクエストをパイプライン化すべきではない(SHOULD NOT)、ただしパイプラインされたシーケンスの部分的失敗を検出・回復する手段がある場合は例外です。

パイプライン化されたリクエストを受け取る仲介者は、送信側のユーザーエージェントが何を安全にパイプライン化できるかを判断することに依存できるため、これらのリクエストをインバウンドにパイプラインすることが MAY あります。もしインバウンド接続がレスポンスを受け取る前に失敗した場合、パイプライン仲介者は、まだレスポンスを受け取っていないリクエストのシーケンスを、すべてが冪等メソッドである場合に再試行することが MAY あります。そうでない場合、パイプライン仲介者は受信したレスポンスを転送し、その後対応するアウトバウンド接続を閉じて、アウトバウンドのユーザーエージェントが適切に回復できるようにすべきである(SHOULD)。

9.4. 並行性

クライアントは特定のサーバに対して維持する同時オープン接続の数を制限するべきです。

以前の改訂では接続数の上限が具体的に示されていましたが、多くのアプリケーションにとって実用的でないことが判明しました。その結果、本仕様は特定の最大接続数を義務付けるのではなく、クライアントが複数接続を開く際には慎重であることを推奨します。

複数接続は通常「ヘッドオブラインブロッキング(head-of-line blocking)」問題を回避するために使用されます。すなわち、サーバ側で大きな処理や非常に大きなコンテンツ転送を伴うリクエストが同じ接続上の後続リクエストをブロックする問題です。ただし、各接続はサーバリソースを消費します。

さらに、複数接続を利用することは混雑したネットワークで望ましくない副作用を引き起こす可能性があります。より多くの接続を使用すると、非混雑環境でも合計して同期的な送信動作が発生し、少ない並列接続の場合には発生しなかった混雑を引き起こすことがあります。

サーバは、単一クライアントからの過剰な数のオープン接続など、不正または DoS 攻撃を特徴づけると判断されるトラフィックを拒否する可能性があることに注意してください。

9.5. 障害とタイムアウト

サーバは通常、非アクティブ接続を維持しないタイムアウト値を持っています。プロキシサーバはクライアントが同じプロキシ経由でより多くの接続を行う可能性があるため、この値を大きく設定する場合があります。持続接続の使用は、クライアントまたはサーバのいずれに対してもこのタイムアウトの長さ(または存在)に関する要件を課しません。

タイムアウトを行いたいクライアントまたはサーバは、接続に対して優雅なクローズを行うべきである(SHOULD)。実装は開かれた接続に対して継続的に受信されたクローズ信号を監視し、適切に応答することが SHOULD 推奨されます。双方の接続を速やかにクローズすることでシステム資源の回収が可能になるためです。

クライアント、サーバ、またはプロキシはいつでもトランスポート接続をクローズしてもよい(MAY)。例えば、クライアントが新しいリクエストの送信を開始したちょうどその時にサーバが「アイドル」接続を閉じることを決定することがあります。サーバの見地では接続はアイドル中に閉じられているが、クライアントの見地ではリクエストが進行中であるという状況です。

サーバは可能な場合に持続接続を維持し、接続を終了するよりも下位のトランスポートのフロー制御機構に一時的な過負荷の解決を委ねることが SHOULD 推奨されます。後者の手法はクライアントが再試行することを期待して接続を終了すると、ネットワーク混雑やサーバ負荷を悪化させる可能性があります。

メッセージ本文を送信するクライアントは、送信中にネットワーク接続でエラー応答がないか監視することが SHOULD です。もしクライアントがサーバがメッセージ本文の受信を望まず接続を閉じることを示す応答を見た場合、クライアントは直ちに本文の送信を停止し、自側の接続を閉じるべきです(SHOULD)。

9.6. 切断

"close" 接続オプションは、送信者が当該レスポンスの完了後にこの接続を閉じることを示す信号として定義されています。送信者は接続を閉じる意図がある場合、Connection ヘッダーフィールド(Section 7.6.1 of [HTTP])に "close" 接続オプションを含めて送信することが SHOULD 推奨されます。例えば、

Connection: close

というリクエストヘッダーフィールドは、クライアントがこの接続上で送信する最後のリクエストであることを示します。レスポンスにおいて同じフィールドは、サーバがレスポンス完了後にこの接続を閉じることを示します。

フィールド名 "Close" は予約されていることに注意してください。ヘッダーフィールドとしてその名前を使用すると "close" 接続オプションと競合する可能性があります。

"close" 接続オプションを送信したクライアントは、そのリクエスト("close" を含むもの)以降その接続でさらなるリクエストを送信してはならず(MUST NOT)、このリクエストに対応する最終レスポンスを読み取った後に接続を閉じなければならない(MUST)。

"close" 接続オプションを受け取ったサーバは、その "close" を含むリクエストに対する最終レスポンスを送信した後に接続の切断を開始しなければならない(MUST)。サーバはその接続上の最終レスポンスで "close" 接続オプションを送信することが望ましい(SHOULD)。サーバはその接続上でそれ以降に受信したリクエストを処理してはならない(MUST NOT)。

"close" 接続オプションを送信するサーバは、その "close" を含むレスポンスを送信した後に接続の切断を開始しなければならない(MUST)。サーバはその接続で以降に受信したリクエストを処理してはならない(MUST NOT)。

"close" 接続オプションを受け取ったクライアントは、その接続でのリクエスト送信を中止し、その "close" を含むレスポンスメッセージを読み取った後に接続を閉じなければならない(MUST)。もしその接続上に追加のパイプライン化されたリクエストが送信されていた場合、クライアントはそれらがサーバで処理されると仮定すべきではない(SHOULD NOT)。

サーバが TCP 接続を即時にクローズすると、クライアントが最後の HTTP レスポンスを読み取れない重大なリスクがあります。もしサーバがクライアントから追加データ(例:サーバのレスポンスを受け取る前にクライアントが送信した別のリクエスト)を受信すると、サーバの TCP スタックはクライアントにリセットパケットを送信します。残念ながら、そのリセットパケットはクライアントの未確認の入力バッファを消してしまい、クライアントの HTTP パーサがそれらを読み取って解釈する前に消失させる可能性があります。

TCP リセット問題を避けるため、サーバは通常接続を段階的に閉じます。まず、サーバは書き込み側のみを閉じるハーフクローズを行います。サーバはその後、クライアントから対応するクローズを受け取るか、または自身の TCP スタックがサーバの最後のレスポンスを含むパケットのクライアント側の確認応答を受け取ったと合理的に確信するまで接続から読み続けます。最後に、サーバは接続を完全に閉じます。

リセット問題が TCP に固有なのか、他のトランスポート接続プロトコルにも見られるのかは不明です。

クライアントによってハーフクローズされた TCP 接続はリクエストメッセージを区切るものではなく、クライアントがもはやレスポンスを期待していないことを意味するわけではないことに注意してください。一般に、HTTP/1.1 はトランスポートに依存しないため、トランスポート信号を境界ケースのシグナルとして頼ることはできません。

9.7. TLS 接続の開始

概念的には、HTTP/TLS は TLS で保護された接続上で HTTP メッセージを送信するだけであり、これは [TLS13] による TLS で保護された接続上での送信と同等です。

HTTP クライアントは TLS クライアントとしても動作します。適切なポートでサーバに接続を開始し、TLS ハンドシェイクを開始するために TLS ClientHello を送信します。TLS ハンドシェイクが終了したら、クライアントは最初の HTTP リクエストを開始することができます。すべての HTTP データは TLS の "application data" として送信されなければならない(MUST)が、それ以外は通常の HTTP 接続と同様に扱われ(持続接続としての再利用を含む)、その他の点では通常の接続と同じです。

9.8. TLS 接続の終了

TLS は非エラーの接続終了に先立ってクローズアラートの交換を使用して安全な接続終了を提供します。詳細は Section 6.1 of [TLS13] を参照してください。有効なクローズアラートを受信した場合、実装はその接続上でこれ以上データを受信しないことを確信できます。

実装が自分が関心を持つ全てのメッセージデータを送受信したことを知ると、通常は HTTP メッセージ境界を検出することで、対応するクローズアラートを待たずにクローズアラートを送り接続を閉じることで「不完全なクローズ」を生成することがあります。

不完全なクローズは既に受信したデータのセキュリティを揺るがすものではありませんが、その後のデータが切り詰められた可能性を示すことがあります。TLS は HTTP メッセージのフレーミングを直接認識しないため、メッセージが完全であるかどうかを判断するには HTTP データ自体を調べる必要があります。不完全なメッセージの処理は Section 8 に定義されています。

不完全なクローズに遭遇した場合、クライアントは完了とみなすべきすべてのリクエストについて次のいずれかを受信しているものとして扱うことが SHOULD です:

  1. Content-Length ヘッダーフィールドで指定された分だけのデータ、または

  2. Transfer-Encoding が chunked の場合の)終端のゼロ長チャンク。

チャンク化も Content-Length もないレスポンスは、有効なクローズアラートを受信した場合にのみ完全とみなされます。不完全なメッセージを完全とみなすことは実装を攻撃に曝す可能性があります。

不完全なクローズを検出したクライアントは、優雅に回復することが SHOULD です。

クライアントは接続を閉じる前にクローズアラートを送信しなければならない(MUST)。これ以上データを受信することを期待しないクライアントは、サーバのクローズアラートを待たずに単に接続を閉じることを選択でき、それによってサーバ側で不完全なクローズを生成することが MAY あります。

サーバはクライアントからの不完全なクローズを受け取る準備をしておくべきです(SHOULD)。クライアントはしばしばサーバデータの終わりを特定できるためです。

サーバは、接続を閉じる前にクライアントとクローズアラートの交換を試みなければならない(MUST)。サーバはクローズアラートを送信した後に接続を閉じることが MAY あります。これによりクライアント側で不完全なクローズが生成されます。

10. データとしての封入メッセージ

10.1. メディアタイプ message/http

"message/http" メディアタイプは、行長およびエンコーディングに関してすべての "message" タイプに適用される MIME 制約を満たす限り、単一の HTTP リクエストまたはレスポンスメッセージを封入するために使用できます。行長の制限のため、"message/http" 内のフィールド値は、obs-fold第5.2節で説明されるような行折り返し)を使用して複数行に渡ってフィールド値を伝えることが許可されています。"message/http" データの受信者は、メッセージが消費される際に任意の旧式の行折り返しを1つ以上のSP文字に置き換えることをMUST行わなければなりません。

タイプ名:
message
サブタイプ名:
http
必須パラメータ:
N/A
オプションパラメータ:
version, msgtype
version:
封入されたメッセージの HTTP バージョン番号(例:"1.1")。存在しない場合、バージョンは本文の最初の行から判定できます。
msgtype:
メッセージタイプ — "request" または "response"。存在しない場合、タイプは本文の最初の行から判定できます。
エンコーディングに関する注意:
許可されるのは "7bit"、"8bit"、または "binary" のみ
セキュリティに関する考慮事項:
11節を参照
相互運用性に関する考慮事項:
N/A
公開仕様:
RFC 9112(第10.1節参照)。
このメディアタイプを使用するアプリケーション:
N/A
フラグメント識別子に関する考慮事項:
N/A
追加情報:
マジックナンバ(複数可):
N/A
このタイプの非推奨エイリアス名:
N/A
ファイル拡張子:
N/A
Macintosh ファイルタイプコード:
N/A
詳細情報の連絡先(人物およびメールアドレス):
著者の連絡先セクションを参照。
想定される利用法:
COMMON
利用制限:
N/A
作成者:
著者の連絡先セクションを参照。
変更管理者:
IESG

10.2. メディアタイプ application/http

"application/http" メディアタイプは、(混在しない)1つ以上の HTTP リクエストまたはレスポンスメッセージのパイプラインを封入するために使用できます。

タイプ名:
application
サブタイプ名:
http
必須パラメータ:
N/A
オプションパラメータ:
version, msgtype
version:
封入されたメッセージの HTTP バージョン番号(例:"1.1")。存在しない場合、バージョンは本文の最初の行から判定できます。
msgtype:
メッセージタイプ — "request" または "response"。存在しない場合、タイプは本文の最初の行から判定できます。
エンコーディングに関する注意:
このタイプで封入された HTTP メッセージは "binary" 形式です;電子メール経由で送信する場合は適切な Content-Transfer-Encoding の使用が必要です。
セキュリティに関する考慮事項:
11節を参照
相互運用性に関する考慮事項:
N/A
公開仕様:
RFC 9112(第10.2節参照)。
このメディアタイプを使用するアプリケーション:
N/A
フラグメント識別子に関する考慮事項:
N/A
追加情報:
このタイプの非推奨エイリアス名:
N/A
マジックナンバ(複数可):
N/A
ファイル拡張子:
N/A
Macintosh ファイルタイプコード:
N/A
詳細情報の連絡先(人物およびメールアドレス):
著者の連絡先セクションを参照。
想定される利用法:
COMMON
利用制限:
N/A
作成者:
著者の連絡先セクションを参照。
変更管理者:
IESG

11. セキュリティに関する考慮事項

この節は、HTTP メッセージの構文およびパースに関連する既知のセキュリティ上の考慮事項について、開発者、情報提供者、ユーザーに通知することを目的としています。HTTP のセマンティクス、コンテンツ、およびルーティングに関するセキュリティ上の考慮事項は [HTTP] に記載されています。

11.1. レスポンス分割

レスポンス分割(別名 CRLF インジェクション)は、HTTP メッセージのフレーミングが行ベースであり、永続的接続上でのリクエストとレスポンスの順序が関連付けられていることを悪用する、Web 利用に対するさまざまな攻撃で一般的に使われる手法です(参照:[Klein])。この手法は、リクエストが共有キャッシュを通過する場合に特に有害になり得ます。

レスポンス分割は、攻撃者がリクエストのあるパラメータ内にエンコードされたデータを送信し、そのデータが後でデコードされてレスポンスの任意のレスポンスヘッダフィールド内にエコーされるような、サーバ(通常はアプリケーションサーバ)内の脆弱性を悪用します。デコードされたデータがレスポンスが終了し、続くレスポンスが開始したように見えるように巧妙に作られている場合、レスポンスは分割され、見かけ上の第二のレスポンス内の内容は攻撃者によって制御されます。攻撃者は同じ永続的接続上で任意の他のリクエストを行い、受信者(中間者を含む)を騙して分割後半が第二のリクエストに対する正当な応答であると信じ込ませることができます。

例えば、リクエストターゲット内のパラメータがアプリケーションサーバによって読み取られ、リダイレクトで再利用され、その結果レスポンスの Location ヘッダフィールドに同じパラメータがエコーされることがあります。パラメータがアプリケーションによってデコードされ、レスポンスフィールドに配置される際に適切にエンコードされていない場合、攻撃者はエンコードされた CRLF オクテットやその他の内容を送信して、アプリケーションの単一レスポンスを二つ以上のレスポンスに見せかけることができます。

レスポンス分割に対する一般的な防御策は、エンコードされた CR および LF に見えるデータ(例:"%0D" および "%0A")に対してリクエストをフィルタリングすることです。しかし、それはアプリケーションサーバが単に URI デコードを行っているだけで、文字セットの変換、XML エンティティ変換、base64 デコード、sprintf 再フォーマットなどのより不明瞭なデータ変換を行っていないと仮定しています。より効果的な緩和策は、ヘッダセクション内に CR または LF を送信できるのはサーバのコアプロトコルライブラリのみに限定し、ヘッダフィールドの出力を悪いオクテットをフィルタする API に制限し、アプリケーションサーバがプロトコルストリームに直接書き込めないようにすることです。

11.2. リクエストスマグリング

リクエストスマグリング(参照:[Linhart])は、さまざまな受信者間のプロトコル解析の差異を悪用して、追加のリクエストを(ポリシーによってブロックまたは無効化される可能性があるものでも)一見無害なリクエスト内に隠す手法です。レスポンス分割と同様に、リクエストスマグリングは HTTP の利用に対するさまざまな攻撃につながる可能性があります。

本仕様では、特にメッセージフレーミングに関して 第6.3節 におけるリクエスト解析に対する新しい要件を導入し、リクエストスマグリングの有効性を低減しています。

11.3. メッセージ整合性

HTTP はメッセージ整合性を保証するための特定のメカニズムを定義しておらず、代わりに基盤となるトランスポートプロトコルの誤り検出能力や、完全性を検出するための長さ指定またはチャンク区切りのフレーミングに依存しています。歴史的に、単一の整合性メカニズムがないことは、ほとんどの HTTP 通信が非公式であるという性質によって正当化されてきました。しかし、情報アクセスの手段としての HTTP の普及により、メッセージ整合性の検証が重要となる環境での使用が増えています。

"https" スキームで提供されるメカニズム(認証付き暗号化など)は、メッセージの改変からの保護を提供します。ただし、接続の終了がメッセージを切り詰めるために利用され得ないことを確実にする必要があります(第9.8節を参照)。ユーザーエージェントは不完全なメッセージを受け入れないか特別に扱う場合があります。例えば、医療履歴や薬物相互作用情報を表示するために使用されるブラウザは、そのような情報が転送中に不完全、期限切れ、または破損しているとプロトコルによって検出された場合にユーザーに示す必要があります。そのようなメカニズムは、ユーザーエージェント拡張やレスポンス内のメッセージ整合性メタデータの存在によって選択的に有効にされる場合があります。

"http" スキームは、メッセージの偶発的または悪意ある改変に対する保護を提供しません。

拡張機能によって、中継者によるメッセージの望ましくない改変のリスクを軽減することが可能です。たとえ "https" スキームが使用されている場合でも、整合性はメッセージ認証コードやデジタル署名を使用して保証され、これらは拡張可能なメタデータフィールドを通じて選択的にメッセージに追加されることがあります。

11.4. メッセージの機密性

HTTP は、メッセージの機密性が望まれる場合にそれを提供するために基盤となるトランスポートプロトコルに依存します。HTTP はトランスポートプロトコルに依存しないように設計されており、多くの形式の暗号化接続上で使用できるようになっており、そのようなトランスポートの選択は URI スキームの選択やユーザーエージェントの設定によって識別されます。

"https" スキームは、機密接続を必要とするリソースを識別するために使用できます(第4.2.2節 を参照、[HTTP])。

12. IANA に関する考慮事項

以下の登録の変更管理者は:"IETF (iesg@ietf.org) - Internet Engineering Task Force" です。

12.1. フィールド名登録

IANA は、https://www.iana.org/assignments/http-fields の "Hypertext Transfer Protocol (HTTP) Field Name Registry" に次のフィールド名を追加しました。これらは 第18.4節 の説明に従います(参照:[HTTP])。

表 1
フィールド名 ステータス コメント
Close permanent 9.6 (reserved)
MIME-Version permanent B.1
Transfer-Encoding permanent 6.1

12.2. メディアタイプ登録

IANA は、https://www.iana.org/assignments/media-types の "Media Types" レジストリを、メディアタイプ "message/http" および "application/http" に関する第10.1節 と第10.2節 の登録情報で更新しました。

12.3. 転送コーディング登録

IANA は、https://www.iana.org/assignments/http-parameters/ の "HTTP Transfer Coding Registry" を、第7.3節 の登録手続きおよび以下の表に要約されたコンテンツコーディング名で更新しました。

表 2
名前 説明
chunked 一連のチャンクでの転送 7.1
compress UNIX "compress" データ形式 [Welch] 7.2
deflate "deflate" 圧縮データ([RFC1951]) が "zlib" データ形式([RFC1950])内にあるもの 7.2
gzip GZIP ファイル形式 [RFC1952] 7.2
trailers (reserved) 12.3
x-compress 非推奨(compress のエイリアス) 7.2
x-gzip 非推奨(gzip のエイリアス) 7.2

12.4. ALPN プロトコル ID 登録

IANA は、https://www.iana.org/assignments/tls-extensiontype-values/ の "TLS Application-Layer Protocol Negotiation (ALPN) Protocol IDs" レジストリを以下の登録で更新しました:

表 3
プロトコル 識別シーケンス 参照
HTTP/1.1 0x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31 ("http/1.1") RFC 9112

13. 参照文献

13.1. 規範的参照

[CACHING]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “HTTP Caching”, STD 98, RFC 9111, DOI 10.17487/RFC9111, June 2022.
[HTTP]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “HTTP Semantics”, STD 97, RFC 9110, DOI 10.17487/RFC9110, June 2022.
[RFC1950]
Deutsch, P. and J-L. Gailly, “ZLIB Compressed Data Format Specification version 3.3”, RFC 1950, DOI 10.17487/RFC1950, May 1996, <https://www.rfc-editor.org/info/rfc1950>.
[RFC1951]
Deutsch, P., “DEFLATE Compressed Data Format Specification version 1.3”, RFC 1951, DOI 10.17487/RFC1951, May 1996, <https://www.rfc-editor.org/info/rfc1951>.
[RFC1952]
Deutsch, P., “GZIP file format specification version 4.3”, RFC 1952, DOI 10.17487/RFC1952, May 1996, <https://www.rfc-editor.org/info/rfc1952>.
[RFC2119]
Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.
[RFC5234]
Crocker, D., Ed. and P. Overell, “Augmented BNF for Syntax Specifications: ABNF”, STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, <https://www.rfc-editor.org/info/rfc5234>.
[RFC7405]
Kyzivat, P., “Case-Sensitive String Support in ABNF”, RFC 7405, DOI 10.17487/RFC7405, December 2014, <https://www.rfc-editor.org/info/rfc7405>.
[RFC8174]
Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[TLS13]
Rescorla, E., “The Transport Layer Security (TLS) Protocol Version 1.3”, RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.
[URI]
Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax”, STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, <https://www.rfc-editor.org/info/rfc3986>.
[USASCII]
American National Standards Institute, “Coded Character Set -- 7-bit American Standard Code for Information Interchange”, ANSI X3.4, 1986.
[Welch]
Welch, T., “A Technique for High-Performance Data Compression”, IEEE Computer 17(6), DOI 10.1109/MC.1984.1659158, June 1984, <https://ieeexplore.ieee.org/document/1659158/>.

13.2. 情報的参照

[HTTP/1.0]
Berners-Lee, T., Fielding, R., and H. Frystyk, “Hypertext Transfer Protocol -- HTTP/1.0”, RFC 1945, DOI 10.17487/RFC1945, May 1996, <https://www.rfc-editor.org/info/rfc1945>.
[Klein]
Klein, A., “Divide and Conquer - HTTP Response Splitting, Web Cache Poisoning Attacks, and Related Topics”, March 2004, <https://packetstormsecurity.com/papers/general/whitepaper_httpresponse.pdf>.
[Linhart]
Linhart, C., Klein, A., Heled, R., and S. Orrin, “HTTP Request Smuggling”, June 2005, <https://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf>.
[RFC2045]
Freed, N. and N. Borenstein, “Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies”, RFC 2045, DOI 10.17487/RFC2045, November 1996, <https://www.rfc-editor.org/info/rfc2045>.
[RFC2046]
Freed, N. and N. Borenstein, “Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types”, RFC 2046, DOI 10.17487/RFC2046, November 1996, <https://www.rfc-editor.org/info/rfc2046>.
[RFC2049]
Freed, N. and N. Borenstein, “Multipurpose Internet Mail Extensions (MIME) Part Five: Conformance Criteria and Examples”, RFC 2049, DOI 10.17487/RFC2049, November 1996, <https://www.rfc-editor.org/info/rfc2049>.
[RFC2068]
Fielding, R., Gettys, J., Mogul, J., Frystyk, H., and T. Berners-Lee, “Hypertext Transfer Protocol -- HTTP/1.1”, RFC 2068, DOI 10.17487/RFC2068, January 1997, <https://www.rfc-editor.org/info/rfc2068>.
[RFC2557]
Palme, J., Hopmann, A., and N. Shelness, “MIME Encapsulation of Aggregate Documents, such as HTML (MHTML)”, RFC 2557, DOI 10.17487/RFC2557, March 1999, <https://www.rfc-editor.org/info/rfc2557>.
[RFC5322]
Resnick, P., Ed., “Internet Message Format”, RFC 5322, DOI 10.17487/RFC5322, October 2008, <https://www.rfc-editor.org/info/rfc5322>.
[RFC7230]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing”, RFC 7230, DOI 10.17487/RFC7230, June 2014, <https://www.rfc-editor.org/info/rfc7230>.
[RFC8126]
Cotton, M., Leiba, B., and T. Narten, “Guidelines for Writing an IANA Considerations Section in RFCs”, BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>.

付録 A. 収集された ABNF

以下の収集された ABNF では、リスト規則は 第5.6.1節 に従って展開されています(参照:[HTTP])。

BWS = <BWS, see [HTTP], Section 5.6.3>

HTTP-message = start-line CRLF *( field-line CRLF ) CRLF [
 message-body ]
HTTP-name = %x48.54.54.50 ; HTTP
HTTP-version = HTTP-name "/" DIGIT "." DIGIT

OWS = <OWS, see [HTTP], Section 5.6.3>

RWS = <RWS, see [HTTP], Section 5.6.3>

Transfer-Encoding = [ transfer-coding *( OWS "," OWS transfer-coding
 ) ]

absolute-URI = <absolute-URI, see [URI], Section 4.3>
absolute-form = absolute-URI
absolute-path = <absolute-path, see [HTTP], Section 4.1>
asterisk-form = "*"
authority = <authority, see [URI], Section 3.2>
authority-form = uri-host ":" port

chunk = chunk-size [ chunk-ext ] CRLF chunk-data CRLF
chunk-data = 1*OCTET
chunk-ext = *( BWS ";" BWS chunk-ext-name [ BWS "=" BWS chunk-ext-val
 ] )
chunk-ext-name = token
chunk-ext-val = token / quoted-string
chunk-size = 1*HEXDIG
chunked-body = *chunk last-chunk trailer-section CRLF

field-line = field-name ":" OWS field-value OWS
field-name = <field-name, see [HTTP], Section 5.1>
field-value = <field-value, see [HTTP], Section 5.5>

last-chunk = 1*"0" [ chunk-ext ] CRLF

message-body = *OCTET
method = token

obs-fold = OWS CRLF RWS
obs-text = <obs-text, see [HTTP], Section 5.6.4>
origin-form = absolute-path [ "?" query ]

port = <port, see [URI], Section 3.2.3>

query = <query, see [URI], Section 3.4>
quoted-string = <quoted-string, see [HTTP], Section 5.6.4>

reason-phrase = 1*( HTAB / SP / VCHAR / obs-text )
request-line = method SP request-target SP HTTP-version
request-target = origin-form / absolute-form / authority-form /
 asterisk-form

start-line = request-line / status-line
status-code = 3DIGIT
status-line = HTTP-version SP status-code SP [ reason-phrase ]

token = <token, see [HTTP], Section 5.6.2>
trailer-section = *( field-line CRLF )
transfer-coding = <transfer-coding, see [HTTP], Section 10.1.4>

uri-host = <host, see [URI], Section 3.2.2>

付録 B. HTTP と MIME の相違点

HTTP/1.1 は、メッセージ本文をさまざまな表現で送信し拡張可能なフィールドを持てるようにするために、Internet Message Format [RFC5322] および Multipurpose Internet Mail Extensions (MIME) [RFC2045] で定義された多くの構成要素を利用しています。しかし、これらの構成要素の一部は対話型通信の要件に合わせて再解釈されており、HTTP 内での MIME 構成要素の使用にはいくつかの相違点があります。これらの相違は、バイナリ接続上でのパフォーマンス最適化、新しいメディアタイプのより自由な使用、日付比較の容易化、および一般的な実装への対応を目的として慎重に選択されています。

この付録は、HTTP が MIME と異なる具体的な点を説明します。プロキシやゲートウェイが厳密な MIME 環境とやり取りする場合、これらの相違を認識し必要に応じて適切な変換を行う必要があります。

B.1. MIME-Version

HTTP は MIME 準拠プロトコルではありません。ただし、メッセージを構築するのに使用された MIME プロトコルのバージョンを示すために単一の MIME-Version ヘッダフィールドを含めることができます。MIME-Version ヘッダフィールドを使用することは、そのメッセージが MIME プロトコル([RFC2045] に定義される)に完全に準拠していることを示します。送信者は、HTTP メッセージを厳格な MIME 環境にエクスポートする際に、可能な限り完全な準拠性を確保する責任があります。

B.2. 正規形式への変換

MIME は、インターネットメールのボディ部を転送前に正規形式に変換することを要求しており(詳細は RFC2049 第4節 を参照)、"text" タイプのコンテンツでは行区切りを CRLF と表現し、行区切り以外での CR または LF の使用を禁止しています。これに対して HTTP は、コンテンツ内で行区切りを示すために CRLF、裸の CR、あるいは裸の LF のどれが使われているかを問題にしません。

HTTP から厳格な MIME 環境へのプロキシやゲートウェイは、テキストメディアタイプ内のすべての行区切りを RFC2049 の正規形式である CRLF に変換するべきです。ただし、これは Content-Encoding の存在や、HTTP がオクテット 13 および 10 をそれぞれ CR と LF として使わない文字セットの使用を許しているという事実によって複雑になる可能性があります。

変換は、元のコンテンツに適用された暗号チェックサムを壊すため、元のコンテンツが既に正規形式でない限りクリプトグラフィックなチェックサムを破壊します。したがって、そのようなチェックサムを HTTP で使用するコンテンツには正規形式の使用が推奨されます。

B.3. 日付形式の変換

HTTP/1.1 は日付比較を簡素化するために制限された日付形式集合(第5.6.7節)を使用します。他のプロトコルからのプロキシやゲートウェイは、メッセージ内に存在する Date ヘッダフィールドが HTTP/1.1 の形式のいずれかに準拠していることを確認し、必要に応じて日付を書き換えるべきです。

B.4. Content-Encoding の変換

MIME には HTTP の Content-Encoding ヘッダフィールドに相当する概念はありません。これはメディアタイプの修飾子として動作するため、HTTP から MIME 準拠プロトコルへのプロキシやゲートウェイは、Content-Type ヘッダフィールドの値を変更するか、メッセージを転送する前に表現をデコードする必要があります。(Internet mail 向けの Content-Type の実験的な応用の中には、";conversions=<content-coding>" のようなメディアタイプパラメータを使って Content-Encoding に相当する機能を実現したものがありますが、このパラメータは MIME 標準の一部ではありません。)

B.5. Content-Transfer-Encoding の変換

HTTP は MIME の Content-Transfer-Encoding フィールドを使用しません。MIME 準拠プロトコルから HTTP へのプロキシやゲートウェイは、HTTP クライアントにレスポンスメッセージを配信する前に、あらゆる Content-Transfer-Encoding を除去する必要があります。

HTTP から MIME 準拠プロトコルへのプロキシやゲートウェイは、そのプロトコル上での安全な転送のためにメッセージが正しい形式とエンコーディングになっていることを保証する責任があります。ここでの「安全な転送」は使用されるプロトコルの制限によって定義されます。そのようなプロキシやゲートウェイは、送信先プロトコル上での安全な転送の可能性を高めるならば、データを変換し適切な Content-Transfer-Encoding を付加してラベル付けするべきです。

B.6. MHTML と行長の制限

MHTML [RFC2557] 実装とコードを共有する HTTP 実装は、MIME の行長制限に注意する必要があります。HTTP にはこの制限がないため、HTTP は長い行を折り返しません。HTTP によって輸送される MHTML メッセージは、MHTML のすべての慣習(行長制限や折り返し、正規化など)に従います。HTTP はメッセージ本文を変更せずに転送し、"multipart/byteranges" 型(第14.6節 を除き)コンテンツや内部に含まれる可能性のある MIME ヘッダ行を解釈しないためです。

付録 C. 以前の RFC からの変更点

C.1. HTTP/0.9 からの変更点

HTTP/0.9 はリクエストにヘッダフィールドをサポートしていなかったため、リクエストで名前ベースの仮想ホスト(リソース選択のための Host ヘッダフィールド の検査)がサポートされる仕組みはありません。名前ベースの仮想ホストを実装するサーバは、HTTP/0.9 のサポートを無効にするべきです。HTTP/0.9 に見える多くのリクエストは、実際にはリクエストターゲットを適切にエンコードできなかったクライアントによって生成された不正な HTTP/1.x リクエストであることがほとんどです。

C.2. HTTP/1.0 からの変更点

C.2.1. マルチホーミング Web サーバ

クライアントとサーバが Host ヘッダフィールド をサポートし、HTTP/1.1 リクエストにそれが欠けている場合はエラーを報告し、絶対 URI を受け入れる(第3.2節)という要件は、HTTP/1.1 によって定義された最も重要な変更点の一つです。

古い HTTP/1.0 クライアントは IP アドレスとサーバの一対一の関係を前提としており、リクエストの意図されたサーバを区別する確立された仕組みはリクエストが送られた IP アドレス以外に存在しませんでした。Host ヘッダフィールドは HTTP/1.1 の開発中に導入され、ほとんどの HTTP/1.0 ブラウザによってすぐに実装されましたが、完全な採用を確実にするためにすべての HTTP/1.1 リクエストに追加の要件が課されました。本稿執筆時点では、ほとんどの HTTP ベースのサービスがターゲティングのために Host ヘッダフィールド に依存しています。

C.2.2. キープアライブ接続

HTTP/1.0 では各接続はリクエストの前にクライアントによって確立され、レスポンス送信後にサーバによって切断されます。しかし、一部の実装では明示的に交渉される持続接続("Keep-Alive")のバージョンを実装しており、これは RFC2068 第19.7.1節 に記述されています。

一部のクライアントおよびサーバは、これら以前の持続接続アプローチと互換性を持たせるために、"Connection: keep-alive" リクエストヘッダフィールドで明示的に交渉することを望むかもしれません。しかし、HTTP/1.0 の持続接続の実験的実装には欠陥があることがあり、例えば HTTP/1.0 プロキシサーバが Connection を理解しない場合、それを次の内向きサーバに誤って転送して接続がハングする原因となることがあります。

この問題に対して試みられた解決策の一つに、プロキシを対象とした Proxy-Connection ヘッダフィールドの導入がありました。しかし実際にはこれも機能しませんでした。なぜならプロキシは多層で配備されることが多く、前述の同じ問題を引き起こすためです。

その結果、クライアントはどのリクエストにおいても Proxy-Connection ヘッダフィールド を送信しないことが推奨されます。

クライアントはまた、リクエストで "Connection: keep-alive" の使用を慎重に検討することが推奨されます。これにより HTTP/1.0 サーバとの持続接続を有効にできますが、使用するクライアントは接続がハングしているかどうかを監視する必要があり(これはクライアントがヘッダフィールドの送信をやめるべきことを示します)、プロキシが使用されている場合にはこの機構を全く使用すべきではありません。

C.2.3. Transfer-Encoding の導入

HTTP/1.1 は Transfer-Encoding ヘッダフィールド(第6.1節)を導入します。Transfer コーディングは、MIME 準拠プロトコルへ HTTP メッセージを転送する前にデコードする必要があります。

C.3. RFC 7230 からの変更点

HTTP の設計目標、歴史、アーキテクチャ、準拠基準、プロトコルのバージョニング、URI、メッセージルーティング、およびヘッダフィールドに関するセクションの大部分は [HTTP] に移動されました。本書は HTTP/1.1 固有のメッセージ構文と接続管理要件のみを扱うように縮小されています。

コンテンツ外での裸の CR は禁止されました。(第2.2節

authority-form の ABNF 定義は、URI のより一般的な authority 成分(ポートがオプションであるもの)から、CONNECT に必要な特定の host:port 形式に変更されました。(第3.2.3節

受信者は、曖昧なメッセージフレーミングを処理する際にスマグリング/スプリット攻撃を回避する必要があります。(第6.1節

チャンク拡張の ABNF では、";" と "=" の周りの(不要な)空白が再導入されました。空白は [RFC7230] で削除されましたが、その変更は既存の実装を壊すことが判明しました。(第7.1.1節

トレーラーフィールドの意味論は、チャンク転送コーディングの詳細を超越するようになりました。チャンクのデコードアルゴリズム(第7.1.3節)は、トレーラーフィールドをヘッダセクションとは別に格納/転送することを奨励し、受信者が対応するフィールド定義がマージを許可しマージ方法を定義している場合にのみヘッダセクションにマージを許可し、さもなければトレーラーフィールドをマージする代わりに破棄するように更新されました。トレーラーパートは現在トレーラセクションと呼ばれ、ヘッダセクションとより整合的でボディパートと区別されやすくなっています。(第7.1.2節

ランクの使用と競合を避けるため、"q" と呼ばれる転送コーディングパラメータは不許可になりました(TE ヘッダフィールド のランク使用と競合を避けるため)。(第7.3節

謝辞

Appendix "Acknowledgements"[HTTP])を参照してください。本ドキュメントにも適用されます。

索引

A C D F G H K L M O R T U W X

著者の連絡先

Roy T. Fielding (editor)
Adobe
345 Park Ave
San Jose, CA 95110
United States of America
Email: fielding@gbiv.com
URI: https://roy.gbiv.com/
Mark Nottingham (editor)
Fastly
Prahran
Australia
Email: mnot@mnot.net
URI: https://www.mnot.net/
Julian Reschke (editor)
greenbytes GmbH
Hafenweg 16
48155 Münster
Germany
Email: julian.reschke@greenbytes.de
URI: https://greenbytes.de/tech/webdav/