Commit 1c895912 authored by tzik's avatar tzik Committed by Commit bot

Make SyncLoad result handling pluggable

Use a base::Callback to dispatch a SyncLoad result instead of
IPC::Message, so that we can share most of synchronous load code between
Chrome IPC version and Mojo IPC version.

BUG=603396

Review-Url: https://codereview.chromium.org/2390313002
Cr-Commit-Position: refs/heads/master@{#423840}
parent da340247
...@@ -120,6 +120,8 @@ using base::Time; ...@@ -120,6 +120,8 @@ using base::Time;
using base::TimeDelta; using base::TimeDelta;
using base::TimeTicks; using base::TimeTicks;
using storage::ShareableFileReference; using storage::ShareableFileReference;
using SyncLoadResultCallback =
content::ResourceDispatcherHostImpl::SyncLoadResultCallback;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
...@@ -222,15 +224,15 @@ bool IsDetachableResourceType(ResourceType type) { ...@@ -222,15 +224,15 @@ bool IsDetachableResourceType(ResourceType type) {
} }
// Aborts a request before an URLRequest has actually been created. // Aborts a request before an URLRequest has actually been created.
void AbortRequestBeforeItStarts(ResourceMessageFilter* filter, void AbortRequestBeforeItStarts(
IPC::Message* sync_result, ResourceMessageFilter* filter,
int request_id, const SyncLoadResultCallback& sync_result_handler,
mojom::URLLoaderClientPtr url_loader_client) { int request_id,
if (sync_result) { mojom::URLLoaderClientPtr url_loader_client) {
if (sync_result_handler) {
SyncLoadResult result; SyncLoadResult result;
result.error_code = net::ERR_ABORTED; result.error_code = net::ERR_ABORTED;
ResourceHostMsg_SyncLoad::WriteReplyParams(sync_result, result); sync_result_handler.Run(&result);
filter->Send(sync_result);
} else { } else {
// Tell the renderer that this request was disallowed. // Tell the renderer that this request was disallowed.
ResourceRequestCompletionStatus request_complete_data; ResourceRequestCompletionStatus request_complete_data;
...@@ -415,6 +417,22 @@ void NotifyForEachFrameFromUI( ...@@ -415,6 +417,22 @@ void NotifyForEachFrameFromUI(
base::Passed(std::move(routing_ids)))); base::Passed(std::move(routing_ids))));
} }
// Sends back the result of a synchronous loading result to the renderer through
// Chrome IPC.
void HandleSyncLoadResult(base::WeakPtr<ResourceMessageFilter> filter,
std::unique_ptr<IPC::Message> sync_result,
const SyncLoadResult* result) {
if (!filter)
return;
if (result) {
ResourceHostMsg_SyncLoad::WriteReplyParams(sync_result.get(), *result);
} else {
sync_result->set_reply_error();
}
filter->Send(sync_result.release());
}
} // namespace } // namespace
ResourceDispatcherHostImpl::LoadInfo::LoadInfo() {} ResourceDispatcherHostImpl::LoadInfo::LoadInfo() {}
...@@ -1060,7 +1078,7 @@ void ResourceDispatcherHostImpl::OnRequestResourceInternal( ...@@ -1060,7 +1078,7 @@ void ResourceDispatcherHostImpl::OnRequestResourceInternal(
request_data.render_frame_id, request_data.render_frame_id,
request_data.url)); request_data.url));
} }
BeginRequest(request_id, request_data, NULL, routing_id, BeginRequest(request_id, request_data, SyncLoadResultCallback(), routing_id,
std::move(mojo_request), std::move(url_loader_client)); std::move(mojo_request), std::move(url_loader_client));
} }
...@@ -1075,7 +1093,10 @@ void ResourceDispatcherHostImpl::OnRequestResourceInternal( ...@@ -1075,7 +1093,10 @@ void ResourceDispatcherHostImpl::OnRequestResourceInternal(
void ResourceDispatcherHostImpl::OnSyncLoad(int request_id, void ResourceDispatcherHostImpl::OnSyncLoad(int request_id,
const ResourceRequest& request_data, const ResourceRequest& request_data,
IPC::Message* sync_result) { IPC::Message* sync_result) {
BeginRequest(request_id, request_data, sync_result, sync_result->routing_id(), SyncLoadResultCallback callback = base::Bind(
&HandleSyncLoadResult, filter_->GetWeakPtr(),
base::Passed(WrapUnique(sync_result)));
BeginRequest(request_id, request_data, callback, sync_result->routing_id(),
nullptr, nullptr); nullptr, nullptr);
} }
...@@ -1182,7 +1203,7 @@ void ResourceDispatcherHostImpl::UpdateRequestForTransfer( ...@@ -1182,7 +1203,7 @@ void ResourceDispatcherHostImpl::UpdateRequestForTransfer(
void ResourceDispatcherHostImpl::BeginRequest( void ResourceDispatcherHostImpl::BeginRequest(
int request_id, int request_id,
const ResourceRequest& request_data, const ResourceRequest& request_data,
IPC::Message* sync_result, // only valid for sync const SyncLoadResultCallback& sync_result_handler, // only valid for sync
int route_id, int route_id,
mojo::InterfaceRequest<mojom::URLLoader> mojo_request, mojo::InterfaceRequest<mojom::URLLoader> mojo_request,
mojom::URLLoaderClientPtr url_loader_client) { mojom::URLLoaderClientPtr url_loader_client) {
...@@ -1257,7 +1278,7 @@ void ResourceDispatcherHostImpl::BeginRequest( ...@@ -1257,7 +1278,7 @@ void ResourceDispatcherHostImpl::BeginRequest(
if (is_shutdown_ || if (is_shutdown_ ||
!ShouldServiceRequest(process_type, child_id, request_data, headers, !ShouldServiceRequest(process_type, child_id, request_data, headers,
filter_, resource_context)) { filter_, resource_context)) {
AbortRequestBeforeItStarts(filter_, sync_result, request_id, AbortRequestBeforeItStarts(filter_, sync_result_handler, request_id,
std::move(url_loader_client)); std::move(url_loader_client));
return; return;
} }
...@@ -1282,22 +1303,22 @@ void ResourceDispatcherHostImpl::BeginRequest( ...@@ -1282,22 +1303,22 @@ void ResourceDispatcherHostImpl::BeginRequest(
it.name(), it.value(), child_id, resource_context, it.name(), it.value(), child_id, resource_context,
base::Bind(&ResourceDispatcherHostImpl::ContinuePendingBeginRequest, base::Bind(&ResourceDispatcherHostImpl::ContinuePendingBeginRequest,
base::Unretained(this), request_id, request_data, base::Unretained(this), request_id, request_data,
sync_result, route_id, headers, sync_result_handler, route_id, headers,
base::Passed(std::move(mojo_request)), base::Passed(std::move(mojo_request)),
base::Passed(std::move(url_loader_client)))); base::Passed(std::move(url_loader_client))));
return; return;
} }
} }
} }
ContinuePendingBeginRequest(request_id, request_data, sync_result, route_id, ContinuePendingBeginRequest(request_id, request_data, sync_result_handler,
headers, std::move(mojo_request), route_id, headers, std::move(mojo_request),
std::move(url_loader_client), true, 0); std::move(url_loader_client), true, 0);
} }
void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
int request_id, int request_id,
const ResourceRequest& request_data, const ResourceRequest& request_data,
IPC::Message* sync_result, // only valid for sync const SyncLoadResultCallback& sync_result_handler, // only valid for sync
int route_id, int route_id,
const net::HttpRequestHeaders& headers, const net::HttpRequestHeaders& headers,
mojo::InterfaceRequest<mojom::URLLoader> mojo_request, mojo::InterfaceRequest<mojom::URLLoader> mojo_request,
...@@ -1308,7 +1329,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( ...@@ -1308,7 +1329,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
// TODO(ananta): Find a way to specify the right error code here. Passing // TODO(ananta): Find a way to specify the right error code here. Passing
// in a non-content error code is not safe. // in a non-content error code is not safe.
bad_message::ReceivedBadMessage(filter_, bad_message::RDH_ILLEGAL_ORIGIN); bad_message::ReceivedBadMessage(filter_, bad_message::RDH_ILLEGAL_ORIGIN);
AbortRequestBeforeItStarts(filter_, sync_result, request_id, AbortRequestBeforeItStarts(filter_, sync_result_handler, request_id,
std::move(url_loader_client)); std::move(url_loader_client));
return; return;
} }
...@@ -1331,7 +1352,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( ...@@ -1331,7 +1352,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
request_data.url, request_data.url,
request_data.resource_type, request_data.resource_type,
resource_context)) { resource_context)) {
AbortRequestBeforeItStarts(filter_, sync_result, request_id, AbortRequestBeforeItStarts(filter_, sync_result_handler, request_id,
std::move(url_loader_client)); std::move(url_loader_client));
return; return;
} }
...@@ -1404,7 +1425,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( ...@@ -1404,7 +1425,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
bool allow_download = request_data.allow_download && bool allow_download = request_data.allow_download &&
IsResourceTypeFrame(request_data.resource_type); IsResourceTypeFrame(request_data.resource_type);
bool do_not_prompt_for_login = request_data.do_not_prompt_for_login; bool do_not_prompt_for_login = request_data.do_not_prompt_for_login;
bool is_sync_load = sync_result != NULL; bool is_sync_load = !!sync_result_handler;
// Raw headers are sensitive, as they include Cookie/Set-Cookie, so only // Raw headers are sensitive, as they include Cookie/Set-Cookie, so only
// allow requesting them if requester has ReadRawCookies permission. // allow requesting them if requester has ReadRawCookies permission.
...@@ -1516,8 +1537,8 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( ...@@ -1516,8 +1537,8 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
request_data.should_reset_appcache); request_data.should_reset_appcache);
std::unique_ptr<ResourceHandler> handler(CreateResourceHandler( std::unique_ptr<ResourceHandler> handler(CreateResourceHandler(
new_request.get(), request_data, sync_result, route_id, process_type, new_request.get(), request_data, sync_result_handler, route_id,
child_id, resource_context, std::move(mojo_request), process_type, child_id, resource_context, std::move(mojo_request),
std::move(url_loader_client))); std::move(url_loader_client)));
if (handler) if (handler)
...@@ -1528,7 +1549,7 @@ std::unique_ptr<ResourceHandler> ...@@ -1528,7 +1549,7 @@ std::unique_ptr<ResourceHandler>
ResourceDispatcherHostImpl::CreateResourceHandler( ResourceDispatcherHostImpl::CreateResourceHandler(
net::URLRequest* request, net::URLRequest* request,
const ResourceRequest& request_data, const ResourceRequest& request_data,
IPC::Message* sync_result, const SyncLoadResultCallback& sync_result_handler,
int route_id, int route_id,
int process_type, int process_type,
int child_id, int child_id,
...@@ -1541,7 +1562,7 @@ ResourceDispatcherHostImpl::CreateResourceHandler( ...@@ -1541,7 +1562,7 @@ ResourceDispatcherHostImpl::CreateResourceHandler(
"456331 ResourceDispatcherHostImpl::CreateResourceHandler")); "456331 ResourceDispatcherHostImpl::CreateResourceHandler"));
// Construct the IPC resource handler. // Construct the IPC resource handler.
std::unique_ptr<ResourceHandler> handler; std::unique_ptr<ResourceHandler> handler;
if (sync_result) { if (sync_result_handler) {
// download_to_file is not supported for synchronous requests. // download_to_file is not supported for synchronous requests.
if (request_data.download_to_file) { if (request_data.download_to_file) {
bad_message::ReceivedBadMessage(filter_, bad_message::RDH_BAD_DOWNLOAD); bad_message::ReceivedBadMessage(filter_, bad_message::RDH_BAD_DOWNLOAD);
...@@ -1550,7 +1571,7 @@ ResourceDispatcherHostImpl::CreateResourceHandler( ...@@ -1550,7 +1571,7 @@ ResourceDispatcherHostImpl::CreateResourceHandler(
DCHECK(!mojo_request.is_pending()); DCHECK(!mojo_request.is_pending());
DCHECK(!url_loader_client); DCHECK(!url_loader_client);
handler.reset(new SyncResourceHandler(request, sync_result, this)); handler.reset(new SyncResourceHandler(request, sync_result_handler, this));
} else { } else {
if (mojo_request.is_pending()) { if (mojo_request.is_pending()) {
handler.reset(new MojoAsyncResourceHandler(request, this, handler.reset(new MojoAsyncResourceHandler(request, this,
...@@ -1570,8 +1591,9 @@ ResourceDispatcherHostImpl::CreateResourceHandler( ...@@ -1570,8 +1591,9 @@ ResourceDispatcherHostImpl::CreateResourceHandler(
bool start_detached = request_data.download_to_network_cache_only; bool start_detached = request_data.download_to_network_cache_only;
// Prefetches and <a ping> requests outlive their child process. // Prefetches and <a ping> requests outlive their child process.
if (!sync_result && (start_detached || if (!sync_result_handler &&
IsDetachableResourceType(request_data.resource_type))) { (start_detached ||
IsDetachableResourceType(request_data.resource_type))) {
std::unique_ptr<DetachableResourceHandler> detachable_handler = std::unique_ptr<DetachableResourceHandler> detachable_handler =
base::MakeUnique<DetachableResourceHandler>( base::MakeUnique<DetachableResourceHandler>(
request, request,
......
...@@ -19,8 +19,10 @@ ...@@ -19,8 +19,10 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/callback_forward.h"
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
...@@ -84,6 +86,11 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl ...@@ -84,6 +86,11 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
: public ResourceDispatcherHost, : public ResourceDispatcherHost,
public ResourceLoaderDelegate { public ResourceLoaderDelegate {
public: public:
// Used to handle the result of SyncLoad IPC. |result| is null if it's
// unavailable due to an error.
using SyncLoadResultCallback =
base::Callback<void(const SyncLoadResult* result)>;
// This constructor should be used if we want downloads to work correctly. // This constructor should be used if we want downloads to work correctly.
// TODO(ananta) // TODO(ananta)
// Work on moving creation of download handlers out of // Work on moving creation of download handlers out of
...@@ -532,12 +539,13 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl ...@@ -532,12 +539,13 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
const ResourceRequest& request_data, const ResourceRequest& request_data,
LoaderMap::iterator iter); LoaderMap::iterator iter);
void BeginRequest(int request_id, void BeginRequest(
const ResourceRequest& request_data, int request_id,
IPC::Message* sync_result, // only valid for sync const ResourceRequest& request_data,
int route_id, // only valid for async const SyncLoadResultCallback& sync_result_handler, // only valid for sync
mojo::InterfaceRequest<mojom::URLLoader> mojo_request, int route_id, // only valid for async
mojom::URLLoaderClientPtr url_loader_client); mojo::InterfaceRequest<mojom::URLLoader> mojo_request,
mojom::URLLoaderClientPtr url_loader_client);
// There are requests which need decisions to be made like the following: // There are requests which need decisions to be made like the following:
// Whether the presence of certain HTTP headers like the Origin header are // Whether the presence of certain HTTP headers like the Origin header are
...@@ -551,7 +559,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl ...@@ -551,7 +559,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
void ContinuePendingBeginRequest( void ContinuePendingBeginRequest(
int request_id, int request_id,
const ResourceRequest& request_data, const ResourceRequest& request_data,
IPC::Message* sync_result, // only valid for sync const SyncLoadResultCallback& sync_result_handler, // only valid for sync
int route_id, int route_id,
const net::HttpRequestHeaders& headers, const net::HttpRequestHeaders& headers,
mojo::InterfaceRequest<mojom::URLLoader> mojo_request, mojo::InterfaceRequest<mojom::URLLoader> mojo_request,
...@@ -564,7 +572,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl ...@@ -564,7 +572,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
std::unique_ptr<ResourceHandler> CreateResourceHandler( std::unique_ptr<ResourceHandler> CreateResourceHandler(
net::URLRequest* request, net::URLRequest* request,
const ResourceRequest& request_data, const ResourceRequest& request_data,
IPC::Message* sync_result, const SyncLoadResultCallback& sync_result_handler,
int route_id, int route_id,
int process_type, int process_type,
int child_id, int child_id,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "content/browser/loader/sync_resource_handler.h" #include "content/browser/loader/sync_resource_handler.h"
#include "base/callback_helpers.h"
#include "base/logging.h" #include "base/logging.h"
#include "content/browser/loader/netlog_observer.h" #include "content/browser/loader/netlog_observer.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/loader/resource_dispatcher_host_impl.h"
...@@ -20,25 +21,19 @@ namespace content { ...@@ -20,25 +21,19 @@ namespace content {
SyncResourceHandler::SyncResourceHandler( SyncResourceHandler::SyncResourceHandler(
net::URLRequest* request, net::URLRequest* request,
IPC::Message* result_message, const SyncLoadResultCallback& result_handler,
ResourceDispatcherHostImpl* resource_dispatcher_host) ResourceDispatcherHostImpl* resource_dispatcher_host)
: ResourceHandler(request), : ResourceHandler(request),
read_buffer_(new net::IOBuffer(kReadBufSize)), read_buffer_(new net::IOBuffer(kReadBufSize)),
result_message_(result_message), result_handler_(result_handler),
rdh_(resource_dispatcher_host), rdh_(resource_dispatcher_host),
total_transfer_size_(0) { total_transfer_size_(0) {
result_.final_url = request->url(); result_.final_url = request->url();
} }
SyncResourceHandler::~SyncResourceHandler() { SyncResourceHandler::~SyncResourceHandler() {
if (result_message_) { if (result_handler_)
result_message_->set_reply_error(); result_handler_.Run(nullptr);
ResourceMessageFilter* filter = GetFilter();
// If the filter doesn't exist at this point, the process has died and isn't
// waiting for the result message anymore.
if (filter)
filter->Send(result_message_);
}
} }
bool SyncResourceHandler::OnRequestRedirected( bool SyncResourceHandler::OnRequestRedirected(
...@@ -114,20 +109,13 @@ bool SyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { ...@@ -114,20 +109,13 @@ bool SyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
void SyncResourceHandler::OnResponseCompleted( void SyncResourceHandler::OnResponseCompleted(
const net::URLRequestStatus& status, const net::URLRequestStatus& status,
bool* defer) { bool* defer) {
ResourceMessageFilter* filter = GetFilter();
if (!filter)
return;
result_.error_code = status.error(); result_.error_code = status.error();
int total_transfer_size = request()->GetTotalReceivedBytes(); int total_transfer_size = request()->GetTotalReceivedBytes();
result_.encoded_data_length = total_transfer_size_ + total_transfer_size; result_.encoded_data_length = total_transfer_size_ + total_transfer_size;
result_.encoded_body_length = request()->GetRawBodyBytes(); result_.encoded_body_length = request()->GetRawBodyBytes();
ResourceHostMsg_SyncLoad::WriteReplyParams(result_message_, result_); base::ResetAndReturn(&result_handler_).Run(&result_);
filter->Send(result_message_);
result_message_ = NULL;
return;
} }
void SyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { void SyncResourceHandler::OnDataDownloaded(int bytes_downloaded) {
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <string> #include <string>
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_handler.h" #include "content/browser/loader/resource_handler.h"
#include "content/public/common/resource_response.h" #include "content/public/common/resource_response.h"
...@@ -23,15 +24,17 @@ class URLRequest; ...@@ -23,15 +24,17 @@ class URLRequest;
namespace content { namespace content {
class ResourceContext; class ResourceContext;
class ResourceDispatcherHostImpl;
class ResourceMessageFilter; class ResourceMessageFilter;
// Used to complete a synchronous resource request in response to resource load // Used to complete a synchronous resource request in response to resource load
// events from the resource dispatcher host. // events from the resource dispatcher host.
class SyncResourceHandler : public ResourceHandler { class SyncResourceHandler : public ResourceHandler {
public: public:
using SyncLoadResultCallback =
ResourceDispatcherHostImpl::SyncLoadResultCallback;
SyncResourceHandler(net::URLRequest* request, SyncResourceHandler(net::URLRequest* request,
IPC::Message* result_message, const SyncLoadResultCallback& sync_result_handler,
ResourceDispatcherHostImpl* resource_dispatcher_host); ResourceDispatcherHostImpl* resource_dispatcher_host);
~SyncResourceHandler() override; ~SyncResourceHandler() override;
...@@ -54,7 +57,7 @@ class SyncResourceHandler : public ResourceHandler { ...@@ -54,7 +57,7 @@ class SyncResourceHandler : public ResourceHandler {
scoped_refptr<net::IOBuffer> read_buffer_; scoped_refptr<net::IOBuffer> read_buffer_;
SyncLoadResult result_; SyncLoadResult result_;
IPC::Message* result_message_; SyncLoadResultCallback result_handler_;
ResourceDispatcherHostImpl* rdh_; ResourceDispatcherHostImpl* rdh_;
int64_t total_transfer_size_; int64_t total_transfer_size_;
}; };
......
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