h2c

Upgrade: h2c (HTTP)

[51] HTTP/2 は、 Upgrade: h2c により HTTP over TCP から HTTP/2 over TCP へと移行する方法を規定しています。

代替

[52] この方法が広く実装されるかどうかは不明です。

[14] 通常は HTTPS (HTTP/2 over TLS) を使うことが期待されています。 HTTPS では Upgrade: h2c は使いません。

[15] そもそも TLS のない HTTP は安全ではないので、使うべきではありません。 相互運用性のため、実装は Upgrade: h2c に対応するべきでもありません。

仕様書

構文

[50] クライアントは、 http: URL にアクセスする場合、 HTTP/1.1 要求Upgrade: ヘッダーに、 h2c と指定します >>47

[53] その場合、HTTP2-Settings: ヘッダーをちょうど1つ指定しなければなりません >>47

[54] 必然的に Connection: ヘッダーUpgradeHTTP2-Settings を指定することになります。
[55] 要求payload body があれば、それも HTTP/2 に切り替わる前に送る必要があります。 次の要求を送れるようになるまでの遅延を嫌う場合は、 OPTIONS 要求をかわりに送ることができます。 >>47
[4] Upgrade: の構文の項も参照。

文脈

[3] クライアントTLS 上の HTTPUpgrade: h2c を指定してはならないと思われます。

[5] Upgrade: の文脈の項も参照。

処理

[6] Upgrade: の処理の項も参照。
C
クライアント
S
サーバー
C -> S
HTTP/1.1 Upgrade: h2c HTTP2-Settings: ...
S -> C
HTTP/1.1 101 Upgrade: h2c
C ## S
HTTP/2 接続序文
S -> C
HTTP/2 ※への応答

[57] サーバーは、HTTP/2 に対応していれば、 101 応答を返します。その末尾の空行の直後から HTTP/2 フレームを送信できます。 >>47

[56] サーバーは、 HTTP/2 に対応していなければ、 Upgrade: を無視して通常通り HTTP/1.1応答を返すことになります。

[61] サーバーは、 TLS 上の HTTP なら Upgrade: h2c を無視しなければならないと考えられます。

[62] サーバーは、要求HTTP2-Settings: ヘッダーが複数あるか、 1つもなければ、HTTP/2 に切り替えてはなりません >>47

[63] サーバーは、HTTP/2 に切り替える場合、 HTTP2-Settings: ヘッダーの値を通常の SETTINGS フレームと同じように解釈します >>47

[18] HTTP2-Settings: ヘッダーbase64url 復号フレーム解釈によりエラーが検出された場合にどうするべきなのかは不明です。 切り替えずに HTTP/1.1 で処理を続けるべきなのでしょうか。

[2] 101 応答が暗示的な acknowledgement となるため、 明示的な acknowledgementSETTINGS フレームは不要です。 >>47

[58] HTTP/2 に切り替えた場合、サーバーが最初に送るフレームは、 SETTINGS フレームserver connection preface でなければなりません >>47

[59] クライアントは、101 応答を受信したら、 SETTINGS フレームを含む connection preface を送信しなければなりません >>47

[7] 切り替えた場合、サーバーは、次のストリームを作成します >>47

ストリーム
ストリーム識別子
1
状態
half-closed (remote)
ストリーム優先度
既定優先度

[8] 切り替えた場合、クライアントは、次のストリームを作成します。

ストリーム
ストリーム識別子
1 >>47, >>9
状態
half-closed (local) >>47, >>9
ストリーム優先度
既定優先度 >>47

[60] 切り替えた場合、サーバーは切り替え前の HTTP/1.1 要求応答しなければなりませんストリーム識別子は、 1 とします。 >>47

メモ

[10] TLS のない素の TCP 上の HTTP は、現在では危険と考えられています。 Webブラウザー開発者やWeb標準の開発者の間では、 HTTPS でない HTTP における新機能の導入を不適切とみなす流れが10年代中頃に固まってきています。

[11] IETF は本機能を HTTP/2 仕様の一部に含めていますが、 Webブラウザーが実装するのかどうか、Webブラウザーが対応しないとしたら Webサーバーが実装するのかどうかには、疑問が持たれています。

[12] しかも HTTP/1.1Upgrade:WebSocket を除き成功例がなく、 TLS の問題がなかったとしても、 相互運用性セキュリティーを十分確保して広く実装できたかは怪しいかもしれません。
[13] HTTP/2 プロトコルネゴシエーション方法と ATS での実装 - Yahoo! JAPAN Tech Blog ( 版) <http://techblog.yahoo.co.jp/infrastructure/http2/ats_http2_pn/>

ATS には現状 HTTP アップグレードメカニズムを使用した HTTP/2 へのアップグレードには対応しておらず、NPN もしくは ALPN によるプロトコルネゴシエーションのみサポートされている状態です。しかしながらアップグレード対応の為の実装作業はそれほど大掛かりな作業ではなく、http スキームからのネゴシエーション方法もサポートしておきたいため(本稿のためのネタ作りも兼ねて!)今回実装してパッチを送りました。