-
Notifications
You must be signed in to change notification settings - Fork 1
/
draft-mcmanus-httpbis-h2-websockets-02.xml
297 lines (215 loc) · 11.2 KB
/
draft-mcmanus-httpbis-h2-websockets-02.xml
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
289
290
291
292
293
294
295
296
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc2629 version -->
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC2119 SYSTEM "https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC6454 SYSTEM "https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.6454.xml">
<!ENTITY RFC6455 SYSTEM "https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.6455.xml">
<!ENTITY RFC7230 SYSTEM "https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.7230.xml">
<!ENTITY RFC7540 SYSTEM "https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.7540.xml">
]>
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc sortrefs="yes"?>
<?rfc symrefs="yes"?>
<rfc ipr="trust200902" docName="draft-mcmanus-httpbis-h2-websockets-02" category="std">
<front>
<title abbrev="I-D">Bootstrapping WebSockets with HTTP/2</title>
<author initials="P." surname="McManus" fullname="Patrick McManus">
<organization>Mozilla</organization>
<address>
<email>[email protected]</email>
</address>
</author>
<date year="2017" month="November" day="11"/>
<area>Applications and Real Time</area>
<abstract>
<t>This document defines a mechanism for running the WebSocket Protocol
<xref target="RFC6455"/> over a single stream of an HTTP/2 connection.</t>
</abstract>
</front>
<middle>
<section anchor="introduction" title="Introduction">
<t>The Hypertext Transfer Protocol (HTTP) provides compatible resource
level semantics across different versions but it does not offer
compatibility at the connection management level. Other protocols,
such as WebSockets, that rely on connection management details of HTTP
must be updated for new versions of HTTP.</t>
<t>The WebSocket Protocol <xref target="RFC6455"/> uses the HTTP/1.1 <xref target="RFC7230"/>
Upgrade mechanism to transition a TCP connection from HTTP into a
WebSocket connection. A different approach must be taken with HTTP/2
<xref target="RFC7540"/>. The multiplexing nature of HTTP/2 does not allow
connection wide header and status codes such as the Upgrade and
Connection request headers or the 101 response code due to its
multiplexing nature. These are all required by the <xref target="RFC6455"/>
opening handshake.</t>
<t>Being able to bootstrap WebSockets from HTTP/2 allows one TCP
connection to be shared by both protocols and extends HTTP/2’s
more efficient use of the network to WebSockets.</t>
<t>This document extends the HTTP/2 CONNECT method. The extension allows
the substitution of a new protocol name to connect to rather than the
external host normally used by CONNECT. The result is a tunnel on a
single HTTP/2 stream that can carry data for WebSockets (or any other
protocol). The other streams on the connection may carry more extended
CONNECT tunnels, traditional HTTP/2 data, or a mixture of both.</t>
<t>This tunneled stream will be multiplexed with other regular streams on
the connection and enjoys the normal priority, cancellation, and flow
control features of HTTP/2.</t>
<t>Streams that successfully establish a WebSocket connection using a
tunneled stream and the modifications to the opening handshake defined
in this document then use the traditional WebSocket Protocol treating
the stream as if were the TCP connection in that specification.</t>
</section>
<section anchor="terminology" title="Terminology">
<t>In this document, the key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”,
“SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” are to be interpreted as
described in BCP 14, <xref target="RFC2119"/>.</t>
</section>
<section anchor="the-enableconnectprotocol-settings-parameter" title="The ENABLE_CONNECT_PROTOCOL SETTINGS Parameter">
<t>This document adds a new SETTINGS Parameter to those defined by
<xref target="RFC7540"/> Section 6.5.2.</t>
<t>The new parameter is ENABLE_CONNECT_PROTOCOL (type = 0x8). The value
of the parameter MUST be 0 or 1.</t>
<t>Upon receipt of ENABLE_CONNECT_PROTOCOL with a value of 1 a client MAY
use the Extended CONNECT definition of this document when creating new
streams. Receipt of this parameter by a server does not have any
impact.</t>
<t>A sender MUST NOT send a ENABLE_CONNECT_PROTOCOL parameter with the
value of 0 after previously sending a value of 1.</t>
<t>The use of a SETTINGS Parameter to opt-in to an otherwise incompatible
protocol change is a use of “Extending HTTP/2” defined by section 5.5
of <xref target="RFC7540"/>. If a client were to use the provisions of the extended
CONNECT method defined in this document without first receiving a
ENABLE_CONNECT_PROTOCOL parameter with the value of 1 it would be a
protocol violation.</t>
</section>
<section anchor="the-extended-connect-method" title="The Extended CONNECT Method">
<t>The CONNECT Method of <xref target="RFC7540"/> Section 8.3 is modified in
the following ways:</t>
<t><list style="symbols">
<t>A new pseudo-header :protocol MAY be included on request HEADERS
indicating the desired protocol to be spoken on the tunnel created
by CONNECT. The pseudo-header is single valued and contains a value
from the HTTP Upgrade Token Registry defined by <xref target="RFC7230"/>.</t>
<t>On requests bearing the :protocol pseudo-header, the :scheme and
:path pseudo-header fields SHOULD be included.</t>
<t>On requests bearing the :protocol pseudo-header, the :authority
pseudo-header field is interpreted according to <xref target="RFC7540"/> Section
8.1.2.3 instead of <xref target="RFC7540"/> Section 8.3. In particular the server
MUST not make a new TCP connection to the host and port indicated by
the :authority.</t>
</list></t>
<t>Upon receiving a CONNECT request bearing the :protocol pseudo-header
the server establishes a tunnel to another service of the protocol
type indicated by the pseudo-header. This service may or may not be
co-located with the server.</t>
</section>
<section anchor="using-extended-connect-to-bootstrap-the-websocket-protocol" title="Using Extended CONNECT To Bootstrap The WebSocket Protocol">
<t>The pseudo-header :protocol MUST be included in the CONNECT request
and it MUST have a value of websocket to initiate a WebSocket
connection on an HTTP/2 stream. Other HTTP request and response
headers, such as those for manipulating cookies, may be included in
the HEADERS with the CONNECT :method as usual. This request replaces
the GET based request in <xref target="RFC6455"/> and is used to process the
WebSockets opening handshake.</t>
<t>The scheme of the Target URI <xref target="RFC7230"/> MUST be https for wss schemed
WebSockets and http for ws schemed WebSockets. The websocket URI is
still used for proxy autoconfiguration.</t>
<t><xref target="RFC6455"/> requires the use of Connection and Upgrade headers that
are not part of HTTP/2. They MUST not be included in the CONNECT
request defined here.</t>
<t><xref target="RFC6455"/> requires the use of a Host header which is also not part of
HTTP/2. The Host information is conveyed as part of the :authority
pseudo-header which is required on every HTTP/2 transaction.</t>
<t>Implementations using this extended CONNECT to bootstrap WebSockets do
not do the processing of the <xref target="RFC6455"/> Sec-WebSocket-Key and
Sec-WebSocket-Accept headers as that functionality has been superceded
by the :protocol pseudo-header.</t>
<t>The Sec-WebSocket-Version, Origin <xref target="RFC6454"/>, Sec-WebSocket-Protocol,
and Sec-WebSocket-Extensions headers are used on the CONNECT request
and response headers in the same way as defined in <xref target="RFC6455"/>. Note
that HTTP/1 header names were case insensitive and HTTP/2 requires
they be encoded as lower case.</t>
<t>After successfully processing the opening handshake the peers should
proceed with The WebSocket Protocol <xref target="RFC6455"/> using the HTTP/2
stream from the CONNECT transaction as if it were the TCP connection
referred to in <xref target="RFC6455"/>. The state of the WebSocket connection at
this point is OPEN as defined by <xref target="RFC6455"/> Section 4.1.</t>
<section anchor="example" title="Example">
<figure><artwork><![CDATA[
[[ From Client ]] [[ From Server ]]
SETTINGS
ENABLE_CONNECT_PROTOCOL = 1
HEADERS + END_HEADERS
:method = CONNECT
:protocol = websocket
:scheme = https
:path = /chat
:authority = server.example.com:443
sec-websocket-protocol = chat, superchat
sec-websocket-extensions = permessage-deflate
sec-websocket-version = 13
origin = http://www.example.com
HEADERS + END_HEADERS
:status = 200
sec-websocket-protocol = chat
DATA
WebSocket Data
DATA + END_STREAM
WebSocket Data
DATA + END_STREAM
WebSocket Data
]]></artwork></figure>
</section>
</section>
<section anchor="design-considerations" title="Design Considerations">
<t>A more native integration with HTTP/2 is certainly possible with
larger additions to HTTP/2. This design was selected to minimize the
solution complexity while still addressing the primary concern of running
HTTP/2 and WebSockets concurrently.</t>
</section>
<section anchor="about-intermediaries" title="About Intermediaries">
<t>This document does not change how WebSockets interacts with HTTP
proxies. If a client wishing to speak WebSockets connects via HTTP/2
to a HTTP proxy it should continue to use a traditional (i.e. not with
a :protocol pseudo-header) CONNECT to tunnel through that proxy to the
WebSocket server via HTTP.</t>
<t>The resulting version of HTTP on that tunnel determines whether
WebSockets is initiated directly or via a modified CONNECT request
described in this document.</t>
</section>
<section anchor="security-considerations" title="Security Considerations">
<t><xref target="RFC6455"/> ensures that non WebSockets clients, especially
XMLHttpRequest based clients, cannot make a WebSocket connection. Its
primary mechanism for doing that is the use of Sec- prefixed request
headers that cannot be created by XMLHttpRequest based clients. This
specification addresses that concern in two ways:</t>
<t><list style="symbols">
<t>The CONNECT method is prohibited from being used by XMLHttpRequest</t>
<t>The use of a pseudo-header is something that is connection specific
and HTTP/2 does not ever allow to be created outside of the protocol stack.</t>
</list></t>
</section>
<section anchor="iana-considerations" title="IANA Considerations">
<t>This document establishes a entry for the HTTP/2 Settings Registry
that was established by <xref target="RFC7540"/> Section 11.3</t>
<t>Name: ENABLE_CONNECT_PROTOCOL</t>
<t>Code: 0x8</t>
<t>Initial Value: 0</t>
<t>Specification: This document</t>
</section>
<section anchor="acknowledgments" title="Acknowledgments">
<t>The 2017 HTTP Workshop had a very productive discussion that helped
determine the key problem and acceptable level of solution complexity.</t>
</section>
</middle>
<back>
<references title='Normative References'>
&RFC2119;
&RFC6454;
&RFC6455;
&RFC7230;
&RFC7540;
</references>
</back>
</rfc>