HTTP/2ではレスポンスが返ってくる前にリクエストを重ねて発行できるようにするため、どのレスポンスがどのリクエストと関連付けられているかを管理する仕組みが必要となる。
仮想パイプ「ストリーム」
そのためにHTTP/2では、「ストリーム」と呼ぶ仮想的なパイプを用意する。これがHTTP/1.1におけるコネクションに相当する(図6)。具体的には「ストリームID」という識別子が使われる。同一のストリームIDであれば、関連する一連のやり取りとして識別できるというわけだ。
このストリームの上を複数の「フレーム▼」がやり取りされる。フレームがHTTP/2におけるやり取りの実体であり、フレームには先ほどのストリームIDが埋め込まれている。HTTP/2におけるリクエストやレスポンス、あるいはヘッダー情報などは、すべてフレームとして送受信される。
逆に言えば、フレームがHTTP/2におけるやり取りの主体だ。フレームはバイナリー形式で、構造が定められている(図7(a))。こうしたバイナリー構造のデータ形式は柔軟性に欠ける面はあるものの、データを解釈する際に余計な手間がかからない。本来WebブラウザーとWebサーバーという機器同士のやり取りに、従来のHTTP/1.1までのようなテキスト形式を使う必要はない。
テキスト形式のデータ構造は柔軟性と拡張性、さらに人間が読めてデバッグが容易というメリットはある。しかしHTTPが生まれた直後ならともかく、プロトコルに求められる役割が確定した現在となっては、手間がかかる方法だ。効率性を重視してバイナリー形式を採用するのは妥当だろう。
バイナリ形式のフレームは10種類
フレームのタイプは10種類定義されている(同(b))。リクエストやレスポンスの本体は「DATA」であり、リクエストヘッダーやレスポンスヘッダーは「HEADERS」フレームに入れてやり取りする。
こうしたタイプごとにもバイナリーのフォーマットが決まっている。つまり図7(a)のペイロードに記述する形式が定められている。
細かくタイプを決めているのは、HTTP/2を特徴付ける様々な機能を実現するためだ。例えば「PRIORITY」。これはデータを受け取る優先順位を、クライアントからサーバーに通知するために使う。画面上部にある画像を早めに受け取るといった場合などに使う。またHTTP/2ではアプリケーションプロトコルでフロー制御▼を実施する。つまり受け取り側が指定したウインドウサイズ▼より大きなブロックのデータを送らないようになっている。このウインドウサイズを更新する際にWINDOW_UPDATEフレームを使う。このほか後述するサーバープッシュに使う「PUSH_PROMISE」や、ストリームのコネクション制御に使う「RST_STREAM」「GOAWAY」などが用意されている。
HTTP/2においてデータやヘッダーなどをやり取りする単位。
受信側がデータを取りこぼさないようにデータの流量を制御すること。
一度の通信で受け取れるデータの量。