summaryrefslogtreecommitdiffstats
path: root/content/browser/renderer_host/resource_dispatcher_host.cc
diff options
context:
space:
mode:
Diffstat (limited to 'content/browser/renderer_host/resource_dispatcher_host.cc')
-rw-r--r--content/browser/renderer_host/resource_dispatcher_host.cc92
1 files changed, 76 insertions, 16 deletions
diff --git a/content/browser/renderer_host/resource_dispatcher_host.cc b/content/browser/renderer_host/resource_dispatcher_host.cc
index fb0f1c3..1bd30fc 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,20 @@ void ResourceDispatcherHost::BeginRequest(
base::strlcpy(url_buf, request_data.url.spec().c_str(), arraysize(url_buf));
base::debug::Alias(url_buf);
+ // If the request that's coming in is being transferred from another process,
+ // we want to reuse and resume the old request rather than start a new one.
+ 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 +531,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 +571,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 +613,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 +656,16 @@ void ResourceDispatcherHost::BeginRequest(
request, resource_context.appcache_service(), child_id,
request_data.appcache_host_id, request_data.resource_type);
- BeginRequestInternal(request);
+ if (deferred_request) {
+ // This is a request that has been transferred from another process, so
+ // resume it rather than continuing the regular procedure for starting a
+ // request. Currently this is only done for redirects.
+ 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) {
@@ -1039,7 +1080,13 @@ void ResourceDispatcherHost::CancelRequestsForRoute(int child_id,
i != pending_requests_.end(); ++i) {
if (i->first.child_id == child_id) {
ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second);
+ GlobalRequestID id(child_id, i->first.request_id);
+ DCHECK(id == i->first);
+ // Don't cancel navigations that are transferring to another process,
+ // since they belong to another process now.
if (!info->is_download() &&
+ (transferred_navigations_.find(id) ==
+ transferred_navigations_.end()) &&
(route_id == -1 || route_id == info->route_id())) {
matching_requests.push_back(
GlobalRequestID(child_id, i->first.request_id));
@@ -1418,8 +1465,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 +1535,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 +2233,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;
+}