summaryrefslogtreecommitdiff
path: root/Ladybird/WebSocketImplQt.cpp
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-11-08 19:17:53 +0100
committerAndrew Kaster <andrewdkaster@gmail.com>2022-12-25 07:58:58 -0700
commit385c12c8b6d65b922c73769ef32d258f6d1324df (patch)
treee1f33b9c626eb9f3afff6d2797593c48f90ca1ef /Ladybird/WebSocketImplQt.cpp
parentacd70f44c2501bcda04d9f8f8aefcc1c44056461 (diff)
downloadserenity-385c12c8b6d65b922c73769ef32d258f6d1324df.zip
Ladybird: Add subclass of WebSocket::WebSocketImpl using Qt networking
Diffstat (limited to 'Ladybird/WebSocketImplQt.cpp')
-rw-r--r--Ladybird/WebSocketImplQt.cpp99
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));
+}
+
+}