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/WebSocketImplQt.cpp | |
parent | acd70f44c2501bcda04d9f8f8aefcc1c44056461 (diff) | |
download | serenity-385c12c8b6d65b922c73769ef32d258f6d1324df.zip |
Ladybird: Add subclass of WebSocket::WebSocketImpl using Qt networking
Diffstat (limited to 'Ladybird/WebSocketImplQt.cpp')
-rw-r--r-- | Ladybird/WebSocketImplQt.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
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)); +} + +} |