mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 02:42:44 +00:00 
			
		
		
		
	 d030f0fe9b
			
		
	
	
		d030f0fe9b
		
	
	
	
	
		
			
			We already have and use HashMap<DeprecatedString, DeprecatedString> nearly everywhere, which is equivalent.
		
			
				
	
	
		
			144 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
	
		
			4.6 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, DeprecatedString const& origin,
 | |
|     Vector<DeprecatedString> const& protocols, Vector<DeprecatedString> const& extensions, HashMap<DeprecatedString, DeprecatedString> 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, DeprecatedString 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 DeprecatedString::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, DeprecatedString 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]] DeprecatedString const& certificate, [[maybe_unused]] DeprecatedString 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, DeprecatedString 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);
 | |
| }
 | |
| 
 | |
| }
 |