invalid session over websocket: the client never got to know
Whoever connected with an expired session received an ordinary http response
with an html page inside. To the browser WebSocket API that is just a failed
upgrade, whose content it cannot read: the client never learned it had to go
back to the login, and retried forever with a red indicator. On xhr, instead,
the same case had always worked.
The root is in Transport::gettype(), which did not know "websocketsec": the
encrypted variant uses the same Transport_websocket class, told apart only in
the constructor (create() does treat them together). Missing from the list, it
fell back on Transport_iframe, that is on an html page.
Three places that contributed to the same symptom were fixed:
- Transport::gettype() recognises websocketsec;
- stream_fini() completes the handshake when the transport is websocket, so
that the exit command arrives as a real message over an established
connection, instead of as the body of a response nobody will read;
- Transport_websocket::fini() frames the message, which used to go out raw.
On top of that, in the table path the farewell was built with $transp_type,
which is the transport guessed from the User-Agent and not the requested one:
for a websocket client it was "xhr".
Checked: with a session that does not exist the answer is now 101 Switching
Protocols with a text frame (0x81) carrying the command to go back to the
login and the close frame right after, both for websocket and for
websocketsec. With a valid session the stream stays open and receives its
frames as before.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014M1jiEq9cHdE5SE5j6vFuE