Skip to content

End server handshake error responses and answer 426 for other versions - #624

Open
wleeaf wants to merge 1 commit into
machinezone:masterfrom
wleeaf:server-handshake-error-responses
Open

wleeaf wants to merge 1 commit into
machinezone:masterfrom
wleeaf:server-handshake-error-responses

Conversation

@wleeaf

@wleeaf wleeaf commented Oct 25, 2026

Copy link
Copy Markdown

When the server rejects a WebSocket handshake, WebSocketHandshake::sendErrorResponse writes the status line and the Server header, but not the empty line that ends the header section. For example, a request without Sec-WebSocket-Key gets exactly these bytes before the connection closes:

HTTP/1.1 400 Missing Sec-WebSocket-Key value\r\n
Server: ixwebsocket/12.1.0 linux nossl zlib 1.3\r\n

That's an incomplete HTTP response. A client can only treat it as finished once the connection drops, and strict HTTP clients report it as truncated.

Also, a client asking for a WebSocket version other than 13 gets a 400 without a Sec-WebSocket-Version header. RFC 6455 section 4.2.2 says that in this case the server sends an appropriate error code (such as 426 Upgrade Required) and a Sec-WebSocket-Version header with the versions it understands, so the client can retry with one of them (section 4.4).

This change:

  • makes sendErrorResponse end the header section, and adds an optional extraHeaders argument;
  • answers an unsupported Sec-WebSocket-Version with 426 and Sec-WebSocket-Version: 13. The reason text and the WebSocketInitResult error message are unchanged.

The new section in test/IXWebSocketServerTest.cpp sends Sec-WebSocket-Version: 8. It expects a 426, the Sec-WebSocket-Version: 13 header, and the empty line that ends the headers. Without the change it fails (400 == 426). All 22 ctest tests pass with the change (Linux, USE_TLS=0), and git clang-format reports nothing for the change.

sendErrorResponse wrote the status line and the Server header but not
the empty line that ends the header section, so every rejected
handshake produced an incomplete HTTP response that a client could only
end by waiting for the connection to close. A client asking for a
WebSocket version other than 13 got 400 without a Sec-WebSocket-Version
header, which RFC 6455 (section 4.2.2) requires so the client knows
which version to use.

Error responses now end with an empty line, and an unsupported version
is answered with 426 and Sec-WebSocket-Version: 13.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant