mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:22:45 +00:00 
			
		
		
		
	LibWeb: Serialize and pass to the WebWorker the current ESO
This allows the initial fetch() in the run a worker AO to use the proper values from the outside settings.
This commit is contained in:
		
							parent
							
								
									4d22358e05
								
							
						
					
					
						commit
						b5acc5f2df
					
				
					 12 changed files with 92 additions and 13 deletions
				
			
		|  | @ -3,6 +3,7 @@ source_set("Scripting") { | ||||||
|   deps = [ "//Userland/Libraries/LibWeb:all_generated" ] |   deps = [ "//Userland/Libraries/LibWeb:all_generated" ] | ||||||
|   sources = [ |   sources = [ | ||||||
|     "ClassicScript.cpp", |     "ClassicScript.cpp", | ||||||
|  |     "EnvironmentSettingsSnapshot.cpp", | ||||||
|     "Environments.cpp", |     "Environments.cpp", | ||||||
|     "ExceptionReporter.cpp", |     "ExceptionReporter.cpp", | ||||||
|     "Fetching.cpp", |     "Fetching.cpp", | ||||||
|  |  | ||||||
|  | @ -383,6 +383,7 @@ set(SOURCES | ||||||
|     HTML/PromiseRejectionEvent.cpp |     HTML/PromiseRejectionEvent.cpp | ||||||
|     HTML/Scripting/ClassicScript.cpp |     HTML/Scripting/ClassicScript.cpp | ||||||
|     HTML/Scripting/Environments.cpp |     HTML/Scripting/Environments.cpp | ||||||
|  |     HTML/Scripting/EnvironmentSettingsSnapshot.cpp | ||||||
|     HTML/Scripting/ExceptionReporter.cpp |     HTML/Scripting/ExceptionReporter.cpp | ||||||
|     HTML/Scripting/Fetching.cpp |     HTML/Scripting/Fetching.cpp | ||||||
|     HTML/Scripting/ModuleMap.cpp |     HTML/Scripting/ModuleMap.cpp | ||||||
|  |  | ||||||
|  | @ -0,0 +1,30 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org> | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <LibWeb/HTML/Scripting/EnvironmentSettingsSnapshot.h> | ||||||
|  | 
 | ||||||
|  | namespace Web::HTML { | ||||||
|  | 
 | ||||||
|  | JS_DEFINE_ALLOCATOR(EnvironmentSettingsSnapshot); | ||||||
|  | 
 | ||||||
|  | EnvironmentSettingsSnapshot::EnvironmentSettingsSnapshot(NonnullOwnPtr<JS::ExecutionContext> execution_context, SerializedEnvironmentSettingsObject const& serialized_settings) | ||||||
|  |     : EnvironmentSettingsObject(move(execution_context)) | ||||||
|  |     , m_api_url_character_encoding(serialized_settings.api_url_character_encoding) | ||||||
|  |     , m_url(serialized_settings.api_base_url) | ||||||
|  |     , m_origin(serialized_settings.origin) | ||||||
|  |     , m_policy_container(serialized_settings.policy_container) | ||||||
|  | { | ||||||
|  |     // Why can't we put these in the init list? grandparent class members are strange it seems
 | ||||||
|  |     this->id = serialized_settings.id; | ||||||
|  |     this->creation_url = serialized_settings.creation_url; | ||||||
|  |     this->top_level_creation_url = serialized_settings.top_level_creation_url; | ||||||
|  |     this->top_level_creation_url = serialized_settings.top_level_creation_url; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Out of line to ensure this class has a key function
 | ||||||
|  | EnvironmentSettingsSnapshot::~EnvironmentSettingsSnapshot() = default; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,39 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org> | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <LibWeb/HTML/PolicyContainers.h> | ||||||
|  | #include <LibWeb/HTML/Scripting/Environments.h> | ||||||
|  | #include <LibWeb/HTML/Scripting/SerializedEnvironmentSettingsObject.h> | ||||||
|  | 
 | ||||||
|  | namespace Web::HTML { | ||||||
|  | 
 | ||||||
|  | class EnvironmentSettingsSnapshot final | ||||||
|  |     : public EnvironmentSettingsObject { | ||||||
|  |     JS_CELL(EnvironmentSettingsSnapshot, EnvironmentSettingsObject); | ||||||
|  |     JS_DECLARE_ALLOCATOR(EnvironmentSettingsSnapshot); | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     EnvironmentSettingsSnapshot(NonnullOwnPtr<JS::ExecutionContext>, SerializedEnvironmentSettingsObject const&); | ||||||
|  | 
 | ||||||
|  |     virtual ~EnvironmentSettingsSnapshot() override; | ||||||
|  | 
 | ||||||
|  |     JS::GCPtr<DOM::Document> responsible_document() override { return nullptr; } | ||||||
|  |     String api_url_character_encoding() override { return m_api_url_character_encoding; } | ||||||
|  |     URL api_base_url() override { return m_url; } | ||||||
|  |     Origin origin() override { return m_origin; } | ||||||
|  |     PolicyContainer policy_container() override { return m_policy_container; } | ||||||
|  |     CanUseCrossOriginIsolatedAPIs cross_origin_isolated_capability() override { return CanUseCrossOriginIsolatedAPIs::No; } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     String m_api_url_character_encoding; | ||||||
|  |     URL m_url; | ||||||
|  |     HTML::Origin m_origin; | ||||||
|  |     HTML::PolicyContainer m_policy_container; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -57,7 +57,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Worker>> Worker::create(String const& scrip | ||||||
|     // Technically not a fixme if our policy is not to throw errors :^)
 |     // Technically not a fixme if our policy is not to throw errors :^)
 | ||||||
| 
 | 
 | ||||||
|     // 2. Let outside settings be the current settings object.
 |     // 2. Let outside settings be the current settings object.
 | ||||||
|     auto& outside_settings = document.relevant_settings_object(); |     auto& outside_settings = current_settings_object(); | ||||||
| 
 | 
 | ||||||
|     // 3. Parse the scriptURL argument relative to outside settings.
 |     // 3. Parse the scriptURL argument relative to outside settings.
 | ||||||
|     auto url = document.parse_url(script_url.to_byte_string()); |     auto url = document.parse_url(script_url.to_byte_string()); | ||||||
|  | @ -110,7 +110,7 @@ void Worker::run_a_worker(URL& url, EnvironmentSettingsObject& outside_settings, | ||||||
|     // and is shared. Run the rest of these steps in that agent.
 |     // and is shared. Run the rest of these steps in that agent.
 | ||||||
| 
 | 
 | ||||||
|     // Note: This spawns a new process to act as the 'agent' for the worker.
 |     // Note: This spawns a new process to act as the 'agent' for the worker.
 | ||||||
|     m_agent = heap().allocate<WorkerAgent>(outside_settings.realm(), url, options, port); |     m_agent = heap().allocate<WorkerAgent>(outside_settings.realm(), url, options, port, outside_settings); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // https://html.spec.whatwg.org/multipage/workers.html#dom-worker-terminate
 | // https://html.spec.whatwg.org/multipage/workers.html#dom-worker-terminate
 | ||||||
|  |  | ||||||
|  | @ -13,10 +13,11 @@ namespace Web::HTML { | ||||||
| 
 | 
 | ||||||
| JS_DEFINE_ALLOCATOR(WorkerAgent); | JS_DEFINE_ALLOCATOR(WorkerAgent); | ||||||
| 
 | 
 | ||||||
| WorkerAgent::WorkerAgent(URL url, WorkerOptions const& options, JS::GCPtr<MessagePort> outside_port) | WorkerAgent::WorkerAgent(URL url, WorkerOptions const& options, JS::GCPtr<MessagePort> outside_port, JS::NonnullGCPtr<EnvironmentSettingsObject> outside_settings) | ||||||
|     : m_worker_options(options) |     : m_worker_options(options) | ||||||
|     , m_url(move(url)) |     , m_url(move(url)) | ||||||
|     , m_outside_port(outside_port) |     , m_outside_port(outside_port) | ||||||
|  |     , m_outside_settings(outside_settings) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -41,7 +42,7 @@ void WorkerAgent::initialize(JS::Realm& realm) | ||||||
|     m_worker_ipc = make_ref_counted<WebWorkerClient>(move(worker_socket)); |     m_worker_ipc = make_ref_counted<WebWorkerClient>(move(worker_socket)); | ||||||
|     m_worker_ipc->set_fd_passing_socket(move(fd_passing_socket)); |     m_worker_ipc->set_fd_passing_socket(move(fd_passing_socket)); | ||||||
| 
 | 
 | ||||||
|     m_worker_ipc->async_start_dedicated_worker(m_url, m_worker_options.type, m_worker_options.credentials, m_worker_options.name, move(data_holder)); |     m_worker_ipc->async_start_dedicated_worker(m_url, m_worker_options.type, m_worker_options.credentials, m_worker_options.name, move(data_holder), m_outside_settings->serialize()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WorkerAgent::visit_edges(Cell::Visitor& visitor) | void WorkerAgent::visit_edges(Cell::Visitor& visitor) | ||||||
|  | @ -49,6 +50,7 @@ void WorkerAgent::visit_edges(Cell::Visitor& visitor) | ||||||
|     Base::visit_edges(visitor); |     Base::visit_edges(visitor); | ||||||
|     visitor.visit(m_message_port); |     visitor.visit(m_message_port); | ||||||
|     visitor.visit(m_outside_port); |     visitor.visit(m_outside_port); | ||||||
|  |     visitor.visit(m_outside_settings); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ class WorkerAgent : public JS::Cell { | ||||||
|     JS_CELL(Agent, JS::Cell); |     JS_CELL(Agent, JS::Cell); | ||||||
|     JS_DECLARE_ALLOCATOR(WorkerAgent); |     JS_DECLARE_ALLOCATOR(WorkerAgent); | ||||||
| 
 | 
 | ||||||
|     WorkerAgent(URL url, WorkerOptions const& options, JS::GCPtr<MessagePort> outside_port); |     WorkerAgent(URL url, WorkerOptions const& options, JS::GCPtr<MessagePort> outside_port, JS::NonnullGCPtr<EnvironmentSettingsObject> outside_settings); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     virtual void initialize(JS::Realm&) override; |     virtual void initialize(JS::Realm&) override; | ||||||
|  | @ -33,6 +33,7 @@ private: | ||||||
| 
 | 
 | ||||||
|     JS::GCPtr<MessagePort> m_message_port; |     JS::GCPtr<MessagePort> m_message_port; | ||||||
|     JS::GCPtr<MessagePort> m_outside_port; |     JS::GCPtr<MessagePort> m_outside_port; | ||||||
|  |     JS::NonnullGCPtr<EnvironmentSettingsObject> m_outside_settings; | ||||||
| 
 | 
 | ||||||
|     RefPtr<Web::HTML::WebWorkerClient> m_worker_ipc; |     RefPtr<Web::HTML::WebWorkerClient> m_worker_ipc; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -1,10 +1,11 @@ | ||||||
| #include <AK/URL.h> | #include <AK/URL.h> | ||||||
| #include <LibIPC/File.h> | #include <LibIPC/File.h> | ||||||
| #include <LibWeb/HTML/StructuredSerialize.h> | #include <LibWeb/HTML/StructuredSerialize.h> | ||||||
|  | #include <LibWeb/HTML/Scripting/SerializedEnvironmentSettingsObject.h> | ||||||
| 
 | 
 | ||||||
| endpoint WebWorkerServer { | endpoint WebWorkerServer { | ||||||
| 
 | 
 | ||||||
|     start_dedicated_worker(URL url, String type, String credentials, String name, Web::HTML::TransferDataHolder message_port) =| |     start_dedicated_worker(URL url, String type, String credentials, String name, Web::HTML::TransferDataHolder message_port, Web::HTML::SerializedEnvironmentSettingsObject outside_settings) =| | ||||||
| 
 | 
 | ||||||
|     handle_file_return(i32 error, Optional<IPC::File> file, i32 request_id) =| |     handle_file_return(i32 error, Optional<IPC::File> file, i32 request_id) =| | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -52,12 +52,12 @@ Web::Page const& ConnectionFromClient::page() const | ||||||
|     return m_page_host->page(); |     return m_page_host->page(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConnectionFromClient::start_dedicated_worker(URL const& url, String const& type, String const&, String const&, Web::HTML::TransferDataHolder const& implicit_port) | void ConnectionFromClient::start_dedicated_worker(URL const& url, String const& type, String const&, String const&, Web::HTML::TransferDataHolder const& implicit_port, Web::HTML::SerializedEnvironmentSettingsObject const& outside_settings) | ||||||
| { | { | ||||||
|     m_worker_host = make_ref_counted<DedicatedWorkerHost>(url, type); |     m_worker_host = make_ref_counted<DedicatedWorkerHost>(url, type); | ||||||
|     // FIXME: Yikes, const_cast to move? Feels like a LibIPC bug.
 |     // FIXME: Yikes, const_cast to move? Feels like a LibIPC bug.
 | ||||||
|     //     We should be able to move non-copyable types from a Message type.
 |     //     We should be able to move non-copyable types from a Message type.
 | ||||||
|     m_worker_host->run(page(), move(const_cast<Web::HTML::TransferDataHolder&>(implicit_port))); |     m_worker_host->run(page(), move(const_cast<Web::HTML::TransferDataHolder&>(implicit_port)), outside_settings); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConnectionFromClient::handle_file_return(i32 error, Optional<IPC::File> const& file, i32 request_id) | void ConnectionFromClient::handle_file_return(i32 error, Optional<IPC::File> const& file, i32 request_id) | ||||||
|  |  | ||||||
|  | @ -39,7 +39,7 @@ private: | ||||||
|     Web::Page& page(); |     Web::Page& page(); | ||||||
|     Web::Page const& page() const; |     Web::Page const& page() const; | ||||||
| 
 | 
 | ||||||
|     virtual void start_dedicated_worker(URL const& url, String const&, String const&, String const&, Web::HTML::TransferDataHolder const&) override; |     virtual void start_dedicated_worker(URL const& url, String const&, String const&, String const&, Web::HTML::TransferDataHolder const&, Web::HTML::SerializedEnvironmentSettingsObject const&) override; | ||||||
|     virtual void handle_file_return(i32 error, Optional<IPC::File> const& file, i32 request_id) override; |     virtual void handle_file_return(i32 error, Optional<IPC::File> const& file, i32 request_id) override; | ||||||
| 
 | 
 | ||||||
|     JS::Handle<PageHost> m_page_host; |     JS::Handle<PageHost> m_page_host; | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| #include <LibWeb/Fetch/Fetching/Fetching.h> | #include <LibWeb/Fetch/Fetching/Fetching.h> | ||||||
| #include <LibWeb/Fetch/Infrastructure/FetchAlgorithms.h> | #include <LibWeb/Fetch/Infrastructure/FetchAlgorithms.h> | ||||||
| #include <LibWeb/HTML/Scripting/ClassicScript.h> | #include <LibWeb/HTML/Scripting/ClassicScript.h> | ||||||
|  | #include <LibWeb/HTML/Scripting/EnvironmentSettingsSnapshot.h> | ||||||
| #include <LibWeb/HTML/Scripting/Fetching.h> | #include <LibWeb/HTML/Scripting/Fetching.h> | ||||||
| #include <LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h> | #include <LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h> | ||||||
| #include <LibWeb/HTML/WorkerDebugConsoleClient.h> | #include <LibWeb/HTML/WorkerDebugConsoleClient.h> | ||||||
|  | @ -28,7 +29,7 @@ DedicatedWorkerHost::~DedicatedWorkerHost() = default; | ||||||
| 
 | 
 | ||||||
| // https://html.spec.whatwg.org/multipage/workers.html#run-a-worker
 | // https://html.spec.whatwg.org/multipage/workers.html#run-a-worker
 | ||||||
| // FIXME: Extract out into a helper for both shared and dedicated workers
 | // FIXME: Extract out into a helper for both shared and dedicated workers
 | ||||||
| void DedicatedWorkerHost::run(JS::NonnullGCPtr<Web::Page> page, Web::HTML::TransferDataHolder message_port_data) | void DedicatedWorkerHost::run(JS::NonnullGCPtr<Web::Page> page, Web::HTML::TransferDataHolder message_port_data, Web::HTML::SerializedEnvironmentSettingsObject const& outside_settings_snapshot) | ||||||
| { | { | ||||||
|     bool const is_shared = false; |     bool const is_shared = false; | ||||||
| 
 | 
 | ||||||
|  | @ -64,6 +65,9 @@ void DedicatedWorkerHost::run(JS::NonnullGCPtr<Web::Page> page, Web::HTML::Trans | ||||||
|     // 11. Append owner to worker global scope's owner set.
 |     // 11. Append owner to worker global scope's owner set.
 | ||||||
|     // FIXME: support for 'owner' set on WorkerGlobalScope
 |     // FIXME: support for 'owner' set on WorkerGlobalScope
 | ||||||
| 
 | 
 | ||||||
|  |     // IMPLEMENTATION DEFINED: We need an object to represent the fetch response's client
 | ||||||
|  |     auto outside_settings = inner_settings->heap().allocate<Web::HTML::EnvironmentSettingsSnapshot>(inner_settings->realm(), inner_settings->realm_execution_context().copy(), outside_settings_snapshot); | ||||||
|  | 
 | ||||||
|     // 12. If is shared is true, then:
 |     // 12. If is shared is true, then:
 | ||||||
|     if (is_shared) { |     if (is_shared) { | ||||||
|         // FIXME: Shared worker support
 |         // FIXME: Shared worker support
 | ||||||
|  | @ -210,8 +214,7 @@ void DedicatedWorkerHost::run(JS::NonnullGCPtr<Web::Page> page, Web::HTML::Trans | ||||||
|         dbgln("Unsupported script type {} for LibWeb/Worker", m_type); |         dbgln("Unsupported script type {} for LibWeb/Worker", m_type); | ||||||
|         TODO(); |         TODO(); | ||||||
|     } |     } | ||||||
|     // FIXME: We don't have outside settings anymore, they live in the owner. https://github.com/whatwg/html/issues/9920
 |     if (auto err = Web::HTML::fetch_classic_worker_script(m_url, outside_settings, destination, inner_settings, perform_fetch, on_complete); err.is_error()) { | ||||||
|     if (auto err = Web::HTML::fetch_classic_worker_script(m_url, inner_settings, destination, inner_settings, perform_fetch, on_complete); err.is_error()) { |  | ||||||
|         dbgln("Failed to run worker script"); |         dbgln("Failed to run worker script"); | ||||||
|         // FIXME: Abort the worker properly
 |         // FIXME: Abort the worker properly
 | ||||||
|         TODO(); |         TODO(); | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ | ||||||
| #include <AK/URL.h> | #include <AK/URL.h> | ||||||
| #include <LibWeb/Bindings/MainThreadVM.h> | #include <LibWeb/Bindings/MainThreadVM.h> | ||||||
| #include <LibWeb/Forward.h> | #include <LibWeb/Forward.h> | ||||||
|  | #include <LibWeb/HTML/Scripting/SerializedEnvironmentSettingsObject.h> | ||||||
| #include <LibWeb/HTML/StructuredSerialize.h> | #include <LibWeb/HTML/StructuredSerialize.h> | ||||||
| 
 | 
 | ||||||
| namespace WebWorker { | namespace WebWorker { | ||||||
|  | @ -19,7 +20,7 @@ public: | ||||||
|     explicit DedicatedWorkerHost(URL url, String type); |     explicit DedicatedWorkerHost(URL url, String type); | ||||||
|     ~DedicatedWorkerHost(); |     ~DedicatedWorkerHost(); | ||||||
| 
 | 
 | ||||||
|     void run(JS::NonnullGCPtr<Web::Page>, Web::HTML::TransferDataHolder message_port_data); |     void run(JS::NonnullGCPtr<Web::Page>, Web::HTML::TransferDataHolder message_port_data, Web::HTML::SerializedEnvironmentSettingsObject const&); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     RefPtr<Web::HTML::WorkerDebugConsoleClient> m_console; |     RefPtr<Web::HTML::WorkerDebugConsoleClient> m_console; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andrew Kaster
						Andrew Kaster