ladybird/Ladybird/Qt/WebSocketImplQt.cpp
Andrew Kaster 391beef707 Ladybird: Move Qt-specific classes and functions to a Qt subdirectory
This will help a lot with developing chromes for different UI frameworks
where we can see which helper classes and processes are really using Qt
vs just using it to get at helper data.

As a bonus, remove Qt dependency from WebDriver.
2023-08-07 14:58:04 -06:00

98 lines
3.1 KiB
C++

/*
* 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
*/
#include "WebSocketImplQt.h"
#include "StringUtils.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_ak_string(connection_info.url().serialized_host().release_value_but_fixme_should_propagate_errors()),
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_ak_string(connection_info.url().serialized_host().release_value_but_fixme_should_propagate_errors()),
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<DeprecatedString> 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 DeprecatedString::copy(buffer.span().slice(0, bytes_read));
}
}