RFC 8441

Bootstrapping WebSockets with HTTP/2

πŸ“… published September 2018, from ietf

RFC 8441: Bootstrapping WebSockets with HTTP/2 πŸŽ€

okay bestie, the title block first πŸ’… this one is by P. McManus at Mozilla, it's a Standards Track doc (so it's the real deal, not a draft vibe), it came out in September 2018, and it's ISSN 2070-1721 ✨ it updates RFC 6455, so it's basically a sequel to the WebSocket spec that adds a new way to start a WebSocket πŸ¦‹

Abstract 🫢

so the big idea is that this doc lets you run the WebSocket Protocol (RFC 6455) over one single stream inside an HTTP/2 connection 🌸

Status of This Memo πŸ“œ

this is an Internet Standards Track document πŸ’œ

it's a product of the Internet Engineering Task Force (IETF), which means it has consensus from the whole IETF community. it got public review and was approved for publication by the Internet Engineering Steering Group (IESG) πŸ‘‘ if you want more on Internet Standards, check out Section 2 of RFC 7841.

all the current status info, errata, and how to send feedback lives at https://www.rfc-editor.org/info/rfc8441 πŸ“

Copyright (c) 2018 IETF Trust and the persons identified as the document authors. All rights reserved. πŸŽ€

this doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they stand on the publication date. read them carefully, because they explain your rights and restrictions for this doc πŸ™ˆ any Code Components pulled out of this doc have to include the Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as described in the Simplified BSD License ⭐

Table of Contents πŸ—‚οΈ

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   2
2.  Terminology . . . . . . . . . . . . . . . . . . . . . . . . .   3
3.  The SETTINGS_ENABLE_CONNECT_PROTOCOL SETTINGS Parameter . . .   3
4.  The Extended CONNECT Method . . . . . . . . . . . . . . . . .   4
5.  Using Extended CONNECT to Bootstrap the WebSocket Protocol  .   4
  5.1.  Example . . . . . . . . . . . . . . . . . . . . . . . . .   6
6.  Design Considerations . . . . . . . . . . . . . . . . . . . .   6
7.  About Intermediaries  . . . . . . . . . . . . . . . . . . . .   6
8.  Security Considerations . . . . . . . . . . . . . . . . . . .   7
9.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .   7
  9.1.  A New HTTP/2 Setting  . . . . . . . . . . . . . . . . . .   7
  9.2.  A New HTTP Upgrade Token  . . . . . . . . . . . . . . . .   7
10. Normative References  . . . . . . . . . . . . . . . . . . . .   8
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . .   8
Author's Address  . . . . . . . . . . . . . . . . . . . . . . . .   8

1. Introduction ✨

HTTP [RFC7230] keeps resource-level semantics compatible across different versions, but it doesn't keep connection-management compatible 😭 so any protocol that leans on HTTP's connection-management details, like WebSockets, has to get updated for every new HTTP version.

the WebSocket Protocol [RFC6455] uses the HTTP/1.1 Upgrade mechanism (Section 6.7 of [RFC7230]) to switch a TCP connection from HTTP over to WebSocket. HTTP/2 [RFC7540] needs a totally different approach πŸ’… because it multiplexes, it doesn't allow connection-wide header fields or status codes. that means no Upgrade or Connection request-header fields, and no 101 (Switching Protocols) response code. the [RFC6455] opening handshake needs all of those, so it can't just be copied over as is πŸ™ƒ

bootstrapping WebSockets from HTTP/2 means one TCP connection can be shared by both protocols, and it brings HTTP/2's more efficient use of the network over to WebSockets too πŸš€

this document extends the HTTP CONNECT method, as specified for HTTP/2 in Section 8.3 of [RFC7540] πŸ”Œ the extension lets you swap in a new protocol name to connect to, instead of the external host CONNECT normally uses. the result is a tunnel on a single HTTP/2 stream that can carry WebSocket data (or data for any other protocol). the other streams on that connection can carry more extended CONNECT tunnels, regular HTTP/2 data, or a mix of both 🌈

the tunneled stream gets multiplexed with the other regular streams, and it gets all the normal HTTP/2 perks: priority, cancellation, and flow control πŸ’–

once a stream successfully sets up a WebSocket connection through a tunneled stream, using the opening handshake changes defined here, it uses the traditional WebSocket Protocol. it treats the stream like it's the TCP connection from that spec, and honestly that's iconic πŸ¦‹

2. Terminology πŸ“–

okay, here's the fine print for the vibe check πŸ’… the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here πŸŽ€

3. The SETTINGS_ENABLE_CONNECT_PROTOCOL SETTINGS Parameter βš™οΈ

this doc adds a brand new SETTINGS parameter on top of the ones defined in [RFC7540], Section 6.5.2 🧚

the new parameter is called SETTINGS_ENABLE_CONNECT_PROTOCOL. its value MUST be 0 or 1 πŸ”₯

when a client gets SETTINGS_ENABLE_CONNECT_PROTOCOL with a value of 1, it MAY use the Extended CONNECT (as defined in this document) when it creates new streams. if a server receives this parameter, nothing changes for it πŸ™ˆ

a sender MUST NOT send a SETTINGS_ENABLE_CONNECT_PROTOCOL parameter with the value 0 after it already sent a value of 1. no take-backs πŸ’…

using a SETTINGS parameter to opt into an otherwise incompatible protocol change counts as "Extending HTTP/2," as defined in Section 5.5 of [RFC7540]. specifically, adding the new pseudo-header field :protocol and changing what the :authority pseudo-header field means (see Section 4) both need opt-in negotiation 🫢

if a client used the extended CONNECT method from this document without first receiving the SETTINGS_ENABLE_CONNECT_PROTOCOL parameter, a peer that doesn't support it would see a malformed request and send back a stream error (Section 8.1.2.6 of [RFC7540]). rip to that peer πŸ’€

4. The Extended CONNECT Method πŸ”Œ

the CONNECT method in HTTP/2 is defined in Section 8.3 of [RFC7540], and this extension changes it in a few ways:

  • a new pseudo-header field :protocol MAY be included on request HEADERS to say which protocol should be spoken on the tunnel that CONNECT creates. the pseudo-header field is single valued, and its value comes from the "Hypertext Transfer Protocol (HTTP) Upgrade Token Registry" at <https://www.iana.org/assignments/http-upgrade-tokens/> 🌸
  • on requests that contain the :protocol pseudo-header field, the :scheme and :path pseudo-header fields of the target URI (see Section 5) MUST also be included πŸ“
  • on requests with the :protocol pseudo-header field, the :authority pseudo-header field gets read according to Section 8.1.2.3 of [RFC7540], not Section 8.3 of that doc. the big deal here is that the server MUST NOT create a tunnel to the host named in :authority, which is different from a plain CONNECT request that this extension doesn't touch 😭

when a server gets a CONNECT request with the :protocol pseudo-header field, it sets up a tunnel to another service of the protocol type named in that field. that service might be on the same machine as the server, or it might not 🧚

7. About Intermediaries 🧚

okay so this part is about proxies 🫢 this doc does NOT change how WebSockets vibes with HTTP forward proxies. if a client that wants WebSockets connects over HTTP/2 to an HTTP proxy, it should keep using a regular CONNECT (so no :protocol pseudo-header field, bestie) to tunnel through that proxy to the WebSocket server over HTTP.

the version of HTTP running on that tunnel is what decides whether WebSockets gets started directly or through the modified CONNECT request this doc describes. it's giving "the tunnel has the final say" πŸ’…βœ¨

8. Security Considerations πŸ”’

okay, serious moment, no bits 😭 [RFC6455] makes sure that non-WebSockets clients, especially XMLHttpRequest-based ones, can't make a WebSocket connection πŸ™…β€β™€οΈ its main trick is using Sec-prefixed request-header fields that XMLHttpRequest-based clients can't create. this spec handles that worry in two ways:

  • XMLHttpRequest also prohibits use of the CONNECT method in addition to Sec-prefixed request-header fields.
  • The use of a pseudo-header field is connection specific, and HTTP/2 never allows a pseudo-header to be created outside of the protocol stack.
The security considerations of [RFC6455], Section 10 still apply when you use this spec πŸ›‘οΈ the only exception is 10.8. that section doesn't matter here because it's all about the bootstrapping handshake, and this doc changes that handshake. so skip 10.8, but read the rest like your life depends on it πŸ’€

9. IANA Considerations πŸ“‹

9.1. A New HTTP/2 Setting 🌸

this doc adds an entry to the "HTTP/2 Settings" registry that was set up by Section 11.3 of [RFC7540] πŸ’–

   Code: 0x8
   Name: SETTINGS_ENABLE_CONNECT_PROTOCOL
   Initial Value: 0
   Specification: This document

9.2. A New HTTP Upgrade Token πŸ¦‹

this doc also adds an entry to the "HTTP Upgrade Tokens" registry, which was set up by [RFC7230] πŸŽ€

   Value: websocket
   Description: The Web Socket Protocol
   Expected Version Tokens:
   References: [RFC6455] [RFC8441]

10. Normative References πŸ“š

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <https://www.rfc-editor.org/info/rfc2119>.

   [RFC6454]  Barth, A., "The Web Origin Concept", RFC 6454,
              DOI 10.17487/RFC6454, December 2011,
              <https://www.rfc-editor.org/info/rfc6454>.

   [RFC6455]  Fette, I. and A. Melnikov, "The WebSocket Protocol",
              RFC 6455, DOI 10.17487/RFC6455, December 2011,
              <https://www.rfc-editor.org/info/rfc6455>.

   [RFC7230]  Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
              Protocol (HTTP/1.1): Message Syntax and Routing",
              RFC 7230, DOI 10.17487/RFC7230, June 2014,
              <https://www.rfc-editor.org/info/rfc7230>.

   [RFC7540]  Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext
              Transfer Protocol Version 2 (HTTP/2)", RFC 7540,
              DOI 10.17487/RFC7540, May 2015,
              <https://www.rfc-editor.org/info/rfc7540>.

   [RFC8164]  Nottingham, M. and M. Thomson, "Opportunistic Security for
              HTTP/2", RFC 8164, DOI 10.17487/RFC8164, May 2017,
              <https://www.rfc-editor.org/info/rfc8164>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              May 2017, <https://www.rfc-editor.org/info/rfc8174>.

Acknowledgments πŸ™Œ

the 2017 HTTP Workshop had a super productive discussion that helped nail down the key problem and how complicated the solution was allowed to get ✨

Author's Address πŸ’Œ

   Patrick McManus
   Mozilla

   Email: mcmanus@ducksong.com
πŸ“¦ where this page comes from