mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-27 14:58:46 +00:00
This adds support for WebSocket subprotocols to WebSocket DOM objects, with some necessary plumbing to LibWebSocket and its clients. See the associated pull request for how this was tested.
100 lines
3.4 KiB
C++
100 lines
3.4 KiB
C++
/*
|
|
* Copyright (c) 2021, Dex♪ <dexes.ttp@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibProtocol/WebSocket.h>
|
|
#include <LibProtocol/WebSocketClient.h>
|
|
|
|
namespace Protocol {
|
|
|
|
WebSocketClient::WebSocketClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
|
: IPC::ConnectionToServer<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, move(socket))
|
|
{
|
|
}
|
|
|
|
RefPtr<WebSocket> WebSocketClient::connect(const URL& url, DeprecatedString const& origin, Vector<DeprecatedString> const& protocols, Vector<DeprecatedString> const& extensions, HashMap<DeprecatedString, DeprecatedString> const& request_headers)
|
|
{
|
|
IPC::Dictionary header_dictionary;
|
|
for (auto& it : request_headers)
|
|
header_dictionary.add(it.key, it.value);
|
|
auto connection_id = IPCProxy::connect(url, origin, protocols, extensions, header_dictionary);
|
|
if (connection_id < 0)
|
|
return nullptr;
|
|
auto connection = WebSocket::create_from_id({}, *this, connection_id);
|
|
m_connections.set(connection_id, connection);
|
|
return connection;
|
|
}
|
|
|
|
u32 WebSocketClient::ready_state(Badge<WebSocket>, WebSocket& connection)
|
|
{
|
|
if (!m_connections.contains(connection.id()))
|
|
return (u32)WebSocket::ReadyState::Closed;
|
|
return IPCProxy::ready_state(connection.id());
|
|
}
|
|
|
|
DeprecatedString WebSocketClient::subprotocol_in_use(Badge<WebSocket>, WebSocket& connection)
|
|
{
|
|
if (!m_connections.contains(connection.id()))
|
|
return DeprecatedString::empty();
|
|
return IPCProxy::subprotocol_in_use(connection.id());
|
|
}
|
|
|
|
void WebSocketClient::send(Badge<WebSocket>, WebSocket& connection, ByteBuffer data, bool is_text)
|
|
{
|
|
if (!m_connections.contains(connection.id()))
|
|
return;
|
|
async_send(connection.id(), is_text, move(data));
|
|
}
|
|
|
|
void WebSocketClient::close(Badge<WebSocket>, WebSocket& connection, u16 code, DeprecatedString message)
|
|
{
|
|
if (!m_connections.contains(connection.id()))
|
|
return;
|
|
async_close(connection.id(), code, move(message));
|
|
}
|
|
|
|
bool WebSocketClient::set_certificate(Badge<WebSocket>, WebSocket& connection, DeprecatedString certificate, DeprecatedString key)
|
|
{
|
|
if (!m_connections.contains(connection.id()))
|
|
return false;
|
|
return IPCProxy::set_certificate(connection.id(), move(certificate), move(key));
|
|
}
|
|
|
|
void WebSocketClient::connected(i32 connection_id)
|
|
{
|
|
auto maybe_connection = m_connections.get(connection_id);
|
|
if (maybe_connection.has_value())
|
|
maybe_connection.value()->did_open({});
|
|
}
|
|
|
|
void WebSocketClient::received(i32 connection_id, bool is_text, ByteBuffer const& data)
|
|
{
|
|
auto maybe_connection = m_connections.get(connection_id);
|
|
if (maybe_connection.has_value())
|
|
maybe_connection.value()->did_receive({}, data, is_text);
|
|
}
|
|
|
|
void WebSocketClient::errored(i32 connection_id, i32 message)
|
|
{
|
|
auto maybe_connection = m_connections.get(connection_id);
|
|
if (maybe_connection.has_value())
|
|
maybe_connection.value()->did_error({}, message);
|
|
}
|
|
|
|
void WebSocketClient::closed(i32 connection_id, u16 code, DeprecatedString const& reason, bool clean)
|
|
{
|
|
auto maybe_connection = m_connections.get(connection_id);
|
|
if (maybe_connection.has_value())
|
|
maybe_connection.value()->did_close({}, code, reason, clean);
|
|
}
|
|
|
|
void WebSocketClient::certificate_requested(i32 connection_id)
|
|
{
|
|
auto maybe_connection = m_connections.get(connection_id);
|
|
if (maybe_connection.has_value())
|
|
maybe_connection.value()->did_request_certificates({});
|
|
}
|
|
|
|
}
|