2.1. HTTP Fields (HTTP フィールド)
2.1. HTTP Fields (HTTP フィールド)
HTTP フィールドのコンポーネント名は, [HTTP] のセクション 5.1 で定義されるフィールド名の小文字形である. HTTP フィールド名は大文字小文字を区別しないが, 実装はコンポーネント名として用いる際に小文字のフィールド名 (例: content-type, date, etag) を用いなければならない.
HTTP フィールドのコンポーネント値は, [HTTP] のセクション 5.5 で定義される名前付きフィールドのフィールド値である. フィールド値は, 下記の req および tr フラグなどの追加パラメータおよび規則により上書きされない限り, ターゲットメッセージの名前付きヘッダフィールドから取り出さなければならない. ほとんどのフィールドでは, フィールド値は [HTTP] が推奨する ASCII 文字列であり, コンポーネント値はまさにその文字列である. 一部の実装では他の符号化が存在しうるが, すべての非 ASCII フィールド値は署名ベースに加える前に ASCII に符号化しなければならない. セクション 2.1.3 で記述する bs パラメータは, そのような問題のあるフィールド値をラップする方法を提供する.
追加のパラメータおよび規則により上書きされない限り, HTTP フィールド値はコンポーネント値を作るために [HTTP] のセクション 5.2 で定義されるとおり単一の値に結合されなければならない. 具体的には, 複数のフィールドとして送信された HTTP フィールドは, 単一のコンマと単一の空白を区切りとして値を連結することにより結合されなければならない ("," + " "). 中間者はコンマの間に任意量の空白を挟んで HTTP フィールドの値を結合してよいことに注意し, 検証者がこの挙動を考慮しない場合, 署名者と検証者はそれぞれの署名ベースで異なるコンポーネント値を見ることになり署名が失敗しうる. 堅牢性のため, 署名付きメッセージでは署名のもとで被覆される任意のフィールドについては単一のインスタンスのみを含めることが推奨される. 特にリストベースのフィールドの値は下記のアルゴリズムでシリアル化することが推奨される. この方針は, フィールド値が中間者を通じて無改変のまま残る可能性を高める. その方針が不可能でフィールドの複数インスタンスを別々に送る必要がある場合, 署名者と検証者はリストベースのフィールドについて個々のフィールド値をすべて取り, 下記の厳密アルゴリズムに基づいて結合して処理することが推奨される. これにより想定される中間者の挙動に対抗できる. 対象フィールドが List または Dictionary 型の Structured Field である場合, セクション 2.1.1 で記述する厳密な Structured Field シリアル化を要求することで, より直接的にこの効果を達成できる.
Set-Cookie [COOKIE] など一部の HTTP フィールドは, この方法でフィールド値を結合しても (複数入力から) 結合出力が曖昧にならないような構文に従わない. コンポーネント値はメッセージ署名過程によってパースされず署名ベース (セクション 2.5) の一部としてのみ用いられるが, そのようなフィールドを署名に含める際は注意が必要である. 結合後の値が曖昧になりうるからである. セクション 2.1.3 で記述する bs パラメータは, そのような問題のあるフィールドをラップする方法を提供する. この問題に関するさらなる議論はセクション 7.5.6 を参照.
所与のフィールドについて実装が結合済みの値を直接利用できない場合, 次のアルゴリズムはリストベースのフィールドに対して正規化された結果を生成する.
-
メッセージ内の当該フィールドの各インスタンスのフィールド値を, メッセージ内に現れる (または現れる予定の) 順序で並べた順序付きリストを作成する.
-
リストの各項目から先頭および末尾の空白を除去する. HTTP フィールド値は先頭末尾の空白を含んではならないため, 適合実装ではこれは何もしない.
-
行内の廃止された行折り (obsolete line folding) を除去し, [HTTP/1.1] のセクション 5.2 で論じるとおり単一の空白 (
" ")) に置き換える. この挙動は HTTP/1.1 に固有であり, 内部行折りを許さない HTTP 仕様の他バージョンには適用されない. -
項目間に単一のコンマ (
,) と単一の空白 (" ") を挟んで値のリストを連結する.
得られた文字列が当該フィールドのコンポーネント値である.
一部の HTTP フィールドは, 意味的に等価な複数の有効なシリアル化 (中間者が変更しうる大文字小文字を区別しない値の許容など) を持つ. そのようなフィールドに署名し処理するアプリケーションは, 署名者と検証者が同一の値を導出できるよう, セクション 7.5.2 で論じるとおり, そのようなフィールドの値の扱いを考慮しなければならない.
次は, 次の例 HTTP メッセージ断片が与えられたときのヘッダフィールドのコンポーネント値の参考例である.
Host: www.example.com Date: Tue, 20 Apr 2021 02:07:56 GMT X-OWS-Header: Leading and trailing whitespace. X-Obs-Fold-Header: Obsolete line folding. Cache-Control: max-age=60 Cache-Control: must-revalidate Example-Dict: a=1, b=2;x=1;y=2, c=(a b c)
次の例は, セクション 2.5 で定義される署名ベース形式で示した, これらの例ヘッダフィールドのコンポーネント値である.
"host": www.example.com "date": Tue, 20 Apr 2021 02:07:56 GMT "x-ows-header": Leading and trailing whitespace. "x-obs-fold-header": Obsolete line folding. "cache-control": max-age=60, must-revalidate "example-dict": a=1, b=2;x=1;y=2, c=(a b c)
メッセージに存在する場合, 空の HTTP フィールドにも署名でき, 正規化された値は空文字列である. つまり, 空のフィールド値の前に単一の末尾空白文字 (SP) がある次の空ヘッダフィールド,
X-Empty-Header:(SP)
は, 署名ベース生成アルゴリズム (セクション 2.5) により, コンポーネント識別子の後に付与されるコロンと空白の後に空文字列値を伴ってシリアル化される.
"x-empty-header":(SP)
任意の HTTP フィールドのコンポーネント識別子は, 特定の状況で次のパラメータを持ってよい. それぞれ別節で詳述する.
sf コンポーネント値が Structured Field 値の厳密符号化 (セクション 2.1.1) を用いてシリアル化されることを示す Boolean フラグ.
key Dictionary Structured Field (セクション 2.1.2) から単一のメンバ値を選択するために用いる String パラメータ.
bs コンポーネント値に結合する前に, 個々のフィールド値が Byte Sequence データ構造で符号化されることを示す Boolean フラグ (セクション 2.1.3).
req 署名付きレスポンス用の Boolean フラグで, コンポーネント値がこのレスポンスメッセージから直接ではなく, このレスポンスを引き起こしたリクエストから導出されることを示す. このパラメータはリクエストを対象とする任意の派生コンポーネント識別子にも適用できてよい (セクション 2.4).
tr フィールド値が [HTTP] のセクション 6.5 で定義されるメッセージのトレーラから取り出されることを示す Boolean フラグ. このフラグがない場合, フィールド値は [HTTP] のセクション 6.3 で定義されるヘッダフィールドから取り出される (セクション 2.1.4).
複数のパラメータを一緒に指定してよいが, 一部の組合せは冗長または両立しない. 例えば, sf パラメータの機能は Dictionary 項目に key パラメータを用いる場合にはすでに key が値の厳密シリアル化を要求するため包含される. メッセージからのフィールド値の生バイトを要する bs パラメータは, 結合後のフィールド値のパース済みデータ構造を要する sf または key パラメータの利用と両立しない.
追加のパラメータはセクション 6.5 で確立する "HTTP Signature Component Parameters" レジストリで定義できてよい.