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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions