1. ウェブブラウザとHTTPのバージョン
ウェブブラウザは HTTP というプロトコルを使ってウェブサーバーにリクエストを送信し、それに対するレスポンスを受け取って画面に表示します。
現在主流になっている HTTP のバージョンは、HTTP/1.1 と HTTP/2 の2つで、ウェブブラウザが https スキームでのHTTPリクエストを送信する際(つまり、https:// で始まるURLにアクセスする場合です)、このどちらかが利用されます。どちらが選ばれるのかは、ALPN という仕組みで決定しています。ALPN は TLS (Transport Layer Security) の拡張という形で実装されています。
※ メジャーなウェブブラウザ、メジャーなウェブサーバーでの話しです。
※ ALPN は TLS の拡張であり、TLS は httpsスキームでのみ利用されプロトコルであるため、http スキームでは ALPN が使えません。つまり、(今のところ)http スキームでは HTTP/2 が使えないということになります。
※ httpスキームでのリクエストや、ALPN に対応していないウェブサーバーに対してのリクエストでは、HTTP/1.1 が選ばれます。
ということなので、ALPN でどのようなやりとりが行われているのかを確認しようと思ったら TLS の通信内容を見る必要があります。これには、Wireshark などのパケットキャプチャツールを使います(TLS の暗号化通信を復号する設定が必要です)。※ ウェブブラウザの開発者ツールでは、HTTPのやり取りしか見れません。
2. ALPN でやっていること
TLSハンドシェイクプロトコル
ウェブブラウザがウェブサーバーと https スキームでの通信を行う際には、まず TLS での暗号化を開始する必要があります。その際の通信シーケンス(TLS ハンドシェイクプロトコル)は以下です。
この中の 「第一フェーズ」で、ALPN に関するデータがやり取りされます。
- 「Client Hello」メッセージ(の拡張部分)で、 ウェブブラウザがサポートしているバージョンを伝える。
- それを受け取った ウェブサーバーは、この後ウェブブラウザから受け取る HTTPリクエストに対してどのバージョンを使うのかを決定し、それを「Server Hello」メッセージ(の拡張部分)で伝える。
ウェブブラウザは、このやり取りによって、この後から使用されるHTTPのバージョンが分かるので、そのバージョンでHTTPリクエストを送ることができます。
Wireshark でやり取りを観察する
あるウェブサーバーに対してウェブブラウザでアクセスした際の通信を、Wireshark でキャプチャしたパケットが以下になります。
TLS のバージョン1.3 でやり取りされている「Client Hello」と「Server Hello」のパケットが見えると思いますが、それぞれをクリックして内容を見ていきます。
まず、ウェブブラウザが送信する「Client Hello」メッセージの拡張部分では、「h2」と「http/1.1」をサポートしていることを伝えています(h2 とは、HTTP/2 over TLS を意味しています)。
これに対して、ウェブサーバーが返送する「Server Hello」メッセージの拡張部分で、「h2」を利用することを伝えています。
ウェブブラウザはこのメッセージを受け取ることで、この後、HTTPリクエストを HTTP/2 を使って送信することになります。
3. その他
- メジャーなウェブサーバーの中には、h2 (HTTP/2 over TLS) だけでなく h2c (HTTP/2 over TCP) もサポートしているものもありますが、メジャーなウェブブラウザが h2 しかサポートしていないため、今後も http スキームでは HTTP/1.1 しか使えないようです。(参考:Implementations · http2/http2-spec Wiki)