From daf01d51f5a8df9eded9555610f56277acab44fa Mon Sep 17 00:00:00 2001 From: David Sanders Date: Sun, 30 May 2021 12:03:51 -0700 Subject: [PATCH] fix: add service worker schemes from command line in renderer --- shell/browser/api/electron_api_protocol.cc | 18 +++++---- shell/browser/api/electron_api_protocol.h | 2 + shell/renderer/renderer_client_base.cc | 6 +++ spec-main/chromium-spec.ts | 37 +++++++++++++++++++ .../service-worker/custom-scheme-index.html | 21 +++++++++++ 5 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 spec/fixtures/pages/service-worker/custom-scheme-index.html diff --git a/shell/browser/api/electron_api_protocol.cc b/shell/browser/api/electron_api_protocol.cc index 952e32d0d3566..ad4c5a8b38a6c 100644 --- a/shell/browser/api/electron_api_protocol.cc +++ b/shell/browser/api/electron_api_protocol.cc @@ -89,6 +89,16 @@ std::vector GetStandardSchemes() { return g_standard_schemes; } +void AddServiceWorkerScheme(const std::string& scheme) { + // There is no API to add service worker scheme, but there is an API to + // return const reference to the schemes vector. + // If in future the API is changed to return a copy instead of reference, + // the compilation will fail, and we should add a patch at that time. + auto& mutable_schemes = + const_cast&>(content::GetServiceWorkerSchemes()); + mutable_schemes.push_back(scheme); +} + void RegisterSchemesAsPrivileged(gin_helper::ErrorThrower thrower, v8::Local val) { std::vector custom_schemes; @@ -125,13 +135,7 @@ void RegisterSchemesAsPrivileged(gin_helper::ErrorThrower thrower, } if (custom_scheme.options.allowServiceWorkers) { service_worker_schemes.push_back(custom_scheme.scheme); - // There is no API to add service worker scheme, but there is an API to - // return const reference to the schemes vector. - // If in future the API is changed to return a copy instead of reference, - // the compilation will fail, and we should add a patch at that time. - auto& mutable_schemes = const_cast&>( - content::GetServiceWorkerSchemes()); - mutable_schemes.push_back(custom_scheme.scheme); + AddServiceWorkerScheme(custom_scheme.scheme); } if (custom_scheme.options.stream) { g_streaming_schemes.push_back(custom_scheme.scheme); diff --git a/shell/browser/api/electron_api_protocol.h b/shell/browser/api/electron_api_protocol.h index 0725e4cea2b88..d0420ff14ad9e 100644 --- a/shell/browser/api/electron_api_protocol.h +++ b/shell/browser/api/electron_api_protocol.h @@ -22,6 +22,8 @@ namespace api { std::vector GetStandardSchemes(); +void AddServiceWorkerScheme(const std::string& scheme); + void RegisterSchemesAsPrivileged(gin_helper::ErrorThrower thrower, v8::Local val); diff --git a/shell/renderer/renderer_client_base.cc b/shell/renderer/renderer_client_base.cc index aae224b038a23..8168b9e6d060d 100644 --- a/shell/renderer/renderer_client_base.cc +++ b/shell/renderer/renderer_client_base.cc @@ -22,6 +22,7 @@ #include "electron/buildflags/buildflags.h" #include "media/blink/multibuffer_data_source.h" #include "printing/buildflags/buildflags.h" +#include "shell/browser/api/electron_api_protocol.h" #include "shell/common/api/electron_api_native_image.h" #include "shell/common/color_util.h" #include "shell/common/gin_helper/dictionary.h" @@ -111,6 +112,11 @@ RendererClientBase* g_renderer_client_base = nullptr; RendererClientBase::RendererClientBase() { auto* command_line = base::CommandLine::ForCurrentProcess(); + // Parse --service-worker-schemes=scheme1,scheme2 + std::vector service_worker_schemes_list = + ParseSchemesCLISwitch(command_line, switches::kServiceWorkerSchemes); + for (const std::string& scheme : service_worker_schemes_list) + electron::api::AddServiceWorkerScheme(scheme); // Parse --standard-schemes=scheme1,scheme2 std::vector standard_schemes_list = ParseSchemesCLISwitch(command_line, switches::kStandardSchemes); diff --git a/spec-main/chromium-spec.ts b/spec-main/chromium-spec.ts index 5b6bf61373e74..c27f652c76036 100644 --- a/spec-main/chromium-spec.ts +++ b/spec-main/chromium-spec.ts @@ -586,6 +586,43 @@ describe('chromium features', () => { w.loadFile(path.join(fixturesPath, 'pages', 'service-worker', 'index.html')); }); + it('should register for custom scheme', (done) => { + const customSession = session.fromPartition('custom-scheme'); + const { serviceWorkerScheme } = global as any; + customSession.protocol.registerFileProtocol(serviceWorkerScheme, (request, callback) => { + let file = url.parse(request.url).pathname!; + if (file[0] === '/' && process.platform === 'win32') file = file.slice(1); + + callback({ path: path.normalize(file) } as any); + }); + + const w = new BrowserWindow({ + show: false, + webPreferences: { + nodeIntegration: true, + session: customSession, + contextIsolation: false + } + }); + w.webContents.on('ipc-message', (event, channel, message) => { + if (channel === 'reload') { + w.webContents.reload(); + } else if (channel === 'error') { + done(`unexpected error : ${message}`); + } else if (channel === 'response') { + expect(message).to.equal('Hello from serviceWorker!'); + customSession.clearStorageData({ + storages: ['serviceworkers'] + }).then(() => { + customSession.protocol.uninterceptProtocol(serviceWorkerScheme); + done(); + }); + } + }); + w.webContents.on('crashed', () => done(new Error('WebContents crashed.'))); + w.loadFile(path.join(fixturesPath, 'pages', 'service-worker', 'custom-scheme-index.html')); + }); + it('should not crash when nodeIntegration is enabled', (done) => { const w = new BrowserWindow({ show: false, diff --git a/spec/fixtures/pages/service-worker/custom-scheme-index.html b/spec/fixtures/pages/service-worker/custom-scheme-index.html new file mode 100644 index 0000000000000..e5be928f04163 --- /dev/null +++ b/spec/fixtures/pages/service-worker/custom-scheme-index.html @@ -0,0 +1,21 @@ +