Skip to content

Commit

Permalink
fix: make webRequest work with WebSocket (#22134)
Browse files Browse the repository at this point in the history
  • Loading branch information
zcbenz committed Feb 12, 2020
1 parent fce3426 commit dc9654c
Show file tree
Hide file tree
Showing 14 changed files with 895 additions and 59 deletions.
2 changes: 2 additions & 0 deletions docs/api/web-request.md
Expand Up @@ -146,6 +146,7 @@ response are visible by the time this listener is fired.
* `timestamp` Double
* `statusLine` String
* `statusCode` Integer
* `requestHeaders` Record<string, string>
* `responseHeaders` Record<string, string[]> (optional)
* `callback` Function
* `headersReceivedResponse` Object
Expand Down Expand Up @@ -228,6 +229,7 @@ redirect is about to occur.
* `fromCache` Boolean
* `statusCode` Integer
* `statusLine` String
* `error` String

The `listener` will be called with `listener(details)` when a request is
completed.
Expand Down
3 changes: 3 additions & 0 deletions filenames.gni
Expand Up @@ -238,12 +238,15 @@ filenames = {
"shell/browser/net/node_stream_loader.h",
"shell/browser/net/proxying_url_loader_factory.cc",
"shell/browser/net/proxying_url_loader_factory.h",
"shell/browser/net/proxying_websocket.cc",
"shell/browser/net/proxying_websocket.h",
"shell/browser/net/resolve_proxy_helper.cc",
"shell/browser/net/resolve_proxy_helper.h",
"shell/browser/net/system_network_context_manager.cc",
"shell/browser/net/system_network_context_manager.h",
"shell/browser/net/url_pipe_loader.cc",
"shell/browser/net/url_pipe_loader.h",
"shell/browser/net/web_request_api_interface.h",
"shell/browser/network_hints_handler_impl.cc",
"shell/browser/network_hints_handler_impl.h",
"shell/browser/node_debugger.cc",
Expand Down
10 changes: 5 additions & 5 deletions shell/browser/api/electron_api_web_request_ns.h
Expand Up @@ -13,7 +13,7 @@
#include "gin/arguments.h"
#include "gin/handle.h"
#include "gin/wrappable.h"
#include "shell/browser/net/proxying_url_loader_factory.h"
#include "shell/browser/net/web_request_api_interface.h"

namespace content {
class BrowserContext;
Expand Down Expand Up @@ -50,10 +50,6 @@ class WebRequestNS : public gin::Wrappable<WebRequestNS>, public WebRequestAPI {
v8::Isolate* isolate) override;
const char* GetTypeName() override;

private:
WebRequestNS(v8::Isolate* isolate, content::BrowserContext* browser_context);
~WebRequestNS() override;

// WebRequestAPI:
bool HasListener() const override;
int OnBeforeRequest(extensions::WebRequestInfo* info,
Expand Down Expand Up @@ -87,6 +83,10 @@ class WebRequestNS : public gin::Wrappable<WebRequestNS>, public WebRequestAPI {
int net_error) override;
void OnRequestWillBeDestroyed(extensions::WebRequestInfo* info) override;

private:
WebRequestNS(v8::Isolate* isolate, content::BrowserContext* browser_context);
~WebRequestNS() override;

enum SimpleEvent {
kOnSendHeaders,
kOnBeforeRedirect,
Expand Down
39 changes: 38 additions & 1 deletion shell/browser/electron_browser_client.cc
Expand Up @@ -72,6 +72,7 @@
#include "shell/browser/net/network_context_service.h"
#include "shell/browser/net/network_context_service_factory.h"
#include "shell/browser/net/proxying_url_loader_factory.h"
#include "shell/browser/net/proxying_websocket.h"
#include "shell/browser/net/system_network_context_manager.h"
#include "shell/browser/network_hints_handler_impl.h"
#include "shell/browser/notifications/notification_presenter.h"
Expand Down Expand Up @@ -985,6 +986,42 @@ void ElectronBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories(
}
}

bool ElectronBrowserClient::WillInterceptWebSocket(
content::RenderFrameHost* frame) {
if (!frame)
return false;

v8::Isolate* isolate = v8::Isolate::GetCurrent();
auto* browser_context = frame->GetProcess()->GetBrowserContext();
auto web_request = api::WebRequestNS::FromOrCreate(isolate, browser_context);

// NOTE: Some unit test environments do not initialize
// BrowserContextKeyedAPI factories for e.g. WebRequest.
if (!web_request.get())
return false;

return web_request->HasListener();
}

void ElectronBrowserClient::CreateWebSocket(
content::RenderFrameHost* frame,
WebSocketFactory factory,
const GURL& url,
const GURL& site_for_cookies,
const base::Optional<std::string>& user_agent,
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
handshake_client) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
auto* browser_context = frame->GetProcess()->GetBrowserContext();
auto web_request = api::WebRequestNS::FromOrCreate(isolate, browser_context);
DCHECK(web_request.get());
ProxyingWebSocket::StartProxying(
web_request.get(), std::move(factory), url, site_for_cookies, user_agent,
std::move(handshake_client), true, frame->GetProcess()->GetID(),
frame->GetRoutingID(), frame->GetLastCommittedOrigin(), browser_context,
&next_id_);
}

bool ElectronBrowserClient::WillCreateURLLoaderFactory(
content::BrowserContext* browser_context,
content::RenderFrameHost* frame_host,
Expand Down Expand Up @@ -1026,7 +1063,7 @@ bool ElectronBrowserClient::WillCreateURLLoaderFactory(

new ProxyingURLLoaderFactory(
web_request.get(), protocol->intercept_handlers(), browser_context,
render_process_id, std::move(navigation_ui_data),
render_process_id, &next_id_, std::move(navigation_ui_data),
std::move(navigation_id), std::move(proxied_receiver),
std::move(target_factory_remote), std::move(header_client_receiver),
type);
Expand Down
13 changes: 13 additions & 0 deletions shell/browser/electron_browser_client.h
Expand Up @@ -174,6 +174,15 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
int render_process_id,
int render_frame_id,
NonNetworkURLLoaderFactoryMap* factories) override;
void CreateWebSocket(
content::RenderFrameHost* frame,
WebSocketFactory factory,
const GURL& url,
const GURL& site_for_cookies,
const base::Optional<std::string>& user_agent,
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
handshake_client) override;
bool WillInterceptWebSocket(content::RenderFrameHost*) override;
bool WillCreateURLLoaderFactory(
content::BrowserContext* browser_context,
content::RenderFrameHost* frame,
Expand Down Expand Up @@ -285,6 +294,10 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
bool disable_process_restart_tricks_ = false;
bool disable_process_restart_tricks_is_default_value_ = true;

// Simple shared ID generator, used by ProxyingURLLoaderFactory and
// ProxyingWebSocket classes.
uint64_t next_id_ = 0;

DISALLOW_COPY_AND_ASSIGN(ElectronBrowserClient);
};

Expand Down
11 changes: 3 additions & 8 deletions shell/browser/net/proxying_url_loader_factory.cc
Expand Up @@ -19,13 +19,6 @@
#include "shell/common/options_switches.h"

namespace electron {

namespace {

int64_t g_request_id = 0;

} // namespace

ProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams::
FollowRedirectParams() = default;
ProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams::
Expand Down Expand Up @@ -675,6 +668,7 @@ ProxyingURLLoaderFactory::ProxyingURLLoaderFactory(
const HandlersMap& intercepted_handlers,
content::BrowserContext* browser_context,
int render_process_id,
uint64_t* request_id_generator,
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data,
base::Optional<int64_t> navigation_id,
network::mojom::URLLoaderFactoryRequest loader_request,
Expand All @@ -686,6 +680,7 @@ ProxyingURLLoaderFactory::ProxyingURLLoaderFactory(
intercepted_handlers_(intercepted_handlers),
browser_context_(browser_context),
render_process_id_(render_process_id),
request_id_generator_(request_id_generator),
navigation_ui_data_(std::move(navigation_ui_data)),
navigation_id_(std::move(navigation_id)),
loader_factory_type_(loader_factory_type) {
Expand Down Expand Up @@ -763,7 +758,7 @@ void ProxyingURLLoaderFactory::CreateLoaderAndStart(
// per-BrowserContext so extensions can make sense of it. Note that
// |network_service_request_id_| by contrast is not necessarily unique, so we
// don't use it for identity here.
const uint64_t web_request_id = ++g_request_id;
const uint64_t web_request_id = ++(*request_id_generator_);

// Notes: Chromium assumes that requests with zero-ID would never use the
// "extraHeaders" code path, however in Electron requests started from
Expand Down
46 changes: 3 additions & 43 deletions shell/browser/net/proxying_url_loader_factory.h
Expand Up @@ -24,52 +24,10 @@
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "shell/browser/net/electron_url_loader_factory.h"
#include "shell/browser/net/web_request_api_interface.h"

namespace electron {

// Defines the interface for WebRequest API, implemented by api::WebRequestNS.
class WebRequestAPI {
public:
virtual ~WebRequestAPI() {}

using BeforeSendHeadersCallback =
base::OnceCallback<void(const std::set<std::string>& removed_headers,
const std::set<std::string>& set_headers,
int error_code)>;

virtual bool HasListener() const = 0;
virtual int OnBeforeRequest(extensions::WebRequestInfo* info,
const network::ResourceRequest& request,
net::CompletionOnceCallback callback,
GURL* new_url) = 0;
virtual int OnBeforeSendHeaders(extensions::WebRequestInfo* info,
const network::ResourceRequest& request,
BeforeSendHeadersCallback callback,
net::HttpRequestHeaders* headers) = 0;
virtual int OnHeadersReceived(
extensions::WebRequestInfo* info,
const network::ResourceRequest& request,
net::CompletionOnceCallback callback,
const net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
GURL* allowed_unsafe_redirect_url) = 0;
virtual void OnSendHeaders(extensions::WebRequestInfo* info,
const network::ResourceRequest& request,
const net::HttpRequestHeaders& headers) = 0;
virtual void OnBeforeRedirect(extensions::WebRequestInfo* info,
const network::ResourceRequest& request,
const GURL& new_location) = 0;
virtual void OnResponseStarted(extensions::WebRequestInfo* info,
const network::ResourceRequest& request) = 0;
virtual void OnErrorOccurred(extensions::WebRequestInfo* info,
const network::ResourceRequest& request,
int net_error) = 0;
virtual void OnCompleted(extensions::WebRequestInfo* info,
const network::ResourceRequest& request,
int net_error) = 0;
virtual void OnRequestWillBeDestroyed(extensions::WebRequestInfo* info) = 0;
};

// This class is responsible for following tasks when NetworkService is enabled:
// 1. handling intercepted protocols;
// 2. implementing webRequest module;
Expand Down Expand Up @@ -210,6 +168,7 @@ class ProxyingURLLoaderFactory
const HandlersMap& intercepted_handlers,
content::BrowserContext* browser_context,
int render_process_id,
uint64_t* request_id_generator,
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data,
base::Optional<int64_t> navigation_id,
network::mojom::URLLoaderFactoryRequest loader_request,
Expand Down Expand Up @@ -269,6 +228,7 @@ class ProxyingURLLoaderFactory

content::BrowserContext* const browser_context_;
const int render_process_id_;
uint64_t* request_id_generator_; // managed by AtomBrowserClient
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data_;
base::Optional<int64_t> navigation_id_;
mojo::ReceiverSet<network::mojom::URLLoaderFactory> proxy_receivers_;
Expand Down

0 comments on commit dc9654c

Please sign in to comment.