RequestServer: Make WebSocket IPC APIs asynchronous

This fixes deadlocking when interacting with WebSockets while
RequestServer is trying to stream downloaded data to WebContent.
This commit is contained in:
Andreas Kling 2024-09-18 10:28:55 +02:00 committed by Andreas Kling
commit e205723b95
Notes: github-actions[bot] 2024-09-19 05:38:37 +00:00
10 changed files with 129 additions and 94 deletions

View file

@ -96,45 +96,61 @@ void RequestClient::certificate_requested(i32 request_id)
RefPtr<WebSocket> RequestClient::websocket_connect(const URL::URL& url, ByteString const& origin, Vector<ByteString> const& protocols, Vector<ByteString> const& extensions, HTTP::HeaderMap const& request_headers)
{
auto connection_id = IPCProxy::websocket_connect(url, origin, protocols, extensions, request_headers);
if (connection_id < 0)
return nullptr;
auto connection = WebSocket::create_from_id({}, *this, connection_id);
m_websockets.set(connection_id, connection);
auto websocket_id = m_next_websocket_id++;
IPCProxy::async_websocket_connect(websocket_id, url, origin, protocols, extensions, request_headers);
auto connection = WebSocket::create_from_id({}, *this, websocket_id);
m_websockets.set(websocket_id, connection);
return connection;
}
void RequestClient::websocket_connected(i32 connection_id)
void RequestClient::websocket_connected(i64 websocket_id)
{
auto maybe_connection = m_websockets.get(connection_id);
auto maybe_connection = m_websockets.get(websocket_id);
if (maybe_connection.has_value())
maybe_connection.value()->did_open({});
}
void RequestClient::websocket_received(i32 connection_id, bool is_text, ByteBuffer const& data)
void RequestClient::websocket_received(i64 websocket_id, bool is_text, ByteBuffer const& data)
{
auto maybe_connection = m_websockets.get(connection_id);
auto maybe_connection = m_websockets.get(websocket_id);
if (maybe_connection.has_value())
maybe_connection.value()->did_receive({}, data, is_text);
}
void RequestClient::websocket_errored(i32 connection_id, i32 message)
void RequestClient::websocket_errored(i64 websocket_id, i32 message)
{
auto maybe_connection = m_websockets.get(connection_id);
auto maybe_connection = m_websockets.get(websocket_id);
if (maybe_connection.has_value())
maybe_connection.value()->did_error({}, message);
}
void RequestClient::websocket_closed(i32 connection_id, u16 code, ByteString const& reason, bool clean)
void RequestClient::websocket_closed(i64 websocket_id, u16 code, ByteString const& reason, bool clean)
{
auto maybe_connection = m_websockets.get(connection_id);
auto maybe_connection = m_websockets.get(websocket_id);
if (maybe_connection.has_value())
maybe_connection.value()->did_close({}, code, reason, clean);
}
void RequestClient::websocket_certificate_requested(i32 connection_id)
void RequestClient::websocket_ready_state_changed(i64 websocket_id, u32 ready_state)
{
auto maybe_connection = m_websockets.get(connection_id);
auto maybe_connection = m_websockets.get(websocket_id);
if (maybe_connection.has_value()) {
VERIFY(ready_state <= static_cast<u32>(WebSocket::ReadyState::Closed));
maybe_connection.value()->set_ready_state(static_cast<WebSocket::ReadyState>(ready_state));
}
}
void RequestClient::websocket_subprotocol(i64 websocket_id, ByteString const& subprotocol)
{
auto maybe_connection = m_websockets.get(websocket_id);
if (maybe_connection.has_value()) {
maybe_connection.value()->set_subprotocol_in_use(subprotocol);
}
}
void RequestClient::websocket_certificate_requested(i64 websocket_id)
{
auto maybe_connection = m_websockets.get(websocket_id);
if (maybe_connection.has_value())
maybe_connection.value()->did_request_certificates({});
}