LibWebSocket+RequestServer: Handle connection drop during closing

This fixes a race condition where a WebSocket would report a fatal
connection error instead of a clean close when the server dropped the
underlying connection immediately after sending a Close frame.

This fixes various timeouts in WPT, such as in:

https://wpt.live/websockets/Send-null.any.worker.html?wss
This commit is contained in:
Shannon Booth
2026-03-09 16:17:45 +01:00
committed by Shannon Booth
parent a1a9ff6bf5
commit c4c0afe4d7
Notes: github-actions[bot] 2026-03-13 16:29:22 +00:00
2 changed files with 16 additions and 0 deletions

View File

@@ -35,6 +35,17 @@ void WebSocket::start()
m_impl = adopt_ref(*new WebSocketImplSerenity);
m_impl->on_connection_error = [this] {
if (m_state == InternalState::Closing) {
// If the connection drops while we are waiting for the server's close frame, check if we actually received
// one in the last read. If we did, we can consider this a clean close.
bool was_clean = m_last_close_code != to_underlying(CloseStatusCode::NoStatusReceived);
set_state(was_clean ? InternalState::Closed : InternalState::Errored);
if (!was_clean)
notify_error(Error::ServerClosedSocket);
notify_close(m_last_close_code, m_last_close_message, was_clean);
discard_connection();
return;
}
dbgln("WebSocket: Connection error (underlying socket)");
fatal_error(WebSocket::Error::CouldNotEstablishConnection);
};