| 
									
										
										
										
											2022-11-08 18:40:33 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2021, Dex♪ <dexes.ttp@gmail.com> | 
					
						
							|  |  |  |  * Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org> | 
					
						
							|  |  |  |  * Copyright (c) 2022, the SerenityOS developers. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <LibCore/EventLoop.h>
 | 
					
						
							| 
									
										
										
										
											2023-02-08 23:05:44 +01:00
										 |  |  | #include <LibCore/Socket.h>
 | 
					
						
							| 
									
										
										
										
											2024-11-21 02:47:45 +04:00
										 |  |  | #include <LibTLS/TLSv12.h>
 | 
					
						
							| 
									
										
										
										
											2022-11-08 18:40:33 +01:00
										 |  |  | #include <LibWebSocket/Impl/WebSocketImplSerenity.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace WebSocket { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | WebSocketImplSerenity::~WebSocketImplSerenity() = default; | 
					
						
							|  |  |  | WebSocketImplSerenity::WebSocketImplSerenity() = default; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool WebSocketImplSerenity::can_read_line() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return MUST(m_socket->can_read_line()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool WebSocketImplSerenity::send(ReadonlyBytes bytes) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-03-01 15:37:45 +01:00
										 |  |  |     return !m_socket->write_until_depleted(bytes).is_error(); | 
					
						
							| 
									
										
										
										
											2022-11-08 18:40:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool WebSocketImplSerenity::eof() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_socket->is_eof(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void WebSocketImplSerenity::discard_connection() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_socket = nullptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void WebSocketImplSerenity::connect(ConnectionInfo const& connection_info) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     VERIFY(!m_socket); | 
					
						
							|  |  |  |     VERIFY(on_connected); | 
					
						
							|  |  |  |     VERIFY(on_connection_error); | 
					
						
							|  |  |  |     VERIFY(on_ready_to_read); | 
					
						
							| 
									
										
										
										
											2023-02-08 23:05:44 +01:00
										 |  |  |     auto socket_result = [&]() -> ErrorOr<NonnullOwnPtr<Core::BufferedSocketBase>> { | 
					
						
							| 
									
										
										
										
											2024-11-28 14:32:07 +00:00
										 |  |  |         auto host = connection_info.url().serialized_host().to_byte_string(); | 
					
						
							| 
									
										
										
										
											2022-11-08 18:40:33 +01:00
										 |  |  |         if (connection_info.is_secure()) { | 
					
						
							| 
									
										
										
										
											2025-02-14 12:24:03 +01:00
										 |  |  |             TLS::Options options; | 
					
						
							|  |  |  |             options.set_root_certificates_path(connection_info.root_certificates_path()); | 
					
						
							| 
									
										
										
										
											2025-02-22 13:02:52 +01:00
										 |  |  |             options.set_blocking(false); | 
					
						
							| 
									
										
										
										
											2025-02-14 12:24:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-06 23:12:39 +02:00
										 |  |  |             return TRY(Core::BufferedSocket<TLS::TLSv12>::create( | 
					
						
							| 
									
										
										
										
											2025-02-14 12:24:03 +01:00
										 |  |  |                 TRY(TLS::TLSv12::connect(host, connection_info.url().port_or_default(), move(options))))); | 
					
						
							| 
									
										
										
										
											2022-11-08 18:40:33 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-22 13:02:52 +01:00
										 |  |  |         auto tcp_socket = TRY(Core::TCPSocket::connect(host, connection_info.url().port_or_default())); | 
					
						
							|  |  |  |         TRY(tcp_socket->set_blocking(false)); | 
					
						
							|  |  |  |         return TRY(Core::BufferedTCPSocket::create(move(tcp_socket))); | 
					
						
							| 
									
										
										
										
											2022-11-08 18:40:33 +01:00
										 |  |  |     }(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (socket_result.is_error()) { | 
					
						
							|  |  |  |         Core::deferred_invoke([this] { | 
					
						
							|  |  |  |             on_connection_error(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_socket = socket_result.release_value(); | 
					
						
							|  |  |  |     m_socket->on_ready_to_read = [this] { | 
					
						
							|  |  |  |         on_ready_to_read(); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Core::deferred_invoke([this] { | 
					
						
							|  |  |  |         on_connected(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ErrorOr<ByteBuffer> WebSocketImplSerenity::read(int max_size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto buffer = TRY(ByteBuffer::create_uninitialized(max_size)); | 
					
						
							| 
									
										
										
										
											2023-02-24 22:38:01 +01:00
										 |  |  |     auto read_bytes = TRY(m_socket->read_some(buffer)); | 
					
						
							| 
									
										
										
										
											2022-11-08 18:40:33 +01:00
										 |  |  |     return buffer.slice(0, read_bytes.size()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 17:49:34 +03:30
										 |  |  | ErrorOr<ByteString> WebSocketImplSerenity::read_line(size_t size) | 
					
						
							| 
									
										
										
										
											2022-11-08 18:40:33 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     auto buffer = TRY(ByteBuffer::create_uninitialized(size)); | 
					
						
							|  |  |  |     auto line = TRY(m_socket->read_line(buffer)); | 
					
						
							| 
									
										
										
										
											2023-12-16 17:49:34 +03:30
										 |  |  |     return line.to_byte_string(); | 
					
						
							| 
									
										
										
										
											2022-11-08 18:40:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |