HTTP/2の正体を探るため、実際にどのようなやり取りをしているのかを確認しながら、その特徴を解説していこう。具体的には図3のようなテスト環境を用意し、Wiresharkを使ってパケットをキャプチャーした。

図3●テスト環境
図3●テスト環境
2台のノートパソコンを用意し、1台にHTTP/2対応のWebサーバーとして「Apache HTTP Server 2.4.20」をインストール。もう1台でWebブラウザー「Firefox」や平文を用いてHTTP/2でアクセスするためのソフト「nghttp」を動かし、「Wireshark」でパケットをキャプチャーした(a)。Webサーバーには画像6個を貼り付けた単純なWebページを置いた(b)。

複数の接続が独立して動作

 実際にパケットをキャプチャーした結果を見ると、一見HTTP/1.1のほうが明らかに冒頭にリクエストが集中し、レスポンスがその後に立て続けに発生しているように見える(図4(a))。実はHTTP/1.1では、それぞれのリクエスト-レスポンスの独立性が高いため、複数ポートを使って並行してリクエストを発行できる。このため、今回用意したような小さなサイトでは、リクエストが最初に一気に送られてしまうのだ。

図4●HTTP/1.1におけるデータのやり取りの流れ
図4●HTTP/1.1におけるデータのやり取りの流れ
HTTP/1.1は非常にシンプルに「GET」とそれに対する応答で成り立っている(a)。リクエスト-レスポンスが並行して実行されているが、これは別のポート番号を使って別のTCPコネクションを使っている。実際、SYNフラグで絞り込むと、6回のハンドシェークが実行されているとわかる(b)。
[画像のクリックで拡大表示]

 これを確認するため、TCPのセッションを遡って、3ウエイハンドシェークのやり取りをチェックした(同(b))。SYNフラグが有効なパケットは、都合12個ある。6個のファイルに対してそれぞれTCPのコネクションを張って、独立してリクエストしているとわかる。Webサイトを構成するコンテンツの各要素の間に依存性があまりないことから、こうした転送が可能になっている。

 逆にHTTP/2の場合を見ると、複雑な処理をいろいろしている(図5(a))。ただよく見ると、いかにもリクエストの情報が入っていそうな「HEADERS」という情報が付与されたパケットが最初の方に集中して、いかにもデータを送っていそうな「DATA」という属性のパケットが後半に集中している。

図5●HTTP/2におけるデータのやり取りの流れ
図5●HTTP/2におけるデータのやり取りの流れ
HTTP/2は非常に複雑だ。序盤のやり取りで「HEADERS」が集中し、中盤以降は「DATA」が集中している(a)。平文でやり取りしている状態でSYNフラグで絞り込んでも、1回のやり取りしかなく、TCPコネクションは1本しか使っていないとわかる(b)。
[画像のクリックで拡大表示]

 一般にHTTP/2はTLS/SSLを使ってコネクションを形成する。これをHTTP/2のRFCでは「h2」と呼ぶ。しかし規格上は平文でのアクセスも認めていて、「h2c」という名称が与えられている。

 TLS/SSLを使う場合は、その経路を利用して通信するので、TCPのコネクションが一つになるのは想像しやすい。そこでここでは、平文でアクセスした際もTCPのコネクションを一つしか使っていないことを確認した(同(b))。3ウエイハンドシェークの最初の二つのやり取りだけがパケットとしては絞り込まれており、コネクションは1本しかないことがわかる。

▼Wireshark
パソコンやMacなどで動作するフリーのパケットキャプチャーソフト。入手先はhttps://www.wireshark.org/。
▼3ウエイハンドシェーク
TCPでコネクションを確立するときの処理。最初にコネクション開始を要求する側が「SYN」パケットを送信。要求を受ける側が了解する場合は「SYN+ACK」を返信する。これに要求する側が「ACK」を返すと、コネクションが確立される。
▼TLS/SSL
Transport Layer Security/Secure Sockets Layerの略。
▼RFC
Request For Commentsの略。IETFが発行する文書はすべてRFCと呼ばれ、番号で管理されている。
▼規格上は
FirefoxやChromeなど一般的に使うWebブラウザーは、TLS/SSLを利用したアクセス方法しか用意していない。今回はHTTP/2を実装したサーバー「nghttp2」に付属するユーティリティである「nghttp」を使ってアクセスした。