diff options
author | DexesTTP <dexes.ttp@gmail.com> | 2022-04-30 12:06:30 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-05-15 12:17:36 +0200 |
commit | c00ae53b664a3a403bfb7036d6aa5fba19e790eb (patch) | |
tree | 107b2ebf31f8e6c5e33ed9937b0064358fbdbc9f /Userland | |
parent | 2a359695c6d2b96080c64bdbcf8cd553bcab71d5 (diff) | |
download | serenity-c00ae53b664a3a403bfb7036d6aa5fba19e790eb.zip |
LibWeb: Abstract the LibProtocol ResourceLoader connection
This is the final component that required LibProtocol as a dependency
of LibWeb. With this, we can now remove the dependency, and LibWeb no
longer requires IPC to work :^)
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Applications/Browser/DownloadWidget.cpp | 3 | ||||
-rw-r--r-- | Userland/Applications/Browser/DownloadWidget.h | 4 | ||||
-rw-r--r-- | Userland/Applications/Browser/main.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CMakeLists.txt | 7 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp | 46 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Loader/ResourceLoader.h | 58 | ||||
-rw-r--r-- | Userland/Libraries/LibWebView/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWebView/RequestServerAdapter.cpp | 103 | ||||
-rw-r--r-- | Userland/Libraries/LibWebView/RequestServerAdapter.h | 53 | ||||
-rw-r--r-- | Userland/Services/WebContent/main.cpp | 3 |
10 files changed, 245 insertions, 37 deletions
diff --git a/Userland/Applications/Browser/DownloadWidget.cpp b/Userland/Applications/Browser/DownloadWidget.cpp index cfd2c82f8b..cfc6df68dd 100644 --- a/Userland/Applications/Browser/DownloadWidget.cpp +++ b/Userland/Applications/Browser/DownloadWidget.cpp @@ -23,7 +23,6 @@ #include <LibWeb/Loader/ResourceLoader.h> #include <LibConfig/Client.h> -#include <LibProtocol/RequestClient.h> namespace Browser { @@ -41,7 +40,7 @@ DownloadWidget::DownloadWidget(const URL& url) auto close_on_finish = Config::read_bool("Browser", "Preferences", "CloseDownloadWidgetOnFinish", false); m_elapsed_timer.start(); - m_download = Web::ResourceLoader::the().protocol_client().start_request("GET", url); + m_download = Web::ResourceLoader::the().connector().start_request("GET", url); VERIFY(m_download); m_download->on_progress = [this](Optional<u32> total_size, u32 downloaded_size) { did_progress(total_size.value(), downloaded_size); diff --git a/Userland/Applications/Browser/DownloadWidget.h b/Userland/Applications/Browser/DownloadWidget.h index c4b8604856..21fc7641ab 100644 --- a/Userland/Applications/Browser/DownloadWidget.h +++ b/Userland/Applications/Browser/DownloadWidget.h @@ -13,7 +13,7 @@ #include <LibGUI/ImageWidget.h> #include <LibGUI/Progressbar.h> #include <LibGUI/Widget.h> -#include <LibProtocol/Request.h> +#include <LibWeb/Loader/ResourceLoader.h> namespace Browser { @@ -31,7 +31,7 @@ private: URL m_url; String m_destination_path; - RefPtr<Protocol::Request> m_download; + RefPtr<Web::ResourceLoaderConnectorRequest> m_download; RefPtr<GUI::Progressbar> m_progressbar; RefPtr<GUI::Label> m_progress_label; RefPtr<GUI::Button> m_cancel_button; diff --git a/Userland/Applications/Browser/main.cpp b/Userland/Applications/Browser/main.cpp index 3d4665c209..65c9cd5aab 100644 --- a/Userland/Applications/Browser/main.cpp +++ b/Userland/Applications/Browser/main.cpp @@ -23,6 +23,8 @@ #include <LibGUI/Icon.h> #include <LibGUI/TabWidget.h> #include <LibMain/Main.h> +#include <LibWeb/Loader/ResourceLoader.h> +#include <LibWebView/RequestServerAdapter.h> #include <unistd.h> namespace Browser { @@ -87,6 +89,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) TRY(Core::System::unveil("/bin/BrowserSettings", "x")); TRY(Core::System::unveil(nullptr, nullptr)); + Web::ResourceLoader::initialize(TRY(WebView::RequestServerAdapter::try_create())); + auto app_icon = GUI::Icon::default_icon("app-browser"); Browser::g_home_url = Config::read_string("Browser", "Preferences", "Home", "file:///res/html/misc/welcome.html"); diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index c34632302a..9e10768eef 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -359,11 +359,6 @@ set(SOURCES XML/XMLDocumentBuilder.cpp ) -set(GENERATED_SOURCES - ../../Services/RequestServer/RequestClientEndpoint.h - ../../Services/RequestServer/RequestServerEndpoint.h -) - generate_css_implementation() set(GENERATED_SOURCES @@ -377,7 +372,7 @@ set(GENERATED_SOURCES ) serenity_lib(LibWeb web) -target_link_libraries(LibWeb LibCore LibJS LibMarkdown LibGemini LibGUI LibGfx LibTextCodec LibProtocol LibWasm LibXML) +target_link_libraries(LibWeb LibCore LibJS LibMarkdown LibGemini LibGUI LibGfx LibTextCodec LibWasm LibXML) link_with_unicode_data(LibWeb) generate_js_wrappers(LibWeb) diff --git a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp index e45ae44d27..c79b17ea8e 100644 --- a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp +++ b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -10,8 +11,6 @@ #include <LibCore/ElapsedTimer.h> #include <LibCore/EventLoop.h> #include <LibCore/File.h> -#include <LibProtocol/Request.h> -#include <LibProtocol/RequestClient.h> #include <LibWeb/Loader/ContentFilter.h> #include <LibWeb/Loader/LoadRequest.h> #include <LibWeb/Loader/ProxyMappings.h> @@ -24,35 +23,50 @@ namespace Web { -ResourceLoader& ResourceLoader::the() +ResourceLoaderConnectorRequest::ResourceLoaderConnectorRequest() = default; + +ResourceLoaderConnectorRequest::~ResourceLoaderConnectorRequest() = default; + +ResourceLoaderConnector::ResourceLoaderConnector() = default; + +ResourceLoaderConnector::~ResourceLoaderConnector() = default; + +static RefPtr<ResourceLoader> s_resource_loader; + +void ResourceLoader::initialize(RefPtr<ResourceLoaderConnector> connector) { - static RefPtr<ResourceLoader> s_the; - if (!s_the) - s_the = ResourceLoader::try_create().release_value_but_fixme_should_propagate_errors(); - return *s_the; + if (connector) + s_resource_loader = ResourceLoader::try_create(connector.release_nonnull()).release_value_but_fixme_should_propagate_errors(); } -ErrorOr<NonnullRefPtr<ResourceLoader>> ResourceLoader::try_create() +ResourceLoader& ResourceLoader::the() { + if (!s_resource_loader) { + dbgln("Web::ResourceLoader was not initialized"); + VERIFY_NOT_REACHED(); + } + return *s_resource_loader; +} - auto protocol_client = TRY(Protocol::RequestClient::try_create()); - return adopt_nonnull_ref_or_enomem(new (nothrow) ResourceLoader(move(protocol_client))); +ErrorOr<NonnullRefPtr<ResourceLoader>> ResourceLoader::try_create(NonnullRefPtr<ResourceLoaderConnector> connector) +{ + return adopt_nonnull_ref_or_enomem(new (nothrow) ResourceLoader(move(connector))); } -ResourceLoader::ResourceLoader(NonnullRefPtr<Protocol::RequestClient> protocol_client) - : m_protocol_client(move(protocol_client)) +ResourceLoader::ResourceLoader(NonnullRefPtr<ResourceLoaderConnector> connector) + : m_connector(move(connector)) , m_user_agent(default_user_agent) { } void ResourceLoader::prefetch_dns(AK::URL const& url) { - m_protocol_client->ensure_connection(url, RequestServer::CacheLevel::ResolveOnly); + m_connector->prefetch_dns(url); } void ResourceLoader::preconnect(AK::URL const& url) { - m_protocol_client->ensure_connection(url, RequestServer::CacheLevel::CreateConnection); + m_connector->preconnect(url); } static HashMap<LoadRequest, NonnullRefPtr<Resource>> s_resource_cache; @@ -217,7 +231,7 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, Has headers.set(it.key, it.value); } - auto protocol_request = protocol_client().start_request(request.method(), url, headers, request.body(), proxy); + auto protocol_request = m_connector->start_request(request.method(), url, headers, request.body(), proxy); if (!protocol_request) { auto start_request_failure_msg = "Failed to initiate load"sv; log_failure(request, start_request_failure_msg); @@ -248,7 +262,7 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, Has }); }; protocol_request->set_should_buffer_all_input(true); - protocol_request->on_certificate_requested = []() -> Protocol::Request::CertificateAndKey { + protocol_request->on_certificate_requested = []() -> ResourceLoaderConnectorRequest::CertificateAndKey { return {}; }; ++m_pending_loads; diff --git a/Userland/Libraries/LibWeb/Loader/ResourceLoader.h b/Userland/Libraries/LibWeb/Loader/ResourceLoader.h index 59cce5bd75..986447316a 100644 --- a/Userland/Libraries/LibWeb/Loader/ResourceLoader.h +++ b/Userland/Libraries/LibWeb/Loader/ResourceLoader.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -7,15 +8,13 @@ #pragma once #include <AK/Function.h> +#include <AK/HashMap.h> +#include <AK/String.h> #include <AK/URL.h> #include <LibCore/Object.h> +#include <LibCore/Proxy.h> #include <LibWeb/Loader/Resource.h> -namespace Protocol { -class RequestClient; -class Request; -} - namespace Web { #if ARCH(I386) @@ -26,9 +25,46 @@ namespace Web { constexpr auto default_user_agent = "Mozilla/5.0 (SerenityOS; " CPU_STRING ") LibWeb+LibJS/1.0 Browser/1.0"; +class ResourceLoaderConnectorRequest : public RefCounted<ResourceLoaderConnectorRequest> { +public: + virtual ~ResourceLoaderConnectorRequest(); + + struct CertificateAndKey { + String certificate; + String key; + }; + + virtual void set_should_buffer_all_input(bool) = 0; + virtual bool stop() = 0; + + virtual void stream_into(Core::Stream::Stream&) = 0; + + Function<void(bool success, u32 total_size, HashMap<String, String, CaseInsensitiveStringTraits> const& response_headers, Optional<u32> response_code, ReadonlyBytes payload)> on_buffered_request_finish; + Function<void(bool success, u32 total_size)> on_finish; + Function<void(Optional<u32> total_size, u32 downloaded_size)> on_progress; + Function<CertificateAndKey()> on_certificate_requested; + +protected: + explicit ResourceLoaderConnectorRequest(); +}; + +class ResourceLoaderConnector : public RefCounted<ResourceLoaderConnector> { +public: + virtual ~ResourceLoaderConnector(); + + virtual void prefetch_dns(AK::URL const&) = 0; + virtual void preconnect(AK::URL const&) = 0; + + virtual RefPtr<ResourceLoaderConnectorRequest> start_request(String const& method, AK::URL const&, HashMap<String, String> const& request_headers = {}, ReadonlyBytes request_body = {}, Core::ProxyData const& = {}) = 0; + +protected: + explicit ResourceLoaderConnector(); +}; + class ResourceLoader : public Core::Object { C_OBJECT_ABSTRACT(ResourceLoader) public: + static void initialize(RefPtr<ResourceLoaderConnector>); static ResourceLoader& the(); RefPtr<Resource> load_resource(Resource::Type, LoadRequest&); @@ -36,6 +72,8 @@ public: void load(LoadRequest&, Function<void(ReadonlyBytes, HashMap<String, String, CaseInsensitiveStringTraits> const& response_headers, Optional<u32> status_code)> success_callback, Function<void(String const&, Optional<u32> status_code)> error_callback = nullptr); void load(const AK::URL&, Function<void(ReadonlyBytes, HashMap<String, String, CaseInsensitiveStringTraits> const& response_headers, Optional<u32> status_code)> success_callback, Function<void(String const&, Optional<u32> status_code)> error_callback = nullptr); + ResourceLoaderConnector& connector() { return *m_connector; } + void prefetch_dns(AK::URL const&); void preconnect(AK::URL const&); @@ -43,8 +81,6 @@ public: int pending_loads() const { return m_pending_loads; } - Protocol::RequestClient& protocol_client() { return *m_protocol_client; } - String const& user_agent() const { return m_user_agent; } void set_user_agent(String const& user_agent) { m_user_agent = user_agent; } @@ -52,15 +88,15 @@ public: void evict_from_cache(LoadRequest const&); private: - ResourceLoader(NonnullRefPtr<Protocol::RequestClient> protocol_client); - static ErrorOr<NonnullRefPtr<ResourceLoader>> try_create(); + ResourceLoader(NonnullRefPtr<ResourceLoaderConnector>); + static ErrorOr<NonnullRefPtr<ResourceLoader>> try_create(NonnullRefPtr<ResourceLoaderConnector>); static bool is_port_blocked(int port); int m_pending_loads { 0 }; - HashTable<NonnullRefPtr<Protocol::Request>> m_active_requests; - RefPtr<Protocol::RequestClient> m_protocol_client; + HashTable<NonnullRefPtr<ResourceLoaderConnectorRequest>> m_active_requests; + NonnullRefPtr<ResourceLoaderConnector> m_connector; String m_user_agent; }; diff --git a/Userland/Libraries/LibWebView/CMakeLists.txt b/Userland/Libraries/LibWebView/CMakeLists.txt index 4fa461b816..77852b5ed6 100644 --- a/Userland/Libraries/LibWebView/CMakeLists.txt +++ b/Userland/Libraries/LibWebView/CMakeLists.txt @@ -2,6 +2,7 @@ set(SOURCES DOMTreeModel.cpp ImageDecoderClientAdapter.cpp OutOfProcessWebView.cpp + RequestServerAdapter.cpp StylePropertiesModel.cpp WebContentClient.cpp WebSocketClientAdapter.cpp diff --git a/Userland/Libraries/LibWebView/RequestServerAdapter.cpp b/Userland/Libraries/LibWebView/RequestServerAdapter.cpp new file mode 100644 index 0000000000..be2374d869 --- /dev/null +++ b/Userland/Libraries/LibWebView/RequestServerAdapter.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibCore/File.h> +#include <LibProtocol/Request.h> +#include <LibProtocol/RequestClient.h> +#include <LibWebView/RequestServerAdapter.h> + +namespace WebView { + +ErrorOr<NonnullRefPtr<RequestServerRequestAdapter>> RequestServerRequestAdapter::try_create(NonnullRefPtr<Protocol::Request> request) +{ + return adopt_nonnull_ref_or_enomem(new (nothrow) RequestServerRequestAdapter(move(request))); +} + +RequestServerRequestAdapter::RequestServerRequestAdapter(NonnullRefPtr<Protocol::Request> request) + : m_request(request) +{ + request->on_buffered_request_finish = [weak_this = make_weak_ptr()](auto success, auto total_size, auto const& response_headers, auto response_code, auto payload) { + if (auto strong_this = weak_this.strong_ref()) + if (strong_this->on_buffered_request_finish) + strong_this->on_buffered_request_finish(success, total_size, response_headers, response_code, move(payload)); + }; + + request->on_finish = [weak_this = make_weak_ptr()](bool success, u32 total_size) { + if (auto strong_this = weak_this.strong_ref()) + if (strong_this->on_finish) + strong_this->on_finish(success, total_size); + }; + + request->on_progress = [weak_this = make_weak_ptr()](Optional<u32> total_size, u32 downloaded_size) { + if (auto strong_this = weak_this.strong_ref()) + if (strong_this->on_progress) + strong_this->on_progress(total_size, downloaded_size); + }; + + request->on_certificate_requested = [weak_this = make_weak_ptr()]() { + if (auto strong_this = weak_this.strong_ref()) { + if (strong_this->on_certificate_requested) { + auto certificate_and_key = strong_this->on_certificate_requested(); + return Protocol::Request::CertificateAndKey { + .certificate = move(certificate_and_key.certificate), + .key = move(certificate_and_key.key), + }; + } + } + + return Protocol::Request::CertificateAndKey {}; + }; +} + +RequestServerRequestAdapter::~RequestServerRequestAdapter() = default; + +void RequestServerRequestAdapter::set_should_buffer_all_input(bool should_buffer_all_input) +{ + m_request->set_should_buffer_all_input(should_buffer_all_input); +} + +bool RequestServerRequestAdapter::stop() +{ + return m_request->stop(); +} + +void RequestServerRequestAdapter::stream_into(Core::Stream::Stream& stream) +{ + m_request->stream_into(stream); +} + +ErrorOr<NonnullRefPtr<RequestServerAdapter>> RequestServerAdapter::try_create() +{ + auto protocol_client = TRY(Protocol::RequestClient::try_create()); + return adopt_nonnull_ref_or_enomem(new (nothrow) RequestServerAdapter(move(protocol_client))); +} + +RequestServerAdapter::RequestServerAdapter(NonnullRefPtr<Protocol::RequestClient> protocol_client) + : m_protocol_client(protocol_client) +{ +} + +RequestServerAdapter::~RequestServerAdapter() = default; + +RefPtr<Web::ResourceLoaderConnectorRequest> RequestServerAdapter::start_request(String const& method, URL const& url, HashMap<String, String> const& headers, ReadonlyBytes body, Core::ProxyData const& proxy) +{ + auto protocol_request = m_protocol_client->start_request(method, url, headers, body, proxy); + if (!protocol_request) + return {}; + return RequestServerRequestAdapter::try_create(protocol_request.release_nonnull()).release_value_but_fixme_should_propagate_errors(); +} + +void RequestServerAdapter::prefetch_dns(AK::URL const& url) +{ + m_protocol_client->ensure_connection(url, RequestServer::CacheLevel::ResolveOnly); +} + +void RequestServerAdapter::preconnect(AK::URL const& url) +{ + m_protocol_client->ensure_connection(url, RequestServer::CacheLevel::CreateConnection); +} + +} diff --git a/Userland/Libraries/LibWebView/RequestServerAdapter.h b/Userland/Libraries/LibWebView/RequestServerAdapter.h new file mode 100644 index 0000000000..0aca3dbdcb --- /dev/null +++ b/Userland/Libraries/LibWebView/RequestServerAdapter.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Function.h> +#include <AK/URL.h> +#include <LibWeb/Loader/ResourceLoader.h> + +namespace Protocol { +class Request; +class RequestClient; +} + +namespace WebView { + +class RequestServerRequestAdapter + : public Web::ResourceLoaderConnectorRequest + , public Weakable<RequestServerRequestAdapter> { +public: + static ErrorOr<NonnullRefPtr<RequestServerRequestAdapter>> try_create(NonnullRefPtr<Protocol::Request>); + virtual ~RequestServerRequestAdapter() override; + + virtual void set_should_buffer_all_input(bool) override; + virtual bool stop() override; + + virtual void stream_into(Core::Stream::Stream&) override; + +private: + RequestServerRequestAdapter(NonnullRefPtr<Protocol::Request>); + NonnullRefPtr<Protocol::Request> m_request; +}; + +class RequestServerAdapter : public Web::ResourceLoaderConnector { +public: + static ErrorOr<NonnullRefPtr<RequestServerAdapter>> try_create(); + virtual ~RequestServerAdapter() override; + + virtual void prefetch_dns(AK::URL const& url) override; + virtual void preconnect(AK::URL const& url) override; + + virtual RefPtr<Web::ResourceLoaderConnectorRequest> start_request(String const& method, URL const&, HashMap<String, String> const& request_headers = {}, ReadonlyBytes request_body = {}, Core::ProxyData const& = {}) override; + +private: + RequestServerAdapter(NonnullRefPtr<Protocol::RequestClient> protocol_client); + + RefPtr<Protocol::RequestClient> m_protocol_client; +}; + +} diff --git a/Userland/Services/WebContent/main.cpp b/Userland/Services/WebContent/main.cpp index b7bfccf6e4..290a34b9a2 100644 --- a/Userland/Services/WebContent/main.cpp +++ b/Userland/Services/WebContent/main.cpp @@ -10,8 +10,10 @@ #include <LibIPC/SingleServer.h> #include <LibMain/Main.h> #include <LibWeb/ImageDecoding.h> +#include <LibWeb/Loader/ResourceLoader.h> #include <LibWeb/WebSockets/WebSocket.h> #include <LibWebView/ImageDecoderClientAdapter.h> +#include <LibWebView/RequestServerAdapter.h> #include <LibWebView/WebSocketClientAdapter.h> #include <WebContent/ConnectionFromClient.h> @@ -28,6 +30,7 @@ ErrorOr<int> serenity_main(Main::Arguments) Web::ImageDecoding::Decoder::initialize(WebView::ImageDecoderClientAdapter::create()); Web::WebSockets::WebSocketClientManager::initialize(TRY(WebView::WebSocketClientManagerAdapter::try_create())); + Web::ResourceLoader::initialize(TRY(WebView::RequestServerAdapter::try_create())); auto client = TRY(IPC::take_over_accepted_client_from_system_server<WebContent::ConnectionFromClient>()); return event_loop.exec(); |