HTTPヘッダに構造定義を与える Structured Headers の提案仕様 (draft-14)

2021/02/09追記 RFC 8941: Structured Field Values for HTTP が出版されました


2年前にも同様の記事を書きましたが、当時はdraft-00でしたが、2年ほど立ち draft-14が出ておりところどころ変わっているので書き直します。
asnokaze.hatenablog.com

背景

新しいHTTPヘッダを定義するときに、新しい仕様毎にシンタックスを記述するのは非常に煩わしい作業です。

そこで、リストや辞書形式のようなデータ構造の定義を「Structured Headers for HTTP」として与えることで、新しいHTTPヘッダを定義するときはこの仕様を参照しリストや辞書形式のヘッダを定義できるようになります。実際、近年提案されている仕様ではしばしば参照されています。

また仕様ではこれらのデータ構造のパース手順も定義されており、実装としてもパースの処理が汎用的に再利用できるようになります。

// 2020/03/10追記
(最新仕様では 名称が "Structured Field Values for HTTP" に変更されました)

概要

Structured Headersでは、

  • トップレベルとして「Lists, Dictionaries, Items」という3つの形式がある
  • ListsとDictionariesはコンテナであり、Items もしくは Inner Listsを持つ
  • ItemsとInner ListsはKey/Value形式でパラメータ化できます
Lists

ListsはItemやInner Listsを持ち、カンマで区切られます。

Example-StrListHeader: "foo", "bar", "It was the best of times."
Inner Lists

Inner Listsはカッコで囲まれ、itemをスペース区切りで持ちます

Example-StrListListHeader: ("foo" "bar"), ("baz"), ("bat" "one"), ()
Parameters

ParametersはitemやInner Listsに関連付けられたKey/Valueのペアです。itemやInner Listsの後ろに;で記述されます。Keyは文字で、valueはitemとなります

Example-ParamListHeader: abc;a=1;b=2; cde_456, (ghi;jk=4 l);q="9";r=w
Dictionaries

DictionariesはKey/Valueからなる順序付きのマップです。

   Example-DictHeader: en="Applepie", da=*w4ZibGV0w6ZydGU=*
   Example-DictListHeader: rating=1.5, feelings=(joy sadness)
   Example-MixDict: a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid=?1
Item

Itemは下記の種類があります

  • Integers
  • Floats
  • Tokens
  • Byte Sequences
  • Booleans

それぞれ例を示します

Integers

Example-IntegerHeader: 42 

Floats

Example-FloatHeader: 4.5

Strings (ダブルクォートで囲まれます)

Example-StringHeader: "hello world"

Tokens (短い単語)
(アルファベット及び":" "/"を持つ。なぜかこれだけ仕様で例が示されていない)

Byte Sequences (*で囲まれたBase64)

Example-BinaryHdr: *cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==*

Booleans (?で始まり、0 or 1)

Example-BoolHdr: ?1

使用例

このStructured Headersは多くの仕様で参照されていますが、一つの例をあげます。

FastlyのMark Nottingham氏が提案する「The Cache-Status HTTP Response Header」では、CacheにHitしたかなどをレスポンスヘッダで通知する新しいヘッダを定義しています。

このようにCache-StatusはListであると定義しています。このようにシンタックスの定義はStructured Headersを参照するだけになります。

   The Cache-Status HTTP response header indicates caches' handling of
   the request corresponding to the response it occurs within.

   Its value is a List [I-D.ietf-httpbis-header-structure]:

Listの中身についてはもう少し細かい言及があるのですが、詳細は割愛します
実際のCache-Statusヘッダの例です。

Cache-Status: "CDN Company Here"; res-fresh=545,
                 OriginCache; cache-fresh=1100; collapse-hit=?1

Parameters及びBooleansが使用されている事がわかりますね。

その他

このようなHTTPヘッダでデータ構造を扱うという案が出たとき、最初はJSONを使うことが検討されましたが、議論のすえ現在の形式となっています。その経緯については提案仕様の Appendix-B に書かれています。興味ある方はよんでみてはいかがでしょうか。