Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Unified Diff: content/child/resource_dispatcher.cc

Issue 268423002: Fix WebURLLoaderImpl::Context leak if a pending request is canceled. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rephrase the comment Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/child/resource_dispatcher.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/child/resource_dispatcher.cc
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc
index b6a877fa65d5f8b9b91658ac2d14d5e01bb74680..6ec8b38bc4a9039fada3efabcc14cb909d6eb37b 100644
--- a/content/child/resource_dispatcher.cc
+++ b/content/child/resource_dispatcher.cc
@@ -297,6 +297,18 @@ bool ResourceDispatcher::OnMessageReceived(const IPC::Message& message) {
return true;
}
+ // If the request has been canceled, only dispatch
+ // ResourceMsg_RequestComplete (otherwise resource leaks) and drop other
+ // messages.
+ if (request_info->is_canceled) {
+ if (message.type() == ResourceMsg_RequestComplete::ID) {
+ DispatchMessage(message);
+ } else {
+ ReleaseResourcesInDataMessage(message);
+ }
+ return true;
+ }
+
if (request_info->is_deferred) {
request_info->deferred_message_queue.push_back(new IPC::Message(message));
return true;
@@ -588,6 +600,46 @@ void ResourceDispatcher::CancelPendingRequest(int request_id) {
return;
}
+ PendingRequestInfo& request_info = it->second;
+ request_info.is_canceled = true;
+
+ // Because message handlers could result in request_info being destroyed,
+ // we need to work with a stack reference to the deferred queue.
+ MessageQueue queue;
+ queue.swap(request_info.deferred_message_queue);
+ // Removes pending requests. If ResourceMsg_RequestComplete was queued,
+ // dispatch it.
+ bool first_message = true;
+ while (!queue.empty()) {
+ IPC::Message* message = queue.front();
mmenke 2014/05/08 17:54:00 optional: I think it would be a little cleaner to
+ if (message->type() == ResourceMsg_RequestComplete::ID) {
+ if (first_message) {
+ // Dispatch as-is.
+ DispatchMessage(*message);
+ } else {
+ // If we skip some ResourceMsg_DataReceived and then dispatched the
+ // original ResourceMsg_RequestComplete(status=success), chrome will
+ // crash because it entered an unexpected state. So replace
+ // ResourceMsg_RequestComplete with failure status.
+ ResourceMsg_RequestCompleteData request_complete_data;
+ request_complete_data.error_code = net::ERR_ABORTED;
+ request_complete_data.was_ignored_by_handler = false;
+ request_complete_data.exists_in_cache = false;
+ request_complete_data.completion_time = base::TimeTicks();
+ request_complete_data.encoded_data_length = 0;
+
+ ResourceMsg_RequestComplete error_message(request_id,
+ request_complete_data);
+ DispatchMessage(error_message);
+ }
+ } else {
+ ReleaseResourcesInDataMessage(*message);
+ }
+ first_message = false;
+ queue.pop_front();
+ delete message;
+ }
+
// |request_id| will be removed from |pending_requests_| when
// OnRequestComplete returns with ERR_ABORTED.
message_sender()->Send(new ResourceHostMsg_CancelRequest(request_id));
@@ -627,6 +679,7 @@ ResourceDispatcher::PendingRequestInfo::PendingRequestInfo()
: peer(NULL),
resource_type(ResourceType::SUB_RESOURCE),
is_deferred(false),
+ is_canceled(false),
blocked_response(false),
buffer_size(0) {
}
@@ -641,6 +694,7 @@ ResourceDispatcher::PendingRequestInfo::PendingRequestInfo(
resource_type(resource_type),
origin_pid(origin_pid),
is_deferred(false),
+ is_canceled(false),
url(request_url),
frame_origin(frame_origin),
response_url(request_url),
« no previous file with comments | « content/child/resource_dispatcher.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698