Skip to content

Commit

Permalink
fix: crash when doing redirect navigation with webRequest listener (8…
Browse files Browse the repository at this point in the history
…-x-y) (#21841)

* fix: pass navigation_ui_data to proxying factory

* fix: clone response instead of move in redirect
  • Loading branch information
zcbenz committed Jan 22, 2020
1 parent 1a309fd commit 71a31d5
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 6 deletions.
15 changes: 14 additions & 1 deletion shell/browser/atom_browser_client.cc
Expand Up @@ -43,6 +43,7 @@
#include "content/public/common/web_preferences.h"
#include "electron/buildflags/buildflags.h"
#include "electron/grit/electron_resources.h"
#include "extensions/browser/extension_navigation_ui_data.h"
#include "net/base/escape.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "ppapi/host/ppapi_host.h"
Expand Down Expand Up @@ -1001,14 +1002,26 @@ bool AtomBrowserClient::WillCreateURLLoaderFactory(
mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory_remote;
*factory_receiver = target_factory_remote.InitWithNewPipeAndPassReceiver();

// Required by WebRequestInfoInitParams.
//
// Note that in Electron we allow webRequest to capture requests sent from
// browser process, so creation of |navigation_ui_data| is different from
// Chromium which only does for renderer-initialized navigations.
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data;
if (navigation_id.has_value()) {
navigation_ui_data =
std::make_unique<extensions::ExtensionNavigationUIData>();
}

mojo::PendingReceiver<network::mojom::TrustedURLLoaderHeaderClient>
header_client_receiver;
if (header_client)
header_client_receiver = header_client->InitWithNewPipeAndPassReceiver();

new ProxyingURLLoaderFactory(
web_request.get(), protocol->intercept_handlers(), browser_context,
render_process_id, std::move(navigation_id), std::move(proxied_receiver),
render_process_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
14 changes: 9 additions & 5 deletions shell/browser/net/proxying_url_loader_factory.cc
Expand Up @@ -94,7 +94,9 @@ void ProxyingURLLoaderFactory::InProgressRequest::UpdateRequestInfo() {
request_for_info.request_initiator = original_initiator_;
info_.emplace(extensions::WebRequestInfoInitParams(
request_id_, factory_->render_process_id_, request_.render_frame_id,
nullptr, routing_id_, request_for_info, false,
factory_->navigation_ui_data_ ? factory_->navigation_ui_data_->DeepCopy()
: nullptr,
routing_id_, request_for_info, false,
!(options_ & network::mojom::kURLLoadOptionSynchronous),
factory_->IsForServiceWorkerScript(), factory_->navigation_id_));

Expand Down Expand Up @@ -303,7 +305,7 @@ void ProxyingURLLoaderFactory::InProgressRequest::OnBeforeSendHeaders(

void ProxyingURLLoaderFactory::InProgressRequest::OnHeadersReceived(
const std::string& headers,
const net::IPEndPoint& endpoint,
const net::IPEndPoint& remote_endpoint,
OnHeadersReceivedCallback callback) {
if (!current_request_uses_header_client_) {
std::move(callback).Run(net::OK, base::nullopt, GURL());
Expand All @@ -314,6 +316,7 @@ void ProxyingURLLoaderFactory::InProgressRequest::OnHeadersReceived(
current_response_ = network::mojom::URLResponseHead::New();
current_response_->headers =
base::MakeRefCounted<net::HttpResponseHeaders>(headers);
current_response_->remote_endpoint = remote_endpoint;
HandleResponseOrRedirectHeaders(
base::BindOnce(&InProgressRequest::ContinueToHandleOverrideHeaders,
weak_factory_.GetWeakPtr()));
Expand Down Expand Up @@ -519,7 +522,7 @@ void ProxyingURLLoaderFactory::InProgressRequest::ContinueToResponseStarted(
proxied_client_receiver_.Resume();

factory_->web_request_api()->OnResponseStarted(&info_.value(), request_);
target_client_->OnReceiveResponse(std::move(current_response_));
target_client_->OnReceiveResponse(current_response_.Clone());
}

void ProxyingURLLoaderFactory::InProgressRequest::ContinueToBeforeRedirect(
Expand All @@ -537,8 +540,7 @@ void ProxyingURLLoaderFactory::InProgressRequest::ContinueToBeforeRedirect(

factory_->web_request_api()->OnBeforeRedirect(&info_.value(), request_,
redirect_info.new_url);
target_client_->OnReceiveRedirect(redirect_info,
std::move(current_response_));
target_client_->OnReceiveRedirect(redirect_info, current_response_.Clone());
request_.url = redirect_info.new_url;
request_.method = redirect_info.new_method;
request_.site_for_cookies = redirect_info.new_site_for_cookies;
Expand Down Expand Up @@ -673,6 +675,7 @@ ProxyingURLLoaderFactory::ProxyingURLLoaderFactory(
const HandlersMap& intercepted_handlers,
content::BrowserContext* browser_context,
int render_process_id,
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data,
base::Optional<int64_t> navigation_id,
network::mojom::URLLoaderFactoryRequest loader_request,
mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory_remote,
Expand All @@ -683,6 +686,7 @@ ProxyingURLLoaderFactory::ProxyingURLLoaderFactory(
intercepted_handlers_(intercepted_handlers),
browser_context_(browser_context),
render_process_id_(render_process_id),
navigation_ui_data_(std::move(navigation_ui_data)),
navigation_id_(std::move(navigation_id)),
loader_factory_type_(loader_factory_type) {
target_factory_.Bind(std::move(target_factory_remote));
Expand Down
2 changes: 2 additions & 0 deletions shell/browser/net/proxying_url_loader_factory.h
Expand Up @@ -210,6 +210,7 @@ class ProxyingURLLoaderFactory
const HandlersMap& intercepted_handlers,
content::BrowserContext* browser_context,
int render_process_id,
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data,
base::Optional<int64_t> navigation_id,
network::mojom::URLLoaderFactoryRequest loader_request,
mojo::PendingRemote<network::mojom::URLLoaderFactory>
Expand Down Expand Up @@ -268,6 +269,7 @@ class ProxyingURLLoaderFactory

content::BrowserContext* const browser_context_;
const int render_process_id_;
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data_;
base::Optional<int64_t> navigation_id_;
mojo::ReceiverSet<network::mojom::URLLoaderFactory> proxy_receivers_;
mojo::Remote<network::mojom::URLLoaderFactory> target_factory_;
Expand Down
8 changes: 8 additions & 0 deletions spec-main/api-web-request-spec.ts
Expand Up @@ -121,6 +121,14 @@ describe('webRequest module', () => {
const { data } = await ajax(defaultURL)
expect(data).to.equal('/redirect')
})

it('does not crash for redirects', async () => {
ses.webRequest.onBeforeRequest((details, callback) => {
callback({ cancel: false })
})
await ajax(defaultURL + 'serverRedirect')
await ajax(defaultURL + 'serverRedirect')
})
})

describe('webRequest.onBeforeSendHeaders', () => {
Expand Down

0 comments on commit 71a31d5

Please sign in to comment.