diff --git a/Libraries/LibWebSocket/WebSocket.cpp b/Libraries/LibWebSocket/WebSocket.cpp index 3b1c56836a..49e16df54e 100644 --- a/Libraries/LibWebSocket/WebSocket.cpp +++ b/Libraries/LibWebSocket/WebSocket.cpp @@ -8,12 +8,15 @@ #include #include #include +#include #include #include #include namespace WebSocket { +static constexpr int s_closing_handshake_timeout_ms = 30'000; + // Note : The websocket protocol is defined by RFC 6455, found at https://tools.ietf.org/html/rfc6455 // In this file, section numbers will refer to the RFC 6455 @@ -703,6 +706,21 @@ void WebSocket::set_state(InternalState state) return; auto old_ready_state = ready_state(); m_state = state; + + if (state == InternalState::Closing) { + if (!m_closing_handshake_timer) { + m_closing_handshake_timer = Core::Timer::create_single_shot(s_closing_handshake_timeout_ms, [this] { + if (m_state != InternalState::Closing) + return; + fail_connection(to_underlying(CloseStatusCode::AbnormalClosure), WebSocket::Error::ServerClosedSocket, "Timed out waiting for the peer's close frame"); + }); + } else { + m_closing_handshake_timer->restart(s_closing_handshake_timeout_ms); + } + } else if (m_closing_handshake_timer) { + m_closing_handshake_timer->stop(); + } + auto new_ready_state = ready_state(); if (old_ready_state != new_ready_state) { if (on_ready_state_change) diff --git a/Libraries/LibWebSocket/WebSocket.h b/Libraries/LibWebSocket/WebSocket.h index 47470b9aaa..f9c05ed65a 100644 --- a/Libraries/LibWebSocket/WebSocket.h +++ b/Libraries/LibWebSocket/WebSocket.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -132,6 +133,7 @@ private: ConnectionInfo m_connection; RefPtr m_impl; + RefPtr m_closing_handshake_timer; Vector m_buffered_data; ByteBuffer m_fragmented_data_buffer;