Web

ウェブブラウザが、HTTP/1.1 もしくは HTTP/2 のどちらを使うか判定する仕組み (httpsスキームのみ)

投稿日:2020年6月29日 更新日:

1. ウェブブラウザとHTTPのバージョン

ウェブブラウザは HTTP というプロトコルを使ってウェブサーバーにリクエストを送信し、それに対するレスポンスを受け取って画面に表示します。

現在主流になっている HTTP のバージョンは、HTTP/1.1HTTP/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 に関するデータがやり取りされます。

  1. Client Hello」メッセージ(の拡張部分)で、 ウェブブラウザがサポートしているバージョンを伝える。
  2. それを受け取った ウェブサーバーは、この後ウェブブラウザから受け取る HTTPリクエストに対してどのバージョンを使うのかを決定し、それを「Server Hello」メッセージ(の拡張部分)で伝える。

ウェブブラウザは、このやり取りによって、この後から使用されるHTTPのバージョンが分かるので、そのバージョンでHTTPリクエストを送ることができます。

Wireshark でやり取りを観察する

あるウェブサーバーに対してウェブブラウザでアクセスした際の通信を、Wireshark でキャプチャしたパケットが以下になります。

Wireshark でキャプチャしたパケット

TLS のバージョン1.3 でやり取りされている「Client Hello」と「Server Hello」のパケットが見えると思いますが、それぞれをクリックして内容を見ていきます。

まず、ウェブブラウザが送信する「Client Hello」メッセージの拡張部分では、「h2」と「http/1.1」をサポートしていることを伝えています(h2 とは、HTTP/2 over TLS を意味しています)。

Client Hello メッセージ内の ALPNデータ

これに対して、ウェブサーバーが返送する「Server Hello」メッセージの拡張部分で、「h2」を利用することを伝えています。

Server Hello メッセージ内の ALPNデータ

ウェブブラウザはこのメッセージを受け取ることで、この後、HTTPリクエストを HTTP/2 を使って送信することになります。

HTTP2 でリクエストが送信されています

3. その他

  • メジャーなウェブサーバーの中には、h2 (HTTP/2 over TLS) だけでなく h2c (HTTP/2 over TCP) もサポートしているものもありますが、メジャーなウェブブラウザが h2 しかサポートしていないため、今後も http スキームでは HTTP/1.1 しか使えないようです。(参考:Implementations · http2/http2-spec Wiki

参考

📂-Web

執筆者:labo


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

Web

シンタックス・ハイライト・ライブラリ「highlight.js」の使い方

シンタックス・ハイライト・ライブラリ「highlight.js」の使い方について説明します。

Web

ツールを公開するWebサイトを作っています

いろいろなツール(Webページ上で提供できるツールに限ります)を公開するサイトを作っています。 Tools on Web https://tools.laboradian.com/ 載せているツールは …

Web Vitals

ファーストビューに配置したLCP対象画像に loading=lazyはいらない?

ファーストビューに配置したLCP対象画像と loading属性について説明します。

Chrome

Chrome で拡張機能を使わずにスクリーンショットを撮る方法

Chrome で拡張機能を使わずにスクリーンショットを撮る方法について説明します。

HTML

HTMLの雛形 (CSS, JavaScriptも)

HTMLの雛形 (CSS, JavaScriptも) を載せています。コピーして使えます。