Browse Source

fix: service worker registration with custom protocols (#34315)

* fix: service worker registration with custom protocols

Refs https://github.com/electron/electron/issues/32664

* chore: update patches

Co-authored-by: deepak1556 <[email protected]>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
trop[bot] 2 years ago
parent
commit
0206a9b7ed

+ 1 - 0
patches/chromium/.patches

@@ -117,3 +117,4 @@ introduce_ozoneplatform_electron_can_call_x11_property.patch
 make_gtk_getlibgtk_public.patch
 build_disable_print_content_analysis.patch
 feat_move_firstpartysets_to_content_browser_client.patch
+custom_protocols_plzserviceworker.patch

+ 53 - 0
patches/chromium/custom_protocols_plzserviceworker.patch

@@ -0,0 +1,53 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: deepak1556 <[email protected]>
+Date: Fri, 20 May 2022 00:29:34 +0900
+Subject: custom_protocols_plzserviceworker.patch
+
+Allow registering custom protocols to handle service worker main script fetching with PlzServiceWorker.
+
+Refs https://bugs.chromium.org/p/chromium/issues/detail?id=996511
+
+diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
+index f827745b9800d4f11a17e405b0eb22601d7e4dd4..0cecbfb2a6fd3daa71338c94bda4b1f45eb51d5e 100644
+--- a/content/browser/service_worker/service_worker_context_wrapper.cc
++++ b/content/browser/service_worker/service_worker_context_wrapper.cc
+@@ -1591,6 +1591,28 @@ ServiceWorkerContextWrapper::GetLoaderFactoryForBrowserInitiatedRequest(
+       loader_factory_bundle_info =
+           context()->loader_factory_bundle_for_update_check()->Clone();
+ 
++  // Give the embedder a chance to register custom schemes that can
++  // handle loading the service worker main script.
++  // Previous registration triggered by
++  // ServiceWorkerContextWrapper::CreateNonNetworkPendingURLLoaderFactoryBundleForUpdateCheck
++  // happens early on browser startup before the JS in the main process
++  // is run by the embedder.
++  auto* factory_bundle = static_cast<blink::PendingURLLoaderFactoryBundle*>(
++          loader_factory_bundle_info.get());
++  ContentBrowserClient::NonNetworkURLLoaderFactoryMap non_network_factories;
++  GetContentClient()
++      ->browser()
++      ->RegisterNonNetworkServiceWorkerUpdateURLLoaderFactories(
++          storage_partition_->browser_context(), &non_network_factories);
++  for (auto& pair : non_network_factories) {
++    const std::string& scheme = pair.first;
++    mojo::PendingRemote<network::mojom::URLLoaderFactory>& factory_remote =
++        pair.second;
++
++    factory_bundle->pending_scheme_specific_factories().emplace(
++        scheme, std::move(factory_remote));
++  }
++
+   if (base::FeatureList::IsEnabled(
+           features::kEnableServiceWorkersForChromeUntrusted) &&
+       scope.scheme_piece() == kChromeUIUntrustedScheme) {
+@@ -1611,9 +1633,7 @@ ServiceWorkerContextWrapper::GetLoaderFactoryForBrowserInitiatedRequest(
+             browser_context(), scope_origin)) {
+       config->RegisterURLDataSource(browser_context());
+ 
+-      static_cast<blink::PendingURLLoaderFactoryBundle*>(
+-          loader_factory_bundle_info.get())
+-          ->pending_scheme_specific_factories()
++      factory_bundle->pending_scheme_specific_factories()
+           .emplace(kChromeUIUntrustedScheme,
+                    CreateWebUIServiceWorkerLoaderFactory(
+                        browser_context(), kChromeUIUntrustedScheme,

+ 5 - 0
shell/browser/electron_browser_client.cc

@@ -1333,6 +1333,11 @@ void ElectronBrowserClient::
   DCHECK(browser_context);
   DCHECK(factories);
 
+  auto* protocol_registry =
+      ProtocolRegistry::FromBrowserContext(browser_context);
+  protocol_registry->RegisterURLLoaderFactories(factories,
+                                                false /* allow_file_access */);
+
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   factories->emplace(
       extensions::kExtensionScheme,

+ 1 - 4
spec-main/api-protocol-spec.ts

@@ -764,10 +764,7 @@ describe('protocol module', () => {
       await expect(contents.executeJavaScript(`navigator.serviceWorker.register('${v4()}.notjs', {scope: './'})`)).to.be.rejected();
     });
 
-    // TODO(nornagon): I'm not sure why this isn't working, but I'm choosing to
-    // disable this test for now to land the roll. See
-    // https://github.com/electron/electron/issues/32664.
-    it.skip('should be able to register service worker for custom scheme', async () => {
+    it('should be able to register service worker for custom scheme', async () => {
       await contents.loadURL(`${serviceWorkerScheme}://${v4()}.com`);
       await contents.executeJavaScript(`navigator.serviceWorker.register('${v4()}.js', {scope: './'})`);
     });