Commit c7932a54 authored by Lukasz Anforowicz's avatar Lukasz Anforowicz Committed by Commit Bot

Enable CORB and request_initiator_site_lock for SharedWorkers.

This CL changes how SharedWorkers create their URLLoaderFactory:

1. Ad-hoc creation code is replaced with a call into
   RenderProcessHost::CreateURLLoaderFactory, which
   1.1. Sets |request_initiator_site_lock| to the right origin,
   1.2. Sets |is_corb_enabled| to true.

2. Code is integrated with URLLoaderInterceptor (at least if the
   NetworkService is enabled) which helps test the changes wrt
   their impact on CORB behavior.

This CL also tweaks RequestInterceptor used by various CORB tests, so
that it forwards the actual headers / body / error-code of the response
(previously the renderer was always told that the response errored out
with ERR_NOT_IMPLEMENTED code).

Bug: 927849
Change-Id: Ic4c673d2f9c74fd89b8482552b7b72346f783c44
Reviewed-on: https://chromium-review.googlesource.com/c/1450430
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#630058}
parent bd6659ae
......@@ -20,6 +20,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/metrics/metrics_hashes.h"
#include "base/metrics/user_metrics.h"
#include "base/no_destructor.h"
#include "base/numerics/safe_conversions.h"
#include "base/process/kill.h"
#include "base/stl_util.h"
......@@ -235,8 +236,12 @@ typedef std::unordered_map<RenderFrameHostID,
base::LazyInstance<RoutingIDFrameMap>::DestructorAtExit g_routing_id_frame_map =
LAZY_INSTANCE_INITIALIZER;
base::LazyInstance<RenderFrameHostImpl::CreateNetworkFactoryCallback>::Leaky
g_create_network_factory_callback_for_test = LAZY_INSTANCE_INITIALIZER;
RenderFrameHostImpl::CreateNetworkFactoryCallback&
GetCreateNetworkFactoryCallback() {
static base::NoDestructor<RenderFrameHostImpl::CreateNetworkFactoryCallback>
s_callback;
return *s_callback;
}
using TokenFrameMap = std::unordered_map<base::UnguessableToken,
RenderFrameHostImpl*,
......@@ -725,11 +730,10 @@ void RenderFrameHostImpl::SetNetworkFactoryForTesting(
DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) ||
BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(create_network_factory_callback.is_null() ||
g_create_network_factory_callback_for_test.Get().is_null())
GetCreateNetworkFactoryCallback().is_null())
<< "It is not expected that this is called with non-null callback when "
<< "another overriding callback is already set.";
g_create_network_factory_callback_for_test.Get() =
create_network_factory_callback;
GetCreateNetworkFactoryCallback() = create_network_factory_callback;
}
RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
......@@ -4541,14 +4545,14 @@ void RenderFrameHostImpl::CommitNavigation(
std::move(subresource_loader_params->appcache_loader_factory_info);
// Inject test intermediary if needed.
if (!g_create_network_factory_callback_for_test.Get().is_null()) {
if (!GetCreateNetworkFactoryCallback().is_null()) {
network::mojom::URLLoaderFactoryPtrInfo original_factory =
std::move(subresource_loader_factories->appcache_factory_info());
network::mojom::URLLoaderFactoryRequest new_request = mojo::MakeRequest(
&subresource_loader_factories->appcache_factory_info());
g_create_network_factory_callback_for_test.Get().Run(
std::move(new_request), GetProcess()->GetID(),
std::move(original_factory));
GetCreateNetworkFactoryCallback().Run(std::move(new_request),
GetProcess()->GetID(),
std::move(original_factory));
}
}
......@@ -5403,16 +5407,16 @@ bool RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryInternal(
&default_factory_request);
// Create the URLLoaderFactory - either via ContentBrowserClient or ourselves.
if (g_create_network_factory_callback_for_test.Get().is_null()) {
if (GetCreateNetworkFactoryCallback().is_null()) {
GetProcess()->CreateURLLoaderFactory(origin, std::move(header_client),
std::move(default_factory_request));
} else {
network::mojom::URLLoaderFactoryPtr original_factory;
GetProcess()->CreateURLLoaderFactory(origin, std::move(header_client),
mojo::MakeRequest(&original_factory));
g_create_network_factory_callback_for_test.Get().Run(
std::move(default_factory_request), GetProcess()->GetID(),
original_factory.PassInterface());
GetCreateNetworkFactoryCallback().Run(std::move(default_factory_request),
GetProcess()->GetID(),
original_factory.PassInterface());
}
return bypass_redirect_checks;
......
......@@ -190,7 +190,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
// Passing a null callback will restore the default behavior.
// This method must be called either on the UI thread or before threads start.
// This callback is run on the UI thread.
using CreateNetworkFactoryCallback = base::Callback<void(
using CreateNetworkFactoryCallback = base::RepeatingCallback<void(
network::mojom::URLLoaderFactoryRequest request,
int process_id,
network::mojom::URLLoaderFactoryPtrInfo original_factory)>;
......
......@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/task/post_task.h"
#include "base/unguessable_token.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
......@@ -40,6 +41,13 @@
namespace content {
namespace {
SharedWorkerHost::CreateNetworkFactoryCallback&
GetCreateNetworkFactoryCallback() {
static base::NoDestructor<SharedWorkerHost::CreateNetworkFactoryCallback>
s_callback;
return *s_callback;
}
void AllowFileSystemOnIOThreadResponse(base::OnceCallback<void(bool)> callback,
bool result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
......@@ -142,6 +150,18 @@ SharedWorkerHost::~SharedWorkerHost() {
}
}
// static
void SharedWorkerHost::SetNetworkFactoryForTesting(
const CreateNetworkFactoryCallback& create_network_factory_callback) {
DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) ||
BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(create_network_factory_callback.is_null() ||
GetCreateNetworkFactoryCallback().is_null())
<< "It is not expected that this is called with non-null callback when "
<< "another overriding callback is already set.";
GetCreateNetworkFactoryCallback() = create_network_factory_callback;
}
void SharedWorkerHost::Start(
blink::mojom::SharedWorkerFactoryPtr factory,
blink::mojom::ServiceWorkerProviderInfoForWorkerPtr
......@@ -293,14 +313,21 @@ void SharedWorkerHost::Start(
// the connection error and terminates the worker.
void SharedWorkerHost::CreateNetworkFactory(
network::mojom::URLLoaderFactoryRequest request) {
network::mojom::URLLoaderFactoryParamsPtr params =
network::mojom::URLLoaderFactoryParams::New();
params->process_id = process_id_;
// TODO(lukasza): https://crbug.com/792546: Start using CORB.
params->is_corb_enabled = false;
service_->storage_partition()->GetNetworkContext()->CreateURLLoaderFactory(
std::move(request), std::move(params));
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderProcessHost* process = RenderProcessHost::FromID(process_id_);
url::Origin origin = instance_->constructor_origin();
network::mojom::TrustedURLLoaderHeaderClientPtrInfo no_header_client;
if (GetCreateNetworkFactoryCallback().is_null()) {
process->CreateURLLoaderFactory(origin, std::move(no_header_client),
std::move(request));
} else {
network::mojom::URLLoaderFactoryPtr original_factory;
process->CreateURLLoaderFactory(origin, std::move(no_header_client),
mojo::MakeRequest(&original_factory));
GetCreateNetworkFactoryCallback().Run(std::move(request), process_id_,
original_factory.PassInterface());
}
}
void SharedWorkerHost::AllowFileSystem(
......
......@@ -57,6 +57,17 @@ class CONTENT_EXPORT SharedWorkerHost
int process_id);
~SharedWorkerHost() override;
// Allows overriding the URLLoaderFactory creation for subresources.
// Passing a null callback will restore the default behavior.
// This method must be called either on the UI thread or before threads start.
// This callback is run on the UI thread.
using CreateNetworkFactoryCallback = base::RepeatingCallback<void(
network::mojom::URLLoaderFactoryRequest request,
int process_id,
network::mojom::URLLoaderFactoryPtrInfo original_factory)>;
static void SetNetworkFactoryForTesting(
const CreateNetworkFactoryCallback& url_loader_factory_callback);
// Starts the SharedWorker in the renderer process.
//
// S13nServiceWorker:
......
......@@ -388,6 +388,9 @@ URLLoaderInterceptor::URLLoaderInterceptor(const InterceptCallback& callback,
RenderFrameHostImpl::SetNetworkFactoryForTesting(base::BindRepeating(
&URLLoaderInterceptor::CreateURLLoaderFactoryForSubresources,
base::Unretained(this)));
SharedWorkerHost::SetNetworkFactoryForTesting(base::BindRepeating(
&URLLoaderInterceptor::CreateURLLoaderFactoryForSubresources,
base::Unretained(this)));
// Note: This URLLoaderFactory creation callback will be used not only for
// subresource loading from service workers (i.e., fetch()), but also for
// loading non-installed service worker scripts.
......@@ -437,6 +440,8 @@ URLLoaderInterceptor::~URLLoaderInterceptor() {
base::FeatureList::IsEnabled(network::features::kNetworkService)) {
RenderFrameHostImpl::SetNetworkFactoryForTesting(
RenderFrameHostImpl::CreateNetworkFactoryCallback());
SharedWorkerHost::SetNetworkFactoryForTesting(
RenderFrameHostImpl::CreateNetworkFactoryCallback());
EmbeddedWorkerInstance::SetNetworkFactoryForTesting(
RenderFrameHostImpl::CreateNetworkFactoryCallback());
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment