mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-01 07:35:02 +03:00
5e1499d104
This commit un-deprecates DeprecatedString, and repurposes it as a byte string. As the null state has already been removed, there are no other particularly hairy blockers in repurposing this type as a byte string (what it _really_ is). This commit is auto-generated: $ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \ Meta Ports Ladybird Tests Kernel) $ perl -pie 's/\bDeprecatedString\b/ByteString/g; s/deprecated_string/byte_string/g' $xs $ clang-format --style=file -i \ $(git diff --name-only | grep \.cpp\|\.h) $ gn format $(git ls-files '*.gn' '*.gni')
145 lines
4.5 KiB
C++
145 lines
4.5 KiB
C++
/*
|
|
* Copyright (c) 2021, Dex♪ <dexes.ttp@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibWebSocket/ConnectionInfo.h>
|
|
#include <LibWebSocket/Message.h>
|
|
#include <WebSocket/ConnectionFromClient.h>
|
|
#include <WebSocket/WebSocketClientEndpoint.h>
|
|
|
|
namespace WebSocket {
|
|
|
|
static HashMap<int, RefPtr<ConnectionFromClient>> s_connections;
|
|
|
|
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket)
|
|
: IPC::ConnectionFromClient<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, move(socket), 1)
|
|
{
|
|
s_connections.set(1, *this);
|
|
}
|
|
|
|
void ConnectionFromClient::die()
|
|
{
|
|
s_connections.remove(client_id());
|
|
if (s_connections.is_empty())
|
|
Core::EventLoop::current().quit(0);
|
|
}
|
|
|
|
Messages::WebSocketServer::ConnectResponse ConnectionFromClient::connect(URL const& url, ByteString const& origin,
|
|
Vector<ByteString> const& protocols, Vector<ByteString> const& extensions, HashMap<ByteString, ByteString> const& additional_request_headers)
|
|
{
|
|
if (!url.is_valid()) {
|
|
dbgln("WebSocket::Connect: Invalid URL requested: '{}'", url);
|
|
return -1;
|
|
}
|
|
|
|
ConnectionInfo connection_info(url);
|
|
connection_info.set_origin(origin);
|
|
connection_info.set_protocols(protocols);
|
|
connection_info.set_extensions(extensions);
|
|
|
|
Vector<ConnectionInfo::Header> headers;
|
|
for (auto const& header : additional_request_headers) {
|
|
headers.append({ header.key, header.value });
|
|
}
|
|
connection_info.set_headers(headers);
|
|
|
|
VERIFY(m_connection_ids < NumericLimits<i32>::max());
|
|
auto id = ++m_connection_ids;
|
|
auto connection = WebSocket::create(move(connection_info));
|
|
connection->on_open = [this, id]() {
|
|
did_connect(id);
|
|
};
|
|
connection->on_message = [this, id](auto message) {
|
|
did_receive_message(id, move(message));
|
|
};
|
|
connection->on_error = [this, id](auto message) {
|
|
did_error(id, (i32)message);
|
|
};
|
|
connection->on_close = [this, id](u16 code, ByteString reason, bool was_clean) {
|
|
did_close(id, code, move(reason), was_clean);
|
|
};
|
|
|
|
connection->start();
|
|
m_connections.set(id, move(connection));
|
|
return id;
|
|
}
|
|
|
|
Messages::WebSocketServer::ReadyStateResponse ConnectionFromClient::ready_state(i32 connection_id)
|
|
{
|
|
RefPtr<WebSocket> connection = m_connections.get(connection_id).value_or({});
|
|
if (connection) {
|
|
return (u32)connection->ready_state();
|
|
}
|
|
return (u32)ReadyState::Closed;
|
|
}
|
|
|
|
Messages::WebSocketServer::SubprotocolInUseResponse ConnectionFromClient::subprotocol_in_use(i32 connection_id)
|
|
{
|
|
RefPtr<WebSocket> connection = m_connections.get(connection_id).value_or({});
|
|
if (connection) {
|
|
return connection->subprotocol_in_use();
|
|
}
|
|
return ByteString::empty();
|
|
}
|
|
|
|
void ConnectionFromClient::send(i32 connection_id, bool is_text, ByteBuffer const& data)
|
|
{
|
|
RefPtr<WebSocket> connection = m_connections.get(connection_id).value_or({});
|
|
if (connection && connection->ready_state() == ReadyState::Open) {
|
|
Message websocket_message(data, is_text);
|
|
connection->send(websocket_message);
|
|
}
|
|
}
|
|
|
|
void ConnectionFromClient::close(i32 connection_id, u16 code, ByteString const& reason)
|
|
{
|
|
RefPtr<WebSocket> connection = m_connections.get(connection_id).value_or({});
|
|
if (connection && connection->ready_state() == ReadyState::Open)
|
|
connection->close(code, reason);
|
|
}
|
|
|
|
Messages::WebSocketServer::SetCertificateResponse ConnectionFromClient::set_certificate(i32 connection_id,
|
|
[[maybe_unused]] ByteString const& certificate, [[maybe_unused]] ByteString const& key)
|
|
{
|
|
RefPtr<WebSocket> connection = m_connections.get(connection_id).value_or({});
|
|
bool success = false;
|
|
if (connection) {
|
|
// NO OP here
|
|
// connection->set_certificate(certificate, key);
|
|
success = true;
|
|
}
|
|
return success;
|
|
}
|
|
|
|
void ConnectionFromClient::did_connect(i32 connection_id)
|
|
{
|
|
async_connected(connection_id);
|
|
}
|
|
|
|
void ConnectionFromClient::did_receive_message(i32 connection_id, Message message)
|
|
{
|
|
async_received(connection_id, message.is_text(), message.data());
|
|
}
|
|
|
|
void ConnectionFromClient::did_error(i32 connection_id, i32 message)
|
|
{
|
|
async_errored(connection_id, message);
|
|
}
|
|
|
|
void ConnectionFromClient::did_close(i32 connection_id, u16 code, ByteString reason, bool was_clean)
|
|
{
|
|
async_closed(connection_id, code, reason, was_clean);
|
|
deferred_invoke([this, connection_id] {
|
|
m_connections.remove(connection_id);
|
|
});
|
|
}
|
|
|
|
void ConnectionFromClient::did_request_certificates(i32 connection_id)
|
|
{
|
|
async_certificate_requested(connection_id);
|
|
}
|
|
|
|
}
|