1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-09-13 07:17:34 +00:00

Everywhere: Merge the WebSocket service into RequestServer

This keeps the APIs separate as they are wildly different, a future
improvement could be to somehow unify the APIs (if possible).

Closes #23080.
This commit is contained in:
Ali Mohammad Pur 2024-03-06 01:50:52 +01:00 committed by Jelle Raaijmakers
parent daf5484d6b
commit 6dfb2f9dc8
56 changed files with 231 additions and 845 deletions

View file

@ -56,11 +56,6 @@
android:enabled="true"
android:exported="false"
android:process=":RequestServer" />
<service
android:name=".WebSocketService"
android:enabled="true"
android:exported="false"
android:process=":WebSocket" />
<service
android:name=".ImageDecoderService"
android:enabled="true"

View file

@ -28,7 +28,6 @@
#include <LibWeb/Platform/AudioCodecPluginAgnostic.h>
#include <LibWeb/Platform/EventLoopPluginSerenity.h>
#include <LibWebView/RequestServerAdapter.h>
#include <LibWebView/WebSocketClientAdapter.h>
#include <WebContent/ConnectionFromClient.h>
#include <WebContent/PageHost.h>
@ -37,11 +36,6 @@ static ErrorOr<NonnullRefPtr<Protocol::RequestClient>> bind_request_server_servi
return bind_service<Protocol::RequestClient>(&bind_request_server_java);
}
static ErrorOr<NonnullRefPtr<Protocol::WebSocketClient>> bind_web_socket_service()
{
return bind_service<Protocol::WebSocketClient>(&bind_web_socket_java);
}
template ErrorOr<NonnullRefPtr<ImageDecoderClient::Client>, Error>
bind_service<ImageDecoderClient::Client>(void (*)(int, int));
@ -64,9 +58,6 @@ ErrorOr<int> service_main(int ipc_socket, int fd_passing_socket)
auto request_server_client = TRY(bind_request_server_service());
Web::ResourceLoader::initialize(TRY(WebView::RequestServerAdapter::try_create(move(request_server_client))));
auto web_socket_client = TRY(bind_web_socket_service());
Web::WebSockets::WebSocketClientManager::initialize(TRY(WebView::WebSocketClientManagerAdapter::try_create(move(web_socket_client))));
bool is_layout_test_mode = false;
Web::HTML::Window::set_internals_object_exposed(is_layout_test_mode);

View file

@ -11,7 +11,6 @@
jobject global_instance;
jclass global_class_reference;
jmethodID bind_request_server_method;
jmethodID bind_web_socket_method;
jmethodID bind_image_decoder_method;
extern "C" JNIEXPORT void JNICALL
@ -30,11 +29,6 @@ Java_org_serenityos_ladybird_WebContentService_nativeInit(JNIEnv* env, jobject t
TODO();
bind_request_server_method = method;
method = env->GetMethodID(global_class_reference, "bindWebSocket", "(II)V");
if (!method)
TODO();
bind_web_socket_method = method;
method = env->GetMethodID(global_class_reference, "bindImageDecoder", "(II)V");
if (!method)
TODO();
@ -47,12 +41,6 @@ void bind_request_server_java(int ipc_socket, int fd_passing_socket)
env.get()->CallVoidMethod(global_instance, bind_request_server_method, ipc_socket, fd_passing_socket);
}
void bind_web_socket_java(int ipc_socket, int fd_passing_socket)
{
Ladybird::JavaEnvironment env(global_vm);
env.get()->CallVoidMethod(global_instance, bind_web_socket_method, ipc_socket, fd_passing_socket);
}
void bind_image_decoder_java(int ipc_socket, int fd_passing_socket)
{
Ladybird::JavaEnvironment env(global_vm);

View file

@ -1,41 +0,0 @@
/*
* Copyright (c) 2021, Dex <dexes.ttp@gmail.com>
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/LexicalPath.h>
#include <Ladybird/Utilities.h>
#include <LibCore/ArgsParser.h>
#include <LibCore/EventLoop.h>
#include <LibCore/LocalServer.h>
#include <LibCore/System.h>
#include <LibFileSystem/FileSystem.h>
#include <LibIPC/SingleServer.h>
#include <LibTLS/Certificate.h>
#include <WebSocket/ConnectionFromClient.h>
// FIXME: Share b/w RequestServer and WebSocket
ErrorOr<ByteString> find_certificates(StringView serenity_resource_root)
{
auto cert_path = ByteString::formatted("{}/ladybird/cacert.pem", serenity_resource_root);
if (!FileSystem::exists(cert_path))
return Error::from_string_view("Don't know how to load certs!"sv);
return cert_path;
}
ErrorOr<int> service_main(int ipc_socket, int fd_passing_socket)
{
// Ensure the certificates are read out here.
DefaultRootCACertificates::set_default_certificate_paths(Vector { TRY(find_certificates(s_serenity_resource_root)) });
[[maybe_unused]] auto& certs = DefaultRootCACertificates::the();
Core::EventLoop event_loop;
auto socket = TRY(Core::LocalSocket::adopt_fd(ipc_socket));
auto client = TRY(WebSocket::ConnectionFromClient::try_create(move(socket)));
client->set_fd_passing_socket(TRY(Core::LocalSocket::adopt_fd(fd_passing_socket)));
return event_loop.exec();
}

View file

@ -35,21 +35,6 @@ class WebContentService : LadybirdServiceBase("WebContentService") {
)
}
private fun bindWebSocket(ipcFd: Int, fdPassingFd: Int)
{
val connector = LadybirdServiceConnection(ipcFd, fdPassingFd, resourceDir)
connector.onDisconnect = {
// FIXME: Notify impl that service is dead and might need restarted
Log.e(TAG, "WebSocket Died! :(")
}
// FIXME: Unbind this at some point maybe
bindService(
Intent(this, WebSocketService::class.java),
connector,
Context.BIND_AUTO_CREATE
)
}
private fun bindImageDecoder(ipcFd: Int, fdPassingFd: Int)
{
val connector = LadybirdServiceConnection(ipcFd, fdPassingFd, resourceDir)

View file

@ -1,21 +0,0 @@
/**
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
package org.serenityos.ladybird
import android.os.Message
class WebSocketService : LadybirdServiceBase("WebSocketService") {
override fun handleServiceSpecificMessage(msg: Message): Boolean {
return false
}
companion object {
init {
System.loadLibrary("websocket")
}
}
}

View file

@ -226,10 +226,9 @@ add_subdirectory(RequestServer)
add_subdirectory(SQLServer)
add_subdirectory(WebContent)
add_subdirectory(WebDriver)
add_subdirectory(WebSocket)
add_subdirectory(WebWorker)
set(ladybird_helper_processes ImageDecoder RequestServer SQLServer WebContent WebDriver WebSocketServer WebWorker headless-browser)
set(ladybird_helper_processes ImageDecoder RequestServer SQLServer WebContent WebDriver WebWorker headless-browser)
add_dependencies(ladybird ${ladybird_helper_processes})
function(create_ladybird_bundle target_name)

View file

@ -178,8 +178,3 @@ ErrorOr<NonnullRefPtr<Protocol::RequestClient>> launch_request_server_process(Re
{
return launch_generic_server_process<Protocol::RequestClient>(candidate_request_server_paths, serenity_resource_root, certificates, "RequestServer"sv);
}
ErrorOr<NonnullRefPtr<Protocol::WebSocketClient>> launch_web_socket_process(ReadonlySpan<ByteString> candidate_web_socket_paths, StringView serenity_resource_root, Vector<ByteString> const& certificates)
{
return launch_generic_server_process<Protocol::WebSocketClient>(candidate_web_socket_paths, serenity_resource_root, certificates, "WebSocket"sv);
}

View file

@ -12,7 +12,6 @@
#include <AK/StringView.h>
#include <LibImageDecoderClient/Client.h>
#include <LibProtocol/RequestClient.h>
#include <LibProtocol/WebSocketClient.h>
#include <LibWeb/Worker/WebWorkerClient.h>
#include <LibWebView/ViewImplementation.h>
#include <LibWebView/WebContentClient.h>
@ -25,4 +24,3 @@ ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content_process(
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, Vector<ByteString> const& certificates);
ErrorOr<NonnullRefPtr<Protocol::RequestClient>> launch_request_server_process(ReadonlySpan<ByteString> candidate_request_server_paths, StringView serenity_resource_root, Vector<ByteString> const& certificates);
ErrorOr<NonnullRefPtr<Protocol::WebSocketClient>> launch_web_socket_process(ReadonlySpan<ByteString> candidate_web_socket_paths, StringView serenity_resource_root, Vector<ByteString> const& certificates);

View file

@ -5,6 +5,8 @@
*/
#include "RequestManagerQt.h"
#include "WebSocketImplQt.h"
#include "WebSocketQt.h"
#include <AK/JsonObject.h>
#include <QNetworkCookie>
@ -76,6 +78,18 @@ ErrorOr<NonnullRefPtr<RequestManagerQt::Request>> RequestManagerQt::Request::cre
return adopt_ref(*new Request(*reply));
}
RefPtr<Web::WebSockets::WebSocketClientSocket> RequestManagerQt::websocket_connect(AK::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)
{

View file

@ -28,6 +28,7 @@ public:
virtual void preconnect(URL const&) override { }
virtual RefPtr<Web::ResourceLoaderConnectorRequest> start_request(ByteString const& method, URL const&, HashMap<ByteString, ByteString> const& request_headers, ReadonlyBytes request_body, Core::ProxyData const&) override;
virtual RefPtr<Web::WebSockets::WebSocketClientSocket> websocket_connect(const URL&, ByteString const& origin, Vector<ByteString> const& protocols) override;
private slots:
void reply_finished(QNetworkReply*);

View file

@ -1,34 +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 "WebSocketClientManagerQt.h"
#include "WebSocketImplQt.h"
#include "WebSocketQt.h"
namespace Ladybird {
NonnullRefPtr<WebSocketClientManagerQt> WebSocketClientManagerQt::create()
{
return adopt_ref(*new WebSocketClientManagerQt());
}
WebSocketClientManagerQt::WebSocketClientManagerQt() = default;
WebSocketClientManagerQt::~WebSocketClientManagerQt() = default;
RefPtr<Web::WebSockets::WebSocketClientSocket> WebSocketClientManagerQt::connect(URL const& url, ByteString const& origin, Vector<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);
}
}

View file

@ -1,28 +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 <LibWeb/WebSockets/WebSocket.h>
#include <LibWebSocket/ConnectionInfo.h>
#include <LibWebSocket/Message.h>
#include <LibWebSocket/WebSocket.h>
#pragma once
namespace Ladybird {
class WebSocketClientManagerQt : public Web::WebSockets::WebSocketClientManager {
public:
static NonnullRefPtr<WebSocketClientManagerQt> create();
virtual ~WebSocketClientManagerQt() override;
virtual RefPtr<Web::WebSockets::WebSocketClientSocket> connect(URL const&, ByteString const& origin, Vector<ByteString> const& protocols) override;
private:
WebSocketClientManagerQt();
};
}

View file

@ -33,7 +33,7 @@ target_link_libraries(RequestServer PRIVATE requestserver)
target_include_directories(requestserver PRIVATE ${SERENITY_SOURCE_DIR}/Userland/Services/)
target_include_directories(requestserver PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/..)
target_link_libraries(requestserver PUBLIC LibCore LibMain LibCrypto LibFileSystem LibGemini LibHTTP LibIPC LibMain LibTLS LibWebView)
target_link_libraries(requestserver PUBLIC LibCore LibMain LibCrypto LibFileSystem LibGemini LibHTTP LibIPC LibMain LibTLS LibWebView LibWebSocket)
if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
# Solaris has socket and networking related functions in two extra libraries
target_link_libraries(requestserver PUBLIC nsl socket)

View file

@ -21,7 +21,6 @@ if (ENABLE_QT)
../Qt/EventLoopImplementationQtEventTarget.cpp
../Qt/RequestManagerQt.cpp
../Qt/StringUtils.cpp
../Qt/WebSocketClientManagerQt.cpp
../Qt/WebSocketQt.cpp
../Qt/WebSocketImplQt.cpp
main.cpp

View file

@ -38,7 +38,6 @@
#if defined(HAVE_QT)
# include <Ladybird/Qt/EventLoopImplementationQt.h>
# include <Ladybird/Qt/RequestManagerQt.h>
# include <Ladybird/Qt/WebSocketClientManagerQt.h>
# include <QCoreApplication>
# if defined(HAVE_QT_MULTIMEDIA)
@ -109,14 +108,11 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
}
#if defined(HAVE_QT)
if (!use_lagom_networking) {
if (!use_lagom_networking)
Web::ResourceLoader::initialize(Ladybird::RequestManagerQt::create());
Web::WebSockets::WebSocketClientManager::initialize(Ladybird::WebSocketClientManagerQt::create());
} else
else
#endif
{
TRY(initialize_lagom_networking(certificates));
}
Web::HTML::Window::set_internals_object_exposed(is_layout_test_mode);
@ -195,9 +191,5 @@ static ErrorOr<void> initialize_lagom_networking(Vector<ByteString> const& certi
auto request_server_client = TRY(launch_request_server_process(candidate_request_server_paths, s_serenity_resource_root, certificates));
Web::ResourceLoader::initialize(TRY(WebView::RequestServerAdapter::try_create(move(request_server_client))));
auto candidate_web_socket_paths = TRY(get_paths_for_helper_process("WebSocket"sv));
auto web_socket_client = TRY(launch_web_socket_process(candidate_web_socket_paths, s_serenity_resource_root, certificates));
Web::WebSockets::WebSocketClientManager::initialize(TRY(WebView::WebSocketClientManagerAdapter::try_create(move(web_socket_client))));
return {};
}

View file

@ -1,18 +0,0 @@
set(SOURCES
"${SERENITY_SOURCE_DIR}/Userland/Services/WebSocket/ConnectionFromClient.cpp"
)
if (ANDROID)
add_library(websocket SHARED
${SOURCES}
../Android/src/main/cpp/WebSocketService.cpp
../Android/src/main/cpp/LadybirdServiceBaseJNI.cpp
../Utilities.cpp
)
else()
add_library(websocket STATIC ${SOURCES})
endif()
add_executable(WebSocketServer main.cpp)
target_link_libraries(WebSocketServer PRIVATE websocket)
set_target_properties(WebSocketServer PROPERTIES OUTPUT_NAME WebSocket)
target_link_libraries(websocket PUBLIC LibCore LibFileSystem LibIPC LibMain LibTLS LibWebSocket LibWebView)

View file

@ -1,54 +0,0 @@
/*
* Copyright (c) 2021, Dex <dexes.ttp@gmail.com>
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/LexicalPath.h>
#include <LibCore/ArgsParser.h>
#include <LibCore/EventLoop.h>
#include <LibCore/LocalServer.h>
#include <LibCore/System.h>
#include <LibFileSystem/FileSystem.h>
#include <LibIPC/SingleServer.h>
#include <LibMain/Main.h>
#include <LibTLS/Certificate.h>
#include <WebSocket/ConnectionFromClient.h>
// FIXME: Share b/w RequestServer and WebSocket
ErrorOr<ByteString> find_certificates(StringView serenity_resource_root)
{
auto cert_path = ByteString::formatted("{}/ladybird/cacert.pem", serenity_resource_root);
if (!FileSystem::exists(cert_path))
return Error::from_string_view("Don't know how to load certs!"sv);
return cert_path;
}
ErrorOr<int> serenity_main(Main::Arguments arguments)
{
AK::set_rich_debug_enabled(true);
int fd_passing_socket { -1 };
StringView serenity_resource_root;
Vector<ByteString> certificates;
Core::ArgsParser args_parser;
args_parser.add_option(fd_passing_socket, "File descriptor of the fd passing socket", "fd-passing-socket", 'c', "fd-passing-socket");
args_parser.add_option(certificates, "Path to a certificate file", "certificate", 'C', "certificate");
args_parser.add_option(serenity_resource_root, "Absolute path to directory for serenity resources", "serenity-resource-root", 'r', "serenity-resource-root");
args_parser.parse(arguments);
// Ensure the certificates are read out here.
if (certificates.is_empty())
certificates.append(TRY(find_certificates(serenity_resource_root)));
DefaultRootCACertificates::set_default_certificate_paths(certificates.span());
[[maybe_unused]] auto& certs = DefaultRootCACertificates::the();
Core::EventLoop event_loop;
auto client = TRY(IPC::take_over_accepted_client_from_system_server<WebSocket::ConnectionFromClient>());
client->set_fd_passing_socket(TRY(Core::LocalSocket::adopt_fd(fd_passing_socket)));
return event_loop.exec();
}

View file

@ -67,9 +67,5 @@ static ErrorOr<void> initialize_lagom_networking(Vector<ByteString> const& certi
auto request_server_client = TRY(launch_request_server_process(candidate_request_server_paths, s_serenity_resource_root, certificates));
Web::ResourceLoader::initialize(TRY(WebView::RequestServerAdapter::try_create(move(request_server_client))));
auto candidate_web_socket_paths = TRY(get_paths_for_helper_process("WebSocket"sv));
auto web_socket_client = TRY(launch_web_socket_process(candidate_web_socket_paths, s_serenity_resource_root, certificates));
Web::WebSockets::WebSocketClientManager::initialize(TRY(WebView::WebSocketClientManagerAdapter::try_create(move(web_socket_client))));
return {};
}