Index: content/browser/loader/resource_dispatcher_host_impl.cc |
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc |
index a67343f71ecde5d73c8cc4d9e9a9e7541eeb6dec..747ed951d2ea7a527a3b091e58f981e60b69125d 100644 |
--- a/content/browser/loader/resource_dispatcher_host_impl.cc |
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc |
@@ -1195,6 +1195,56 @@ void ResourceDispatcherHostImpl::UpdateRequestForTransfer( |
} |
} |
+void ResourceDispatcherHostImpl::CompleteTransfer( |
+ int request_id, |
+ const ResourceRequest& request_data, |
+ int route_id) { |
+ // Caller should ensure that |request_data| is associated with a transfer. |
+ DCHECK(request_data.transferred_request_child_id != -1 || |
+ request_data.transferred_request_request_id != -1); |
+ |
+ bool is_navigational_request = |
+ request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME || |
+ request_data.resource_type == RESOURCE_TYPE_SUB_FRAME; |
+ if (!is_navigational_request) { |
+ // Transfers apply only to navigational requests - the renderer seems to |
+ // have sent bogus IPC data. |
+ bad_message::ReceivedBadMessage( |
+ filter_, bad_message::RDH_TRANSFERRING_NONNAVIGATIONAL_REQUEST); |
+ return; |
+ } |
+ |
+ // Attempt to find a loader associated with the deferred transfer request. |
+ LoaderMap::iterator it = pending_loaders_.find( |
+ GlobalRequestID(request_data.transferred_request_child_id, |
+ request_data.transferred_request_request_id)); |
+ if (it == pending_loaders_.end()) { |
+ // Renderer sent transferred_request_request_id and/or |
+ // transferred_request_child_id that doesn't have a corresponding entry on |
+ // the browser side. |
+ bad_message::ReceivedBadMessage( |
+ filter_, bad_message::RDH_TRANSFERRING_REQUEST_NOT_FOUND); |
+ return; |
+ } |
+ ResourceLoader* pending_loader = it->second.get(); |
+ |
+ if (!pending_loader->is_transferring()) { |
+ // Renderer sent transferred_request_request_id and/or |
+ // transferred_request_child_id that doesn't correspond to an actually |
+ // transferring loader on the browser side. |
+ base::debug::Alias(pending_loader); |
+ bad_message::ReceivedBadMessage(filter_, |
+ bad_message::RDH_REQUEST_NOT_TRANSFERRING); |
+ return; |
+ } |
+ |
+ // If the request is transferring to a new process, we can update our |
+ // state and let it resume with its existing ResourceHandlers. |
+ UpdateRequestForTransfer(filter_->child_id(), route_id, request_id, |
+ request_data, it); |
+ pending_loader->CompleteTransfer(); |
+} |
+ |
void ResourceDispatcherHostImpl::BeginRequest( |
int request_id, |
const ResourceRequest& request_data, |
@@ -1239,24 +1289,12 @@ void ResourceDispatcherHostImpl::BeginRequest( |
// If the request that's coming in is being transferred from another process, |
// we want to reuse and resume the old loader rather than start a new one. |
- LoaderMap::iterator it = pending_loaders_.find( |
- GlobalRequestID(request_data.transferred_request_child_id, |
- request_data.transferred_request_request_id)); |
- if (it != pending_loaders_.end()) { |
+ if (request_data.transferred_request_child_id != -1 || |
+ request_data.transferred_request_request_id != -1) { |
// TODO(yhirano): Make mojo work for this case. |
DCHECK(!url_loader_client); |
- // If the request is transferring to a new process, we can update our |
- // state and let it resume with its existing ResourceHandlers. |
- if (it->second->is_transferring()) { |
- ResourceLoader* deferred_loader = it->second.get(); |
- UpdateRequestForTransfer(child_id, route_id, request_id, |
- request_data, it); |
- deferred_loader->CompleteTransfer(); |
- } else { |
- bad_message::ReceivedBadMessage( |
- filter_, bad_message::RDH_REQUEST_NOT_TRANSFERRING); |
- } |
+ CompleteTransfer(request_id, request_data, route_id); |
return; |
} |