Summary

  • RFC 6455 opened WebSockets through HTTP/1.1 GET, Upgrade and a 101 response. RFC 7540 removed that connection-wide 101 mechanism from multiplexed HTTP/2.
  • RFC 8441 added an extended CONNECT: the client puts :protocol = websocket, :scheme and :path on one new HTTP/2 stream after receiving the server’s SETTINGS_ENABLE_CONNECT_PROTOCOL = 1. IANA lists setting 0x8 with default value 0.
  • The opened stream carries WebSocket data while other streams use the same connection. The HTTP/1.1 Connection, Upgrade and Sec-WebSocket-Key/Accept processing do not make the crossing; WebSocket framing resumes inside the accepted stream.

One switch was too large for the corridor

The 2011 WebSocket protocol began with an HTTP/1.1 request. A client sent a GET with Upgrade: websocket and Connection: Upgrade; the server could answer 101 Switching Protocols. After that handshake, the TCP connection became the two-way WebSocket channel. That was a sensible bargain when one request occupied one connection. The entire pipe could be handed to the conversation.

HTTP/2 changed the shape of the pipe. Several streams could coexist on one TCP connection. A page might be receiving images and style sheets while a separate feature wanted a continuous conversation. RFC 7540 removed support for 101 within HTTP/2 because switching the whole connection would make no sense for its neighbours. Upgrade and Connection are connection-wide concepts; one stream cannot commandeer every other stream’s transport. An old WebSocket opening was therefore the wrong key for a new door.

The practical cost was visible even before any cryptography or application logic: a program could have an HTTP/2 connection ready for its page and still need a different opening path for its WebSocket. The protocol family had a mismatch between how it shared a connection and how it began a real-time channel. RFC 8441 addressed that mismatch without requiring every stream on the connection to accept a change.

The server must unlock the smaller door

The server advertises support with SETTINGS_ENABLE_CONNECT_PROTOCOL set to 1. The IANA HTTP/2 settings registry assigns it code 0x8 and an initial value of 0. After receiving 1, a client may use the extended CONNECT on new streams. A client that sends the new pseudo-header before opt-in gives a server without this extension a malformed request. The setting is a gate on changing the meaning of the request, not a decorative capability badge.

Once the gate opens, the client creates an HTTP/2 stream with :method = CONNECT and :protocol = websocket. It also sends :scheme and :path for the target URI, plus the usual :authority. That combination is unusual because ordinary CONNECT uses :authority to name the host of a tunnel. Under the extension, the server reads it as the target URI’s authority and must not open a separate tunnel to that host merely because CONNECT appeared. The extra pseudo-header tells the server which protocol the new stream is to carry.

For a secure WebSocket URI, the target scheme becomes https; an unsecured one uses http. The rest of the target URI retains the WebSocket location. The WebSocket URI still matters for proxy configuration. RFC 8441 does not ask an HTTP/2 forward proxy to pretend that this new origin-facing request is a traditional proxy tunnel: a client going through such a proxy should first use ordinary CONNECT, and the resulting tunneled HTTP version determines how WebSocket is opened afterward.

A stream begins where the old upgrade ended

The extended CONNECT replaces the old GET-based opening. It does not send Connection or Upgrade, and it does not perform the HTTP/1.1 Sec-WebSocket-Key and Sec-WebSocket-Accept exchange. RFC 8441 says :protocol supersedes that key/accept processing in this path. Origin, Sec-WebSocket-Version, subprotocol and extension headers still participate under the WebSocket rules. The adaptation is targeted at the opening, not at discarding the WebSocket protocol that follows.

The RFC’s example has the server opt in, the client send extended CONNECT and the server reply :status = 200. Then HTTP/2 DATA frames carry WebSocket data in both directions. The stream is treated as the TCP connection had been treated in RFC 6455, while other HTTP/2 streams continue to carry ordinary requests or other tunnels. The stream keeps HTTP/2’s priority, cancellation and flow-control mechanisms. END_STREAM and RST_STREAM serve as the orderly and exceptional endings for this particular channel.

Those details put ownership at the right scale. A chat can live as long as it needs without taking the page’s image requests hostage. A server can decline the extension by never enabling the setting. A client can observe that absence before attempting the special CONNECT. The change is visible to both endpoints in a setting and a request; it does not rely on an intermediary guessing what an old 101 might mean inside multiplexed traffic.

The whole connection kept its tenants

RFC 8441 chose a modest design. A fuller redesign of WebSocket for HTTP/2 was possible, the RFC says, but the extended CONNECT answered the immediate problem of running WebSockets and ordinary HTTP/2 together. The 2018 standard changed the admission ceremony. Once the tunnel is open, WebSocket frames still run inside it, and most of RFC 6455’s security considerations still apply. The existing WebSocket masking story belongs to those frames; the new question here is how a single stream gains permission to carry them.

The four official records establish the mechanism and registered setting. Dated client, server and proxy releases plus captured SETTINGS and HEADERS exchanges would show where a named service actually used it. The historical point does not need a market-share chart: HTTP/2 refused to surrender a shared connection for one conversation, and WebSocket gained a negotiated room within it.