Serenity Operating System
1/*
2 * Copyright (c) 2021, Dex♪ <dexes.ttp@gmail.com>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <LibProtocol/WebSocket.h>
8#include <LibProtocol/WebSocketClient.h>
9
10namespace Protocol {
11
12WebSocketClient::WebSocketClient(NonnullOwnPtr<Core::LocalSocket> socket)
13 : IPC::ConnectionToServer<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, move(socket))
14{
15}
16
17RefPtr<WebSocket> WebSocketClient::connect(const URL& url, DeprecatedString const& origin, Vector<DeprecatedString> const& protocols, Vector<DeprecatedString> const& extensions, HashMap<DeprecatedString, DeprecatedString> const& request_headers)
18{
19 IPC::Dictionary header_dictionary;
20 for (auto& it : request_headers)
21 header_dictionary.add(it.key, it.value);
22 auto connection_id = IPCProxy::connect(url, origin, protocols, extensions, header_dictionary);
23 if (connection_id < 0)
24 return nullptr;
25 auto connection = WebSocket::create_from_id({}, *this, connection_id);
26 m_connections.set(connection_id, connection);
27 return connection;
28}
29
30u32 WebSocketClient::ready_state(Badge<WebSocket>, WebSocket& connection)
31{
32 if (!m_connections.contains(connection.id()))
33 return (u32)WebSocket::ReadyState::Closed;
34 return IPCProxy::ready_state(connection.id());
35}
36
37DeprecatedString WebSocketClient::subprotocol_in_use(Badge<WebSocket>, WebSocket& connection)
38{
39 if (!m_connections.contains(connection.id()))
40 return DeprecatedString::empty();
41 return IPCProxy::subprotocol_in_use(connection.id());
42}
43
44void WebSocketClient::send(Badge<WebSocket>, WebSocket& connection, ByteBuffer data, bool is_text)
45{
46 if (!m_connections.contains(connection.id()))
47 return;
48 async_send(connection.id(), is_text, move(data));
49}
50
51void WebSocketClient::close(Badge<WebSocket>, WebSocket& connection, u16 code, DeprecatedString message)
52{
53 if (!m_connections.contains(connection.id()))
54 return;
55 async_close(connection.id(), code, move(message));
56}
57
58bool WebSocketClient::set_certificate(Badge<WebSocket>, WebSocket& connection, DeprecatedString certificate, DeprecatedString key)
59{
60 if (!m_connections.contains(connection.id()))
61 return false;
62 return IPCProxy::set_certificate(connection.id(), move(certificate), move(key));
63}
64
65void WebSocketClient::connected(i32 connection_id)
66{
67 auto maybe_connection = m_connections.get(connection_id);
68 if (maybe_connection.has_value())
69 maybe_connection.value()->did_open({});
70}
71
72void WebSocketClient::received(i32 connection_id, bool is_text, ByteBuffer const& data)
73{
74 auto maybe_connection = m_connections.get(connection_id);
75 if (maybe_connection.has_value())
76 maybe_connection.value()->did_receive({}, data, is_text);
77}
78
79void WebSocketClient::errored(i32 connection_id, i32 message)
80{
81 auto maybe_connection = m_connections.get(connection_id);
82 if (maybe_connection.has_value())
83 maybe_connection.value()->did_error({}, message);
84}
85
86void WebSocketClient::closed(i32 connection_id, u16 code, DeprecatedString const& reason, bool clean)
87{
88 auto maybe_connection = m_connections.get(connection_id);
89 if (maybe_connection.has_value())
90 maybe_connection.value()->did_close({}, code, reason, clean);
91}
92
93void WebSocketClient::certificate_requested(i32 connection_id)
94{
95 auto maybe_connection = m_connections.get(connection_id);
96 if (maybe_connection.has_value())
97 maybe_connection.value()->did_request_certificates({});
98}
99
100}