筆致についてはタイトル毎に統一されていません。あらかじめご了承ください。
「重要なのは、変わらないことだ。ウェブは、人々がすでに使っているものを壊すことなく進化できなければならない。」
("What’s important is the thing that doesn’t change.The Web must be able to evolve without breaking what people already use. ")
— Tim Berners-Lee
ITの世界ではどんどんと新しい技術が生まれていく。
最近では生成AIがアツい。
ただ、技術の進歩というのは必ずしも目につくものとは限らない。
Webの技術では特に進歩が目まぐるしいが、今回は、HTTP/1.1 から HTTP/2 へ移行する過程で気付いた “ある疑問” と “確認結果” を共有したい。
目次
ある疑問
HTTP のプロトコルバージョンを気にしている人は多くないと思う。
まず、ひと昔前の主流は HTTP/1.1 だった。
HTTP/1.1 での変更点は多いが、代表例として Host ヘッダの必須化と持続接続(Keep-Alive)の標準化 がある。
Host ヘッダにより “name-based virtual host” が実現した。Host ヘッダにはアクセス先の FQDN が含まれ、クライアントが望むホストを識別できる。
この仕組みにより、1 つの IP アドレスに複数の公開 FQDN を紐づけられ、インフラ規模を縮小できる。
※ 近年は常時 HTTPS が当たり前となり、TLS の SNI (Server Name Indication) も関与する。
HTTP/2 ではさらに大きな変化があった。
Web が主要プロトコルとなり、やり取りするデータ量が増加したことで、プロトコル自体がボトルネックとなる場面があった。より効率的な データ転送を実現するためにHTTP/2 が策定された。
かつては「Web 通信の半分が HTTP/2 へ移行しつつある」と言われていたが、2025 年現在、サイトベースの採用率は約 33 %。ただし大規模サイトに限れば過半数が HTTP/2 を利用している。主要 CDN(Cloudflare など)もサポートしており、実際のトラフィック比率はサイト数より高いと見込まれる。
(実際には HTTP/3 を Google や YouTube が積極的に使っており、動画トラフィックを加味すると HTTP/3 の方がバイト数で上回る可能性もある。詳細な統計は公開情報が限られるため推測に留まる。)
HTTP/2 は HTTP/1.1 のようなテキスト形式ではなく、バイナリ形式 に変更された。
他にも多くの仕様追加があるが、ここではこの点に着目する。
バイナリ化に伴い、HTTP のリクエスト/レスポンスの情報は “疑似ヘッダ” と呼ばれる形式で表現される。
# HTTP/1.1
GET /index.html HTTP/1.1
Host: example.com
# HTTP/2
:method: GET
:scheme: https
:authority: example.com
:path: /index.html
ここで注目したいのは、HTTP/1.1 では Host ヘッダ、HTTP/2 では :authority 疑似ヘッダがホスト名を示す点だ。
「HTTP/1.1 時代のリバースプロキシや Web サーバは Host ヘッダを基に制御していたが、HTTP/2 では :authority を基に制御を切り替える必要があるのだろうか?」という疑問が湧いた──これが今回のテーマである。
検証
BIG-IPを使った検証を行う
BIG-IP v17.1を利用する。
※BIG-IPとServer間はHTTP/1.1です。
LTMポリシーにて、上記の記述を行い、HTTPホストヘッダがexample.comだったらリクエストヘッダに特別なヘッダを挿入する。
利用するサーバでは、送信されたリクエスト内容をレスポンス本文で表示するプログラムが動いている。
HTTP/1.1
想定通り、hitruleヘッダが追加されている。
www.secuavail.comをHostヘッダにもつリクエストには、hitruleヘッダが追加されていない。
HTTP/2
想定通り、hitruleヘッダが追加されている。
※BIG-IPによってHTTP/1.1に切替えられるため、疑似ヘッダを確認することはできない。
その他、別の指定方法を行ったとしても、同じ挙動であり、HTTP/2においてもHostヘッダでの制御が有効だった。authorityヘッダを指定した制御設定を入れてみたが、動作はしなかった。authorityヘッダでの制御は考えないほうがよさそう。
結果
HTTP/2において、Host名に関する制御を行うにあたって、authorityヘッダが利用されることを認知しておく必要がないことがわかった。
いくつかドキュメントを探したところ、RFC 7040の以下の記述により、BIG-IPがHTTP/1.1の適切なフォーマットに変換しているものと思われる。
An intermediary that converts an HTTP/2 request to HTTP/1.1 MUST create a Host header field if one is not present in a request by copying the value of the ":authority" pseudo-header field.
(HTTP / 2リクエストをHTTP / 1.1に変換する仲介者は、 ":authority"疑似ヘッダーフィールドの値をコピーすることにより、リクエストにホストヘッダーフィールドがない場合は作成する必要があります。)
(https://tex2e.github.io/rfc-translater/html/rfc7540.htmlより)
そのため、基本的にはHostヘッダでの制御という動作は保障されている。
※一部例外的なものとしては、EnvoyではHostヘッダを使わずにむしろauthorityヘッダのみを使うらしい。
authorityヘッダの値とHostヘッダは同じ値にならないといけないというのもMust Notとして定義されているので、Hostヘッダとauthorityヘッダの値の不一致をユーザ側が気にする必要なさそう。(ミドルウェアの実装の不備とかはあるかもしれないが)
Clients that generate HTTP/2 requests directly MUST use the ":authority" pseudo-header field to convey authority information, unless there is no authority information to convey (in which case it MUST NOT generate ":authority").
Clients MUST NOT generate a request with a Host header field that differs from the ":authority" pseudo-header field.
(HTTP/2 リクエストを直接生成するクライアントは、伝えるべき権限情報がない場合 (その場合は 「:authority」 を生成してはなりません (MUST NOT))を除き、権限情報を伝えるために 「:authority」 擬似ヘッダーフィールドを使用しなければなりません (MUST)。
クライアントは、「:authority」 擬似ヘッダーフィールドと異なる Host ヘッダーフィールドを持つリクエストを生成してはなりません (MUST NOT)。)
(https://tex2e.github.io/rfc-translater/html/rfc9113.htmlより)
感想
HTTP/2とHTTP/1.1の互換性を取るためのルールがRFCに明示的に定められていました。
Hostヘッダの動作とauthorityヘッダを別々のものとして扱う場合、HTTP/2を有効化したら急にリクエストが受け取れなくなる可能性もありました。それが起きていないのは、後方互換性を大事に、Webのルールを策定されているためだと感じました。
記載されている会社名、システム名、製品名は一般に各社の登録商標または商標です。
当社製品以外のサードパーティ製品の設定内容につきましては、弊社サポート対象外となります。