InfraLab

HTTP/2 仕様

38 / 38 items

InfraLab Reference Series

Category: HTTP/2

Updated: 2026-05-14

infralab.jp

http-2

38 items

HTTP/2 仕様

Abstract

HTTP/2 のフレーム、ストリーム状態、HPACK、SETTINGS、フロー制御、エラーコード、Server Push 非推奨化と運用確認を日本語で整理。

Table of Contents

  1. 1. 概要 (RFC 9113)3
  2. 2. フレーム11
  3. 3. ストリーム・優先度7
  4. 4. HPACK4
  5. 5. Settings7
  6. 6. エラー処理3
  7. 7. 運用3
  8. 8. References19

1. 概要 (RFC 9113)

1.1. HTTP/2 とは

HTTP セマンティクスを保ったまま、単一 TCP 接続上で多重化、ヘッダ圧縮、バイナリフレーミングを提供するプロトコル。

RFC 9113。RFC 7540 を置換。既定 ALPN token: h2

1.2. 主要 RFC

HTTP/2 本体は RFC 9113。HPACK は RFC 7541 として残り、優先度は RFC 9218 の Priority Header へ移行した。

RFC 9113 (HTTP/2), RFC 7541 (HPACK), RFC 9218 (HTTP Priority)。QPACK は RFC 9204 で HTTP/3 用

1.3. 接続確立

HTTPS では TLS ALPN で h2 を交渉する。平文 h2c は仕様上存在するが、インターネット運用では事実上ほぼ使われない。

TLS ALPN: h2。Connection Preface: PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n

2. フレーム

2.1. フレームヘッダ

すべての HTTP/2 フレームは 9B の共通ヘッダを持ち、ストリーム単位または接続全体に作用する。

Length 24bit / Type 8bit / Flags 8bit / R 1bit + Stream Identifier 31bit。Stream 0 は接続制御

RFC 9113 Frame Layout ASCII 図:

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                    Length                     |     Type      |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |     Flags     |R|              Stream Identifier              |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |   Stream ID   |                  Payload ...                  |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2.2. DATA

リクエストまたはレスポンス body を運ぶ。フロー制御の対象で、END_STREAM により片方向終了を示せる。

Type=0x0。Flags: END_STREAM(0x1), PADDED(0x8)。Stream ID は 0 不可

RFC 9113 DATA frame payload ASCII 図:

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  Pad Length   |                   Data ...                    |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                      Data / Padding ...                       |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2.3. HEADERS

HPACK で圧縮したヘッダブロックを送る。リクエスト開始、レスポンス開始、trailers に使われる。

Type=0x1。Flags: END_STREAM, END_HEADERS, PADDED, PRIORITY。CONTINUATION と連続可能

RFC 9113 HEADERS frame payload ASCII 図:

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  Pad Length   |E|              Stream Dependency              |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  Stream Dep   |    Weight     |        Field Block ...        |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                   Field Block Fragment ...                    |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2.4. PRIORITY

旧 HTTP/2 優先度ツリーを変更するフレーム。RFC 9113 では deprecated 扱いで、新規設計では RFC 9218 を使う。

Type=0x2。Stream Dependency 31bit + Weight 1-256。Deprecated in RFC 9113

2.5. RST_STREAM

個別ストリームを即時終了する。キャンセル、プロトコルエラー、不要になったリクエストで使う。

Type=0x3。Payload: Error Code 32bit。Stream ID 0 不可

2.6. SETTINGS

接続単位の設定を交換する。受信側は適用後に ACK を返す。

Type=0x4。Stream ID=0。Parameter: Identifier 16bit + Value 32bit。ACK flag=0x1

RFC 9113 SETTINGS frame payload ASCII 図:

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |          Identifier           |             Value             |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |             Value             |      Next Identifier ...      |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2.7. PUSH_PROMISE

サーバプッシュ予約に使うフレーム。ブラウザ運用で問題が多く、RFC 9113 で deprecated になった。

Type=0x5。Promised Stream ID 31bit。Deprecated in RFC 9113

2.8. PING

接続到達性と RTT を確認する。必ず 8B opaque data を持ち、ACK で同じ値を返す。

Type=0x6。Stream ID=0。Payload 8B。ACK flag=0x1

RFC 9113 PING frame payload ASCII 図:

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                          Opaque Data                          |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                          Opaque Data                          |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2.9. GOAWAY

接続の正常終了または接続単位エラーを通知する。Last Stream ID で処理済み範囲を示す。

Type=0x7。Stream ID=0。Last-Stream-ID 31bit + Error Code 32bit + debug data

RFC 9113 GOAWAY frame payload ASCII 図:

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |R|                       Last-Stream-ID                        |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                          Error Code                           |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                   Additional Debug Data ...                   |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2.10. WINDOW_UPDATE

フロー制御ウィンドウを増やす。接続レベルとストリームレベルの両方に存在する。

Type=0x8。Window Size Increment 31bit。0 は PROTOCOL_ERROR

RFC 9113 WINDOW_UPDATE frame payload ASCII 図:

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |R|                    Window Size Increment                    |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2.11. CONTINUATION

HEADERS または PUSH_PROMISE のヘッダブロックを継続する。END_HEADERS まで他フレームを挟めない。

Type=0x9。Flags: END_HEADERS。直前のヘッダブロックと同じ Stream ID

3. ストリーム・優先度

3.1. ストリーム ID

クライアント起点ストリームは奇数、サーバ起点ストリームは偶数を使う。0 は接続制御用でリクエストには使わない。

31bit。client initiated: 1,3,5... server initiated: 2,4,6... Stream 0 control

3.2. idle

ストリーム未使用状態。HEADERS 送信/受信で open、PUSH_PROMISE で reserved へ進む。

idle -> open / reserved(local|remote)

3.3. reserved

Server Push で予約された状態。PUSH_PROMISE deprecated に伴い、新規運用ではほぼ使わない。

reserved(local) / reserved(remote)。HEADERS により half-closed へ

3.4. open

双方向にフレームを送れる通常状態。END_STREAM で片方向終了し half-closed へ進む。

open -> half-closed(local|remote) -> closed

3.5. half-closed

片方向だけ終了した状態。もう片方向の END_STREAM または RST_STREAM で closed になる。

half-closed(local): 送信不可・受信可。half-closed(remote): 送信可・受信不可

3.6. closed

ストリーム終了状態。閉じたストリームへの不正フレームは STREAM_CLOSED などのエラーになる。

END_STREAM 双方完了、RST_STREAM、エラーで closed

3.7. 優先度の現状

HTTP/2 の依存ツリー優先度は実装差が大きく、RFC 9113 で PRIORITY/PUSH_PROMISE は deprecated になった。

RFC 9218: Priority response/request header (urgency, incremental) を推奨

4. HPACK

4.1. HPACK 概要

HTTP ヘッダを静的テーブル、動的テーブル、Huffman 符号化で圧縮する。HTTP/2 専用のヘッダ圧縮方式。

RFC 7541。Static Table 61 entries + Dynamic Table + Huffman coding

4.2. 静的テーブル

よく使う疑似ヘッダやヘッダ名・値を固定 index で持つ。:method GET や :status 200 などが含まれる。

HPACK Static Table index 1-61。例: :authority, :method GET/POST, :path /, :scheme https, :status 200

4.3. 動的テーブル

接続ごとに学習するヘッダテーブル。サイズを制限しないとメモリ消費や圧縮コンテキスト攻撃の面で危険。

SETTINGS_HEADER_TABLE_SIZE で上限通知。サイズ計算: name length + value length + 32

4.4. HPACK Bomb 対策

圧縮後は小さいが展開後に大きいヘッダでメモリや CPU を消費させる攻撃に注意する。

MAX_HEADER_LIST_SIZE、ヘッダ数/総サイズ制限、CONTINUATION 連続制限、タイムアウトを設定

5. Settings

5.1. SETTINGS_HEADER_TABLE_SIZE

HPACK 動的テーブルの最大サイズを通知する。小さくすると圧縮効率は落ちるがメモリを抑えられる。

Identifier=0x1。初期値 4096 octets

5.2. SETTINGS_ENABLE_PUSH

サーバプッシュを許可するかを指定する。RFC 9113 では Push は deprecated のため 0 が一般的。

Identifier=0x2。0=false, 1=true。クライアント初期値 1 だが運用では無効化が多い

5.3. SETTINGS_MAX_CONCURRENT_STREAMS

同時に開けるストリーム数を制限する。サーバ保護とクライアント並列度に影響する。

Identifier=0x3。初期値 unlimited。実運用例: 100-1000 程度

5.4. SETTINGS_INITIAL_WINDOW_SIZE

新規ストリームの初期フロー制御ウィンドウ。大きすぎるとメモリ、小さすぎるとスループットに影響する。

Identifier=0x4。初期値 65535 octets。最大 2^31-1

5.5. SETTINGS_MAX_FRAME_SIZE

受信可能な最大フレーム payload サイズを示す。範囲外は PROTOCOL_ERROR になる。

Identifier=0x5。初期値 16384。許容範囲 2^14-2^24-1

5.6. SETTINGS_MAX_HEADER_LIST_SIZE

展開後ヘッダリストの最大サイズ目安を通知する。厳密な強制値ではないが防御上重要。

Identifier=0x6。単位 octets。HPACK Bomb と巨大 Cookie 対策

5.7. フロー制御

HTTP/2 は接続レベルとストリームレベルの 2 段フロー制御を持つ。DATA フレームだけが対象。

初期 window 65535。WINDOW_UPDATE で増加。接続 window と stream window の両方を消費

6. エラー処理

6.1. 主要エラーコード

接続またはストリームの終了理由を 32bit エラーコードで表す。RST_STREAM と GOAWAY で使われる。

NO_ERROR(0), PROTOCOL_ERROR(1), INTERNAL_ERROR(2), FLOW_CONTROL_ERROR(3), SETTINGS_TIMEOUT(4), STREAM_CLOSED(5), FRAME_SIZE_ERROR(6)

6.2. 追加エラーコード

圧縮、セキュリティ、HTTP/1.1 必須など、より具体的な失敗理由を表す。

REFUSED_STREAM(7), CANCEL(8), COMPRESSION_ERROR(9), CONNECT_ERROR(10), ENHANCE_YOUR_CALM(11), INADEQUATE_SECURITY(12), HTTP_1_1_REQUIRED(13)

6.3. SETTINGS_TIMEOUT

SETTINGS に対する ACK が時間内に返らない場合の接続エラー。中間装置や実装不具合の切り分け対象になる。

Error Code=0x4。SETTINGS ACK 未受信

7. 運用

7.1. Server Push 非推奨

キャッシュ整合、過剰送信、ブラウザ実装差、優先度制御の難しさから、RFC 9113 で Server Push は deprecated になった。

PUSH_PROMISE と PRIORITY は RFC 9113 で deprecated。代替: preload hints / 103 Early Hints / HTTP Priority

7.2. 運用確認コマンド

ALPN、フレーム、設定値、ヘッダ圧縮の影響を確認するには curl と nghttp2 ツールが便利。

curl -v --http2 https://example.com / nghttp -nv https://example.com / openssl s_client -alpn h2

7.3. 典型トラブルシュート

HTTP/2 だけ遅い場合は HOL blocking、巨大ヘッダ、MAX_CONCURRENT_STREAMS、フロー制御、TLS ALPN、プロキシ変換を確認する。

確認: ALPN=h2、SETTINGS、RST_STREAM/GOAWAY、WINDOW_UPDATE 停滞、header list size、backend h1 変換

8. References

  1. HTTP/2
  2. h2
  3. RFC 9113
  4. RFC 7540
  5. RFC 7541
  6. RFC 9218
  7. HPACK
  8. DATA
  9. HEADERS
  10. SETTINGS
  11. PING
  12. GOAWAY
  13. WINDOW_UPDATE
  14. CONTINUATION
  15. Stream
  16. ALPN
  17. Server Push
  18. フロー制御
  19. ヘッダ圧縮
Related