diff options
author | Andreas Kling <kling@serenityos.org> | 2022-11-08 19:17:53 +0100 |
---|---|---|
committer | Andrew Kaster <andrewdkaster@gmail.com> | 2022-12-25 07:58:58 -0700 |
commit | 385c12c8b6d65b922c73769ef32d258f6d1324df (patch) | |
tree | e1f33b9c626eb9f3afff6d2797593c48f90ca1ef /Ladybird | |
parent | acd70f44c2501bcda04d9f8f8aefcc1c44056461 (diff) | |
download | serenity-385c12c8b6d65b922c73769ef32d258f6d1324df.zip |
Ladybird: Add subclass of WebSocket::WebSocketImpl using Qt networking
Diffstat (limited to 'Ladybird')
-rw-r--r-- | Ladybird/WebContent/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Ladybird/WebSocketClientManagerLadybird.cpp | 7 | ||||
-rw-r--r-- | Ladybird/WebSocketImplQt.cpp | 99 | ||||
-rw-r--r-- | Ladybird/WebSocketImplQt.h | 35 |
4 files changed, 140 insertions, 2 deletions
diff --git a/Ladybird/WebContent/CMakeLists.txt b/Ladybird/WebContent/CMakeLists.txt index 99d752ddc8..141bc730da 100644 --- a/Ladybird/WebContent/CMakeLists.txt +++ b/Ladybird/WebContent/CMakeLists.txt @@ -13,6 +13,7 @@ set(WEBCONTENT_SOURCES ../Utilities.cpp ../WebSocketClientManagerLadybird.cpp ../WebSocketLadybird.cpp + ../WebSocketImplQt.cpp main.cpp ) diff --git a/Ladybird/WebSocketClientManagerLadybird.cpp b/Ladybird/WebSocketClientManagerLadybird.cpp index e059a73e4a..1a086dfcf6 100644 --- a/Ladybird/WebSocketClientManagerLadybird.cpp +++ b/Ladybird/WebSocketClientManagerLadybird.cpp @@ -6,6 +6,7 @@ */ #include "WebSocketClientManagerLadybird.h" +#include "WebSocketImplQt.h" #include "WebSocketLadybird.h" namespace Ladybird { @@ -23,8 +24,10 @@ RefPtr<Web::WebSockets::WebSocketClientSocket> WebSocketClientManagerLadybird::c WebSocket::ConnectionInfo connection_info(url); connection_info.set_origin(origin); - auto connection = WebSocketLadybird::create(WebSocket::WebSocket::create(move(connection_info))); - return connection; + auto impl = adopt_ref(*new WebSocketImplQt); + auto web_socket = WebSocket::WebSocket::create(move(connection_info), move(impl)); + web_socket->start(); + return WebSocketLadybird::create(web_socket); } } diff --git a/Ladybird/WebSocketImplQt.cpp b/Ladybird/WebSocketImplQt.cpp new file mode 100644 index 0000000000..d3ffa956d6 --- /dev/null +++ b/Ladybird/WebSocketImplQt.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2021, Dex♪ <dexes.ttp@gmail.com> + * Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org> + * Copyright (c) 2022, the SerenityOS developers. + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#define AK_DONT_REPLACE_STD + +#include "WebSocketImplQt.h" +#include "Utilities.h" +#include <LibCore/EventLoop.h> +#include <QSslSocket> +#include <QTcpSocket> + +namespace Ladybird { + +WebSocketImplQt::~WebSocketImplQt() = default; +WebSocketImplQt::WebSocketImplQt() = default; + +bool WebSocketImplQt::can_read_line() +{ + return m_socket->canReadLine(); +} + +bool WebSocketImplQt::send(ReadonlyBytes bytes) +{ + auto bytes_written = m_socket->write(reinterpret_cast<char const*>(bytes.data()), bytes.size()); + if (bytes_written == -1) + return false; + VERIFY(static_cast<size_t>(bytes_written) == bytes.size()); + return true; +} + +bool WebSocketImplQt::eof() +{ + return m_socket->state() == QTcpSocket::SocketState::UnconnectedState + && !m_socket->bytesAvailable(); +} + +void WebSocketImplQt::discard_connection() +{ + m_socket = nullptr; +} + +void WebSocketImplQt::connect(WebSocket::ConnectionInfo const& connection_info) +{ + VERIFY(!m_socket); + VERIFY(on_connected); + VERIFY(on_connection_error); + VERIFY(on_ready_to_read); + + if (connection_info.is_secure()) { + auto ssl_socket = make<QSslSocket>(); + ssl_socket->connectToHostEncrypted( + qstring_from_akstring(connection_info.url().host()), + connection_info.url().port_or_default()); + QObject::connect(ssl_socket.ptr(), &QSslSocket::alertReceived, [this](QSsl::AlertLevel level, QSsl::AlertType, QString const&) { + if (level == QSsl::AlertLevel::Fatal) + on_connection_error(); + }); + m_socket = move(ssl_socket); + } else { + m_socket = make<QTcpSocket>(); + m_socket->connectToHost( + qstring_from_akstring(connection_info.url().host()), + connection_info.url().port_or_default()); + } + + QObject::connect(m_socket.ptr(), &QTcpSocket::readyRead, [this] { + on_ready_to_read(); + }); + + QObject::connect(m_socket.ptr(), &QTcpSocket::connected, [this] { + on_connected(); + }); +} + +ErrorOr<ByteBuffer> WebSocketImplQt::read(int max_size) +{ + auto buffer = TRY(ByteBuffer::create_uninitialized(max_size)); + auto bytes_read = m_socket->read(reinterpret_cast<char*>(buffer.data()), buffer.size()); + if (bytes_read == -1) + return Error::from_string_literal("WebSocketImplQt::read(): Error reading from socket"); + return buffer.slice(0, bytes_read); +} + +ErrorOr<String> WebSocketImplQt::read_line(size_t size) +{ + auto buffer = TRY(ByteBuffer::create_uninitialized(size)); + auto bytes_read = m_socket->readLine(reinterpret_cast<char*>(buffer.data()), buffer.size()); + if (bytes_read == -1) + return Error::from_string_literal("WebSocketImplQt::read_line(): Error reading from socket"); + return String::copy(buffer.span().slice(0, bytes_read)); +} + +} diff --git a/Ladybird/WebSocketImplQt.h b/Ladybird/WebSocketImplQt.h new file mode 100644 index 0000000000..ff0b508cd3 --- /dev/null +++ b/Ladybird/WebSocketImplQt.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021, Dex♪ <dexes.ttp@gmail.com> + * Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org> + * Copyright (c) 2022, the SerenityOS developers. + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibWebSocket/Impl/WebSocketImpl.h> + +class QTcpSocket; + +namespace Ladybird { + +class WebSocketImplQt final : public WebSocket::WebSocketImpl { +public: + explicit WebSocketImplQt(); + virtual ~WebSocketImplQt() override; + + virtual void connect(WebSocket::ConnectionInfo const&) override; + virtual bool can_read_line() override; + virtual ErrorOr<String> read_line(size_t) 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<QTcpSocket> m_socket; +}; + +} |