HTTP/2ではレスポンスが返ってくる前にリクエストを重ねて発行できるようにするため、どのレスポンスがどのリクエストと関連付けられているかを管理する仕組みが必要となる。

仮想パイプ「ストリーム」

 そのためにHTTP/2では、「ストリーム」と呼ぶ仮想的なパイプを用意する。これがHTTP/1.1におけるコネクションに相当する(図6)。具体的には「ストリームID」という識別子が使われる。同一のストリームIDであれば、関連する一連のやり取りとして識別できるというわけだ。

図6●ストリームとフレーム
図6●ストリームとフレーム
HTTP/2では順不同でリクエスト-レスポンスが流れる。このため、リクエストとレスポンスを関連付ける仕組みが必要だ。そのために「ストリーム」という考え方が導入された。1対のリクエスト-レスポンスを表現する仮想的な通信経路が「ストリーム」である。ストリームの間を、複数種類のフレームがやり取りされる。
[画像のクリックで拡大表示]

 このストリームの上を複数の「フレーム」がやり取りされる。フレームがHTTP/2におけるやり取りの実体であり、フレームには先ほどのストリームIDが埋め込まれている。HTTP/2におけるリクエストやレスポンス、あるいはヘッダー情報などは、すべてフレームとして送受信される。

 逆に言えば、フレームがHTTP/2におけるやり取りの主体だ。フレームはバイナリー形式で、構造が定められている(図7(a))。こうしたバイナリー構造のデータ形式は柔軟性に欠ける面はあるものの、データを解釈する際に余計な手間がかからない。本来WebブラウザーとWebサーバーという機器同士のやり取りに、従来のHTTP/1.1までのようなテキスト形式を使う必要はない。

 テキスト形式のデータ構造は柔軟性と拡張性、さらに人間が読めてデバッグが容易というメリットはある。しかしHTTPが生まれた直後ならともかく、プロトコルに求められる役割が確定した現在となっては、手間がかかる方法だ。効率性を重視してバイナリー形式を採用するのは妥当だろう。

バイナリ形式のフレームは10種類

 フレームのタイプは10種類定義されている(同(b))。リクエストやレスポンスの本体は「DATA」であり、リクエストヘッダーやレスポンスヘッダーは「HEADERS」フレームに入れてやり取りする。

 こうしたタイプごとにもバイナリーのフォーマットが決まっている。つまり図7(a)のペイロードに記述する形式が定められている。

図7●バイナリー形式の「フレーム」
図7●バイナリー形式の「フレーム」
HTTP/2ではクライアントとサーバーの間で、「フレーム」を送り合う。バイナリー形式で構造が決められた9バイトのヘッダーと、ペイロード部分から成る(a)。フレームは10種類定義されていて、それぞれペイロードのフォーマットも定義されている。
[画像のクリックで拡大表示]

 細かくタイプを決めているのは、HTTP/2を特徴付ける様々な機能を実現するためだ。例えば「PRIORITY」。これはデータを受け取る優先順位を、クライアントからサーバーに通知するために使う。画面上部にある画像を早めに受け取るといった場合などに使う。またHTTP/2ではアプリケーションプロトコルでフロー制御を実施する。つまり受け取り側が指定したウインドウサイズより大きなブロックのデータを送らないようになっている。このウインドウサイズを更新する際にWINDOW_UPDATEフレームを使う。このほか後述するサーバープッシュに使う「PUSH_PROMISE」や、ストリームのコネクション制御に使う「RST_STREAM」「GOAWAY」などが用意されている。

▼フレーム
HTTP/2においてデータやヘッダーなどをやり取りする単位。
▼フロー制御
受信側がデータを取りこぼさないようにデータの流量を制御すること。
▼ウインドウサイズ
一度の通信で受け取れるデータの量。