/
375.txt
141 lines (104 loc) · 7.16 KB
/
375.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
[51] [[HTTP/2]] は、 [DFN[[CODE(HTTP)@en[[[Upgrade:]] [[h2c]]]]]]
により [[HTTP]] over [[TCP]] から [[HTTP/2]] over [[TCP]]
へと移行する方法を規定しています。
* 代替
[52] この方法が広く実装されるかどうかは不明です。
[14] 通常は [[HTTPS]] ([[HTTP/2]] over [[TLS]]) を使うことが期待されています。
[[HTTPS]] では [CODE(HTTP)@en[Upgrade: h2c]] は使いません。
[15] そもそも [[TLS]] のない [[HTTP]] は安全ではないので、使うべきではありません。
[[相互運用性]]のため、実装は [CODE(HTTP)@en[Upgrade: h2c]]
に対応するべきでもありません。
* 仕様書
[REFS[
- [47] '''[CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-3.2>'''
- [9] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-5.1.1>
]REFS]
* 構文
[50] [[クライアント]]は、 [CODE(URI)@en[[[http:]]]] [[URL]]
にアクセスする場合、 [[HTTP/1.1]] [[要求]]の [CODE(HTTP)@en[[[Upgrade:]]]]
[[ヘッダー]]に、 [CODE(HTTP)@en[[[h2c]]]] と指定します [SRC[>>47]]。
[53] その場合、[CODE(HTTP)@en[[[HTTP2-Settings:]]]] [[ヘッダー]]をちょうど1つ指定しなければ[['''なりません''']] [SRC[>>47]]。
;; [54] 必然的に [CODE(HTTP)@en[[[Connection:]]]] [[ヘッダー]]に
[CODE(HTTP)@en[[[Upgrade]]]] と [CODE(HTTP)@en[[[HTTP2-Settings]]]]
を指定することになります。
;; [55] [[要求]]に [[payload body]] があれば、それも [[HTTP/2]] に切り替わる前に送る必要があります。
次の[[要求]]を送れるようになるまでの遅延を嫌う場合は、
[CODE(HTTP)@en[[[OPTIONS]]]] [[要求]]をかわりに送ることができます。 [SRC[>>47]]
;; [4] [CODE(HTTP)@en[[[Upgrade:]]]] の構文の項も参照。
* 文脈
[3] [[クライアント]]は [[TLS]] 上の [[HTTP]] で [CODE(HTTP)@en[[[Upgrade: h2c]]]]
を指定してはならないと思われます。
;; [5] [CODE(HTTP)@en[[[Upgrade:]]]] の文脈の項も参照。
* 処理
;; [6] [CODE(HTTP)@en[[[Upgrade:]]]] の処理の項も参照。
[FIG(sequence)[
:C:[[クライアント]]
:S:[[サーバー]]
:C -> S:[[HTTP/1.1]] [CODE(HTTP)@en[[[Upgrade: h2c]]]] [CODE(HTTP)@en[[[HTTP2-Settings:]] ...]] ※
:S -> C:[[HTTP/1.1]] [CODE(HTTP)[[[101]]]] [CODE(HTTP)@en[[[Upgrade: h2c]]]]
:C ## S:[[HTTP/2]] [[接続序文]]
:S -> C:[[HTTP/2]] ※への[[応答]]
]FIG]
[57] [[サーバー]]は、[[HTTP/2]] に対応していれば、 [CODE(HTTP)[[[101]]]]
[[応答]]を返します。その末尾の[[空行]]の直後から [[HTTP/2]] [[フレーム]]を送信できます。
[SRC[>>47]]
[56] [[サーバー]]は、 [[HTTP/2]] に対応していなければ、
[CODE(HTTP)@en[[[Upgrade:]]]] を無視して通常通り [[HTTP/1.1]] で[[応答]]を返すことになります。
[61] [[サーバー]]は、 [[TLS]] 上の [[HTTP]] なら [CODE(HTTP)@en[[[Upgrade:]] [[h2c]]]]
を無視しなければならないと考えられます。
[62] [[サーバー]]は、[[要求]]に [CODE(HTTP)@en[[[HTTP2-Settings:]]]] [[ヘッダー]]が複数あるか、
1つもなければ、[[HTTP/2]] に切り替えては[['''なりません''']] [SRC[>>47]]。
[63] [[サーバー]]は、[[HTTP/2]] に切り替える場合、
[CODE(HTTP)@en[[[HTTP2-Settings:]]]] [[ヘッダー]]の値を通常の
[CODE[[[SETTINGS]]]] [[フレーム]]と同じように解釈します [SRC[>>47]]。
[18] [CODE(HTTP)@en[[[HTTP2-Settings:]]]] [[ヘッダー]]の
[[base64url]] [[復号]]や[[フレーム]]解釈によりエラーが検出された場合にどうするべきなのかは不明です。
切り替えずに [[HTTP/1.1]] で処理を続けるべきなのでしょうか。
[2] [CODE(HTTP)[[[101]]]] [[応答]]が暗示的な [[acknowledgement]] となるため、
明示的な [[acknowledgement]] の [CODE(HTTP)@en[[[SETTINGS]]]]
[[フレーム]]は不要です。 [SRC[>>47]]
[58] [[HTTP/2]] に切り替えた場合、[[サーバー]]が最初に送る[[フレーム]]は、
[CODE[[[SETTINGS]]]] [[フレーム]]の [[server connection preface]]
でなければ[['''なりません''']] [SRC[>>47]]。
[59] [[クライアント]]は、[CODE(HTTP)[[[101]]]] [[応答]]を受信したら、
[CODE[[[SETTINGS]]]] [[フレーム]]を含む [[connection preface]]
を送信しなければ[['''なりません''']] [SRC[>>47]]。
[7] 切り替えた場合、[[サーバー]]は、次の[[ストリーム]]を作成します [SRC[>>47]]。
[FIG(list members)[
[FIGCAPTION[
[[ストリーム]]
]FIGCAPTION]
:[[ストリーム識別子]]:[CODE[[[1]]]]
:状態:[[half-closed (remote)]]
:[[ストリーム優先度]]:[[既定優先度]]
]FIG]
[8] 切り替えた場合、[[クライアント]]は、次の[[ストリーム]]を作成します。
[FIG(list members)[
[FIGCAPTION[
[[ストリーム]]
]FIGCAPTION]
:[[ストリーム識別子]]:[CODE[[[1]]]] [SRC[>>47, >>9]]
:状態:[[half-closed (local)]] [SRC[>>47, >>9]]
:[[ストリーム優先度]]:[[既定優先度]] [SRC[>>47]]
]FIG]
[60] 切り替えた場合、[[サーバー]]は切り替え前の [[HTTP/1.1]]
[[要求]]に[[応答]]しなければ[['''なりません''']]。
[[ストリーム識別子]]は、 [CODE[[[1]]]] とします。 [SRC[>>47]]
* メモ
[10] [[TLS]] のない素の [[TCP]] 上の [[HTTP]] は、現在では危険と考えられています。
[[Webブラウザー]]開発者や[[Web標準]]の開発者の間では、 [[HTTPS]]
でない [[HTTP]] における新機能の導入を不適切とみなす流れが10年代中頃に固まってきています。
[11] [[IETF]] は本機能を [[HTTP/2]] 仕様の一部に含めていますが、
[[Webブラウザー]]が実装するのかどうか、[[Webブラウザー]]が対応しないとしたら
[[Webサーバー]]が実装するのかどうかには、疑問が持たれています。
;; [12] しかも [[HTTP/1.1]] の [CODE(HTTP)@en[[[Upgrade:]]]] は
[[WebSocket]] を除き成功例がなく、 [[TLS]] の問題がなかったとしても、
[[相互運用性]]と[[セキュリティー]]を十分確保して広く実装できたかは怪しいかもしれません。
[FIG(quote)[
[FIGCAPTION[
[13] [CITE@ja[HTTP/2 プロトコルネゴシエーション方法と ATS での実装 - Yahoo! JAPAN Tech Blog]]
([TIME[2016-03-02 18:02:58 +09:00]] 版)
<http://techblog.yahoo.co.jp/infrastructure/http2/ats_http2_pn/>
]FIGCAPTION]
> ATS には現状 HTTP アップグレードメカニズムを使用した HTTP/2 へのアップグレードには対応しておらず、NPN もしくは ALPN によるプロトコルネゴシエーションのみサポートされている状態です。しかしながらアップグレード対応の為の実装作業はそれほど大掛かりな作業ではなく、http スキームからのネゴシエーション方法もサポートしておきたいため(本稿のためのネタ作りも兼ねて!)今回実装してパッチを送りました。
]FIG]