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

Unified Diff: content/browser/renderer_host/resource_dispatcher_host.cc

Issue 8669014: Fix a bug where redirect chain gets lost on process swap. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: latest Created 9 years 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
Index: content/browser/renderer_host/resource_dispatcher_host.cc
diff --git a/content/browser/renderer_host/resource_dispatcher_host.cc b/content/browser/renderer_host/resource_dispatcher_host.cc
index fb0f1c33e0108169ae32d8423f1e4cc823466d0b..69010ba08140a2fa8f16761e2be337ad9647998e 100644
--- a/content/browser/renderer_host/resource_dispatcher_host.cc
+++ b/content/browser/renderer_host/resource_dispatcher_host.cc
@@ -312,7 +312,12 @@ ResourceDispatcherHost::ResourceDispatcherHost(
ResourceDispatcherHost::~ResourceDispatcherHost() {
AsyncResourceHandler::GlobalCleanup();
+ for (PendingRequestList::const_iterator i = pending_requests_.begin();
+ i != pending_requests_.end(); ++i) {
+ transferred_navigations_.erase(i->first);
+ }
STLDeleteValues(&pending_requests_);
+ DCHECK(transferred_navigations_.empty());
}
void ResourceDispatcherHost::Initialize() {
@@ -340,6 +345,10 @@ void ResourceDispatcherHost::OnShutdown() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
is_shutdown_ = true;
resource_queue_.Shutdown();
+ for (PendingRequestList::const_iterator i = pending_requests_.begin();
+ i != pending_requests_.end(); ++i) {
+ transferred_navigations_.erase(i->first);
+ }
STLDeleteValues(&pending_requests_);
// Make sure we shutdown the timer now, otherwise by the time our destructor
// runs if the timer is still running the Task is deleted twice (once by
@@ -457,6 +466,31 @@ void ResourceDispatcherHost::BeginRequest(
base::strlcpy(url_buf, request_data.url.spec().c_str(), arraysize(url_buf));
base::debug::Alias(url_buf);
+ // TODO(mpcomplete): Step 3. (See steps 1-2 below).
Charlie Reis 2011/12/02 22:38:11 This comment needs updating and should probably ha
Matt Perry 2011/12/03 00:14:24 Done.
+ // If the request that's coming in is a cross-process transferring, then we
+ // want to reuse and resume the old request rather than start a new one.
+ // I'm not entirely sure how much of the BeginRequest code should run. We
+ // definitely want to create new ResourceHandlers and ExtraInfo, since those
+ // are tied to the process.
+ // Also, I'm not clear what should happen if any of the early returns are hit
+ // before we actually resume the request via FollowDeferredRedirect. I think
+ // we're then left with an orphaned request that will never be deleted. We
+ // probably want to cancel it in those cases.
+ // It's probably best to split apart BeginRequest into 2 methods, 1 for
+ // regular requests and one for transferred ones - probably with some shared
+ // code, but not all.
+ net::URLRequest* deferred_request = NULL;
+
+ GlobalRequestID old_request_id(request_data.transferred_request_child_id,
+ request_data.transferred_request_request_id);
+ TransferredNavigations::iterator iter =
+ transferred_navigations_.find(old_request_id);
+ if (iter != transferred_navigations_.end()) {
+ deferred_request = iter->second;
+ pending_requests_.erase(old_request_id);
+ transferred_navigations_.erase(iter);
+ }
+
const content::ResourceContext& resource_context =
filter_->resource_context();
@@ -508,13 +542,18 @@ void ResourceDispatcherHost::BeginRequest(
}
// Construct the request.
- net::URLRequest* request = new net::URLRequest(request_data.url, this);
- request->set_method(request_data.method);
- request->set_first_party_for_cookies(request_data.first_party_for_cookies);
- request->set_referrer(referrer.spec());
- net::HttpRequestHeaders headers;
- headers.AddHeadersFromString(request_data.headers);
- request->SetExtraRequestHeaders(headers);
+ net::URLRequest* request;
+ if (deferred_request) {
+ request = deferred_request;
+ } else {
+ request = new net::URLRequest(request_data.url, this);
+ request->set_method(request_data.method);
+ request->set_first_party_for_cookies(request_data.first_party_for_cookies);
+ request->set_referrer(referrer.spec());
+ net::HttpRequestHeaders headers;
+ headers.AddHeadersFromString(request_data.headers);
+ request->SetExtraRequestHeaders(headers);
+ }
int load_flags = request_data.load_flags;
// Although EV status is irrelevant to sub-frames and sub-resources, we have
@@ -543,15 +582,16 @@ void ResourceDispatcherHost::BeginRequest(
net::LOAD_DO_NOT_SAVE_COOKIES);
}
- // Raw headers are sensitive, as they inclide Cookie/Set-Cookie, so only
- // allow requesting them if requestor has ReadRawCookies permission.
+ // Raw headers are sensitive, as they include Cookie/Set-Cookie, so only
+ // allow requesting them if requester has ReadRawCookies permission.
if ((load_flags & net::LOAD_REPORT_RAW_HEADERS)
&& !policy->CanReadRawCookies(child_id)) {
- VLOG(1) << "Denied unathorized request for raw headers";
+ VLOG(1) << "Denied unauthorized request for raw headers";
load_flags &= ~net::LOAD_REPORT_RAW_HEADERS;
}
request->set_load_flags(load_flags);
+
request->set_context(
filter_->GetURLRequestContext(request_data.resource_type));
request->set_priority(DetermineRequestPriority(request_data.resource_type));
@@ -584,8 +624,11 @@ void ResourceDispatcherHost::BeginRequest(
if (delegate_) {
bool sub = request_data.resource_type != ResourceType::MAIN_FRAME;
- handler = delegate_->RequestBeginning(handler, request, resource_context,
- sub, child_id, route_id);
+ bool is_continuation_of_transferred_request =
+ (deferred_request != NULL);
+ handler = delegate_->RequestBeginning(
+ handler, request, resource_context, sub, child_id, route_id,
+ is_continuation_of_transferred_request);
}
// Make extra info and read footer (contains request ID).
@@ -624,7 +667,13 @@ void ResourceDispatcherHost::BeginRequest(
request, resource_context.appcache_service(), child_id,
request_data.appcache_host_id, request_data.resource_type);
- BeginRequestInternal(request);
+ if (deferred_request) {
+ GlobalRequestID global_id(extra_info->child_id(), extra_info->request_id());
+ pending_requests_[global_id] = request;
+ request->FollowDeferredRedirect();
+ } else {
+ BeginRequestInternal(request);
+ }
}
void ResourceDispatcherHost::OnReleaseDownloadedFile(int request_id) {
@@ -1186,6 +1235,13 @@ void ResourceDispatcherHost::RemovePendingRequest(
const PendingRequestList::iterator& iter) {
ResourceDispatcherHostRequestInfo* info = InfoForRequest(iter->second);
+ // This is called via CancelRequestsForRoute to remove all requests for a
+ // closing tab. We don't want to remove requests that are being transferred
+ // to a new tab.
Charlie Reis 2011/12/02 22:38:11 When would a request be transferred from one tab t
Matt Perry 2011/12/03 00:14:24 I moved this block to a more isolated location, an
+ GlobalRequestID id(info->child_id(), info->request_id());
+ if (transferred_navigations_.find(id) != transferred_navigations_.end())
+ return;
+
// Remove the memory credit that we added when pushing the request onto
// the pending list.
IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(),
@@ -1418,8 +1474,15 @@ bool ResourceDispatcherHost::CompleteResponseStarted(net::URLRequest* request) {
void ResourceDispatcherHost::CancelRequest(int child_id,
int request_id,
bool from_renderer) {
- PendingRequestList::iterator i = pending_requests_.find(
- GlobalRequestID(child_id, request_id));
+ GlobalRequestID id(child_id, request_id);
+ if (from_renderer) {
+ // When the old renderer dies, it sends a message to us to cancel its
+ // requests.
+ if (transferred_navigations_.find(id) != transferred_navigations_.end())
+ return;
+ }
+
+ PendingRequestList::iterator i = pending_requests_.find(id);
if (i == pending_requests_.end()) {
// We probably want to remove this warning eventually, but I wanted to be
// able to notice when this happens during initial development since it
@@ -1481,7 +1544,7 @@ int ResourceDispatcherHost::IncrementOutstandingRequestsMemoryCost(
new_cost += cost;
CHECK(new_cost >= 0);
if (new_cost == 0)
- outstanding_requests_memory_cost_map_.erase(prev_entry);
+ outstanding_requests_memory_cost_map_.erase(child_id);
else
outstanding_requests_memory_cost_map_[child_id] = new_cost;
@@ -2179,3 +2242,9 @@ bool ResourceDispatcherHost::allow_cross_origin_auth_prompt() {
void ResourceDispatcherHost::set_allow_cross_origin_auth_prompt(bool value) {
allow_cross_origin_auth_prompt_ = value;
}
+
+void ResourceDispatcherHost::MarkAsTransferredNavigation(
+ const GlobalRequestID& transferred_request_id,
+ net::URLRequest* ransferred_request) {
+ transferred_navigations_[transferred_request_id] = ransferred_request;
+}

Powered by Google App Engine
This is Rietveld 408576698