Bundled HTTP Exchanges とは (WebPackagingの議論より)

20190709追記
draft 01が出ました。幾つかの修正が入っています。そのため、本記事は内容が古くなっています。
https://tools.ietf.org/html/draft-yasskin-wpack-bundled-exchanges-01

20180615追記
Bundled HTTP Exchangesの仕様がIETFに提出されました
https://tools.ietf.org/html/draft-yasskin-wpack-bundled-exchanges-00


WebPackagingという仕様が議論されている。簡単な概要は以下の記事に書いたとおり
asnokaze.hatenablog.com

WICG/webpackageで書かれている通り、WebPackagingは以下の2つに分離して標準化が進められそうです

  • Signed HTTP exchanges: HTTPリクエスト/レスポンスをブラウザが信頼できるように署名する仕組み
  • Bundled HTTP exchanges: 複数のHTTPリクエスト/レスポンスを一つのCBOR形式で表現できるようにする仕組み


Signed HTTP exchangesの方は、既にIETFに提案しようが出ており下記の記事で軽く触れた。
asnokaze.hatenablog.com


Bundled HTTP exchangesの方は、未だIETFには提出されていないが、著者様の個人リポジトリにdraftがあるため軽く読んでおく。
(まだIETFに提出されていないため変更される可能性があります)

Bundled HTTP exchanges

仕様は「https://jyasskin.github.io/webpackage/bundles/draft-yasskin-dispatch-bundled-exchanges.html」から確認できる

bundleは複数のHTTPリクエストレスポンスを一つにまとめる。データ構造はCDDLで記述する。

bundle = [
  ; 🌐📦 in UTF-8.
  magic: h'F0 9F 8C 90 F0 9F 93 A6',
  section-offsets: {* (($section-name .within tstr) => uint) },
  sections: [* $section ],
  length: bytes .size 8,  ; Big-endian number of bytes in the bundle.
]

$section-name /= "index" / "manifest" / "critical" / "responses"

$section /= index / manifest / critical / responses

responses = [*response]

まず最初にメタ情報のロードが行われる

  • bundleは🌐📦であるmagicから開始される
  • 続いて、0以上のsection-offsetsが続く。
    • section-offsetsのkeyは、"index", "manifest", "critical", "responses"のどれかである (未知のセクションは無視される)
    • section-offsetsのvalueは、それらのセクションが何バイト目から開始されるかのオフセットである。
  • sectionは各セクションの構造毎にパースされる
    • responsesは実際にデータをロードする際にパースされる。
  • lengthは、このbundleの長さ

indexセクション

HTTPリクエストに対応するレスポンスが、responsesセクションのどこに存在するかのインデックス。responsesセクション開始からのオフセットと長さが与えられる。

index = {* http-request => [ offset: uint,
                             length: uint] }

http-requestは下記の構造で表現される

http-request = {
  * bstr => bstr
}

manifestセクション

bundle自身を識別するためのマニフェストファイル(Web App Manifest形式)へのHTTPリクエスト情報。

manifestセクションはhttp-requestからのみなる

manifest = http-request

詳しくは (Web App Manifest形式)

criticalセクション

将来のバージョンを想定して、未知のセクションは無視されるが、サポートすべきセクション名を記述できる。

criticalセクションは以下の通り

critical = [*tstr]

ココに書かれているsection-nameをサポートしていない場合はパースは失敗となる。

responseセクション

responseセクションは下記の通りである

response = [headers: {* bstr => bstr}, payload: bstr]

各responseはレスポンスヘッダと、HTTPボディであるペイロードからなる。ヘッダとしてステータスコードを示す":status"を含めなければなりません。