diff options
author | Andreas Kling <kling@serenityos.org> | 2022-11-08 18:40:33 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-11-09 02:06:33 +0100 |
commit | be5f6aa46eb1f5e1bb17b705010399f2dfd831f8 (patch) | |
tree | c3bb9787d6ec9e1a9621b932ebc6b5e25040b494 /Userland | |
parent | cc78a74c51e5ab61ef34cc8d027f4ff6335324be (diff) | |
download | serenity-be5f6aa46eb1f5e1bb17b705010399f2dfd831f8.zip |
LibWebSocket: Make WebSocketImpl an abstract class
The LibCore sockets implementation becomes WebSocketImplSerenity.
This will allow us to create a custom WebSocketImpl subclass for Qt
to use in Ladybird.
Diffstat (limited to 'Userland')
6 files changed, 144 insertions, 81 deletions
diff --git a/Userland/Libraries/LibWebSocket/CMakeLists.txt b/Userland/Libraries/LibWebSocket/CMakeLists.txt index 6e7e7fca7c..dae1899fd6 100644 --- a/Userland/Libraries/LibWebSocket/CMakeLists.txt +++ b/Userland/Libraries/LibWebSocket/CMakeLists.txt @@ -1,6 +1,7 @@ set(SOURCES ConnectionInfo.cpp Impl/WebSocketImpl.cpp + Impl/WebSocketImplSerenity.cpp WebSocket.cpp ) diff --git a/Userland/Libraries/LibWebSocket/Impl/WebSocketImpl.cpp b/Userland/Libraries/LibWebSocket/Impl/WebSocketImpl.cpp index 379bd0a4b4..5d03921117 100644 --- a/Userland/Libraries/LibWebSocket/Impl/WebSocketImpl.cpp +++ b/Userland/Libraries/LibWebSocket/Impl/WebSocketImpl.cpp @@ -10,61 +10,7 @@ namespace WebSocket { -WebSocketImpl::WebSocketImpl(Core::Object* parent) - : Object(parent) -{ -} - -void WebSocketImpl::connect(ConnectionInfo const& connection_info) -{ - VERIFY(!m_socket); - VERIFY(on_connected); - VERIFY(on_connection_error); - VERIFY(on_ready_to_read); - auto socket_result = [&]() -> ErrorOr<NonnullOwnPtr<Core::Stream::BufferedSocketBase>> { - if (connection_info.is_secure()) { - TLS::Options options; - options.set_alert_handler([this](auto) { - on_connection_error(); - }); - return TRY(Core::Stream::BufferedSocket<TLS::TLSv12>::create( - TRY(TLS::TLSv12::connect(connection_info.url().host(), connection_info.url().port_or_default(), move(options))))); - } - - return TRY(Core::Stream::BufferedTCPSocket::create( - TRY(Core::Stream::TCPSocket::connect(connection_info.url().host(), connection_info.url().port_or_default())))); - }(); - - if (socket_result.is_error()) { - deferred_invoke([this] { - on_connection_error(); - }); - return; - } - - m_socket = socket_result.release_value(); - - m_socket->on_ready_to_read = [this] { - on_ready_to_read(); - }; - - deferred_invoke([this] { - on_connected(); - }); -} - -ErrorOr<ByteBuffer> WebSocketImpl::read(int max_size) -{ - auto buffer = TRY(ByteBuffer::create_uninitialized(max_size)); - auto read_bytes = TRY(m_socket->read(buffer)); - return buffer.slice(0, read_bytes.size()); -} - -ErrorOr<String> WebSocketImpl::read_line(size_t size) -{ - auto buffer = TRY(ByteBuffer::create_uninitialized(size)); - auto line = TRY(m_socket->read_line(buffer)); - return line.to_string(); -} +WebSocketImpl::WebSocketImpl() = default; +WebSocketImpl::~WebSocketImpl() = default; } diff --git a/Userland/Libraries/LibWebSocket/Impl/WebSocketImpl.h b/Userland/Libraries/LibWebSocket/Impl/WebSocketImpl.h index f572eaa82c..597a9d6c76 100644 --- a/Userland/Libraries/LibWebSocket/Impl/WebSocketImpl.h +++ b/Userland/Libraries/LibWebSocket/Impl/WebSocketImpl.h @@ -11,41 +11,29 @@ #include <AK/ByteBuffer.h> #include <AK/Span.h> #include <AK/String.h> -#include <LibCore/Object.h> #include <LibWebSocket/ConnectionInfo.h> namespace WebSocket { -class WebSocketImpl : public Core::Object { - C_OBJECT(WebSocketImpl); - +class WebSocketImpl : public RefCounted<WebSocketImpl> { public: - virtual ~WebSocketImpl() override = default; - explicit WebSocketImpl(Core::Object* parent = nullptr); - - void connect(ConnectionInfo const&); - - bool can_read_line() { return MUST(m_socket->can_read_line()); } - ErrorOr<String> read_line(size_t size); - - bool can_read() { return MUST(m_socket->can_read_without_blocking()); } - ErrorOr<ByteBuffer> read(int max_size); - - bool send(ReadonlyBytes bytes) { return m_socket->write_or_error(bytes); } - - bool eof() { return m_socket->is_eof(); } + virtual ~WebSocketImpl(); - void discard_connection() - { - m_socket.clear(); - } + virtual void connect(ConnectionInfo const&) = 0; + virtual bool can_read_line() = 0; + virtual ErrorOr<String> read_line(size_t) = 0; + virtual bool can_read() = 0; + virtual ErrorOr<ByteBuffer> read(int max_size) = 0; + virtual bool send(ReadonlyBytes) = 0; + virtual bool eof() = 0; + virtual void discard_connection() = 0; Function<void()> on_connected; Function<void()> on_connection_error; Function<void()> on_ready_to_read; -private: - OwnPtr<Core::Stream::BufferedSocketBase> m_socket; +protected: + WebSocketImpl(); }; } diff --git a/Userland/Libraries/LibWebSocket/Impl/WebSocketImplSerenity.cpp b/Userland/Libraries/LibWebSocket/Impl/WebSocketImplSerenity.cpp new file mode 100644 index 0000000000..cf291569ba --- /dev/null +++ b/Userland/Libraries/LibWebSocket/Impl/WebSocketImplSerenity.cpp @@ -0,0 +1,94 @@ +/* + * 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> +#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::can_read() +{ + return MUST(m_socket->can_read_without_blocking()); +} + +bool WebSocketImplSerenity::send(ReadonlyBytes bytes) +{ + return m_socket->write_or_error(bytes); +} + +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); + auto socket_result = [&]() -> ErrorOr<NonnullOwnPtr<Core::Stream::BufferedSocketBase>> { + if (connection_info.is_secure()) { + TLS::Options options; + options.set_alert_handler([this](auto) { + on_connection_error(); + }); + return TRY(Core::Stream::BufferedSocket<TLS::TLSv12>::create( + TRY(TLS::TLSv12::connect(connection_info.url().host(), connection_info.url().port_or_default(), move(options))))); + } + + return TRY(Core::Stream::BufferedTCPSocket::create( + TRY(Core::Stream::TCPSocket::connect(connection_info.url().host(), connection_info.url().port_or_default())))); + }(); + + 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)); + auto read_bytes = TRY(m_socket->read(buffer)); + return buffer.slice(0, read_bytes.size()); +} + +ErrorOr<String> WebSocketImplSerenity::read_line(size_t size) +{ + auto buffer = TRY(ByteBuffer::create_uninitialized(size)); + auto line = TRY(m_socket->read_line(buffer)); + return line.to_string(); +} + +} diff --git a/Userland/Libraries/LibWebSocket/Impl/WebSocketImplSerenity.h b/Userland/Libraries/LibWebSocket/Impl/WebSocketImplSerenity.h new file mode 100644 index 0000000000..664caa2954 --- /dev/null +++ b/Userland/Libraries/LibWebSocket/Impl/WebSocketImplSerenity.h @@ -0,0 +1,33 @@ +/* + * 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 + */ + +#pragma once + +#include <LibWebSocket/Impl/WebSocketImpl.h> + +namespace WebSocket { + +class WebSocketImplSerenity final : public WebSocketImpl { +public: + explicit WebSocketImplSerenity(); + virtual ~WebSocketImplSerenity() override; + + virtual void connect(ConnectionInfo const&) override; + virtual bool can_read_line() override; + virtual ErrorOr<String> read_line(size_t) override; + virtual bool can_read() override; + virtual ErrorOr<ByteBuffer> read(int max_size) override; + virtual bool send(ReadonlyBytes) override; + virtual bool eof() override; + virtual void discard_connection() override; + +private: + OwnPtr<Core::Stream::BufferedSocketBase> m_socket; +}; + +} diff --git a/Userland/Libraries/LibWebSocket/WebSocket.cpp b/Userland/Libraries/LibWebSocket/WebSocket.cpp index 31f4557acb..ff7bddec15 100644 --- a/Userland/Libraries/LibWebSocket/WebSocket.cpp +++ b/Userland/Libraries/LibWebSocket/WebSocket.cpp @@ -8,6 +8,7 @@ #include <AK/Base64.h> #include <AK/Random.h> #include <LibCrypto/Hash/HashManager.h> +#include <LibWebSocket/Impl/WebSocketImplSerenity.h> #include <LibWebSocket/WebSocket.h> #include <unistd.h> @@ -30,7 +31,7 @@ void WebSocket::start() { VERIFY(m_state == WebSocket::InternalState::NotStarted); VERIFY(!m_impl); - m_impl = WebSocketImpl::construct(); + m_impl = adopt_ref(*new WebSocketImplSerenity); m_impl->on_connection_error = [this] { dbgln("WebSocket: Connection error (underlying socket)"); |