HTTP 2.0の最新動向

SPDYからHTTP/2.0へ~HTTPbis WG Interim Meetingレポート

 2013年1月30日から3日間に渡り、東京六本木のGoogle Japanを会場として、HTTPbis WG Interim Meetingが開催された。そこでは、30名弱の参加者によってHTTP/2.0の仕様についての技術的な議論が行われ、策定に向けてまた一歩踏み出されたように思われる。

 まず、Interim Meetingが行われる1週間ほど前に、HTTP/2.0のドラフト 第01版が公開された。このドラフトはまだ実装できるようなステータスではなく、実装作業に入るべきではないとされているものの、ほぼSPDYのコピーであった第00版に対して、主に以下のような変更が加えられている。

  • 名称の変更(SPDYからHTTP/2.0へ)
  • HTTP/2.0通信の開始方法(アップグレードメカニズム、バージョン識別方法等)を記述する章の追加
    - 策定完了より前の段階における試験実装が用いるべきHTTPバージョン識別子の定義
    - Upgradeヘッダーを用いたアップグレード方法の追加
  • フロー制御について記述する節の追加
    - HTTP 2.0 Principles for Flow Controlの取り込み

 今回のInterim Meetingにおいては、SPDY由来であったフレーム構造等の大幅な変更をはじめ、優先度やフローコントロールの制御に対するより詳細な指針等についても議論が行われた。その結果をもとに、メーリングリストにおいて議論を行い、ドラフトの改定と試験用の実装作成をワーキンググループ内で行うとしている。

 Interim Meetingでは主に以下のような点について議論が行われた。

  • アップグレード
  • ヘッダー圧縮
  • フレーム構造
  • フロー制御
  • 優先制御
  • サーバープッシュ

 今回は、これらの議論から一部を抜粋し、紹介することとする。

アップグレード

 まず初めに議論されたのは、ちょうど前回の記事でテーマとしても取り上げた、アップグレードメカニズムについてだ。

 内容はTLS NPN拡張の現状やHTTPバージョンの識別方法、Alternate-Protocol HeaderやDNSを用いたアップグレード方法について等多岐にわたる。全体として、アップグレードメカニズムは1つにまで削減するほどではないが、できる限り少ないほうがよく、アップグレードメカニズムによって通信方法の選択肢が制限されるのは好ましくないといったコンセンサスが得られているようだ。現状、HTTPS通信時にはNPN拡張を、HTTP通信時にはUpgradeヘッダーフィールドをそれぞれ使用した方法が、とりあえずの前提となっている。

 HTTPのバージョンを識別する方法として、ネゴシエーションに使う文字列はHTTP/1.1を踏襲する形で「HTTP/2.0」を用いることになるだろう。NPN拡張などでは文字列として意味を持たない数バイトの識別子を使用すると考えられる。加えて、策定完了より前の段階での実装においては、「HTTP-draft-03/2.0」のような形の文字列を識別子として用いることを必須とし、試験段階での相互接続性の確保と実運用時のトラブルを減らそうとしている。

 関連事項として、フレーム内のバージョン情報フィールドの削除や、アップグレードの際に用いる識別子の取り扱い、設定パラメータのネゴシエーション等について大まかに決められた。また、HTTP/1.1しかサポートしないサーバーに接続した際に、高速かつ確実にフォールバックを行うための方法について、既存の実装に対するテストと議論を行うこととなった。

 HTTPS通信時におけるアップグレード手段としてほぼ前提とされているTLS NPN拡張だが、議論が行われた時点ではTLSワーキンググループから返答がないステータスが続いていたものの、ひとまずHTTP/2.0のドラフトにおいては使用できる前提で一旦作業を進めることとなった。

 その数日後、TLSワーキンググループの議長であるEric Rescorla氏がMLに対して、次回オーランドで開催されるIETF86のセッションにおいて、NPN等についての議論を行おうと考えている旨の投稿を行った。現時点において、議論を行いたいという声や、現在提案されているドラフトについてのコメント等が多数見受けられることから、おそらく次回には議論が進むことになると思われる。

 TLSワーキンググループにおいては、NPN拡張のほかALPN(Application Layer Protocol Negotiation)という方式も提案されており、これら二つの提案についてひとまず議論されると思われるが、今後新たな方式が提案される可能性もあり得るだろう。

 SPDY2に存在したAlternate-Protocolヘッダを用いたアップグレード方法はあまり前向きに議論はされていなったものの、現時点で既に実装があることもあり、代替手段の一つ程度の位置づけとしてではあるが、継続的に議論の対象にはなりそうだ。

 DNSを用いるアップグレード方法については、新たにインスタンス識別子とトランスポートプロトコル、ポート番号、プロトコルバージョンの情報を持つSVCINFOリソースタイプレコードを定義し、接続先がサポートするバージョンと、対応するトランスポートプロトコルやポート番号の組み合わせを解決する提案が紹介された。

 この提案方式では、URIに含まれるホスト名とHTTPのポート番号の組から、同じコンテンツを提供する上位バージョンのプロトコルが利用するポート番号を解決することができるため、DNSレコード解決後、直ちにHTTP/2.0通信を開始することができる。提案者は既にBINDに対して試験的に実装を行っており、その実装作業は比較的容易なものであったという。

 しかし、DNSを用いることについてはやはり賛否両論がある。たとえば、ゾーンカットされているためにリクエストが複数のネームサーバーにまたがる場合におけるレイテンシの問題を始め、安価なルータなどでTTLをきちんと実装できていないキャッシュサーバーが多々あることなどが問題点として挙げられたほか、新しいレコードタイプを追加し運用するために必要なコストの高さも懸念の1つとなっている。

 新しいレコードタイプを追加するのではなく、TXTレコード内に構造を持たせることによって同等の機能を実現できるのではないかという案も出たものの、TXTレコードを使用するのは様々な理由により好ましくないため、現状は新たなレコードタイプを追加する方向で検討が進められている。

ヘッダー圧縮

 ヘッダー圧縮の議論における前提として、2012年9月頃に発表された、TLSへのCRIME攻撃と呼ばれるような攻撃手法に対する耐性が必須だろうとされている。

 CRIME攻撃は、本来であれば内容を知ることができないTLSで暗号化されたデータの一部を、ある特定の条件下で推測できるというもので、実際にTLSで暗号化されたSPDY通信を対象として、Cookieを盗み出すことに成功していた。

 CRIME攻撃の出現により、SPDY3ではセキュリティ対策として圧縮効率を落とさざるを得なかったことは記憶に新しい。その点を反省材料として、理論的にもCRIME攻撃のような攻撃手法に対して安全で、かつ通信およびリソース利用の効率に優れた圧縮方式が求められている。

 また、将来にわたってアルゴリズム改善や脆弱性への対応などを考慮する必要があるため、使用するアルゴリズムを選択し、場合によっては無効にするための方法を準備することになるだろう。

 HTTPbisワーキンググループのGithubリポジトリに公開されている圧縮ベンチマークツールの使い方の説明の後、2組(3方式)の手法について紹介がされた。1つはBOHE(Binary Optimized Header Encoding)とDelta Encodingと呼ばれる方式をそれぞれを組み合わせたもの、もう1つはHeaderDiffと呼ばれるものだ。

 3つの方式のうちの1つであるBOHEは、HTTPヘッダを可逆な形でバイナリエンコードすることにより、通信量を削減する方法だ。単純なバイナリ化だけでなく、よく使われるヘッダ(たとえば、「Connection: Keep-Alive」など)についての辞書を規定することによる削減効果も大きい。HTTPサーバーあるいはProxyがBOHEを解釈可能であれば、ブラウザーで送受信するヘッダーについてはそれなりに圧縮の効果が期待でき、かつステートレスであるため、Proxyなど中間ノードによるヘッダの追加等も容易である。

 3つの方式のうち残り2つの方式、Delta EncodingとHeaderDiffは、リクエストごとに共通なヘッダーの送信を削減するために、セッションごとにテーブルを用意して、前のリクエストとの差分に相当するデータを送受信するものだ。差分しか送信しないことから、CRIME攻撃のような攻撃手法に対しては、耐性があると考えられる上に、効率もかなり上がるようだ。

 Delta EncodingとHeaderDiffの方式では、中間ノードがヘッダの内容を理解する必要がほとんどない場合においては、単純にパススルーするのみでよいと考えられる。しかし、中間ノードによってヘッダを解釈・追加したいケース等においては、中間ノードもサーバーと同等のテーブルを保持する必要があり、実際のユースケースにおいては、中間ノードに対する影響が大きいといえる。また、テーブルを保持する性質から、DDoSなどの攻撃に弱いといった側面もあり、まだまだ考えるべきポイントは少なくない。

 HeaderDiffについては未だ明確な仕様が提出されていなかったこともあり、ひとまずBOHEとDelta Encodingを組み合わせたものをベースに今後議論が行われる予定だが、今後もさらに新たな方式が提案されることが望まれている。

フレームサイズ

 続いて、フレームサイズについての議論に移った。具体的に議論されたのは、主にフレーム当たりのデータ長についてだ。

 HTTP/2.0はSPDYをスタートポイントとしてドラフトが作成しているため、フレーム等の構造もSPDYの物がまずたたき台になっている。SPDYにおいては、符号なし24ビット整数の領域が各フレーム内にデータ長を示すフィールドとして用意されており、1フレーム当たり最大約16MBのデータが格納可能となっているが、フレーム当たり16MBは多いのではないかという意見が多数あり、データ長フィールドの長さを変更することとなった。

 フレーム長がパフォーマンスに及ぼす影響は大きく、フレームが長ければ長いほどフレーム内のデータ転送効率は良くなるものの、送信が終わるまで他のフレームの送信をブロックすることになる。一方、フレームが短いと多くのフレームを利用する必要があるため、フレームのヘッダを都度送ることになる。帯域幅やレイテンシ、パケットロス率等による効率の変化も大きいだろう。そのため、4KB位でもよいのではという意見から、サーバーがコントロールすればよいことだから大きければ大きいほど良いという意見もあったが、最終的には1フレーム当たり16ビット、データのサイズでいうと約64KBのデータを格納可能にすることとなった。

 なお、64KBを超えるデータを同じコンテキストで送信したい場合、継続を示すフラグをONにすることで、続けてデータを送信する。

フロー制御・優先制御

 フレームサイズにも関連する話題であるが、フロー制御及び優先制御についても、議論が行われた。少なくともフロー制御が必要だという認識は全員が持っており、ドラフト第1版の時点で追加されたフロー制御に関するプリンシプルを前提として議論が行われた。

 具体的な制御方法としては、通信先に対してウィンドウサイズを広告し、一度に送信するデータの量をホップバイホップにコントロールするといった、ごく一般的なソフトウェアフロー制御方式が考えられている。もちろん、ウィンドウサイズは通信の途中で動的に変更できるようになるだろう。

 ほとんどの場合においてはウィンドウサイズを制限しないことが推奨されるものの、メモリー等の資源を削減するためにフロー制御を使用することができるとしている。初期パラメータやコントロール方法を議論するためには様々な環境によるテスト結果が必要となるため、まずは、試験実装とデータ収集から取り組むことになりそうだ。

 優先制御では、どうすればブラウザーという環境において最良のユーザビリティを提供できるかに焦点が移った。ブラウザーがファイルタイプ等で優先制御設定を行うモデルもある程度はうまく動くものの、サイトによっては適切でないケースも少なくない。そのほか、表示されているタブとそうでないタブ、別のウィンドウで表示されているページなどが同時に読み込まれるケースなど、実装者の視点からも議論が交わされており、収束までにはかなり時間がかかりそうだと言える。

 ひとまずの方針として、優先度フィールドを32bitまで拡大してきめ細やかな制御が行えるようにし、また優先度の依存関係設定や付け直しを可能にする方向で、引き続き議論が行われるだろう。

サーバープッシュ

 サーバープッシュに関する議論では、ユースケースが本当に存在するかという根本的な点から議論が始まり、若干先行き怪しく感じたものの、ユースケースを持っているという人も多く、HTTP/2.0からオミットする流れとまではならなかった。

 しかし、実装の難しさ等の問題があるうえ、SPDYでも実際に使われているケースはほとんどないため、まずはユースケースの明確化と試験実装・効果測定が、一旦のスタートポイントとなる。

 今までの記事でサーバープッシュについて具体的に記述したことが無いため簡単に紹介しておくと、サーバープッシュとは、コンテンツをサーバーから事前にプッシュし、クライアントのキャッシュに格納する機能である。たとえば、サーバーがHTMLを送信する際に、画像やCSS等をサーバープッシュによって同時に配信しておけば、クライアントはキャッシュから画像やCSSを取得することができ、サーバーへのリクエストが不要になることが期待される。

 考慮するべき点として、前述した実装の難しさやユースケースの他に、プライバシーやセキュリティについて十分な議論が必要だと考えられる。見えてはいけないコンテンツを誤ってプッシュ配信することによるプライバシー問題が考えられるほか、もしクロスドメインでのプッシュ配信が可能であれば、セキュリティ上の大きな問題になるだろう。もちろん、これらの問題も考慮して議論が行われてはいるものの、実装に依存した問題の発生等は危惧せざるを得ないだろう。

MLの議論も活況を呈し、着実に策定に向けて動く

 今回のInterim Meetingで議論された内容は多岐にわたるため、とても全て紹介することはできなかったが、なんとなく雰囲気程度は伝わっただろうか。これ以降、MLでは活発に議論が行われており、着実に策定に向けて動いていることは間違いない。

 そのほか、次回のInterim Meetingも計画されており、今のスピード感を保って策定を進めていきたいと皆が思っているようだ。

 スピード感を保つためにも、HTTPbis WGではドラフトの執筆作業にGithubを使用するとしており、既にGithubでリアルタイムにドラフトが更新され、誰でも閲覧可能な状態となっている。また、幅広い層からの議論への参加や意見の投稿を奨励している。少しでも興味がある方は、覗いてみて損はしないだろう。

清水一貴

株式会社レピダム(https://lepidum.co.jp/)所属。平成4年生まれの駆け出しSE(標準化エンジニア)。2011年頃から標準化活動に従事しており、IETF82以降継続的にIETFに参加している。