「Binary Structured HTTP Headers」について

Fastlyの「Binary Structured HTTP Headers」という提案仕様がでています。

目次

概要

HTTPヘッダはテキストで表現されます。特に値に関して数値、日付やブーリアン値もテキストで表現されます。また、Accept-Encodingのようにリスト構造を持つヘッダ値もあります。

本来バイナリで表現できるデータ形式や構造をテキストで表現するのは、データ量が増えるほかパースコストがかかります。

そこで、Structured Headersの定義に基づいて、HTTPヘッダ値を直接バイナリで表現できるようにするのが「Binary Structured HTTP Headers」です。この仕様では、バイナリのヘッダを送るBINHEADERSフレームと、HPACKに追加でBinary Literal Representationを定義します。

エンドポイントがこの仕様に対応していることを示すSETTINGS_BINARY_STRUCTURED_HEADERSパラメータも定義されます。

Structured Headersについては以前書いたとおり(少々内容は古くなっており、データ型の種類が異なっています)
asnokaze.hatenablog.com

BINHEADERSフレーム

BINHEADERSフレームは、次の一点を除きHEADERSフレームと同じフィールドを持ちます。HEADERSフレームとの違いは、ヘッダ圧縮(HPACK)でテキストを表現するのに使用されるString Literal Representationの代わりにBinary Literal Representationを使用することです。

ただし、Binary Literal Representationはヘッダ値でのみ使用されます。

Binary Literal Representation

Binary Literal Representationはデータ構造が示す部分と、値のデータ型を示す部分からなります。まずは、データ構造を示す部分から説明してきます。(ヘッダ構造を示すtypeと、データ型を示すtypeはそれぞれ別の種類であることに注意してください)

Binary Literal Representationは以下のフィールドを持ちます
f:id:ASnoKaze:20191102224210p:plain

ヘッダの構造を表す4つのTypeがあります

  • Lists (type=0x1)
  • Dictionaries (type=0x2)
  • Items (type=0x3)
  • String Literals (type=0x4)

(Inner Lists, Parametersは説明を省略)

Lists

Listsとは下記のような ’,’ で区切られているようなヘッダ値です。Binary Literal RepresentationではInner ListsやItemを複数書くことで表現されます。

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

Dictionariesとは下記のような、key=valueの構造を複数持つヘッダ値です。

   Example-DictHeader: en="Applepie", da=*w4ZibGV0w6ZydGU=*

Binary Literal Representationでは下記のように、Keyの長さ、Keyの文字列、値(Binary Structure Types)からなります。
f:id:ASnoKaze:20191102225721p:plain

Items

整数、実数、base64値、ブーリアンなどを示す単体の値です。それぞれごとにdata typeを持つので、それを見ることでどのデータ型なのか識別できます。

f:id:ASnoKaze:20191102230315p:plain

String Literals

これはバイナリではなく、単純な文字列表現です。バイナリ表現が使用できない場合に使用されます。HPACKで定義されるString Literal Representationsと同じものです。

Item Payload Types

具体的なItemのバイナリ表現方法です。

Itemには下記の種類があります。それぞれごとにバイナリフォーマットが定義されています。

  • Integers (type=0x3)
  • Floats (type=0x4)
  • Strings (type=0x5)
  • Tokens (type=0x6)
  • Byte Sequences (type=0x7)
  • Booleans (type=0x8)

(説明を省略したInner Lists, Parametersがそれぞれtype=1, 2です)

例えばInteger(整数)は下記のバイナリフォーマとを持ちます。
Sは正負、Xはパディング、その後に長さと値が入ります。
f:id:ASnoKaze:20191102232742p:plain

Booleansであれば以下のように短く表現できます。
f:id:ASnoKaze:20191102231737p:plain

Aliased Fields

この仕様ではいくつかのヘッダにおいて、Binary Structured HTTP Headersを使えるようにエイリアスというものを定義しています。

Dataヘッダは以下のとおりです。そのままではBinary表現は使用できません

Date: Sun, 06 Nov 1994 08:49:37 GMT

DataヘッダのエイリアスであるSH-Dateでは、Unixタイムを使用して以下のようにIntegerのバイナリ表現を使用できます。

SH-Date: 784072177

どのようなエイリアスが定義されているかは仕様を御覧ください。