Skip to content

Support WebSockets over HTTP/2 via RFC 8441 Extended CONNECT #1112

Description

@mkurz

Problem

Pekko HTTP supports HTTP/2 and WebSockets, but WebSocket support currently appears to be limited to the classic HTTP/1.1 upgrade handshake.

RFC 8441 defines how to bootstrap WebSockets over HTTP/2 using Extended CONNECT:

  • server advertises SETTINGS_ENABLE_CONNECT_PROTOCOL = 1
  • client sends :method = CONNECT
  • client sends :protocol = websocket
  • request also includes :scheme, :path, and :authority
  • server accepts with :status = 200
  • WebSocket frames are then carried over the HTTP/2 stream

This would allow applications to serve HTTP/2 requests and WebSockets on the same HTTP/2 connection instead of falling back to a separate HTTP/1.1 WebSocket upgrade connection.

RFC: https://www.rfc-editor.org/rfc/rfc8441.html

Current Behavior

Pekko HTTP WebSocket handling is based on the HTTP/1.1 upgrade model:

  • request validation expects Upgrade: websocket, Connection: Upgrade, Sec-WebSocket-Key, and Sec-WebSocket-Version
  • accepted WebSockets return 101 Switching Protocols
  • the existing WebSocketUpgrade API represents upgrading the connection to WebSocket

That matches RFC 6455 over HTTP/1.1, but not RFC 8441 over HTTP/2.

Expected Behavior

When HTTP/2 is enabled, Pekko HTTP should optionally support RFC 8441 WebSockets over HTTP/2.

At a high level this likely means:

  • advertise SETTINGS_ENABLE_CONNECT_PROTOCOL = 1 when server-side support is enabled
  • accept HTTP/2 Extended CONNECT requests with :protocol = websocket
  • expose those requests to routing / low-level APIs similarly to existing WebSocket upgrade requests
  • allow existing handleWebSocketMessages / WebSocketUpgrade style APIs to work where practical
  • respond with HTTP/2 :status = 200 when the WebSocket is accepted
  • connect the existing WebSocket frame/message stack to the HTTP/2 stream DATA flow
  • map HTTP/2 stream end/reset/failure semantics sensibly to WebSocket close behavior

Motivation

Modern browsers support WebSockets over HTTP/2 via RFC 8441. Supporting this in Pekko HTTP would allow one server port and one HTTP/2 connection to handle both normal HTTP traffic and WebSockets.

This is useful for frameworks built on Pekko HTTP as well. For example, Play Framework can enable HTTP/2 on its Pekko HTTP backend, but WebSocket support still depends on the HTTP/1.1 upgrade path because Pekko HTTP does not currently expose RFC 8441 WebSocket support.

Notes

Netty has already added several low-level RFC 8441 building blocks, but still tracks high-level WebSocket-over-HTTP/2 support as an open feature request:

A third-party Netty implementation also exists:

Questions

  • Would the Pekko HTTP project be open to RFC 8441 server-side support?
  • Should this be implemented behind an explicit config flag, for example under pekko.http.server.websocket or pekko.http.server.http2?
  • Should the existing WebSocketUpgrade API be reused for HTTP/2 Extended CONNECT, or should there be a separate API to distinguish HTTP/1.1 upgrade from HTTP/2 stream-based WebSocket bootstrap?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions