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

Side by Side Diff: content/browser/loader/resource_dispatcher_host_impl.cc

Issue 25772002: Allows prefetch requests to live beyond the renderer by delaying (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added DetachableType function for generality. Created 7 years, 2 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading
6 6
7 #include "content/browser/loader/resource_dispatcher_host_impl.h" 7 #include "content/browser/loader/resource_dispatcher_host_impl.h"
8 8
9 #include <set> 9 #include <set>
10 #include <vector> 10 #include <vector>
(...skipping 14 matching lines...) Expand all
25 #include "content/browser/appcache/chrome_appcache_service.h" 25 #include "content/browser/appcache/chrome_appcache_service.h"
26 #include "content/browser/cert_store_impl.h" 26 #include "content/browser/cert_store_impl.h"
27 #include "content/browser/child_process_security_policy_impl.h" 27 #include "content/browser/child_process_security_policy_impl.h"
28 #include "content/browser/cross_site_request_manager.h" 28 #include "content/browser/cross_site_request_manager.h"
29 #include "content/browser/download/download_resource_handler.h" 29 #include "content/browser/download/download_resource_handler.h"
30 #include "content/browser/download/save_file_manager.h" 30 #include "content/browser/download/save_file_manager.h"
31 #include "content/browser/download/save_file_resource_handler.h" 31 #include "content/browser/download/save_file_resource_handler.h"
32 #include "content/browser/fileapi/chrome_blob_storage_context.h" 32 #include "content/browser/fileapi/chrome_blob_storage_context.h"
33 #include "content/browser/loader/async_resource_handler.h" 33 #include "content/browser/loader/async_resource_handler.h"
34 #include "content/browser/loader/buffered_resource_handler.h" 34 #include "content/browser/loader/buffered_resource_handler.h"
35 #include "content/browser/loader/detached_resource_handler.h"
35 #include "content/browser/loader/cross_site_resource_handler.h" 36 #include "content/browser/loader/cross_site_resource_handler.h"
36 #include "content/browser/loader/power_save_block_resource_throttle.h" 37 #include "content/browser/loader/power_save_block_resource_throttle.h"
37 #include "content/browser/loader/redirect_to_file_resource_handler.h" 38 #include "content/browser/loader/redirect_to_file_resource_handler.h"
38 #include "content/browser/loader/resource_message_filter.h" 39 #include "content/browser/loader/resource_message_filter.h"
39 #include "content/browser/loader/resource_request_info_impl.h" 40 #include "content/browser/loader/resource_request_info_impl.h"
40 #include "content/browser/loader/stream_resource_handler.h" 41 #include "content/browser/loader/stream_resource_handler.h"
41 #include "content/browser/loader/sync_resource_handler.h" 42 #include "content/browser/loader/sync_resource_handler.h"
42 #include "content/browser/loader/throttling_resource_handler.h" 43 #include "content/browser/loader/throttling_resource_handler.h"
43 #include "content/browser/loader/upload_data_stream_builder.h" 44 #include "content/browser/loader/upload_data_stream_builder.h"
44 #include "content/browser/plugin_service_impl.h" 45 #include "content/browser/plugin_service_impl.h"
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 delete loaders; 400 delete loaders;
400 } else { 401 } else {
401 ++i; 402 ++i;
402 } 403 }
403 } 404 }
404 405
405 #ifndef NDEBUG 406 #ifndef NDEBUG
406 for (LoaderList::iterator i = loaders_to_cancel.begin(); 407 for (LoaderList::iterator i = loaders_to_cancel.begin();
407 i != loaders_to_cancel.end(); ++i) { 408 i != loaders_to_cancel.end(); ++i) {
408 // There is no strict requirement that this be the case, but currently 409 // There is no strict requirement that this be the case, but currently
409 // downloads, streams and transferred requests are the only requests that 410 // downloads, streams, prefetches, and transferred requests are the only
410 // aren't cancelled when the associated processes go away. It may be OK for 411 // requests that aren't cancelled when the associated processes go away. It
411 // this invariant to change in the future, but if this assertion fires 412 // may be OK for this invariant to change in the future, but if this
412 // without the invariant changing, then it's indicative of a leak. 413 // assertion fires without the invariant changing, then it's indicative of a
414 // leak.
413 DCHECK((*i)->GetRequestInfo()->is_download() || 415 DCHECK((*i)->GetRequestInfo()->is_download() ||
414 (*i)->GetRequestInfo()->is_stream() || 416 (*i)->GetRequestInfo()->is_stream() ||
417 DetachableType((*i)->GetRequestInfo()->GetResourceType()) ||
415 (*i)->is_transferring()); 418 (*i)->is_transferring());
416 } 419 }
417 #endif 420 #endif
418 421
419 loaders_to_cancel.clear(); 422 loaders_to_cancel.clear();
420 423
421 // Validate that no more requests for this context were added. 424 // Validate that no more requests for this context were added.
422 for (LoaderMap::const_iterator i = pending_loaders_.begin(); 425 for (LoaderMap::const_iterator i = pending_loaders_.begin();
423 i != pending_loaders_.end(); ++i) { 426 i != pending_loaders_.end(); ++i) {
424 // http://crbug.com/90971 427 // http://crbug.com/90971
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 new_url)); 690 new_url));
688 BrowserThread::PostTask( 691 BrowserThread::PostTask(
689 BrowserThread::UI, FROM_HERE, 692 BrowserThread::UI, FROM_HERE,
690 base::Bind( 693 base::Bind(
691 &NotifyRedirectOnUI, 694 &NotifyRedirectOnUI,
692 render_process_id, render_view_id, base::Passed(&detail))); 695 render_process_id, render_view_id, base::Passed(&detail)));
693 } 696 }
694 697
695 void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) { 698 void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) {
696 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); 699 ResourceRequestInfoImpl* info = loader->GetRequestInfo();
700
701 // Exit early in case of detachable types as they may not have a policy after
702 // the renderer is canceled.
703 if (DetachableType(info->GetResourceType()))
704 return;
mmenke 2013/10/11 16:39:07 Should this only protect against messing with the
jkarlin2 2013/10/11 18:37:04 Done.
705
697 // There should be an entry in the map created when we dispatched the 706 // There should be an entry in the map created when we dispatched the
698 // request. 707 // request.
699 OfflineMap::iterator policy_it( 708 OfflineMap::iterator policy_it(
700 offline_policy_map_.find(info->GetGlobalRoutingID())); 709 offline_policy_map_.find(info->GetGlobalRoutingID()));
701 if (offline_policy_map_.end() != policy_it) { 710 if (offline_policy_map_.end() != policy_it) {
702 policy_it->second->UpdateStateForSuccessfullyStartedRequest( 711 policy_it->second->UpdateStateForSuccessfullyStartedRequest(
703 loader->request()->response_info()); 712 loader->request()->response_info());
704 } else { 713 } else {
705 // We should always have an entry in offline_policy_map_ from when 714 // We should always have an entry in offline_policy_map_ from when
706 // this request traversed Begin{Download,SaveFile,Request}. 715 // this request traversed Begin{Download,SaveFile,Request}.
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 1101
1093 // Have the appcache associate its extra info with the request. 1102 // Have the appcache associate its extra info with the request.
1094 appcache::AppCacheInterceptor::SetExtraRequestInfo( 1103 appcache::AppCacheInterceptor::SetExtraRequestInfo(
1095 request, filter_->appcache_service(), child_id, 1104 request, filter_->appcache_service(), child_id,
1096 request_data.appcache_host_id, request_data.resource_type); 1105 request_data.appcache_host_id, request_data.resource_type);
1097 1106
1098 // Construct the IPC resource handler. 1107 // Construct the IPC resource handler.
1099 scoped_ptr<ResourceHandler> handler; 1108 scoped_ptr<ResourceHandler> handler;
1100 if (sync_result) { 1109 if (sync_result) {
1101 handler.reset(new SyncResourceHandler(request, sync_result, this)); 1110 handler.reset(new SyncResourceHandler(request, sync_result, this));
1111 } else if (DetachableType(request_data.resource_type)) {
1112 // put in detached handler
1113 handler.reset(new DetachedResourceHandler(request, this));
1102 } else { 1114 } else {
1103 handler.reset(new AsyncResourceHandler(request, this)); 1115 handler.reset(new AsyncResourceHandler(request, this));
1104 } 1116 }
1105 1117
1106 // The RedirectToFileResourceHandler depends on being next in the chain. 1118 // The RedirectToFileResourceHandler depends on being next in the chain.
1107 if (request_data.download_to_file) { 1119 if (request_data.download_to_file) {
1108 handler.reset( 1120 handler.reset(
1109 new RedirectToFileResourceHandler(handler.Pass(), request, this)); 1121 new RedirectToFileResourceHandler(handler.Pass(), request, this));
1110 } 1122 }
1111 1123
(...skipping 27 matching lines...) Expand all
1139 1151
1140 throttles.push_back( 1152 throttles.push_back(
1141 scheduler_->ScheduleRequest(child_id, route_id, request).release()); 1153 scheduler_->ScheduleRequest(child_id, route_id, request).release());
1142 1154
1143 handler.reset( 1155 handler.reset(
1144 new ThrottlingResourceHandler(handler.Pass(), request, throttles.Pass())); 1156 new ThrottlingResourceHandler(handler.Pass(), request, throttles.Pass()));
1145 1157
1146 BeginRequestInternal(new_request.Pass(), handler.Pass()); 1158 BeginRequestInternal(new_request.Pass(), handler.Pass());
1147 } 1159 }
1148 1160
1161 bool ResourceDispatcherHostImpl::DetachableType(
mmenke 2013/10/11 16:39:07 Suggest IsDetachableResouceType, or maybe IsResouc
mmenke 2013/10/11 16:39:07 Since this is only used in this file and doesn't d
jkarlin2 2013/10/11 18:37:04 Done.
jkarlin2 2013/10/11 18:37:04 Done.
1162 const ResourceType::Type type) const {
1163 switch (type) {
1164 case ResourceType::PREFETCH:
1165 return true;
1166 default:
1167 return false;
1168 }
1169 }
1170
1149 void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) { 1171 void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) {
1150 UnregisterDownloadedTempFile(filter_->child_id(), request_id); 1172 UnregisterDownloadedTempFile(filter_->child_id(), request_id);
1151 } 1173 }
1152 1174
1153 void ResourceDispatcherHostImpl::OnDataDownloadedACK(int request_id) { 1175 void ResourceDispatcherHostImpl::OnDataDownloadedACK(int request_id) {
1154 // TODO(michaeln): maybe throttle DataDownloaded messages 1176 // TODO(michaeln): maybe throttle DataDownloaded messages
1155 } 1177 }
1156 1178
1157 void ResourceDispatcherHostImpl::RegisterDownloadedTempFile( 1179 void ResourceDispatcherHostImpl::RegisterDownloadedTempFile(
1158 int child_id, int request_id, ShareableFileReference* reference) { 1180 int child_id, int request_id, ShareableFileReference* reference) {
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 ResourceLoader* loader = GetLoader(id); 1330 ResourceLoader* loader = GetLoader(id);
1309 if (loader) { 1331 if (loader) {
1310 // The response we were meant to resume could have already been canceled. 1332 // The response we were meant to resume could have already been canceled.
1311 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); 1333 ResourceRequestInfoImpl* info = loader->GetRequestInfo();
1312 if (info->cross_site_handler()) 1334 if (info->cross_site_handler())
1313 info->cross_site_handler()->ResumeResponse(); 1335 info->cross_site_handler()->ResumeResponse();
1314 } 1336 }
1315 } 1337 }
1316 1338
1317 // The object died, so cancel and detach all requests associated with it except 1339 // The object died, so cancel and detach all requests associated with it except
1318 // for downloads, which belong to the browser process even if initiated via a 1340 // for downloads and prefetches, which belong to the browser process even if
1319 // renderer. 1341 // initiated via a renderer.
1320 void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) { 1342 void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) {
1321 CancelRequestsForRoute(child_id, -1 /* cancel all */); 1343 CancelRequestsForRoute(child_id, -1 /* cancel all */);
1322 registered_temp_files_.erase(child_id); 1344 registered_temp_files_.erase(child_id);
1323 } 1345 }
1324 1346
1325 void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id, 1347 void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id,
1326 int route_id) { 1348 int route_id) {
1327 // Since pending_requests_ is a map, we first build up a list of all of the 1349 // Since pending_requests_ is a map, we first build up a list of all of the
1328 // matching requests to be cancelled, and then we cancel them. Since there 1350 // matching requests to be cancelled, and then we cancel them. Since there
1329 // may be more than one request to cancel, we cannot simply hold onto the map 1351 // may be more than one request to cancel, we cannot simply hold onto the map
1330 // iterators found in the first loop. 1352 // iterators found in the first loop.
1331 1353
1332 // Find the global ID of all matching elements. 1354 // Find the global ID of all matching elements.
1333 bool any_requests_transferring = false; 1355 bool any_requests_transferring = false;
1334 std::vector<GlobalRequestID> matching_requests; 1356 std::vector<GlobalRequestID> matching_requests;
1335 for (LoaderMap::const_iterator i = pending_loaders_.begin(); 1357 for (LoaderMap::const_iterator i = pending_loaders_.begin();
1336 i != pending_loaders_.end(); ++i) { 1358 i != pending_loaders_.end(); ++i) {
1337 if (i->first.child_id != child_id) 1359 if (i->first.child_id != child_id)
1338 continue; 1360 continue;
1339 1361
1340 ResourceRequestInfoImpl* info = i->second->GetRequestInfo(); 1362 ResourceRequestInfoImpl* info = i->second->GetRequestInfo();
1341 1363
1342 GlobalRequestID id(child_id, i->first.request_id); 1364 GlobalRequestID id(child_id, i->first.request_id);
1343 DCHECK(id == i->first); 1365 DCHECK(id == i->first);
1344 1366 // Don't cancel navigations that are expected to live beyond this process.
1345 // Don't cancel navigations that are transferring to another process,
1346 // since they belong to another process now.
1347 if (IsTransferredNavigation(id)) 1367 if (IsTransferredNavigation(id))
1348 any_requests_transferring = true; 1368 any_requests_transferring = true;
1349 if (!info->is_download() && !info->is_stream() && 1369 if (!info->is_download() && !info->is_stream() &&
1370 !DetachableType(info->GetResourceType()) &&
1350 !IsTransferredNavigation(id) && 1371 !IsTransferredNavigation(id) &&
1351 (route_id == -1 || route_id == info->GetRouteID())) { 1372 (route_id == -1 || route_id == info->GetRouteID())) {
1352 matching_requests.push_back(id); 1373 matching_requests.push_back(id);
1353 } 1374 }
1354 } 1375 }
1355 1376
1356 // Remove matches. 1377 // Remove matches.
1357 for (size_t i = 0; i < matching_requests.size(); ++i) { 1378 for (size_t i = 0; i < matching_requests.size(); ++i) {
1358 LoaderMap::iterator iter = pending_loaders_.find(matching_requests[i]); 1379 LoaderMap::iterator iter = pending_loaders_.find(matching_requests[i]);
1359 // Although every matching request was in pending_requests_ when we built 1380 // Although every matching request was in pending_requests_ when we built
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
1912 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) 1933 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS)
1913 && !policy->CanReadRawCookies(child_id)) { 1934 && !policy->CanReadRawCookies(child_id)) {
1914 VLOG(1) << "Denied unauthorized request for raw headers"; 1935 VLOG(1) << "Denied unauthorized request for raw headers";
1915 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS; 1936 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS;
1916 } 1937 }
1917 1938
1918 return load_flags; 1939 return load_flags;
1919 } 1940 }
1920 1941
1921 } // namespace content 1942 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698