mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 01:08:11 +00:00
Ladybird: Add subclass of WebSocket::WebSocketImpl using Qt networking
This commit is contained in:
parent
acd70f44c2
commit
385c12c8b6
4 changed files with 140 additions and 2 deletions
|
@ -13,6 +13,7 @@ set(WEBCONTENT_SOURCES
|
|||
../Utilities.cpp
|
||||
../WebSocketClientManagerLadybird.cpp
|
||||
../WebSocketLadybird.cpp
|
||||
../WebSocketImplQt.cpp
|
||||
main.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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
99
Ladybird/WebSocketImplQt.cpp
Normal file
99
Ladybird/WebSocketImplQt.cpp
Normal file
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
35
Ladybird/WebSocketImplQt.h
Normal file
35
Ladybird/WebSocketImplQt.h
Normal file
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue