Skip to content

connectd websocket: HTTP handshake headers matched case-sensitively, rejecting RFC-compliant clients #9307

Description

@coreyphillips

Issue

connectd/websocketd.c matches HTTP header names byte-exactly (get_http_hdr uses memstarts) and matches the Upgrade/Connection values with case-sensitive strstr. RFC 9110 section 5.1 makes field names case-insensitive, and the RFC 6455 excerpt quoted in the file itself says the Upgrade and Connection values are "treated as an ASCII case-insensitive value".

Practical impact: Node.js's built-in WebSocket (undici) sends lowercased request headers, so it can never connect to a bind-addr=ws: listener. Any other client that normalizes header casing fails the same way.

Steps to reproduce

Against v26.06.1 with bind-addr=ws:0.0.0.0:19847:

printf 'GET / HTTP/1.1\r\nhost: x\r\nupgrade: websocket\r\nconnection: Upgrade\r\nsec-websocket-key: dGhlIHNhbXBsZSBub25jZQ==\r\nsec-websocket-version: 13\r\n\r\n' | nc <host> 19847

returns:

HTTP/1.1 400 I only speak websocket
Upgrade: websocket missing

The identical request with RFC-cased header names (Upgrade, Connection, Sec-WebSocket-Key, Sec-WebSocket-Version) succeeds with 101 Switching Protocols. new WebSocket('ws://<host>:19847') from Node 22 fails the same way, while browsers happen to send RFC casing and work.

PR with a fix to follow shortly.

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