ClientConnection.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * Copyright (c) 2021, Dex♪ <dexes.ttp@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Badge.h>
  7. #include <LibWebSocket/ConnectionInfo.h>
  8. #include <LibWebSocket/Message.h>
  9. #include <WebSocket/ClientConnection.h>
  10. #include <WebSocket/WebSocketClientEndpoint.h>
  11. namespace WebSocket {
  12. static HashMap<int, RefPtr<ClientConnection>> s_connections;
  13. ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket, int client_id)
  14. : IPC::ClientConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, move(socket), client_id)
  15. {
  16. s_connections.set(client_id, *this);
  17. }
  18. ClientConnection::~ClientConnection()
  19. {
  20. }
  21. void ClientConnection::die()
  22. {
  23. s_connections.remove(client_id());
  24. if (s_connections.is_empty())
  25. Core::EventLoop::current().quit(0);
  26. }
  27. void ClientConnection::handle(const Messages::WebSocketServer::Greet&)
  28. {
  29. }
  30. Messages::WebSocketServer::ConnectResponse ClientConnection::handle(const Messages::WebSocketServer::Connect& message)
  31. {
  32. const auto& url = message.url();
  33. if (!url.is_valid()) {
  34. dbgln("WebSocket::Connect: Invalid URL requested: '{}'", url);
  35. return -1;
  36. }
  37. ConnectionInfo connection_info(url);
  38. connection_info.set_origin(message.origin());
  39. connection_info.set_protocols(message.protocols());
  40. connection_info.set_extensions(message.extensions());
  41. Vector<ConnectionInfo::Header> headers;
  42. for (const auto& header : message.additional_request_headers().entries()) {
  43. headers.append({ header.key, header.value });
  44. }
  45. connection_info.set_headers(headers);
  46. VERIFY(m_connection_ids < NumericLimits<i32>::max());
  47. auto id = ++m_connection_ids;
  48. auto connection = WebSocket::create(move(connection_info));
  49. connection->on_open = [this, id]() {
  50. did_connect(id);
  51. };
  52. connection->on_message = [this, id](auto message) {
  53. did_receive_message(id, move(message));
  54. };
  55. connection->on_error = [this, id](auto message) {
  56. did_error(id, (i32)message);
  57. };
  58. connection->on_close = [this, id](u16 code, String reason, bool was_clean) {
  59. did_close(id, code, move(reason), was_clean);
  60. };
  61. connection->start();
  62. m_connections.set(id, move(connection));
  63. return id;
  64. }
  65. Messages::WebSocketServer::ReadyStateResponse ClientConnection::handle(const Messages::WebSocketServer::ReadyState& message)
  66. {
  67. RefPtr<WebSocket> connection = m_connections.get(message.connection_id()).value_or({});
  68. if (connection) {
  69. return (u32)connection->ready_state();
  70. }
  71. return (u32)ReadyState::Closed;
  72. }
  73. void ClientConnection::handle(const Messages::WebSocketServer::Send& message)
  74. {
  75. RefPtr<WebSocket> connection = m_connections.get(message.connection_id()).value_or({});
  76. if (connection && connection->ready_state() == ReadyState::Open) {
  77. Message websocket_message(message.data(), message.is_text());
  78. connection->send(websocket_message);
  79. }
  80. }
  81. void ClientConnection::handle(const Messages::WebSocketServer::Close& message)
  82. {
  83. RefPtr<WebSocket> connection = m_connections.get(message.connection_id()).value_or({});
  84. if (connection && connection->ready_state() == ReadyState::Open)
  85. connection->close(message.code(), message.reason());
  86. }
  87. Messages::WebSocketServer::SetCertificateResponse ClientConnection::handle(const Messages::WebSocketServer::SetCertificate& message)
  88. {
  89. RefPtr<WebSocket> connection = m_connections.get(message.connection_id()).value_or({});
  90. bool success = false;
  91. if (connection) {
  92. // NO OP here
  93. // connection->set_certificate(message.certificate(), message.key());
  94. success = true;
  95. }
  96. return success;
  97. }
  98. void ClientConnection::did_connect(i32 connection_id)
  99. {
  100. post_message(Messages::WebSocketClient::Connected(connection_id));
  101. }
  102. void ClientConnection::did_receive_message(i32 connection_id, Message message)
  103. {
  104. post_message(Messages::WebSocketClient::Received(connection_id, message.is_text(), message.data()));
  105. }
  106. void ClientConnection::did_error(i32 connection_id, i32 message)
  107. {
  108. post_message(Messages::WebSocketClient::Errored(connection_id, message));
  109. }
  110. void ClientConnection::did_close(i32 connection_id, u16 code, String reason, bool was_clean)
  111. {
  112. post_message(Messages::WebSocketClient::Closed(connection_id, code, reason, was_clean));
  113. deferred_invoke([this, connection_id] {
  114. m_connections.remove(connection_id);
  115. });
  116. }
  117. void ClientConnection::did_request_certificates(i32 connection_id)
  118. {
  119. post_message(Messages::WebSocketClient::CertificateRequested(connection_id));
  120. }
  121. }