Commit 4020282e authored by tzik's avatar tzik Committed by Commit bot

Implement Mojo SyncLoad

This CL add a Mojo IPC for synchronous resource loading, and plumps it
from content::ResourceDispatcher to content::ResourceDispatcherHost.

BUG=603396

Review-Url: https://codereview.chromium.org/2390983003
Cr-Commit-Position: refs/heads/master@{#427011}
parent 6a97fb88
......@@ -2272,6 +2272,18 @@ void ResourceDispatcherHostImpl::OnRequestResourceWithMojo(
filter_ = nullptr;
}
void ResourceDispatcherHostImpl::OnSyncLoadWithMojo(
int routing_id,
int request_id,
const ResourceRequest& request_data,
ResourceMessageFilter* filter,
const SyncLoadResultCallback& result_handler) {
filter_ = filter;
BeginRequest(request_id, request_data, result_handler, routing_id,
nullptr, nullptr);
filter_ = nullptr;
}
// static
int ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(
net::URLRequest* request) {
......
......@@ -308,6 +308,12 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
mojom::URLLoaderClientPtr url_loader_client,
ResourceMessageFilter* filter);
void OnSyncLoadWithMojo(int routing_id,
int request_id,
const ResourceRequest& request_data,
ResourceMessageFilter* filter,
const SyncLoadResultCallback& result_handler);
// Helper function for initializing the |request| passed in. By initializing
// we mean setting the |referrer| on the |request|, associating the
// ResourceRequestInfoImpl structure with the |request|, etc.
......@@ -547,7 +553,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
int request_id,
const ResourceRequest& request_data,
const SyncLoadResultCallback& sync_result_handler, // only valid for sync
int route_id, // only valid for async
int route_id,
mojo::InterfaceRequest<mojom::URLLoader> mojo_request,
mojom::URLLoaderClientPtr url_loader_client);
......
......@@ -3697,6 +3697,72 @@ TEST_P(ResourceDispatcherHostTest, ThrottleMustProcessResponseBeforeRead) {
base::RunLoop().RunUntilIdle();
}
namespace {
void StoreSyncLoadResult(bool* called,
bool* was_null,
SyncLoadResult* result_out,
const SyncLoadResult* result) {
*called = true;
*was_null = !result;
if (result)
*result_out = *result;
}
} // namespace
TEST_P(ResourceDispatcherHostTest, SyncLoadWithMojoSuccess) {
ResourceRequest request = CreateResourceRequest(
"GET", RESOURCE_TYPE_XHR, net::URLRequestTestJob::test_url_1());
request.priority = net::MAXIMUM_PRIORITY;
bool called = false;
bool was_null = false;
SyncLoadResult result;
host_.OnSyncLoadWithMojo(0, 1, request, filter_.get(),
base::Bind(&StoreSyncLoadResult,
&called, &was_null, &result));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
EXPECT_FALSE(was_null);
EXPECT_EQ(net::OK, result.error_code);
}
TEST_P(ResourceDispatcherHostTest, SyncLoadWithMojoError) {
ResourceRequest request = CreateResourceRequest(
"GET", RESOURCE_TYPE_XHR, net::URLRequestTestJob::test_url_error());
request.priority = net::MAXIMUM_PRIORITY;
bool called = false;
bool was_null = false;
SyncLoadResult result;
host_.OnSyncLoadWithMojo(0, 1, request, filter_.get(),
base::Bind(&StoreSyncLoadResult,
&called, &was_null, &result));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
EXPECT_FALSE(was_null);
EXPECT_EQ(net::ERR_INVALID_URL, result.error_code);
}
TEST_P(ResourceDispatcherHostTest, SyncLoadWithMojoCancel) {
ResourceRequest request = CreateResourceRequest(
"GET", RESOURCE_TYPE_XHR, net::URLRequestTestJob::test_url_error());
request.priority = net::MAXIMUM_PRIORITY;
bool called = false;
bool was_null = false;
SyncLoadResult result;
host_.OnSyncLoadWithMojo(0, 1, request, filter_.get(),
base::Bind(&StoreSyncLoadResult,
&called, &was_null, &result));
host_.CancelRequestsForProcess(filter_->child_id());
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
EXPECT_TRUE(was_null);
}
// A URLRequestTestJob that sets a test certificate on the |ssl_info|
// field of the response.
class TestHTTPSURLRequestJob : public net::URLRequestTestJob {
......
......@@ -13,6 +13,26 @@
namespace content {
namespace {
void DispatchSyncLoadResult(
const URLLoaderFactoryImpl::SyncLoadCallback& callback,
const SyncLoadResult* result) {
// |result| can be null when a loading task is aborted unexpectedly. Reply
// with a failure result on that case.
// TODO(tzik): Test null-result case.
if (!result) {
SyncLoadResult failure;
failure.error_code = net::ERR_FAILED;
callback.Run(failure);
return;
}
callback.Run(*result);
}
} // namespace
URLLoaderFactoryImpl::URLLoaderFactoryImpl(
scoped_refptr<ResourceMessageFilter> resource_message_filter)
: resource_message_filter_(std::move(resource_message_filter)) {
......@@ -38,6 +58,18 @@ void URLLoaderFactoryImpl::CreateLoaderAndStart(
resource_message_filter_.get());
}
void URLLoaderFactoryImpl::SyncLoad(int32_t routing_id,
int32_t request_id,
const ResourceRequest& url_request,
const SyncLoadCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get();
rdh->OnSyncLoadWithMojo(routing_id, request_id, url_request,
resource_message_filter_.get(),
base::Bind(&DispatchSyncLoadResult, callback));
}
void URLLoaderFactoryImpl::Create(
scoped_refptr<ResourceMessageFilter> filter,
mojo::InterfaceRequest<mojom::URLLoaderFactory> request) {
......
......@@ -26,6 +26,10 @@ class URLLoaderFactoryImpl final : public mojom::URLLoaderFactory {
int32_t request_id,
const ResourceRequest& url_request,
mojom::URLLoaderClientPtr client) override;
void SyncLoad(int32_t routing_id,
int32_t request_id,
const ResourceRequest& request,
const SyncLoadCallback& callback) override;
// Creates a URLLoaderFactoryImpl instance. The instance is held by the
// StrongBinding in it, so this function doesn't return the instance.
......
......@@ -618,10 +618,15 @@ void ResourceDispatcher::StartSync(
mojom::URLLoaderFactory* url_loader_factory) {
CheckSchemeForReferrerPolicy(*request);
// TODO(yhirano): Use url_loader_factory otherwise.
DCHECK_EQ(blink::WebURLRequest::LoadingIPCType::ChromeIPC, ipc_type);
SyncLoadResult result;
if (ipc_type == blink::WebURLRequest::LoadingIPCType::Mojo) {
if (!url_loader_factory->SyncLoad(
routing_id, MakeRequestID(), *request, &result)) {
response->error_code = net::ERR_FAILED;
return;
}
} else {
IPC::SyncMessage* msg = new ResourceHostMsg_SyncLoad(
routing_id, MakeRequestID(), *request, &result);
......@@ -630,6 +635,7 @@ void ResourceDispatcher::StartSync(
response->error_code = net::ERR_FAILED;
return;
}
}
response->error_code = result.error_code;
response->url = result.final_url;
......
......@@ -11,6 +11,7 @@ typemaps = [
"//content/common/url_loader_status.typemap",
"//content/common/url_request.typemap",
"//content/common/url_response_head.typemap",
"//content/common/url_sync_load_result.typemap",
"//content/common/video_capture.typemap",
"//content/common/web_preferences.typemap",
"//content/common/media/media_session.typemap",
......
......@@ -6,6 +6,9 @@ module content.mojom;
import "url_loader.mojom";
[Native]
struct URLSyncLoadResult;
interface URLLoaderFactory {
// Creats a URLLoader and starts loading with the given |request|. |client|'s
// method will be called when certain events related to that loading
......@@ -16,4 +19,11 @@ interface URLLoaderFactory {
int32 request_id,
URLRequest request,
URLLoaderClient client);
// Loads the resource for the given |request| synchronously.
// |request_id| is for compatibility with the existing Chrome IPC.
[Sync] SyncLoad(int32 routing_id,
int32 request_id,
URLRequest request)
=> (URLSyncLoadResult result);
};
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
mojom = "//content/common/url_loader_factory.mojom"
public_headers = [ "//content/public/common/resource_response.h" ]
traits_headers = [ "//content/common/resource_messages.h" ]
type_mappings = [ "content.mojom.URLSyncLoadResult=content::SyncLoadResult" ]
......@@ -274,6 +274,11 @@
"base": "webexposed",
"args": ["--enable-blink-features=LoadingWithMojo"]
},
{
"prefix": "mojo-loading",
"base": "http/tests/xmlhttprequest/web-apps",
"args": ["--enable-blink-features=LoadingWithMojo"]
},
{
"prefix": "scalefactor150",
"base": "fast/events/synthetic-events",
......
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