Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(extensions): implement missing web_request hooks #27098

Merged
merged 1 commit into from Jan 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/api/extensions.md
Expand Up @@ -115,3 +115,9 @@ The following methods of `chrome.management` are supported:
- `chrome.management.getPermissionWarningsByManifest`
- `chrome.management.onEnabled`
- `chrome.management.onDisabled`

### `chrome.webRequest`

All features of this API are supported.

> **NOTE:** Electron's [`webRequest`](web-request.md) module takes precedence over `chrome.webRequest` if there are conflicting handlers.
47 changes: 46 additions & 1 deletion shell/browser/electron_browser_client.cc
Expand Up @@ -137,6 +137,7 @@
#include "content/public/browser/file_url_loader.h"
#include "content/public/browser/web_ui_url_loader_factory.h"
#include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
#include "extensions/browser/api/web_request/web_request_api.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_message_filter.h"
Expand Down Expand Up @@ -1449,7 +1450,17 @@ bool ElectronBrowserClient::WillInterceptWebSocket(
if (!web_request.get())
return false;

return web_request->HasListener();
bool has_listener = web_request->HasListener();
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
const auto* web_request_api =
extensions::BrowserContextKeyedAPIFactory<extensions::WebRequestAPI>::Get(
browser_context);

if (web_request_api)
has_listener |= web_request_api->MayHaveProxies();
#endif

return has_listener;
}

void ElectronBrowserClient::CreateWebSocket(
Expand All @@ -1463,8 +1474,24 @@ void ElectronBrowserClient::CreateWebSocket(
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope scope(isolate);
auto* browser_context = frame->GetProcess()->GetBrowserContext();

auto web_request = api::WebRequest::FromOrCreate(isolate, browser_context);
DCHECK(web_request.get());

#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
if (!web_request->HasListener()) {
auto* web_request_api = extensions::BrowserContextKeyedAPIFactory<
extensions::WebRequestAPI>::Get(browser_context);

if (web_request_api && web_request_api->MayHaveProxies()) {
web_request_api->ProxyWebSocket(frame, std::move(factory), url,
site_for_cookies.RepresentativeUrl(),
user_agent, std::move(handshake_client));
return;
}
}
#endif

ProxyingWebSocket::StartProxying(
web_request.get(), std::move(factory), url,
site_for_cookies.RepresentativeUrl(), user_agent,
Expand Down Expand Up @@ -1492,6 +1519,24 @@ bool ElectronBrowserClient::WillCreateURLLoaderFactory(
auto web_request = api::WebRequest::FromOrCreate(isolate, browser_context);
DCHECK(web_request.get());

#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
if (!web_request->HasListener()) {
auto* web_request_api = extensions::BrowserContextKeyedAPIFactory<
extensions::WebRequestAPI>::Get(browser_context);

DCHECK(web_request_api);
bool use_proxy_for_web_request =
web_request_api->MaybeProxyURLLoaderFactory(
browser_context, frame_host, render_process_id, type, navigation_id,
ukm_source_id, factory_receiver, header_client);

if (bypass_redirect_checks)
*bypass_redirect_checks = use_proxy_for_web_request;
if (use_proxy_for_web_request)
return true;
}
#endif

auto proxied_receiver = std::move(*factory_receiver);
mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory_remote;
*factory_receiver = target_factory_remote.InitWithNewPipeAndPassReceiver();
Expand Down
20 changes: 20 additions & 0 deletions shell/browser/extensions/electron_extension_loader.cc
Expand Up @@ -12,12 +12,15 @@
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "extensions/browser/extension_file_task_runner.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/pref_names.h"
#include "extensions/common/file_util.h"

namespace extensions {
Expand Down Expand Up @@ -110,6 +113,23 @@ void ElectronExtensionLoader::FinishExtensionLoad(
if (extension) {
extension_registrar_.AddExtension(extension);
}

// Write extension install time to ExtensionPrefs. This is required by
// WebRequestAPI which calls extensions::ExtensionPrefs::GetInstallTime.
//
// Implementation for writing the pref was based on
// PreferenceAPIBase::SetExtensionControlledPref.
{
ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(browser_context_);
ExtensionPrefs::ScopedDictionaryUpdate update(
extension_prefs, extension.get()->id(),
extensions::pref_names::kPrefPreferences);
auto preference = update.Create();
const base::Time install_time = base::Time().Now();
preference->SetString("install_time",
base::NumberToString(install_time.ToInternalValue()));
}

std::move(cb).Run(extension.get(), result.second);
}

Expand Down
4 changes: 1 addition & 3 deletions shell/common/extensions/electron_extensions_client.cc
Expand Up @@ -130,9 +130,7 @@ const GURL& ElectronExtensionsClient::GetWebstoreUpdateURL() const {
}

bool ElectronExtensionsClient::IsBlacklistUpdateURL(const GURL& url) const {
// TODO(rockot): Maybe we want to do something else here. For now we accept
// any URL as a blacklist URL because we don't really care.
return true;
return false;
}

} // namespace electron