Bootstrapping WebSockets with HTTP/2
updates
- rfc-6455 — The WebSocket Protocol
Extracted elements (22)
The Extended CONNECT approach was chosen to minimize solution complexity while addressing the primary concern of running HTTP/2 and WebSockets concurrently. A more native HTTP/2 integration would have required larger additions to HTTP/2.
The Host header field required by RFC 6455 is omitted from the Extended CONNECT request because the host information is conveyed by the :authority pseudo-header, which is required on every HTTP/2 transaction.
Using a SETTINGS parameter to opt into the Extended CONNECT feature avoids breaking non-supporting peers. Without the SETTINGS negotiation, a non-supporting server would detect the :protocol pseudo-header as a malformed request and generate a stream error.
Implementations using Extended CONNECT to bootstrap WebSockets do not perform the Sec-WebSocket-Key and Sec-WebSocket-Accept header field processing of RFC 6455, as that functionality is superseded by the :protocol pseudo-header field.
The Origin, Sec-WebSocket-Version, Sec-WebSocket-Protocol, and Sec-WebSocket-Extensions header fields are used in CONNECT request and response headers as defined in RFC 6455. However, HTTP/2 requires header field names to be encoded as lowercase, unlike HTTP/1.1 where they were case-insensitive.
When a client connecting via HTTP/2 to an HTTP forward proxy wishes to speak WebSockets, it should continue to use traditional CONNECT (without :protocol) to tunnel through the proxy. The resulting HTTP version on that tunnel then determines whether WebSockets is initiated directly or via modified CONNECT.
A sender MUST NOT send a SETTINGS_ENABLE_CONNECT_PROTOCOL parameter with the value of 0 after previously sending a value of 1. The setting is a one-way ratchet.
On requests bearing :protocol, the server MUST NOT create a tunnel to the host indicated by :authority as it would with an unmodified CONNECT request. The :authority pseudo-header is interpreted per RFC 7540 Section 8.1.2.3 rather than Section 8.3.
On requests that contain the :protocol pseudo-header field, the :scheme and :path pseudo-header fields of the target URI MUST also be included.
The Connection and Upgrade header fields required by RFC 6455 MUST NOT be included in the Extended CONNECT request, as they are not part of HTTP/2.
The scheme of the target URI MUST be "https" for "wss"-schemed WebSockets and "http" for "ws"-schemed WebSockets. The remainder of the target URI matches the WebSocket URI.
The value of the SETTINGS_ENABLE_CONNECT_PROTOCOL parameter MUST be 0 or 1.
To initiate a WebSocket connection on an HTTP/2 stream, the :protocol pseudo-header field MUST be included in the CONNECT request and MUST have the value "websocket".
Upon receipt of SETTINGS_ENABLE_CONNECT_PROTOCOL with a value of 1, a client MAY use the Extended CONNECT method when creating new streams. Receipt of this parameter by a server does not have any impact.
HTTP/2 stream closure maps to TCP connection closure from RFC 6455. Orderly closures are represented as END_STREAM flags; RST exceptions are represented with RST_STREAM frames using the CANCEL error code.
SETTINGS_ENABLE_CONNECT_PROTOCOL is a new HTTP/2 SETTINGS parameter (code 0x8) added by this document. When sent by a server with value 1, it signals that the client may use the Extended CONNECT method defined here. The initial value is 0.
The Extended CONNECT method introduces a new pseudo-header field :protocol that MAY be included on CONNECT request HEADERS, indicating the desired protocol for the tunnel. Its value comes from the HTTP Upgrade Token Registry.
IANA registered SETTINGS_ENABLE_CONNECT_PROTOCOL in the "HTTP/2 Settings" registry with code 0x8 and initial value 0, established by RFC 7540 Section 11.3.
IANA registered "websocket" as an entry in the "HTTP Upgrade Tokens" registry (established by RFC 7230), with description "The Web Socket Protocol" and references to RFC 6455 and RFC 8441.
RFC 6455's protections against non-WebSocket clients (e.g., XMLHttpRequest) are preserved: XMLHttpRequest prohibits both the CONNECT method and Sec-prefixed headers. Additionally, HTTP/2 pseudo-headers like :protocol can never be created outside the protocol stack, preventing forgery.
The security considerations of RFC 6455 Section 10 continue to apply, with the exception of Section 10.8, which is specific to the HTTP/1.1-based bootstrapping handshake that this document replaces.
After successfully processing the opening handshake, the WebSocket connection state is OPEN (as defined by RFC 6455 Section 4.1). The HTTP/2 stream from the CONNECT transaction is treated as if it were the TCP connection referenced in RFC 6455.