Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |