mirror of
https://github.com/SerenityOS/serenity
synced 2026-04-25 17:15:42 +02:00
Ladybird: Remove Qt Network support
Now that ladybird was moved moved to its own repository, we don't need to keep unnecessary features like Qt networking around. Ladybird only still exists in the SerenityOS repo to make testing LibWeb easier. Upstream ladybird also removed Qt networking support in 1b324f3ae11.
This commit is contained in:
@@ -59,7 +59,9 @@ ErrorOr<NonnullRefPtr<WebView::WebContentClient>> ApplicationBridge::launch_web_
|
||||
ErrorOr<IPC::File> ApplicationBridge::launch_web_worker()
|
||||
{
|
||||
auto web_worker_paths = TRY(get_paths_for_helper_process("WebWorker"sv));
|
||||
auto worker_client = TRY(launch_web_worker_process(web_worker_paths, m_impl->request_server_client));
|
||||
|
||||
VERIFY(!m_impl->request_server_client.is_null());
|
||||
auto worker_client = TRY(launch_web_worker_process(web_worker_paths, m_impl->request_server_client.release_nonnull()));
|
||||
|
||||
return worker_client->dup_socket();
|
||||
}
|
||||
|
||||
@@ -115,8 +115,6 @@ ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content_process(
|
||||
|
||||
if (web_content_options.is_layout_test_mode == Ladybird::IsLayoutTestMode::Yes)
|
||||
arguments.append("--layout-test-mode"sv);
|
||||
if (web_content_options.use_lagom_networking == Ladybird::UseLagomNetworking::Yes)
|
||||
arguments.append("--use-lagom-networking"sv);
|
||||
if (web_content_options.enable_gpu_painting == Ladybird::EnableGPUPainting::Yes)
|
||||
arguments.append("--use-gpu-painting"sv);
|
||||
if (web_content_options.enable_experimental_cpu_transforms == Ladybird::EnableExperimentalCPUTransforms::Yes)
|
||||
@@ -148,16 +146,12 @@ ErrorOr<NonnullRefPtr<ImageDecoderClient::Client>> launch_image_decoder_process(
|
||||
return launch_generic_server_process<ImageDecoderClient::Client>("ImageDecoder"sv, candidate_image_decoder_paths, {}, RegisterWithProcessManager::Yes, Ladybird::EnableCallgrindProfiling::No);
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<Web::HTML::WebWorkerClient>> launch_web_worker_process(ReadonlySpan<ByteString> candidate_web_worker_paths, RefPtr<Protocol::RequestClient> request_client)
|
||||
ErrorOr<NonnullRefPtr<Web::HTML::WebWorkerClient>> launch_web_worker_process(ReadonlySpan<ByteString> candidate_web_worker_paths, NonnullRefPtr<Protocol::RequestClient> request_client)
|
||||
{
|
||||
Vector<ByteString> arguments;
|
||||
if (request_client) {
|
||||
auto socket = TRY(connect_new_request_server_client(*request_client));
|
||||
arguments.append("--request-server-socket"sv);
|
||||
arguments.append(ByteString::number(socket.fd()));
|
||||
arguments.append("--use-lagom-networking"sv);
|
||||
return launch_generic_server_process<Web::HTML::WebWorkerClient>("WebWorker"sv, candidate_web_worker_paths, move(arguments), RegisterWithProcessManager::Yes, Ladybird::EnableCallgrindProfiling::No);
|
||||
}
|
||||
auto socket = TRY(connect_new_request_server_client(*request_client));
|
||||
arguments.append("--request-server-socket"sv);
|
||||
arguments.append(ByteString::number(socket.fd()));
|
||||
|
||||
return launch_generic_server_process<Web::HTML::WebWorkerClient>("WebWorker"sv, candidate_web_worker_paths, move(arguments), RegisterWithProcessManager::Yes, Ladybird::EnableCallgrindProfiling::No);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content_process(
|
||||
Optional<IPC::File> request_server_socket = {});
|
||||
|
||||
ErrorOr<NonnullRefPtr<ImageDecoderClient::Client>> launch_image_decoder_process(ReadonlySpan<ByteString> candidate_image_decoder_paths);
|
||||
ErrorOr<NonnullRefPtr<Web::HTML::WebWorkerClient>> launch_web_worker_process(ReadonlySpan<ByteString> candidate_web_worker_paths, RefPtr<Protocol::RequestClient>);
|
||||
ErrorOr<NonnullRefPtr<Web::HTML::WebWorkerClient>> launch_web_worker_process(ReadonlySpan<ByteString> candidate_web_worker_paths, NonnullRefPtr<Protocol::RequestClient>);
|
||||
ErrorOr<NonnullRefPtr<Protocol::RequestClient>> launch_request_server_process(ReadonlySpan<ByteString> candidate_request_server_paths, StringView serenity_resource_root, Vector<ByteString> const& certificates);
|
||||
ErrorOr<NonnullRefPtr<SQL::SQLClient>> launch_sql_server_process(ReadonlySpan<ByteString> candidate_sql_server_paths);
|
||||
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "RequestManagerQt.h"
|
||||
#include "WebSocketImplQt.h"
|
||||
#include "WebSocketQt.h"
|
||||
#include <QNetworkCookie>
|
||||
|
||||
namespace Ladybird {
|
||||
|
||||
RequestManagerQt::RequestManagerQt()
|
||||
{
|
||||
m_qnam = new QNetworkAccessManager(this);
|
||||
|
||||
QObject::connect(m_qnam, &QNetworkAccessManager::finished, this, &RequestManagerQt::reply_finished);
|
||||
}
|
||||
|
||||
void RequestManagerQt::reply_finished(QNetworkReply* reply)
|
||||
{
|
||||
auto request = m_pending.get(reply).value();
|
||||
m_pending.remove(reply);
|
||||
request->did_finish();
|
||||
}
|
||||
|
||||
RefPtr<Web::ResourceLoaderConnectorRequest> RequestManagerQt::start_request(ByteString const& method, URL::URL const& url, HTTP::HeaderMap const& request_headers, ReadonlyBytes request_body, Core::ProxyData const& proxy)
|
||||
{
|
||||
if (!url.scheme().bytes_as_string_view().is_one_of_ignoring_ascii_case("http"sv, "https"sv)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto request_or_error = Request::create(*m_qnam, method, url, request_headers, request_body, proxy);
|
||||
if (request_or_error.is_error()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto request = request_or_error.release_value();
|
||||
m_pending.set(&request->reply(), *request);
|
||||
return request;
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<RequestManagerQt::Request>> RequestManagerQt::Request::create(QNetworkAccessManager& qnam, ByteString const& method, URL::URL const& url, HTTP::HeaderMap const& request_headers, ReadonlyBytes request_body, Core::ProxyData const&)
|
||||
{
|
||||
QNetworkRequest request { QString(url.to_byte_string().characters()) };
|
||||
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy);
|
||||
request.setAttribute(QNetworkRequest::CookieLoadControlAttribute, QNetworkRequest::Manual);
|
||||
request.setAttribute(QNetworkRequest::CookieSaveControlAttribute, QNetworkRequest::Manual);
|
||||
|
||||
// NOTE: We disable HTTP2 as it's significantly slower (up to 5x, possibly more)
|
||||
request.setAttribute(QNetworkRequest::Http2AllowedAttribute, false);
|
||||
|
||||
QNetworkReply* reply = nullptr;
|
||||
|
||||
for (auto const& it : request_headers.headers()) {
|
||||
// FIXME: We currently strip the Accept-Encoding header on outgoing requests from LibWeb
|
||||
// since otherwise it'll ask for compression without Qt being aware of it.
|
||||
// This is very hackish and I'm sure we can do it in concert with Qt somehow.
|
||||
if (it.name == "Accept-Encoding")
|
||||
continue;
|
||||
request.setRawHeader(QByteArray(it.name.characters()), QByteArray(it.value.characters()));
|
||||
}
|
||||
|
||||
if (method.equals_ignoring_ascii_case("head"sv)) {
|
||||
reply = qnam.head(request);
|
||||
} else if (method.equals_ignoring_ascii_case("get"sv)) {
|
||||
reply = qnam.get(request);
|
||||
} else if (method.equals_ignoring_ascii_case("post"sv)) {
|
||||
reply = qnam.post(request, QByteArray((char const*)request_body.data(), request_body.size()));
|
||||
} else if (method.equals_ignoring_ascii_case("put"sv)) {
|
||||
reply = qnam.put(request, QByteArray((char const*)request_body.data(), request_body.size()));
|
||||
} else if (method.equals_ignoring_ascii_case("delete"sv)) {
|
||||
reply = qnam.deleteResource(request);
|
||||
} else {
|
||||
reply = qnam.sendCustomRequest(request, QByteArray(method.characters()), QByteArray((char const*)request_body.data(), request_body.size()));
|
||||
}
|
||||
|
||||
return adopt_ref(*new Request(*reply));
|
||||
}
|
||||
|
||||
RefPtr<Web::WebSockets::WebSocketClientSocket> RequestManagerQt::websocket_connect(URL::URL const& url, AK::ByteString const& origin, Vector<AK::ByteString> const& protocols)
|
||||
{
|
||||
WebSocket::ConnectionInfo connection_info(url);
|
||||
connection_info.set_origin(origin);
|
||||
connection_info.set_protocols(protocols);
|
||||
|
||||
auto impl = adopt_ref(*new WebSocketImplQt);
|
||||
auto web_socket = WebSocket::WebSocket::create(move(connection_info), move(impl));
|
||||
web_socket->start();
|
||||
return WebSocketQt::create(web_socket);
|
||||
}
|
||||
|
||||
RequestManagerQt::Request::Request(QNetworkReply& reply)
|
||||
: m_reply(reply)
|
||||
{
|
||||
}
|
||||
|
||||
RequestManagerQt::Request::~Request() = default;
|
||||
|
||||
void RequestManagerQt::Request::set_buffered_request_finished_callback(Protocol::Request::BufferedRequestFinished on_buffered_request_finished)
|
||||
{
|
||||
this->on_buffered_request_finish = move(on_buffered_request_finished);
|
||||
}
|
||||
|
||||
void RequestManagerQt::Request::set_unbuffered_request_callbacks(Protocol::Request::HeadersReceived, Protocol::Request::DataReceived, Protocol::Request::RequestFinished on_request_finished)
|
||||
{
|
||||
dbgln("Unbuffered requests are not yet supported with Qt networking");
|
||||
on_request_finished(false, 0);
|
||||
}
|
||||
|
||||
void RequestManagerQt::Request::did_finish()
|
||||
{
|
||||
auto buffer = m_reply.readAll();
|
||||
auto http_status_code = m_reply.attribute(QNetworkRequest::Attribute::HttpStatusCodeAttribute).toInt();
|
||||
HTTP::HeaderMap response_headers;
|
||||
for (auto& it : m_reply.rawHeaderPairs()) {
|
||||
auto name = ByteString(it.first.data(), it.first.length());
|
||||
auto value = ByteString(it.second.data(), it.second.length());
|
||||
if (name.equals_ignoring_ascii_case("set-cookie"sv)) {
|
||||
// NOTE: Qt may have bundled multiple Set-Cookie headers into a single one.
|
||||
// We have to extract the full list of cookies via QNetworkReply::header().
|
||||
auto set_cookie_list = m_reply.header(QNetworkRequest::SetCookieHeader).value<QList<QNetworkCookie>>();
|
||||
for (auto const& cookie : set_cookie_list) {
|
||||
response_headers.set(name, cookie.toRawForm().data());
|
||||
}
|
||||
} else {
|
||||
response_headers.set(name, value);
|
||||
}
|
||||
}
|
||||
bool success = http_status_code != 0;
|
||||
on_buffered_request_finish(success, buffer.length(), response_headers, http_status_code, ReadonlyBytes { buffer.data(), (size_t)buffer.size() });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Loader/ResourceLoader.h>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
|
||||
namespace Ladybird {
|
||||
|
||||
class RequestManagerQt
|
||||
: public QObject
|
||||
, public Web::ResourceLoaderConnector {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static NonnullRefPtr<RequestManagerQt> create()
|
||||
{
|
||||
return adopt_ref(*new RequestManagerQt());
|
||||
}
|
||||
|
||||
virtual ~RequestManagerQt() override { }
|
||||
|
||||
virtual void prefetch_dns(URL::URL const&) override { }
|
||||
virtual void preconnect(URL::URL const&) override { }
|
||||
|
||||
virtual RefPtr<Web::ResourceLoaderConnectorRequest> start_request(ByteString const& method, URL::URL const&, HTTP::HeaderMap const& request_headers, ReadonlyBytes request_body, Core::ProxyData const&) override;
|
||||
virtual RefPtr<Web::WebSockets::WebSocketClientSocket> websocket_connect(const URL::URL&, ByteString const& origin, Vector<ByteString> const& protocols) override;
|
||||
|
||||
private slots:
|
||||
void reply_finished(QNetworkReply*);
|
||||
|
||||
private:
|
||||
RequestManagerQt();
|
||||
|
||||
class Request
|
||||
: public Web::ResourceLoaderConnectorRequest {
|
||||
public:
|
||||
static ErrorOr<NonnullRefPtr<Request>> create(QNetworkAccessManager& qnam, ByteString const& method, URL::URL const& url, HTTP::HeaderMap const& request_headers, ReadonlyBytes request_body, Core::ProxyData const&);
|
||||
|
||||
virtual ~Request() override;
|
||||
|
||||
virtual void set_buffered_request_finished_callback(Protocol::Request::BufferedRequestFinished) override;
|
||||
virtual void set_unbuffered_request_callbacks(Protocol::Request::HeadersReceived, Protocol::Request::DataReceived, Protocol::Request::RequestFinished) override;
|
||||
virtual bool stop() override { return false; }
|
||||
|
||||
void did_finish();
|
||||
|
||||
QNetworkReply& reply() { return m_reply; }
|
||||
|
||||
private:
|
||||
Request(QNetworkReply&);
|
||||
|
||||
QNetworkReply& m_reply;
|
||||
|
||||
Protocol::Request::BufferedRequestFinished on_buffered_request_finish;
|
||||
};
|
||||
|
||||
HashMap<QNetworkReply*, NonnullRefPtr<Request>> m_pending;
|
||||
QNetworkAccessManager* m_qnam { nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
@@ -136,11 +136,9 @@ WebContentView::WebContentView(QWidget* window, WebContentOptions const& web_con
|
||||
};
|
||||
|
||||
on_request_worker_agent = [&]() {
|
||||
RefPtr<Protocol::RequestClient> request_server_client {};
|
||||
if (m_web_content_options.use_lagom_networking == Ladybird::UseLagomNetworking::Yes)
|
||||
request_server_client = static_cast<Ladybird::Application*>(QApplication::instance())->request_server_client;
|
||||
auto& request_server_client = static_cast<Ladybird::Application*>(QApplication::instance())->request_server_client;
|
||||
|
||||
auto worker_client = MUST(launch_web_worker_process(MUST(get_paths_for_helper_process("WebWorker"sv)), request_server_client));
|
||||
auto worker_client = MUST(launch_web_worker_process(MUST(get_paths_for_helper_process("WebWorker"sv)), *request_server_client));
|
||||
return worker_client->dup_socket();
|
||||
};
|
||||
|
||||
@@ -654,14 +652,10 @@ void WebContentView::initialize_client(WebView::ViewImplementation::CreateNewCli
|
||||
if (create_new_client == CreateNewClient::Yes) {
|
||||
m_client_state = {};
|
||||
|
||||
Optional<IPC::File> request_server_socket;
|
||||
if (m_web_content_options.use_lagom_networking == UseLagomNetworking::Yes) {
|
||||
auto& protocol = static_cast<Ladybird::Application*>(QApplication::instance())->request_server_client;
|
||||
auto& request_server_client = static_cast<Ladybird::Application*>(QApplication::instance())->request_server_client;
|
||||
|
||||
// FIXME: Fail to open the tab, rather than crashing the whole application if this fails
|
||||
auto socket = connect_new_request_server_client(*protocol).release_value_but_fixme_should_propagate_errors();
|
||||
request_server_socket = AK::move(socket);
|
||||
}
|
||||
// FIXME: Fail to open the tab, rather than crashing the whole application if this fails
|
||||
auto request_server_socket = connect_new_request_server_client(*request_server_client).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
auto candidate_web_content_paths = get_paths_for_helper_process("WebContent"sv).release_value_but_fixme_should_propagate_errors();
|
||||
auto new_client = launch_web_content_process(*this, candidate_web_content_paths, m_web_content_options, AK::move(request_server_socket)).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* 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(MUST(connection_info.url().serialized_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_ak_string(MUST(connection_info.url().serialized_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<ByteString> 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 ByteString::copy(buffer.span().slice(0, bytes_read));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* 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<ByteString> 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;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com>
|
||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "WebSocketQt.h"
|
||||
|
||||
namespace Ladybird {
|
||||
|
||||
NonnullRefPtr<WebSocketQt> WebSocketQt::create(NonnullRefPtr<WebSocket::WebSocket> underlying_socket)
|
||||
{
|
||||
return adopt_ref(*new WebSocketQt(move(underlying_socket)));
|
||||
}
|
||||
|
||||
WebSocketQt::WebSocketQt(NonnullRefPtr<WebSocket::WebSocket> underlying_socket)
|
||||
: m_websocket(move(underlying_socket))
|
||||
{
|
||||
m_websocket->on_open = [weak_this = make_weak_ptr()] {
|
||||
if (auto strong_this = weak_this.strong_ref())
|
||||
if (strong_this->on_open)
|
||||
strong_this->on_open();
|
||||
};
|
||||
m_websocket->on_message = [weak_this = make_weak_ptr()](auto message) {
|
||||
if (auto strong_this = weak_this.strong_ref()) {
|
||||
if (strong_this->on_message) {
|
||||
strong_this->on_message(Web::WebSockets::WebSocketClientSocket::Message {
|
||||
.data = move(message.data()),
|
||||
.is_text = message.is_text(),
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
m_websocket->on_error = [weak_this = make_weak_ptr()](auto error) {
|
||||
if (auto strong_this = weak_this.strong_ref()) {
|
||||
if (strong_this->on_error) {
|
||||
switch (error) {
|
||||
case WebSocket::WebSocket::Error::CouldNotEstablishConnection:
|
||||
strong_this->on_error(Web::WebSockets::WebSocketClientSocket::Error::CouldNotEstablishConnection);
|
||||
return;
|
||||
case WebSocket::WebSocket::Error::ConnectionUpgradeFailed:
|
||||
strong_this->on_error(Web::WebSockets::WebSocketClientSocket::Error::ConnectionUpgradeFailed);
|
||||
return;
|
||||
case WebSocket::WebSocket::Error::ServerClosedSocket:
|
||||
strong_this->on_error(Web::WebSockets::WebSocketClientSocket::Error::ServerClosedSocket);
|
||||
return;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
};
|
||||
m_websocket->on_close = [weak_this = make_weak_ptr()](u16 code, ByteString reason, bool was_clean) {
|
||||
if (auto strong_this = weak_this.strong_ref())
|
||||
if (strong_this->on_close)
|
||||
strong_this->on_close(code, move(reason), was_clean);
|
||||
};
|
||||
}
|
||||
|
||||
WebSocketQt::~WebSocketQt() = default;
|
||||
|
||||
Web::WebSockets::WebSocket::ReadyState WebSocketQt::ready_state()
|
||||
{
|
||||
switch (m_websocket->ready_state()) {
|
||||
case WebSocket::ReadyState::Connecting:
|
||||
return Web::WebSockets::WebSocket::ReadyState::Connecting;
|
||||
case WebSocket::ReadyState::Open:
|
||||
return Web::WebSockets::WebSocket::ReadyState::Open;
|
||||
case WebSocket::ReadyState::Closing:
|
||||
return Web::WebSockets::WebSocket::ReadyState::Closing;
|
||||
case WebSocket::ReadyState::Closed:
|
||||
return Web::WebSockets::WebSocket::ReadyState::Closed;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
ByteString WebSocketQt::subprotocol_in_use()
|
||||
{
|
||||
return m_websocket->subprotocol_in_use();
|
||||
}
|
||||
|
||||
void WebSocketQt::send(ByteBuffer binary_or_text_message, bool is_text)
|
||||
{
|
||||
m_websocket->send(WebSocket::Message(binary_or_text_message, is_text));
|
||||
}
|
||||
|
||||
void WebSocketQt::send(StringView message)
|
||||
{
|
||||
m_websocket->send(WebSocket::Message(message));
|
||||
}
|
||||
|
||||
void WebSocketQt::close(u16 code, ByteString reason)
|
||||
{
|
||||
m_websocket->close(code, reason);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com>
|
||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/WebSockets/WebSocket.h>
|
||||
#include <LibWebSocket/WebSocket.h>
|
||||
|
||||
namespace Ladybird {
|
||||
|
||||
class WebSocketQt
|
||||
: public Web::WebSockets::WebSocketClientSocket
|
||||
, public Weakable<WebSocketQt> {
|
||||
public:
|
||||
static NonnullRefPtr<WebSocketQt> create(NonnullRefPtr<WebSocket::WebSocket>);
|
||||
|
||||
virtual ~WebSocketQt() override;
|
||||
|
||||
virtual Web::WebSockets::WebSocket::ReadyState ready_state() override;
|
||||
virtual ByteString subprotocol_in_use() override;
|
||||
virtual void send(ByteBuffer binary_or_text_message, bool is_text) override;
|
||||
virtual void send(StringView message) override;
|
||||
virtual void close(u16 code, ByteString reason) override;
|
||||
|
||||
private:
|
||||
explicit WebSocketQt(NonnullRefPtr<WebSocket::WebSocket>);
|
||||
|
||||
NonnullRefPtr<WebSocket::WebSocket> m_websocket;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -93,7 +93,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
Vector<ByteString> certificates;
|
||||
bool enable_callgrind_profiling = false;
|
||||
bool disable_sql_database = false;
|
||||
bool enable_qt_networking = false;
|
||||
bool expose_internals_object = false;
|
||||
bool use_gpu_painting = false;
|
||||
bool use_experimental_cpu_transform_support = false;
|
||||
@@ -111,7 +110,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
args_parser.add_option(webdriver_content_ipc_path, "Path to WebDriver IPC for WebContent", "webdriver-content-path", 0, "path", Core::ArgsParser::OptionHideMode::CommandLineAndMarkdown);
|
||||
args_parser.add_option(enable_callgrind_profiling, "Enable Callgrind profiling", "enable-callgrind-profiling", 'P');
|
||||
args_parser.add_option(disable_sql_database, "Disable SQL database", "disable-sql-database");
|
||||
args_parser.add_option(enable_qt_networking, "Enable Qt as the backend networking service", "enable-qt-networking");
|
||||
args_parser.add_option(use_gpu_painting, "Enable GPU painting", "enable-gpu-painting");
|
||||
args_parser.add_option(use_experimental_cpu_transform_support, "Enable experimental CPU transform support", "experimental-cpu-transforms");
|
||||
args_parser.add_option(debug_web_content, "Wait for debugger to attach to WebContent", "debug-web-content");
|
||||
@@ -169,11 +167,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
auto cookie_jar = database ? TRY(WebView::CookieJar::create(*database)) : WebView::CookieJar::create();
|
||||
|
||||
// FIXME: Create an abstraction to re-spawn the RequestServer and re-hook up its client hooks to each tab on crash
|
||||
if (!enable_qt_networking) {
|
||||
auto request_server_paths = TRY(get_paths_for_helper_process("RequestServer"sv));
|
||||
auto protocol_client = TRY(launch_request_server_process(request_server_paths, s_serenity_resource_root, certificates));
|
||||
app.request_server_client = move(protocol_client);
|
||||
}
|
||||
auto request_server_paths = TRY(get_paths_for_helper_process("RequestServer"sv));
|
||||
auto protocol_client = TRY(launch_request_server_process(request_server_paths, s_serenity_resource_root, certificates));
|
||||
app.request_server_client = move(protocol_client);
|
||||
|
||||
StringBuilder command_line_builder;
|
||||
command_line_builder.join(' ', arguments.strings);
|
||||
@@ -183,7 +179,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
.enable_callgrind_profiling = enable_callgrind_profiling ? Ladybird::EnableCallgrindProfiling::Yes : Ladybird::EnableCallgrindProfiling::No,
|
||||
.enable_gpu_painting = use_gpu_painting ? Ladybird::EnableGPUPainting::Yes : Ladybird::EnableGPUPainting::No,
|
||||
.enable_experimental_cpu_transforms = use_experimental_cpu_transform_support ? Ladybird::EnableExperimentalCPUTransforms::Yes : Ladybird::EnableExperimentalCPUTransforms::No,
|
||||
.use_lagom_networking = enable_qt_networking ? Ladybird::UseLagomNetworking::No : Ladybird::UseLagomNetworking::Yes,
|
||||
.wait_for_debugger = debug_web_content ? Ladybird::WaitForDebugger::Yes : Ladybird::WaitForDebugger::No,
|
||||
.log_all_js_exceptions = log_all_js_exceptions ? Ladybird::LogAllJSExceptions::Yes : Ladybird::LogAllJSExceptions::No,
|
||||
.enable_idl_tracing = enable_idl_tracing ? Ladybird::EnableIDLTracing::Yes : Ladybird::EnableIDLTracing::No,
|
||||
|
||||
@@ -30,11 +30,6 @@ enum class IsLayoutTestMode {
|
||||
Yes
|
||||
};
|
||||
|
||||
enum class UseLagomNetworking {
|
||||
No,
|
||||
Yes
|
||||
};
|
||||
|
||||
enum class WaitForDebugger {
|
||||
No,
|
||||
Yes
|
||||
@@ -67,7 +62,6 @@ struct WebContentOptions {
|
||||
EnableGPUPainting enable_gpu_painting { EnableGPUPainting::No };
|
||||
EnableExperimentalCPUTransforms enable_experimental_cpu_transforms { EnableExperimentalCPUTransforms::No };
|
||||
IsLayoutTestMode is_layout_test_mode { IsLayoutTestMode::No };
|
||||
UseLagomNetworking use_lagom_networking { UseLagomNetworking::Yes };
|
||||
WaitForDebugger wait_for_debugger { WaitForDebugger::No };
|
||||
LogAllJSExceptions log_all_js_exceptions { LogAllJSExceptions::No };
|
||||
EnableIDLTracing enable_idl_tracing { EnableIDLTracing::No };
|
||||
|
||||
@@ -19,13 +19,10 @@ if (ENABLE_QT)
|
||||
target_sources(WebContent PRIVATE
|
||||
../Qt/EventLoopImplementationQt.cpp
|
||||
../Qt/EventLoopImplementationQtEventTarget.cpp
|
||||
../Qt/RequestManagerQt.cpp
|
||||
../Qt/StringUtils.cpp
|
||||
../Qt/WebSocketQt.cpp
|
||||
../Qt/WebSocketImplQt.cpp
|
||||
main.cpp
|
||||
)
|
||||
target_link_libraries(WebContent PRIVATE Qt::Core Qt::Network)
|
||||
target_link_libraries(WebContent PRIVATE Qt::Core)
|
||||
target_compile_definitions(WebContent PRIVATE HAVE_QT=1)
|
||||
set_target_properties(WebContent PROPERTIES AUTOMOC ON)
|
||||
else()
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
# include <Ladybird/Qt/EventLoopImplementationQt.h>
|
||||
# include <Ladybird/Qt/RequestManagerQt.h>
|
||||
# include <QCoreApplication>
|
||||
#endif
|
||||
|
||||
@@ -93,7 +92,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
int request_server_socket { -1 };
|
||||
bool is_layout_test_mode = false;
|
||||
bool expose_internals_object = false;
|
||||
bool use_lagom_networking = false;
|
||||
bool use_gpu_painting = false;
|
||||
bool use_experimental_cpu_transform_support = false;
|
||||
bool wait_for_debugger = false;
|
||||
@@ -107,7 +105,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
args_parser.add_option(request_server_socket, "File descriptor of the socket for the RequestServer connection", "request-server-socket", 'r', "request_server_socket");
|
||||
args_parser.add_option(is_layout_test_mode, "Is layout test mode", "layout-test-mode");
|
||||
args_parser.add_option(expose_internals_object, "Expose internals object", "expose-internals-object");
|
||||
args_parser.add_option(use_lagom_networking, "Enable Lagom servers for networking", "use-lagom-networking");
|
||||
args_parser.add_option(use_gpu_painting, "Enable GPU painting", "use-gpu-painting");
|
||||
args_parser.add_option(use_experimental_cpu_transform_support, "Enable experimental CPU transform support", "experimental-cpu-transforms");
|
||||
args_parser.add_option(wait_for_debugger, "Wait for debugger", "wait-for-debugger");
|
||||
@@ -146,12 +143,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
if (!use_lagom_networking)
|
||||
Web::ResourceLoader::initialize(Ladybird::RequestManagerQt::create());
|
||||
else
|
||||
#endif
|
||||
TRY(initialize_lagom_networking(request_server_socket));
|
||||
TRY(initialize_lagom_networking(request_server_socket));
|
||||
|
||||
Web::HTML::Window::set_internals_object_exposed(expose_internals_object);
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ static ErrorOr<pid_t> launch_process(StringView application, ReadonlySpan<char c
|
||||
return result;
|
||||
}
|
||||
|
||||
static ErrorOr<pid_t> launch_browser(ByteString const& socket_path, bool use_qt_networking)
|
||||
static ErrorOr<pid_t> launch_browser(ByteString const& socket_path)
|
||||
{
|
||||
auto arguments = Vector {
|
||||
"--webdriver-content-path",
|
||||
@@ -47,8 +47,6 @@ static ErrorOr<pid_t> launch_browser(ByteString const& socket_path, bool use_qt_
|
||||
|
||||
arguments.append("--allow-popups");
|
||||
arguments.append("--force-new-process");
|
||||
if (use_qt_networking)
|
||||
arguments.append("--enable-qt-networking");
|
||||
|
||||
arguments.append("about:blank");
|
||||
|
||||
@@ -74,13 +72,11 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
|
||||
auto listen_address = "0.0.0.0"sv;
|
||||
int port = 8000;
|
||||
bool enable_qt_networking = false;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_option(listen_address, "IP address to listen on", "listen-address", 'l', "listen_address");
|
||||
args_parser.add_option(port, "Port to listen on", "port", 'p', "port");
|
||||
args_parser.add_option(certificates, "Path to a certificate file", "certificate", 'C', "certificate");
|
||||
args_parser.add_option(enable_qt_networking, "Launch browser with Qt networking enabled", "enable-qt-networking");
|
||||
args_parser.parse(arguments);
|
||||
|
||||
auto ipv4_address = IPv4Address::from_string(listen_address);
|
||||
@@ -117,7 +113,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
}
|
||||
|
||||
auto launch_browser_callback = [&](ByteString const& socket_path) {
|
||||
return launch_browser(socket_path, enable_qt_networking);
|
||||
return launch_browser(socket_path);
|
||||
};
|
||||
|
||||
auto maybe_client = WebDriver::Client::try_create(maybe_buffered_socket.release_value(), { move(launch_browser_callback), launch_headless_browser }, server);
|
||||
|
||||
@@ -19,13 +19,10 @@ if (ENABLE_QT)
|
||||
qt_add_executable(WebWorker
|
||||
../Qt/EventLoopImplementationQt.cpp
|
||||
../Qt/EventLoopImplementationQtEventTarget.cpp
|
||||
../Qt/RequestManagerQt.cpp
|
||||
../Qt/StringUtils.cpp
|
||||
../Qt/WebSocketQt.cpp
|
||||
../Qt/WebSocketImplQt.cpp
|
||||
main.cpp
|
||||
)
|
||||
target_link_libraries(WebWorker PRIVATE Qt::Core Qt::Network)
|
||||
target_link_libraries(WebWorker PRIVATE Qt::Core)
|
||||
target_link_libraries(WebWorker PRIVATE webworker LibWebSocket)
|
||||
target_compile_definitions(WebWorker PRIVATE HAVE_QT=1)
|
||||
set_target_properties(WebWorker PROPERTIES AUTOMOC ON)
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
# include <Ladybird/Qt/EventLoopImplementationQt.h>
|
||||
# include <Ladybird/Qt/RequestManagerQt.h>
|
||||
# include <QCoreApplication>
|
||||
#endif
|
||||
|
||||
@@ -40,12 +39,10 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
|
||||
int request_server_socket { -1 };
|
||||
StringView serenity_resource_root;
|
||||
bool use_lagom_networking { false };
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_option(request_server_socket, "File descriptor of the request server socket", "request-server-socket", 's', "request-server-socket");
|
||||
args_parser.add_option(serenity_resource_root, "Absolute path to directory for serenity resources", "serenity-resource-root", 'r', "serenity-resource-root");
|
||||
args_parser.add_option(use_lagom_networking, "Enable Lagom servers for networking", "use-lagom-networking");
|
||||
args_parser.parse(arguments);
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
@@ -60,12 +57,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
|
||||
Web::Platform::FontPlugin::install(*new Web::Platform::FontPluginSerenity);
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
if (!use_lagom_networking)
|
||||
Web::ResourceLoader::initialize(Ladybird::RequestManagerQt::create());
|
||||
else
|
||||
#endif
|
||||
TRY(initialize_lagom_networking(request_server_socket));
|
||||
TRY(initialize_lagom_networking(request_server_socket));
|
||||
|
||||
TRY(Web::Bindings::initialize_main_thread_vm(Web::HTML::EventLoop::Type::Worker));
|
||||
|
||||
|
||||
@@ -4,10 +4,7 @@ import("//Ladybird/moc_qt_objects.gni")
|
||||
import("//Meta/gn/build/libs/pulse/enable.gni")
|
||||
|
||||
moc_qt_objects("generate_moc") {
|
||||
sources = [
|
||||
"//Ladybird/Qt/EventLoopImplementationQtEventTarget.h",
|
||||
"//Ladybird/Qt/RequestManagerQt.h",
|
||||
]
|
||||
sources = [ "//Ladybird/Qt/EventLoopImplementationQtEventTarget.h" ]
|
||||
}
|
||||
|
||||
link_qt("WebContent_qt") {
|
||||
@@ -64,10 +61,7 @@ executable("WebContent") {
|
||||
sources += [
|
||||
"//Ladybird/Qt/EventLoopImplementationQt.cpp",
|
||||
"//Ladybird/Qt/EventLoopImplementationQtEventTarget.cpp",
|
||||
"//Ladybird/Qt/RequestManagerQt.cpp",
|
||||
"//Ladybird/Qt/StringUtils.cpp",
|
||||
"//Ladybird/Qt/WebSocketImplQt.cpp",
|
||||
"//Ladybird/Qt/WebSocketQt.cpp",
|
||||
]
|
||||
|
||||
sources += get_target_outputs(":generate_moc")
|
||||
|
||||
@@ -305,6 +305,11 @@ serenity_cherry_picks.add('b118c99c271e34e2c5020022d062a4371f199a71')
|
||||
# cherry-pick of serenity's https://github.com/SerenityOS/serenity/pull/24533
|
||||
serenity_cherry_picks.add('50dc1c3c19b82af797c79b5aa694b3ac7f0114bb')
|
||||
|
||||
# Qt networking support was removed both by ladybird in the first commit of
|
||||
# https://github.com/LadybirdBrowser/ladybird/pull/1671 and by serenity's
|
||||
# PR https://github.com/SerenityOS/serenity/pull/26114
|
||||
serenity_cherry_picks.add('1b324f3ae11d4f5750d89183f97bb3b3b2b4f801')
|
||||
|
||||
# Define a list of pull request IDs that should never be merged
|
||||
# and the reasons why they shouldn't be merged.
|
||||
# We fairly likely don't want the PRs in here (but it isn't 100% set
|
||||
|
||||
@@ -80,7 +80,6 @@ python3 ./wpt/wpt run ladybird \
|
||||
--manifest ./MANIFEST.json \
|
||||
--webdriver-arg="--certificate=${PWD}/wpt/tools/certs/cacert.pem" \
|
||||
--webdriver-arg="--certificate=${SERENITY_SOURCE_DIR}/Build/lagom/cacert.pem" \
|
||||
--webdriver-arg="--enable-qt-networking" \
|
||||
--log-raw "${wpt_run_log_filename}"
|
||||
|
||||
# Update expectations metadata files if requested
|
||||
|
||||
Reference in New Issue
Block a user