【入門編】HTTP/2のヘッダー圧縮(HPACK)における静的テーブル – HTTPプロトコル・通信規格実践ガイド

こんにちは!インフラ・ネットワークの世界へようこそ。
Webブラウザでホームページを開くとき、裏側では数え切れないほどの「データ(リクエストとレスポンス)」がインターネットの海を行き来していますよね。

さて、私たちが普段なにげなく使っているWebですが、その通信のルールである「HTTP」は、長年の歴史の中で進化を続けてきました。特に「HTTP/2」という規格になってから、Webの表示速度は劇的に速くなりました。その立役者の一つが、今回スポットを当てる「HPACK(エイチパック)」によるヘッダー圧縮です。

「ヘッダー圧縮? なんか難しそう……」と思ったそこのあなた、安心してください!
今回は、パケットの細かいビットの計算なんていったん忘れて、身近な「郵便配達」の仕組みに例えながら、一緒に楽しく紐解いていきましょう。一歩ずつ理解していけば、決して怖くありませんよ!

—

1. Webの「荷札」には、いつも同じことが書かれている?

まず、HTTP通信が普段どんなやり取りをしているのかをイメージしてみましょう。
あなたがブラウザで画像やテキストを見るたびに、パソコン(クライアント)からサーバーへ「これちょうだい!」というリクエストが送られます。このとき、データ本体だけでなく、「荷札(HTTPヘッダー)」が必ず一緒にくっついています。

この荷札には、例えばこんなことが書かれています。

  • 「私はこんなブラウザを使っていますよ」 (`user-agent`)
  • 「こんな言葉(言語)が読めますよ」 (`accept-language`)
  • 「このサイトを見に来ましたよ」 (`authority` または `host`)

ここで、ちょっと考えてみてください。
あなたが同じWebサイトの中で、ページAからページBへ移動したとします。このとき、ブラウザから送られる荷札の内容は、先ほどとほとんど同じですよね? ブラウザの種類も、読める言語も、見に来ているサイトのURLも変わりません。

つまり、「毎回、ほぼ同じような決まり文句の長文を、律儀に何度も何度も繰り返し送っていた」のです。これって、ちょっともったいない(帯域の無駄遣い)だと思いませんか?

—

2. 実例で見る「ムダな繰り返し」

実際のHTTPリクエストのヘッダーを、少しだけ覗いてみましょう。

GET /index.html HTTP/2
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Accept-Language: ja,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

どうでしょう? `User-Agent` なんて、ものすごく長い文字列ですよね。これがページを移動するたびに、パケットのなかにポンと乗っかって流れていくわけです。小さなリクエストなら、ヘッダーの文字数の方がデータ本体より多い、なんてこともしばしばありました。

HTTP/1.1の時代は、このテキストのままの荷札を毎回せっせと送っていました。これではネットワークが渋滞してしまうのも無理はありません。

—

3. 救世主「静的テーブル」を郵便配達に例えてみよう!

そこでHTTP/2で登場したのが、HPACKというヘッダー専用の圧縮技術です。中でも今回フォーカスする「静的テーブル(Static Table)」は、いわば「あらかじめ用意された短縮コード表」のようなものです。

ここで、身近な例えをしてみましょう。
あなたが毎日、同じ宛先の会社へ手紙を送るとします。毎回「東京都〇〇区……株式会社〇〇 御中」と封筒に書くのは大変ですよね。

そこで、郵便局とあなたとの間で、こんな約束を交わしました。
> 「これからは、よく使う宛先やフレーズに番号を振っておきましょう。例えば、『1番』と言ったら『東京都〇〇区……株式会社〇〇 御中』のことね!」

これなら、封筒に長たらしい住所を書く代わりに、「1」とだけ書いた小さなハンコをポンと押すだけで、郵便局員さんは「ああ、あの会社ね」と一発で理解して配達してくれます。これが、HPACKの静的テーブルの考え方です。

—

4. 静的テーブルの仕組みとインデックス番号

HTTP/2の規格(RFC 7540 / RFC 7541)では、世界中のWebで「これ、絶対みんな毎回使うよね!」という定番のヘッダーフィールドの組み合わせを、あらかじめ61個リストアップして決め打ちしています。これが「静的テーブル」です。

具体的に、仕様書で定義されている静的テーブルの一部を覗いてみましょう。

| インデックス番号 | ヘッダーフィールド名 (`:name`) | よくある値 (`:value` ※空の場合もあり) |
| :— | :— | :— |
| 1 | `:authority` | (なし) |
| 2 | `:method` | `GET` |
| 3 | `:method` | `POST` |
| 4 | `:path` | `/` |
| 5 | `:path` | `/index.html` |
| 8 | `:status` | `200` |
| 32 | `accept-encoding` | `gzip, deflate, br` |
| 54 | `user-agent` | (なし) |

このように、1から61までの番号(インデックス)が世界共通の辞書として、ブラウザ(クライアント)とサーバーの両方に最初からインプットされています。

実際の通信はどう変わるの?

例えば、あなたがサーバーに対して「`GET`メソッドで `/` にアクセスしたい」と思ったとき、HTTP/2のパケットの中では文字をそのまま書きません。

  • メソッドが `GET` なら、辞書の 「2番」
  • パスが `/` なら、辞書の 「4番」

たったこれだけ!
文字の羅列を送る代わりに、「2」「4」といった小さな数字(インデックス番号)に置き換えて送信するのです。受信したサーバーは、自分の頭の中にある同じ辞書(静的テーブル)を開き、「なるほど、2番だから `GET` だな」「4番だから `/` だな」と瞬時に復元します。

文字データを送るのに比べて、データ量が圧倒的に小さくなるのがイメージできますよね。これが、ネットワークの帯域を節約し、Web表示を爆速にする秘密なのです。

—

5. まとめ:インフラの裏側で働く「お片付けの工夫」

今回は、HTTP/2のヘッダー圧縮(HPACK)における「静的テーブル」についてお話しました。

  • HTTP通信では、毎回似たような長い荷札(ヘッダー)を何度も送っていた。
  • HTTP/2のHPACKには、よく使う定番のヘッダーに番号を振った「静的テーブル」があらかじめ用意されている。
  • 長い文字列をそのまま送るのではなく、「番号(インデックス)」に置き換えてやり取りすることで、通信をスマートに高速化している。

ネットワークの世界を覗いてみると、こうした「いかにムダなデータを減らし、効率よく情報を伝えるか」という先人たちの知恵や工夫が、至るところに散りばめられています。

「難しそう」に見えた技術も、こうして身近な例えに置き換えてみると、なんだかグッと身近に感じられるのではないでしょうか?
それではまた、次回のテック解説でお会いしましょう! 一歩ずつ、楽しくネットワークをマスターしていきましょうね。

コメント

タイトルとURLをコピーしました