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

5. フィールド

HTTPは、登録されたキー名前空間を持つ拡張可能な名前/値ペアの形式でデータを提供するために「フィールド」(Fields) を使用します。フィールドは、メッセージのヘッダーおよびトレーラーセクション (セクション6) 内で送受信されます。

5.1. フィールド名

フィールド名 (Field Name) は、対応するフィールド値に、その名前によって定義されたセマンティクスを持つものとしてラベル付けします。例えば、Dateヘッダーフィールドは、セクション6.6.1で、それが現れるメッセージの発信タイムスタンプを含むものとして定義されています。

field-name     = token

フィールド名は大文字と小文字を区別せず、「ハイパーテキスト転送プロトコル (HTTP) フィールド名レジストリ」内に登録されるべきです; セクション16.3.1を参照してください。

フィールドの解釈は、同じHTTPメジャーバージョンのマイナーバージョン間で変わることはありませんが、そのようなフィールドがない場合の受信者のデフォルト動作は変わる可能性があります。特に指定されない限り、フィールドはHTTPのすべてのバージョンに対して定義されます。特に、HostおよびConnectionフィールドは、HTTP/1.1への準拠を表明するかどうかにかかわらず、すべてのHTTP実装によって認識されるべきです。

定義されたセマンティクスが、それらを認識しない受信者によって安全に無視されることを許可する場合、プロトコルバージョンを変更せずに新しいフィールドを導入できます; セクション16.3を参照してください。

プロキシは、フィールド名がConnectionヘッダーフィールド (セクション7.6.1) にリストされているか、またはプロキシがそのようなフィールドをブロックするか、その他の方法で変換するように特別に構成されていない限り、認識されないヘッダーフィールドを転送しなければなりません (MUST)。他の受信者は、認識されないヘッダーおよびトレーラーフィールドを無視すべきです (SHOULD)。これらの要件に従うことで、デプロイされた仲介者を更新または削除することなく、HTTPの機能を拡張できます。

5.2. フィールド行と結合フィールド値

フィールドセクション (Field Sections) は、任意の数の「フィールド行」(Field Lines) で構成され、各フィールド行には、フィールドを識別する「フィールド名」(セクション5.1を参照) と、そのフィールドのインスタンスのデータを伝達する「フィールド行値」(Field Line Value) があります。

フィールド名がセクション内に一度だけ存在する場合、そのフィールドの結合された「フィールド値」(Field Value) は、対応するフィールド行値で構成されます。フィールド名がセクション内で繰り返される場合、その結合されたフィールド値は、そのセクション内の対応するフィールド行値のリストで構成され、順番に連結され、各フィールド行値はカンマで区切られます。

例えば、このセクション:

Example-Field: Foo, Bar
Example-Field: Baz

には2つのフィールド行が含まれ、両方ともフィールド名「Example-Field」を持っています。最初のフィールド行のフィールド行値は「Foo, Bar」であり、2番目のフィールド行値は「Baz」です。「Example-Field」のフィールド値は、リスト「Foo, Bar, Baz」です。

5.3. フィールドの順序

受信者は、フィールドセクション内で同じフィールド名を持つ複数のフィールド行を、メッセージのセマンティクスを変更することなく、1つのフィールド行に結合してもよいです (MAY)。これは、各後続のフィールド行値を、カンマ (",") とオプションの空白 (OWS、セクション5.6.3で定義) で区切って、最初のフィールド行値に順番に追加することによって行われます。一貫性のために、カンマSPを使用します。

したがって、同じ名前のフィールド行が受信される順序は、フィールド値の解釈にとって重要です; プロキシは、メッセージを転送する際にこれらのフィールド行値の順序を変更してはなりません (MUST NOT)。

これは、以下で言及されている既知の例外を除いて、送信者がメッセージ内 (ヘッダーまたはトレーラーのいずれにおいても) に同じ名前の複数のフィールド行を生成してはならない (MUST NOT) か、または同じ名前のフィールド行がメッセージ内に既に存在する場合にフィールド行を追加してはならないことを意味します。ただし、そのフィールドの定義が、複数のフィールド行値をカンマ区切りリストとして再結合することを許可している場合は除きます (つまり、フィールドの定義の少なくとも1つの代替がカンマ区切りリストを許可している場合、例えばセクション5.6.1で定義されている#(values)のABNFルールなど)。

注意: 実際には、「Set-Cookie」ヘッダーフィールド ([COOKIE]) は、複数のフィールド行にわたって応答メッセージに現れることが多く、リスト構文を使用しないため、同じフィールド名を持つ複数のフィールド行に関する上記の要件に違反しています。これを単一のフィールド値に結合できないため、受信者はフィールドを処理する際に「Set-Cookie」を特殊なケースとして処理すべきです。(詳細については、[Kri2001]の付録A.2.3を参照してください。)

セクション内で異なるフィールド名を持つフィールド行が受信される順序は重要ではありません。ただし、リクエストのHostや応答のDateなど、追加の制御データを含むヘッダーフィールドを最初に送信することは良い習慣です。これにより、実装はメッセージを処理しないことをできるだけ早く決定できます。

サーバーは、リクエストヘッダーセクション全体を受信するまで、リクエストをターゲットリソースに適用してはなりません (MUST NOT)。これは、後のヘッダーフィールド行に、条件、認証資格情報、またはリクエスト処理に影響を与える可能性のある意図的に誤解を招く重複ヘッダーフィールドが含まれる可能性があるためです。

5.4. フィールドの制限

HTTPは、セクション2で説明されているように、各フィールド行、フィールド値、またはヘッダーまたはトレーラーセクション全体の長さに事前定義された制限を設けていません。個々の長さに対するさまざまなアドホックな制限が実際に見られ、多くの場合、特定のフィールドのセマンティクスに依存しています。

処理したいよりも大きいリクエストヘッダーフィールド行、フィールド値、またはフィールドセットを受信するサーバーは、適切な4xx (クライアントエラー) ステータスコードで応答しなければなりません (MUST)。そのようなヘッダーフィールドを無視すると、サーバーのリクエストスマグリング攻撃に対する脆弱性が増加します ([HTTP/1.1]のセクション11.2)。

クライアントは、フィールドのセマンティクスが、ドロップされた値がメッセージフレーミングまたは応答セマンティクスを変更することなく安全に無視できるものである場合、処理したいよりも大きい受信フィールド行を破棄または切り捨ててもよいです (MAY)。

5.5. フィールド値

HTTPフィールド値 (Field Values) は、フィールドの文法によって定義された形式の文字シーケンスで構成されます。各フィールドの文法は通常、ABNF ([RFC5234]) を使用して定義されます。

field-value    = *field-content
field-content = field-vchar
[ 1*( SP / HTAB / field-vchar ) field-vchar ]
field-vchar = VCHAR / obs-text
obs-text = %x80-FF

フィールド値には、先頭または末尾の空白は含まれません。HTTPの特定のバージョンでそのような空白がメッセージに現れることを許可する場合、フィールド解析の実装は、フィールド値を評価する前にそのような空白を除外しなければなりません (MUST)。

フィールド値は通常、US-ASCII文字 [USASCII] の範囲に制限されます。より大きな文字範囲を必要とするフィールドは、[RFC8187]で定義されているようなエンコーディングを使用できます。歴史的に、HTTPはフィールドコンテンツがISO-8859-1文字セット [ISO-8859-1] のテキストを持つことを許可してきましたが、[RFC2047]エンコーディングの使用を通じてのみ他の文字セットをサポートしています。新しく定義されるフィールドの仕様は、その値を可視のUS-ASCIIオクテット (VCHAR)、SP、およびHTABに制限すべきです (SHOULD)。受信者は、フィールドコンテンツ内の他の許可されたオクテット (つまり、obs-text) を不透明なデータとして扱うべきです (SHOULD)。

CR、LF、またはNUL文字を含むフィールド値は無効であり危険です。これは、実装がこれらの文字を異なる方法で解析および解釈する可能性があるためです; フィールド値内でCR、LF、またはNULを受信する受信者は、メッセージを拒否するか、そのメッセージをさらに処理または転送する前にこれらの文字のそれぞれをSPに置き換えなければなりません (MUST)。他のCTL文字を含むフィールド値も無効です; ただし、受信者は、安全なコンテキスト (例えば、下流のHTTPパーサーによって処理されないアプリケーション固有の引用文字列) 内に現れる場合、堅牢性のためにそのような文字を保持してもよいです (MAY)。

フィールド値として単一のメンバーのみを予期するフィールドは、「シングルトンフィールド」(Singleton Fields) と呼ばれます。

フィールド値として複数のメンバーを許可するフィールドは、「リストベースのフィールド」(List-Based Fields) と呼ばれます。セクション5.6.1のリスト演算子拡張は、複数のメンバーを含むことができるフィールド値を定義するための一般的な表記法として使用されます。

カンマ (",") がメンバー間の区切り文字として使用されるため、メンバー内のデータとして許可される場合は注意して処理する必要があります。これは、リストベースのフィールドとシングルトンフィールドの両方に当てはまります。なぜなら、シングルトンフィールドが誤って複数のメンバーで送信される可能性があり、そのようなエラーを検出することで相互運用性が向上するためです。メンバー内にカンマを含むことが予想されるフィールド、例えばHTTP日付またはURI参照要素内のカンマは、そのデータ内の任意のカンマを潜在的なリスト区切り文字と区別するために、その要素の周りに区切り文字を定義すべきです。

例えば、テキスト日付とURI (どちらもカンマを含む可能性があります) は、次のようなリストベースのフィールド値で安全に運ぶことができます:

Example-URIs: "http://example.com/a.html,foo",
"http://without-a-comma.example.com/"
Example-Dates: "Sat, 04 May 1996", "Wed, 14 Sep 2005"

二重引用符の区切り文字は、ほとんど常にquoted-string生成規則 (セクション5.6.4) とともに使用されることに注意してください; 二重引用符内で異なる構文を使用すると、不必要な混乱を引き起こす可能性があります。

多くのフィールド (例えば、セクション8.3で定義されているContent-Type) は、パラメータに共通の構文を使用しており、パラメータ値に引用符なし (token) と引用符付き (quoted-string) の両方の構文を許可しています (セクション5.6.6)。共通の構文を使用することで、受信者は既存のパーサーコンポーネントを再利用できます。両方の形式を許可する場合、パラメータ値の意味は、その値を伝達するために使用される形式に依存しないものであるべきです。

注意: フィールド値の構文を定義するために、この仕様では、フィールド名にちなんで名付けられたABNFルールを使用して、そのフィールドの値に許可される文法を定義します (基礎となるメッセージング構文からフィールド値が抽出され、複数のインスタンスがリストに結合された後)。

5.6. フィールド値を定義するための共通ルール

5.6.1. リスト (#ルールABNF拡張)

[RFC5234]のABNFルールへの#ルール拡張は、いくつかのリストベースのフィールド値の定義の可読性を向上させるために使用されます。

"*"に似た構成"#"が定義されており、カンマ区切りの要素のリストを定義するために使用されます。完全な形式は「<n>#<m>element」であり、最小<n>個、最大<m>個の要素を示し、各要素は単一のカンマ (",") とオプションの空白 (OWS、セクション5.6.3で定義) で区切られます。

5.6.1.1. 送信者の要件

リスト構成を使用する任意の生成規則において、送信者は空のリスト要素を生成してはなりません (MUST NOT)。言い換えれば、送信者は次の構文を満たすリストを生成しなければなりません:

1#element => element *( OWS "," OWS element )

および:

#element => [ 1#element ]

およびn >= 1およびm > 1の場合:

<n>#<m>element => element <n-1>*<m-1>( OWS "," OWS element )

付録Aは、リスト構成が展開された後の送信者の収集されたABNFを示しています。

5.6.1.2. 受信者の要件

空の要素は、存在する要素の数にカウントされません。受信者は、合理的な数の空のリスト要素を解析して無視しなければなりません (MUST): 値をマージする送信者による一般的な間違いを処理するのに十分な数ですが、サービス拒否メカニズムとして使用できるほど多くはありません。言い換えれば、受信者は次の構文を満たすリストを受け入れなければなりません (MUST):

#element => [ element ] *( OWS "," OWS [ element ] )

空のリスト要素の潜在的な存在のため、RFC 5234 ABNFはリスト要素の基数を強制できないことに注意してください。したがって、すべてのケースは、基数が指定されていないかのようにマップされます。

例えば、これらのABNF生成規則が与えられた場合:

example-list      = 1#example-list-elmt
example-list-elmt = token ; セクション5.6.2を参照

次に、以下はexample-listの有効な値です (二重引用符は区切りのためにのみ存在し、含まれません):

"foo,bar"
"foo ,bar,"
"foo , ,bar,charlie"

対照的に、以下は無効です。なぜなら、example-list生成規則は少なくとも1つの非空要素を必要とするためです:

""
","
", ,"

5.6.2. トークン

トークン (Tokens) は、空白や区切り文字を含まない短いテキスト識別子です。

token          = 1*tchar

tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
/ "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
/ DIGIT / ALPHA
; 区切り文字を除く任意のVCHAR

多くのHTTPフィールド値は、空白または特定の区切り文字で区切られた共通の構文コンポーネントを使用して定義されます。区切り文字は、トークンで許可されていないUS-ASCII可視文字のセットから選択されます (DQUOTEおよび"(),/:;<=>?@[\]{}").

5.6.3. 空白

この仕様では、線形空白の使用を示すために3つのルールを使用します: OWS (オプションの空白、Optional Whitespace)、RWS (必須の空白、Required Whitespace)、およびBWS (「悪い」空白、"Bad" Whitespace)。

OWSルールは、ゼロ個以上の線形空白オクテットが現れる可能性がある場所で使用されます。オプションの空白が可読性を向上させることが望ましいプロトコル要素の場合、送信者はオプションの空白を単一のSPとして生成すべきです (SHOULD); それ以外の場合、送信者は、インプレースメッセージフィルタリング中に無効または不要なプロトコル要素をフィルタリングする必要がある場合を除き、オプションの空白を生成すべきではありません (SHOULD NOT)。

RWSルールは、フィールドトークンを区切るために少なくとも1つの線形空白オクテットが必要な場合に使用されます。送信者はRWSを単一のSPとして生成すべきです (SHOULD)。

OWSおよびRWSルールは、単一のSPと同じセマンティクスを持ちます。OWSまたはRWSとして定義されることが知られている任意のコンテンツは、それを解釈するか、メッセージをダウンストリームに転送する前に、単一のSPに置き換えてもよいです (MAY)。

BWSルールは、文法が歴史的な理由でのみオプションの空白を許可する場所で使用されます。送信者はメッセージ内でBWSを生成してはなりません (MUST NOT)。受信者はそのような悪い空白を解析し、プロトコル要素を解釈する前にそれを削除しなければなりません (MUST)。

BWSにはセマンティクスはありません。BWSとして定義されることが知られている任意のコンテンツは、それを解釈するか、メッセージをダウンストリームに転送する前に削除してもよいです (MAY)。

OWS            = *( SP / HTAB )
; オプションの空白
RWS = 1*( SP / HTAB )
; 必須の空白
BWS = OWS
; 「悪い」空白

5.6.4. 引用文字列

テキスト文字列は、二重引用符を使用して引用されている場合、単一の値として解析されます。

quoted-string  = DQUOTE *( qdtext / quoted-pair ) DQUOTE
qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text

バックスラッシュオクテット ("") は、quoted-stringおよびcomment構成内で単一オクテットの引用メカニズムとして使用できます。quoted-stringの値を処理する受信者は、quoted-pairを、バックスラッシュに続くオクテットに置き換えられたかのように処理しなければなりません (MUST)。

quoted-pair    = "\" ( HTAB / SP / VCHAR / obs-text )

送信者は、その文字列内に現れるDQUOTEおよびバックスラッシュオクテットを引用する必要がある場所を除き、quoted-string内でquoted-pairを生成すべきではありません (SHOULD NOT)。送信者は、そのコメント内に現れる括弧 ["("および")"] およびバックスラッシュオクテットを引用する必要がある場所を除き、コメント内でquoted-pairを生成すべきではありません (SHOULD NOT)。

5.6.5. コメント

コメントテキストを括弧で囲むことにより、一部のHTTPフィールドにコメントを含めることができます。コメントは、フィールド値定義の一部として「comment」を含むフィールドでのみ許可されます。

comment        = "(" *( ctext / quoted-pair / comment ) ")"
ctext = HTAB / SP / %x21-27 / %x2A-5B / %x5D-7E / obs-text

5.6.6. パラメータ

パラメータ (Parameters) は名前/値ペアのインスタンスです; それらは多くの場合、アイテムに補助情報を付加するための共通の構文として、フィールド値で使用されます。各パラメータは通常、直前のセミコロンによって区切られます。

parameters      = *( OWS ";" OWS [ parameter ] )
parameter = parameter-name "=" parameter-value
parameter-name = token
parameter-value = ( token / quoted-string )

パラメータ名は大文字と小文字を区別しません。パラメータ値は、パラメータ名のセマンティクスに応じて、大文字と小文字を区別する場合と区別しない場合があります。パラメータの例といくつかの同等の形式は、メディアタイプ (セクション8.3.1) およびAcceptヘッダーフィールド (セクション12.5.1) で見ることができます。

token生成規則に一致するパラメータ値は、tokenとして、またはquoted-string内で送信できます。引用された値と引用されていない値は同等です。

注意: パラメータは「=」文字の周りに空白 (「悪い」空白でさえも) を許可しません。

5.6.7. 日付/時刻形式

1995年以前には、サーバーがタイムスタンプを伝達するために一般的に使用する3つの異なる形式がありました。古い実装との互換性のために、ここでは3つすべてが定義されています。推奨される形式は、インターネットメッセージ形式 [RFC5322] で使用される日付と時刻の仕様の固定長かつ単一タイムゾーンのサブセットです。

HTTP-date    = IMF-fixdate / obs-date

推奨される形式の例は

Sun, 06 Nov 1994 08:49:37 GMT    ; IMF-fixdate

2つの時代遅れの形式の例は

Sunday, 06-Nov-94 08:49:37 GMT   ; 時代遅れのRFC 850形式
Sun Nov 6 08:49:37 1994 ; ANSI CのASCTIME()形式

HTTPフィールドでタイムスタンプ値を解析する受信者は、3つのHTTP-date形式すべてを受け入れなければなりません (MUST)。送信者がHTTP-dateとして定義された1つ以上のタイムスタンプを含むフィールドを生成する場合、送信者はそれらのタイムスタンプをIMF-fixdate形式で生成しなければなりません (MUST)。

HTTP-date値は、協定世界時 (Coordinated Universal Time, UTC) のインスタンスとして時間を表します。最初の2つの形式は、UTCの前身であるグリニッジ標準時の3文字の略語「GMT」によってUTCを示します; asctime形式の値はUTCであると仮定されます。

「時計」(Clock) は、UTCで現在の瞬間の合理的な近似値を提供できる実装です。時計の実装は、NTP ([RFC5905]) または類似のプロトコルを使用してUTCと同期すべきです。

推奨される形式:

IMF-fixdate  = day-name "," SP date1 SP time-of-day SP GMT
; 固定長/ゾーン/大文字化形式のサブセット
; [RFC5322]のセクション3.3を参照

day-name = %s"Mon" / %s"Tue" / %s"Wed"
/ %s"Thu" / %s"Fri" / %s"Sat" / %s"Sun"

date1 = day SP month SP year
; 例: 02 Jun 1982

day = 2DIGIT
month = %s"Jan" / %s"Feb" / %s"Mar" / %s"Apr"
/ %s"May" / %s"Jun" / %s"Jul" / %s"Aug"
/ %s"Sep" / %s"Oct" / %s"Nov" / %s"Dec"
year = 4DIGIT

GMT = %s"GMT"

time-of-day = hour ":" minute ":" second
; 00:00:00 - 23:59:60 (うるう秒)

hour = 2DIGIT
minute = 2DIGIT
second = 2DIGIT

時代遅れの形式:

obs-date     = rfc850-date / asctime-date

rfc850-date = day-name-l "," SP date2 SP time-of-day SP GMT
date2 = day "-" month "-" 2DIGIT
; 例: 02-Jun-82

day-name-l = %s"Monday" / %s"Tuesday" / %s"Wednesday"
/ %s"Thursday" / %s"Friday" / %s"Saturday"
/ %s"Sunday"

asctime-date = day-name SP date3 SP time-of-day SP year
date3 = month SP ( 2DIGIT / ( SP 1DIGIT ))
; 例: Jun 2

HTTP-dateは大文字と小文字を区別します。[CACHING]のセクション4.2は、キャッシュ受信者に対してこれを緩和していることに注意してください。

送信者は、文法でSPとして明示的に含まれているもの以外の、HTTP-date内に追加の空白を生成してはなりません (MUST NOT)。day-name、day、month、year、およびtime-of-dayのセマンティクスは、インターネットメッセージ形式で対応する名前を持つ構成に対して定義されたセマンティクスと同じです ([RFC5322]、セクション3.3)。

2桁の年を使用するrfc850-date形式のタイムスタンプ値を受信する受信者は、未来50年以上先に見えるタイムスタンプを、同じ下2桁を持つ過去の最も最近の年を表すものとして解釈しなければなりません (MUST)。

タイムスタンプ値の受信者は、フィールド定義によって他に制限されていない限り、タイムスタンプの解析において堅牢であることが推奨されます。例えば、メッセージは、インターネットメッセージ形式で定義された任意の日付と時刻の仕様を生成する可能性のある非HTTPソースからHTTP経由で転送されることがあります。

注意: 日付/時刻スタンプ形式に対するHTTP要件は、プロトコルストリーム内でのそれらの使用にのみ適用されます。実装は、ユーザープレゼンテーション、リクエストロギングなどにこれらの形式を使用する必要はありません。