/
435.txt
288 lines (219 loc) · 16.2 KB
/
435.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
[5] [[HTTP]] の [DFN[[CODE(HTTP)@en[[[CONNECT]]]] [[メソッド]]]]は、
[[串]]をすり抜ける[[トンネル]]を確立します。
[47] この[[メソッド]]は [[HTTPS]] 通信が[[串]]を通過するために使われています。
;; [48] このような動作をするものは一般的には[[串]] ([[プロキシ]]) と呼ばれていますが、
[[RFC 7230]] の用語では[[中間器]]の一種である[[トンネル]]に分類されています。
* 仕様書
[REFS[
- [49] '''[CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-06-07 01:55:45 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-4.3.6>'''
- [45] [CITE@en[RFC 7230 - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing]] ([TIME[2014-06-07 01:59:35 +09:00]] 版) <https://tools.ietf.org/html/rfc7230#section-3.3>
- [10] [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-7>
- [12] [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-8.3>
- [32] [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-10.5.2>
]REFS]
* 意味
[50] [CODE(HTTP)@en[[[CONNECT]]]] [[メソッド]]は、
[[要求対象]]によって識別される[[起源鯖]]を出口とする[[トンネル]]を確立し、
成功した場合には、[[トンネル]]が閉じられるまでの間、
[[パケット]]を盲目的に[[転送]]するだけの動作をすることを[[受信者]]に対して[[要求]]するものです
[SRC[>>49]]。
[FIG(sequence)[
:C:[[クライアント]]
:P:[[串]]
:S:[[鯖]]
:C -> P:[[鯖]]への [CODE(HTTP)@en[[[CONNECT]]]] [[要求]]
:P ## S:[[接続]]の確立
:P -> C:[CODE(HTTP)[[[200]]]] [[応答]]
:C ## S:以後[[串]]は無変更で[[鯖]]・[[クライアント]]間を中継
:C ## S:[[串]]は一方の[[接続]]が閉じられたら、他方の[[接続]]も閉じる
]FIG]
[65] [CODE(HTTP)@en[[[CONNECT]]]] は、動作としては [CODE(HTTP)@en[[[Upgrade:]]]]
による[[プロトコル]]の切り替えと然程違いません。どちらも一旦切り替えられると元の
[[HTTP]] とは異なる[[プロトコル]]の規定に支配される[[接続]]となり、
基本的に元の [[HTTP]] に戻ってくることはできません。それでも [CODE(HTTP)@en[[[Upgrade:]]]]
は理論上は元の[[要求]]の処理を[[鯖]]が新しい[[プロトコル]]で継続することが期待されるのに対し、
[CODE(HTTP)@en[[[CONNECT]]]] は新しい[[プロトコル]]ではじめから通信が始まることが期待されています。
また [CODE(HTTP)@en[[[Upgrade:]]]] は[[受信者]]である[[鯖]]が直接処理することを期待されているのに対し、
[CODE(HTTP)@en[[[CONNECT]]]] は[[受信者]]自身ではなく中継された先にあるはずの[[鯖]]が処理することが期待されているという大きな違いがあります。
[14] [CODE(HTTP)@en[[[CONNECT]]]] [[メソッド]]は、主として [[HTTP]]
[[プロキシ]]を通して [CODE(URI)@en[[[https]]]] [[資源]]にアクセスするために[[起源サーバー]]との間に
[[TLSセッション]]を確立するために使います [SRC[>>12]]。
;; [15] [[RFC 7540]] は [CODE(HTTP)@en[[[CONNECT]]]] のことを
「[RUBYB[疑似メソッド]@en[pseudo-method]]」と呼んでおり [SRC[>>12]]、
それがどういう意味かは不明ですが、通常の[[要求メソッド]]とは性質が違うことをほのめかしています。
[16] [[HTTP/2]] では [CODE(HTTP)@en[[[CONNECT]]]] [[メソッド]]は、
([[接続]]全体ではなく) [[ストリーム]]において[[トンネル]]を確立するために使います [SRC[>>12]]。
* 構文
[54] [[HTTP/1.1]] [[以下]]の [CODE(HTTP)@en[[[CONNECT]]]] [[要求]]の[[要求対象]]は、 [CODE(ABNF)@en[[[authority-form]]]]
でなければ[['''なりません''']] [SRC[>>49]]。
[17] [[HTTP/2]] では、[[疑似ヘッダー]]を次のようにします。
[FIG(list members)[
- [18] [CODE(HTTP)@en[[[:method]]]] は、 [CODE(HTTP)@en[[[CONNECT]]]] とします [SRC[>>12]]。
- [19] [CODE(HTTP)@en[[[:scheme]]]] は、省略しなければ[['''なりません''']] [SRC[>>12]]。
- [20] [CODE(HTTP)@en[[[:path]]]] は、省略しなければ[['''なりません''']] [SRC[>>12]]。
- [21] [CODE(HTTP)@en[[[:authority]]]] は、[[ホスト]]と[[ポート]]を指定します。
[[要求対象]]の [CODE(ABNF)@en[[[authority-form]]]] に相当します。 [SRC[>>12]]
]FIG]
[62] [CODE(HTTP)@en[[[CONNECT]]]] [[要求]]の [[payload]] の意味は定義されていません。 [SRC[>>49]]
;; [63] [[payload body]] があると実装によっては[[要求]]を拒絶するかもしれません。 [SRC[>>49]]
[34] [[Chrome]] は次の[[ヘッダー]]を指定するようです。
[TIME[2015-08-04T10:02:41.00Z]]
[FIG(list)[
- [[HTTP/1.1]]
- [CODE(HTTP)@en[[[Host:]]]]
- [CODE(HTTP)@en[[[Proxy-Connection:]] [[keep-alive]]]]
- [CODE(HTTP)@en[[[User-Agent:]]]]
]FIG]
[35] [[Firefox]] は次の[[ヘッダー]]を指定するようです。
[TIME[2015-08-04T10:02:41.00Z]]
[FIG(list)[
- [[HTTP/1.1]]
- [CODE(HTTP)@en[[[User-Agent:]]]]
- [CODE(HTTP)@en[[[Proxy-Connection:]] [[keep-alive]]]]
- [CODE(HTTP)@en[[[Connection:]] [[keep-alive]]]]
- [CODE(HTTP)@en[[[Host:]]]]
]FIG]
[36] [[IE]] は次の[[ヘッダー]]を指定するようです。
[TIME[2015-08-04T10:02:41.00Z]]
[FIG(list)[
- [[HTTP/1.0]]
- [CODE(HTTP)@en[[[User-Agent:]]]]
- [CODE(HTTP)@en[[[Connection:]] [[keep-alive]]]]
- [CODE(HTTP)@en[[[Content-Length:]] 0]]
- [CODE(HTTP)@en[[[Host:]]]]
- [CODE(HTTP)@en[[[Pragma:]] [[no-cache]]]]
]FIG]
* 性質
[64] [CODE(HTTP)@en[[[CONNECT]]]] [[要求]]に対する[[応答]]は、
[[キャッシュ可能]]ではありません [SRC[>>49]]。
* 処理
[51] [CODE(HTTP)@en[[[CONNECT]]]] [[要求]]は[[串]]に対する[[要求]]での利用のみを想定しています
[SRC[>>49]]。
[22] [[HTTP/2]] で >>17 の[[疑似ヘッダー]]の制約に違反する場合は、
[[奇形]]です [SRC[>>12]]。
[55] [[串]]は、[[要求対象]]に直接[[接続]]しても構いませんし、
他の[[串]]を使うよう設定されている場合には次の[[内向き]]の[[串]]に
[CODE(HTTP)@en[[[CONNECT]]]] [[要求]]を[[転送]]しても構いません [SRC[>>49]]。
[23] [CODE(HTTP)@en[[[CONNECT]]]] に対応する [[HTTP/2]] [[プロキシ]]は、
[CODE(HTTP)@en[[[:authority]]]] [[疑似ヘッダー]]で識別される[[サーバー]]への
[[TCP接続]]を確立します。確立に成功したら、
[[状態符号]] [CODE(HTTP)@en[[[2xx]]]] の [CODE(HTTP)@en[[[HEADERS]]]]
[[フレーム]]を[[クライアント]]に送信します。 [SRC[>>12]]
[52] 自身への [CODE(HTTP)@en[[[CONNECT]]]] [[要求]]を受信した[[起源鯖]]は、
[[接続]]が確立されたことを示す [CODE(HTTP)[[[2xx]]]] [[応答]]を返しても構いません [SRC[>>49]]。
;; [57] [[持続接続]]により引き続き [[HTTP]] の[[接続]]の処理が継続されているのか、
[CODE(HTTP)@en[[[CONNECT]]]] によって[[トンネル]]として動作しているのか、
[[クライアント]]側から判別する方法はありません。
;; [53] ただしほとんどの[[起源鯖]]は、 [CODE(HTTP)@en[[[CONNECT]]]]
を実装していません [SRC[>>49]]。
[60] [[トンネル]]の確立は大きな危険を生じさせるものですから、[[串]]は、
既知の[[ポート]]や安全な[[要求対象]]の[[ホワイトリスト]]により、
[CODE(HTTP)@en[[[CONNECT]]]] の利用を制限する[['''べきです''']] [SRC[>>49]]。
[46] [CODE(HTTP)[[[CONNECT]]]] [[要求]]に対する [CODE(HTTP)[[[2xx]]]]
[[応答]]は、[[メッセージ本体]]を持ちません [SRC[>>45, >>49]]。
[24] [[HTTP/1.1]] [[以下]]では、[[メッセージ本体]]の代わりに、
[[ヘッダー]]の次の [[CRLF]] の直後から、[[トンネル]]モードに切り替わります。 [SRC[>>45, >>49]]
[61] [[鯖]]は、 [CODE(HTTP)@en[[[Transfer-Encoding:]]]] や [CODE(HTTP)@en[[[Content-Length:]]]]
を [CODE(HTTP)[[[2xx]]]] [[応答]]に含めては[['''なりません''']] [SRC[>>49]]。
[[クライアント]]はこれらを無視しなければ[['''なりません''']] [SRC[>>49]]。
[25] [[HTTP/2]] では、 最初の [CODE(HTTP)@en[[[HEADERS]]]] [[フレーム]]の後、
以後のすべての [CODE(HTTP)@en[[[DATA]]]] [[フレーム]]は [[TCP接続]]上のデータに対応します。
[[クライアント]]から送信された [CODE(HTTP)@en[[[DATA]]]] [[フレーム]]は[[プロキシ]]から [[TCPサーバー]]へと送信され、
[[TCPサーバー]]から受信したデータは[[プロキシ]]から[[クライアント]]へと
[CODE(HTTP)@en[[[DATA]]]] [[フレーム]]で送信されます。 [SRC[>>12]]
[26] [CODE(HTTP)@en[[[DATA]]]] [[フレーム]]と[[ストリーム]]管理のための[[フレーム]]
([CODE(HTTP)@en[[[RST_STREAM]]]], [CODE(HTTP)@en[[[WINDOW_UPDATE]]]],
[CODE(HTTP)@en[[[PRIORITY]]]]) を除き、当該[[ストリーム]]を使って送信しては[['''ならず''']]、
受信したら[[ストリームエラー]]としなければ[['''なりません''']]。 [SRC[>>12]]
[56] [CODE(HTTP)[[[2xx]]]] 以外の[[応答]]は、[[トンネル]]が形成されていないことを表し、
[[トンネル]]としてではなく [[HTTP]] による解釈を継続するべきものです [SRC[>>49]]。
[58] [[HTTP/1.1]] [[以下]]の[[トンネル]]は、そのいずれかの側の[[接続]]が閉じられたと検出した時、
閉じられます。その場合、閉じられた側からの残りのデータをすべて送信し、
両方の[[接続]]を閉じ、残ったデータがあれば捨てる、という処理を試みなければ[['''なりません''']]。
[SRC[>>49]]
[27] [[HTTP/2]] では [CODE(HTTP)@en[[[END_STREAM]]]] [[フラグ]]が [[TCP]]
[CODE[[[FIN]]]] フラグに相当します。[[クライアント]]は、
[CODE[[[END_STREAM]]]] フラグが設定された [CODE(HTTP)@en[[[DATA]]]]
[[フレーム]]を受信したら、 [CODE(HTTP)@en[[[END_STREAM]]]]
フラグが設定された [CODE(HTTP)@en[[[DATA]]]] [[フレーム]]を送信することが期待されています。
[[プロキシ]]は、[CODE(HTTP)@en[[[END_STREAM]]]] フラグが設定された [CODE(HTTP)@en[[[DATA]]]]
[[フレーム]]を受信したら、 [CODE[[[FI]]]] ビットを設定した
[[TCPセグメント]]を最後に送ります。[[プロキシ]]は
[CODE[[[FIN]]]] ビットが設定された [[TCPセグメント]]を受信したら、
[CODE(HTTP)@en[[[END_STREAM]]]] フラグが設定された
[CODE(HTTP)@en[[[DATA]]]] [[フレーム]]を送信します。 [SRC[>>12]]
;; [28] 最後の [CODE(HTTP)@en[[[DATA]]]] [[フレーム]]や [[TCPセグメント]]は、
空になることもあります。 [SRC[>>12]]
[29] [[HTTP/2]] [[プロキシ]]は、 [CODE[[[RST]]]] ビットが設定された [[TCPセグメント]]をはじめとする
[[TCP接続]]のエラーを検出したら、[[ストリームエラー]] [CODE[[[CONNECT_ERROR]]]]
とします。 [SRC[>>12]]
[30] [[HTTP/2]] [[プロキシ]]は、 [[HTTP/2]] の[[ストリーム]]や[[接続]]でエラーを検出したら、
[CODE[[[RST]]]] ビットが設定された [[TCPセグメント]]を送信しなければ[['''なりません''']]
[SRC[>>12]]。
;; [31] [[HTTP/1.1]] [[以下]]でも同じようにエラー処理が必要なのかもしれませんが、
[[RFC]] では規定されていません。
[33] [CODE(HTTP)@en[[[CONNECT]]]] は、 [[TCP接続]]を維持しなければならず、
その分の[[資源]]を消費することに注意が必要です。 [CODE(HTTP)@en[[[CONNECT]]]]
が閉じられた後も [CODE[[[TIME_WAIT]]]] 状態の間、 [[TCP接続]]の情報を残す必要があることにも注意が必要です。
[[設定]] [CODE[[[SETTINGS_MAX_CONCURRENT_STREAMS]]]] とは別に
[CODE(HTTP)[[[CONNECT]]]] の[[資源]]消費にも制限が必要かもしれません。 [SRC[>>32]]
[6] [[トンネル]]内では [[HTTPS]] ([[HTTP]] over [[TLS]]) を用いるのが主たる用途ですが、
[[TCP]] で動作する任意の[[プロトコル]]を使うことができます。
[[トンネル]]としてはどのような[[プロトコル]]が使われているか感知しません。
[37] [[HTTPS]] [[プロキシ]]としての利用の際、 [[Firefox]] は[[応答]]を待たずに[[ヘッダー]]と空行の後直ちに
[[TLS]] を開始します。 [[Chrome]] と [[IE]] は、[[応答]]を待ちます。
[[応答]]が [CODE(HTTP)[[[200]]]] 以外の場合、 [[Chrome]] と [[IE]] は[[接続]]を閉じますが、
[[Firefox]] は[[接続]]が閉じられるのを待ちます。
ただし [CODE(HTTP)[[[101]]]] なら直ちに閉じます。 [TIME[2015-08-04T10:16:18.800Z]]
[38] [[Firefox]] も [[Chrome]] も [[IE]] も、 [CODE(HTTP)[[[1xx]]]]
はエラーとみなし、その後の[[応答]]を待ちません。 [TIME[2015-08-04T10:19:45.500Z]]
[39] [[Firefox]] も [[Chrome]] も [[IE]] も、 [CODE(HTTP)[[[407]]]]
で [CODE(HTTP)@en[[[Proxy-Authenticate:]]]] があれば、
[[モーダルダイアログ]]を表示します。 [TIME[2015-08-04T10:26:52.400Z]]
[40] [[Firefox]] と [[Chrome]] は[[持続的接続]]により [CODE(HTTP)[[[407]]]]
の[[接続]]を再利用しようとします。 [[IE]] は再利用しないようにみえます
(が条件次第で再利用するかもしれず断言はできません)。 [TIME[2015-08-04T10:32:16.00Z]]
* 誤り符号 [CODE[CONNECT_ERROR]]
[11] [[誤り符号]] [DFN[[CODE[[[CONNECT_ERROR]]]]]] ([CODE[[[0xa]]]])
は、 [CODE[[[CONNECT]]]] [[要求]]により確立された[[接続]]が[[再設定]]または異常に閉じられたことを表します [SRC[>>10]]。
* 歴史
** draft-luotonen-web-proxy-tunneling (1998)
[REFS[
- [1] [CITE@en[draft-luotonen-web-proxy-tunneling - Tunneling TCP based protocols through Web proxy servers]]
<http://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling>
]REFS]
** RFC 2616
[FIG(quote)[
[FIGCAPTION[
[2] RFC 2616 (HTTP/1.1) 9.9 CONNECT
]FIGCAPTION]
> This specification reserves the method name CONNECT for use with a
proxy that can dynamically switch to being a tunnel (e.g. SSL tunneling [44]).
>
この仕様書は、方式名 [CODE(HTTP)[[[CONNECT]]]] を、動的に[[トンネル]]になるように切り替える[[串]]
(たとえば [[SSL]] トンネル化) で使うために予約します。
]FIG]
** RFC 2817
[4] [[RFC 2817]] が [CODE(HTTP)@en[[[CONNECT]]]] [[要求メソッド]]を初めて正式に規定する[[仕様書]]となりました。
[8] [[RFC 2817]] は >>1 に言及しつつ、既に[[串]]で広く実装されている [SRC[>>3]]
と述べています。
[REFS[
- [3] [CITE@en[RFC 2817 - Upgrading to TLS Within HTTP/1.1]] ([TIME[2012-01-09 20:05:09 +09:00]] 版) <http://tools.ietf.org/html/rfc2817#section-5>
]REFS]
** RFC 723x
[7] [[RFC 7230]] と [[RFC 7231]] により [[RFC 2817]] が[[更新]]され、
より正確に動作が規定されるようになりました。これにより [[RFC 2817]]
の該当部分の規定は失効したものと考えられます。
[13] [[RFC 7540]] [SRC[>>12]] は [[HTTP/2]] における用法を規定しています。
* 関連
[59] [CODE(HTTP)@en[[[CONNECT]]]] [[メソッド]]に [CODE(HTTP)@en[[[Proxy-Authorization:]]]]
を含めることで、[[串]]の[[認証]]を利用できます。
[201] [CITE@en[draft-maes-lemonade-http-binding-04 - IMAP and SMTP HTTP Binding]]
( ([TIME[2014-08-20 10:08:37 +09:00]] 版))
<http://tools.ietf.org/html/draft-maes-lemonade-http-binding-04#section-2.1.3>
[202] [CITE@en[draft-maes-lemonade-p-imap-12 - Push Extensions to the IMAP Protocol (P-IMAP)]]
( ([TIME[2014-08-24 09:14:38 +09:00]] 版))
<http://tools.ietf.org/html/draft-maes-lemonade-p-imap-12#page-47>
[9] [CITE@en[mod_proxy_connect - Apache HTTP Server Version 2.4]]
([TIME[2015-01-02 00:30:56 +09:00]] 版)
<http://httpd.apache.org/docs/current/en/mod/mod_proxy_connect.html>