feat: make Chrome extensions work on custom protocols (#49951)

This commit is contained in:
Niklas Wenzel
2026-03-27 01:00:51 +01:00
committed by GitHub
parent 8cb61e8b9b
commit 4eff8f20f2
22 changed files with 489 additions and 4 deletions

View File

@@ -38,6 +38,7 @@ struct SchemeOptions {
bool corsEnabled = false;
bool stream = false;
bool codeCache = false;
bool allowExtensions = false;
};
struct CustomScheme {
@@ -70,6 +71,7 @@ struct Converter<CustomScheme> {
opt.Get("corsEnabled", &(out->options.corsEnabled));
opt.Get("stream", &(out->options.stream));
opt.Get("codeCache", &(out->options.codeCache));
opt.Get("allowExtensions", &(out->options.allowExtensions));
}
return true;
}
@@ -124,7 +126,7 @@ void RegisterSchemesAsPrivileged(gin_helper::ErrorThrower thrower,
}
std::vector<std::string> secure_schemes, cspbypassing_schemes, fetch_schemes,
service_worker_schemes, cors_schemes;
service_worker_schemes, cors_schemes, extension_schemes;
for (const auto& custom_scheme : custom_schemes) {
// Register scheme to privileged list (https, wss, data, chrome-extension)
if (custom_scheme.options.standard) {
@@ -160,6 +162,10 @@ void RegisterSchemesAsPrivileged(gin_helper::ErrorThrower thrower,
GetCodeCacheSchemes().push_back(custom_scheme.scheme);
url::AddCodeCacheScheme(custom_scheme.scheme.c_str());
}
if (custom_scheme.options.allowExtensions) {
extension_schemes.push_back(custom_scheme.scheme);
url::AddExtensionScheme(custom_scheme.scheme.c_str());
}
}
const auto AppendSchemesToCmdLine = [](const std::string_view switch_name,
@@ -179,6 +185,8 @@ void RegisterSchemesAsPrivileged(gin_helper::ErrorThrower thrower,
AppendSchemesToCmdLine(electron::switches::kFetchSchemes, fetch_schemes);
AppendSchemesToCmdLine(electron::switches::kServiceWorkerSchemes,
service_worker_schemes);
AppendSchemesToCmdLine(electron::switches::kExtensionSchemes,
extension_schemes);
AppendSchemesToCmdLine(electron::switches::kStandardSchemes,
GetStandardSchemes());
AppendSchemesToCmdLine(electron::switches::kStreamingSchemes,

View File

@@ -558,7 +558,7 @@ void ElectronBrowserClient::AppendExtraCommandLineSwitches(
if (process_type == ::switches::kUtilityProcess ||
process_type == ::switches::kRendererProcess) {
// Copy following switches to child process.
static constexpr std::array<const char*, 10U> kCommonSwitchNames = {
static constexpr std::array<const char*, 11U> kCommonSwitchNames = {
switches::kStandardSchemes.c_str(),
switches::kEnableSandbox.c_str(),
switches::kSecureSchemes.c_str(),
@@ -568,7 +568,8 @@ void ElectronBrowserClient::AppendExtraCommandLineSwitches(
switches::kServiceWorkerSchemes.c_str(),
switches::kStreamingSchemes.c_str(),
switches::kNoStdioInit.c_str(),
switches::kCodeCacheSchemes.c_str()};
switches::kCodeCacheSchemes.c_str(),
switches::kExtensionSchemes.c_str()};
command_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
kCommonSwitchNames);
if (process_type == ::switches::kUtilityProcess ||

View File

@@ -58,6 +58,7 @@
#include "third_party/blink/public/common/page/page_zoom.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "url/url_util.h"
#include "v8/include/v8.h"
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
@@ -869,6 +870,13 @@ void InspectableWebContents::GetSyncInformation(DispatchCallback callback) {
void InspectableWebContents::GetHostConfig(DispatchCallback callback) {
base::DictValue response_dict;
base::ListValue extension_schemes;
for (const std::string& scheme : url::GetExtensionSchemes())
extension_schemes.Append(scheme + ":");
response_dict.Set("devToolsExtensionSchemes",
base::Value(std::move(extension_schemes)));
base::Value response = base::Value(std::move(response_dict));
std::move(callback).Run(&response);
}

View File

@@ -270,6 +270,9 @@ inline constexpr base::cstring_view kStreamingSchemes = "streaming-schemes";
// Register schemes as supporting V8 code cache.
inline constexpr base::cstring_view kCodeCacheSchemes = "code-cache-schemes";
// Register schemes as supporting extensions.
inline constexpr base::cstring_view kExtensionSchemes = "extension-schemes";
// The browser process app model ID
inline constexpr base::cstring_view kAppUserModelId = "app-user-model-id";

View File

@@ -162,6 +162,11 @@ RendererClientBase::RendererClientBase() {
ParseSchemesCLISwitch(command_line, switches::kSecureSchemes);
for (const std::string& scheme : secure_schemes_list)
url::AddSecureScheme(scheme.data());
// Parse --extension-schemes=scheme1,scheme2
std::vector<std::string> extension_schemes_list =
ParseSchemesCLISwitch(command_line, switches::kExtensionSchemes);
for (const std::string& scheme : extension_schemes_list)
url::AddExtensionScheme(scheme.c_str());
// We rely on the unique process host id which is notified to the
// renderer process via command line switch from the content layer,
// if this switch is removed from the content layer for some reason,