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 22 matching lines...) Expand all Loading... | |
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/cross_site_resource_handler.h" | 35 #include "content/browser/loader/cross_site_resource_handler.h" |
36 #include "content/browser/loader/detachable_resource_handler.h" | 36 #include "content/browser/loader/detachable_resource_handler.h" |
37 #include "content/browser/loader/power_save_block_resource_throttle.h" | 37 #include "content/browser/loader/power_save_block_resource_throttle.h" |
38 #include "content/browser/loader/redirect_to_file_resource_handler.h" | 38 #include "content/browser/loader/redirect_to_file_resource_handler.h" |
39 #include "content/browser/loader/resource_message_filter.h" | 39 #include "content/browser/loader/resource_message_filter.h" |
40 #include "content/browser/loader/resource_request_info_impl.h" | 40 #include "content/browser/loader/resource_request_info_impl.h" |
41 #include "content/browser/loader/stream_resource_handler.h" | 41 #include "content/browser/loader/stream_resource_handler.h" |
42 #include "content/browser/loader/sync_resource_handler.h" | 42 #include "content/browser/loader/sync_resource_handler.h" |
43 #include "content/browser/loader/temporary_file_manager.h" | |
43 #include "content/browser/loader/throttling_resource_handler.h" | 44 #include "content/browser/loader/throttling_resource_handler.h" |
44 #include "content/browser/loader/upload_data_stream_builder.h" | 45 #include "content/browser/loader/upload_data_stream_builder.h" |
45 #include "content/browser/plugin_service_impl.h" | 46 #include "content/browser/plugin_service_impl.h" |
46 #include "content/browser/renderer_host/render_view_host_delegate.h" | 47 #include "content/browser/renderer_host/render_view_host_delegate.h" |
47 #include "content/browser/renderer_host/render_view_host_impl.h" | 48 #include "content/browser/renderer_host/render_view_host_impl.h" |
48 #include "content/browser/resource_context_impl.h" | 49 #include "content/browser/resource_context_impl.h" |
49 #include "content/browser/streams/stream.h" | 50 #include "content/browser/streams/stream.h" |
50 #include "content/browser/streams/stream_context.h" | 51 #include "content/browser/streams/stream_context.h" |
51 #include "content/browser/streams/stream_registry.h" | 52 #include "content/browser/streams/stream_registry.h" |
52 #include "content/browser/worker_host/worker_service_impl.h" | 53 #include "content/browser/worker_host/worker_service_impl.h" |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
230 << iter->filesystem_url().spec(); | 231 << iter->filesystem_url().spec(); |
231 return false; | 232 return false; |
232 } | 233 } |
233 } | 234 } |
234 } | 235 } |
235 } | 236 } |
236 | 237 |
237 return true; | 238 return true; |
238 } | 239 } |
239 | 240 |
240 void RemoveDownloadFileFromChildSecurityPolicy(int child_id, | |
241 const base::FilePath& path) { | |
242 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile( | |
243 child_id, path); | |
244 } | |
245 | |
246 #if defined(OS_WIN) | 241 #if defined(OS_WIN) |
247 #pragma warning(disable: 4748) | 242 #pragma warning(disable: 4748) |
248 #pragma optimize("", off) | 243 #pragma optimize("", off) |
249 #endif | 244 #endif |
250 | 245 |
251 #if defined(OS_WIN) | 246 #if defined(OS_WIN) |
252 #pragma optimize("", on) | 247 #pragma optimize("", on) |
253 #pragma warning(default: 4748) | 248 #pragma warning(default: 4748) |
254 #endif | 249 #endif |
255 | 250 |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
790 *render_process_id = -1; | 785 *render_process_id = -1; |
791 *render_view_id = -1; | 786 *render_view_id = -1; |
792 return false; | 787 return false; |
793 } | 788 } |
794 | 789 |
795 return info->GetAssociatedRenderView(render_process_id, render_view_id); | 790 return info->GetAssociatedRenderView(render_process_id, render_view_id); |
796 } | 791 } |
797 | 792 |
798 void ResourceDispatcherHostImpl::OnInit() { | 793 void ResourceDispatcherHostImpl::OnInit() { |
799 scheduler_.reset(new ResourceScheduler); | 794 scheduler_.reset(new ResourceScheduler); |
795 temporary_file_manager_.reset(new TemporaryFileManager); | |
800 appcache::AppCacheInterceptor::EnsureRegistered(); | 796 appcache::AppCacheInterceptor::EnsureRegistered(); |
801 } | 797 } |
802 | 798 |
803 void ResourceDispatcherHostImpl::OnShutdown() { | 799 void ResourceDispatcherHostImpl::OnShutdown() { |
804 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 800 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
805 | 801 |
806 is_shutdown_ = true; | 802 is_shutdown_ = true; |
807 pending_loaders_.clear(); | 803 pending_loaders_.clear(); |
808 | 804 |
809 // Make sure we shutdown the timer now, otherwise by the time our destructor | 805 // Make sure we shutdown the timer now, otherwise by the time our destructor |
(...skipping 11 matching lines...) Expand all Loading... | |
821 std::pair<std::set<GlobalRoutingID>::iterator, bool> result = | 817 std::pair<std::set<GlobalRoutingID>::iterator, bool> result = |
822 ids.insert(iter->first); | 818 ids.insert(iter->first); |
823 // We should not have duplicates. | 819 // We should not have duplicates. |
824 DCHECK(result.second); | 820 DCHECK(result.second); |
825 } | 821 } |
826 for (std::set<GlobalRoutingID>::const_iterator iter = ids.begin(); | 822 for (std::set<GlobalRoutingID>::const_iterator iter = ids.begin(); |
827 iter != ids.end(); ++iter) { | 823 iter != ids.end(); ++iter) { |
828 CancelBlockedRequestsForRoute(iter->child_id, iter->route_id); | 824 CancelBlockedRequestsForRoute(iter->child_id, iter->route_id); |
829 } | 825 } |
830 | 826 |
827 temporary_file_manager_.reset(); | |
831 scheduler_.reset(); | 828 scheduler_.reset(); |
832 } | 829 } |
833 | 830 |
834 bool ResourceDispatcherHostImpl::OnMessageReceived( | 831 bool ResourceDispatcherHostImpl::OnMessageReceived( |
835 const IPC::Message& message, | 832 const IPC::Message& message, |
836 ResourceMessageFilter* filter, | 833 ResourceMessageFilter* filter, |
837 bool* message_was_ok) { | 834 bool* message_was_ok) { |
838 filter_ = filter; | 835 filter_ = filter; |
839 bool handled = true; | 836 bool handled = true; |
840 IPC_BEGIN_MESSAGE_MAP_EX(ResourceDispatcherHostImpl, message, *message_was_ok) | 837 IPC_BEGIN_MESSAGE_MAP_EX(ResourceDispatcherHostImpl, message, *message_was_ok) |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1147 int route_id, | 1144 int route_id, |
1148 int process_type, | 1145 int process_type, |
1149 int child_id, | 1146 int child_id, |
1150 ResourceContext* resource_context) { | 1147 ResourceContext* resource_context) { |
1151 // Construct the IPC resource handler. | 1148 // Construct the IPC resource handler. |
1152 scoped_ptr<ResourceHandler> handler; | 1149 scoped_ptr<ResourceHandler> handler; |
1153 if (sync_result) { | 1150 if (sync_result) { |
1154 handler.reset(new SyncResourceHandler(request, sync_result, this)); | 1151 handler.reset(new SyncResourceHandler(request, sync_result, this)); |
1155 } else { | 1152 } else { |
1156 handler.reset(new AsyncResourceHandler(request, this)); | 1153 handler.reset(new AsyncResourceHandler(request, this)); |
1157 if (IsDetachableResourceType(request_data.resource_type)) { | |
1158 handler.reset(new DetachableResourceHandler( | |
1159 request, | |
1160 base::TimeDelta::FromMilliseconds(kDefaultDetachableCancelDelayMs), | |
1161 handler.Pass())); | |
1162 } | |
1163 } | 1154 } |
1164 | 1155 |
1165 // The RedirectToFileResourceHandler depends on being next in the chain. | 1156 // The RedirectToFileResourceHandler depends on being next in the chain. |
1166 if (request_data.download_to_file) { | 1157 if (request_data.download_to_file) { |
1167 handler.reset( | 1158 handler.reset( |
1168 new RedirectToFileResourceHandler(handler.Pass(), request, this)); | 1159 new RedirectToFileResourceHandler(handler.Pass(), request, |
1160 temporary_file_manager_.get())); | |
1161 } | |
1162 | |
1163 // Prefetches and <a ping> requests outlive their child process. | |
darin (slow to review)
2013/12/06 17:56:07
Is this part of a different CL?
davidben
2013/12/19 22:21:01
I moved it out from the code above where AsyncReso
| |
1164 if (!sync_result && IsDetachableResourceType(request_data.resource_type)) { | |
1165 handler.reset(new DetachableResourceHandler( | |
1166 request, | |
1167 base::TimeDelta::FromMilliseconds(kDefaultDetachableCancelDelayMs), | |
1168 handler.Pass())); | |
1169 } | 1169 } |
1170 | 1170 |
1171 // Install a CrossSiteResourceHandler for all main frame requests. This will | 1171 // Install a CrossSiteResourceHandler for all main frame requests. This will |
1172 // let us check whether a transfer is required and pause for the unload | 1172 // let us check whether a transfer is required and pause for the unload |
1173 // handler either if so or if a cross-process navigation is already under way. | 1173 // handler either if so or if a cross-process navigation is already under way. |
1174 if (request_data.resource_type == ResourceType::MAIN_FRAME && | 1174 if (request_data.resource_type == ResourceType::MAIN_FRAME && |
1175 process_type == PROCESS_TYPE_RENDERER) { | 1175 process_type == PROCESS_TYPE_RENDERER) { |
1176 handler.reset(new CrossSiteResourceHandler(handler.Pass(), request)); | 1176 handler.reset(new CrossSiteResourceHandler(handler.Pass(), request)); |
1177 } | 1177 } |
1178 | 1178 |
(...skipping 20 matching lines...) Expand all Loading... | |
1199 throttles.push_back( | 1199 throttles.push_back( |
1200 scheduler_->ScheduleRequest(child_id, route_id, request).release()); | 1200 scheduler_->ScheduleRequest(child_id, route_id, request).release()); |
1201 | 1201 |
1202 handler.reset( | 1202 handler.reset( |
1203 new ThrottlingResourceHandler(handler.Pass(), request, throttles.Pass())); | 1203 new ThrottlingResourceHandler(handler.Pass(), request, throttles.Pass())); |
1204 | 1204 |
1205 return handler.Pass(); | 1205 return handler.Pass(); |
1206 } | 1206 } |
1207 | 1207 |
1208 void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) { | 1208 void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) { |
1209 UnregisterDownloadedTempFile(filter_->child_id(), request_id); | 1209 if (temporary_file_manager_) { |
1210 temporary_file_manager_->UnregisterDownloadedTempFile(filter_->child_id(), | |
1211 request_id); | |
1212 } else { | |
1213 // Can the RDH still receive messages after being shut down? | |
1214 NOTREACHED(); | |
1215 } | |
1210 } | 1216 } |
1211 | 1217 |
1212 void ResourceDispatcherHostImpl::OnDataDownloadedACK(int request_id) { | 1218 void ResourceDispatcherHostImpl::OnDataDownloadedACK(int request_id) { |
1213 // TODO(michaeln): maybe throttle DataDownloaded messages | 1219 // TODO(michaeln): maybe throttle DataDownloaded messages |
1214 } | 1220 } |
1215 | 1221 |
1216 void ResourceDispatcherHostImpl::RegisterDownloadedTempFile( | |
1217 int child_id, int request_id, ShareableFileReference* reference) { | |
1218 registered_temp_files_[child_id][request_id] = reference; | |
1219 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( | |
1220 child_id, reference->path()); | |
1221 | |
1222 // When the temp file is deleted, revoke permissions that the renderer has | |
1223 // to that file. This covers an edge case where the file is deleted and then | |
1224 // the same name is re-used for some other purpose, we don't want the old | |
1225 // renderer to still have access to it. | |
1226 // | |
1227 // We do this when the file is deleted because the renderer can take a blob | |
1228 // reference to the temp file that outlives the url loaded that it was | |
1229 // loaded with to keep the file (and permissions) alive. | |
1230 reference->AddFinalReleaseCallback( | |
1231 base::Bind(&RemoveDownloadFileFromChildSecurityPolicy, | |
1232 child_id)); | |
1233 } | |
1234 | |
1235 void ResourceDispatcherHostImpl::UnregisterDownloadedTempFile( | |
1236 int child_id, int request_id) { | |
1237 DeletableFilesMap& map = registered_temp_files_[child_id]; | |
1238 DeletableFilesMap::iterator found = map.find(request_id); | |
1239 if (found == map.end()) | |
1240 return; | |
1241 | |
1242 map.erase(found); | |
1243 | |
1244 // Note that we don't remove the security bits here. This will be done | |
1245 // when all file refs are deleted (see RegisterDownloadedTempFile). | |
1246 } | |
1247 | |
1248 bool ResourceDispatcherHostImpl::Send(IPC::Message* message) { | 1222 bool ResourceDispatcherHostImpl::Send(IPC::Message* message) { |
1249 delete message; | 1223 delete message; |
1250 return false; | 1224 return false; |
1251 } | 1225 } |
1252 | 1226 |
1253 void ResourceDispatcherHostImpl::OnUploadProgressACK(int request_id) { | 1227 void ResourceDispatcherHostImpl::OnUploadProgressACK(int request_id) { |
1254 ResourceLoader* loader = GetLoader(filter_->child_id(), request_id); | 1228 ResourceLoader* loader = GetLoader(filter_->child_id(), request_id); |
1255 if (loader) | 1229 if (loader) |
1256 loader->OnUploadProgressACK(); | 1230 loader->OnUploadProgressACK(); |
1257 } | 1231 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1372 if (info->cross_site_handler()) | 1346 if (info->cross_site_handler()) |
1373 info->cross_site_handler()->ResumeResponse(); | 1347 info->cross_site_handler()->ResumeResponse(); |
1374 } | 1348 } |
1375 } | 1349 } |
1376 | 1350 |
1377 // The object died, so cancel and detach all requests associated with it except | 1351 // The object died, so cancel and detach all requests associated with it except |
1378 // for downloads and detachable resources, which belong to the browser process | 1352 // for downloads and detachable resources, which belong to the browser process |
1379 // even if initiated via a renderer. | 1353 // even if initiated via a renderer. |
1380 void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) { | 1354 void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) { |
1381 CancelRequestsForRoute(child_id, -1 /* cancel all */); | 1355 CancelRequestsForRoute(child_id, -1 /* cancel all */); |
1382 registered_temp_files_.erase(child_id); | 1356 // The RDH may already have been shutdown by the time this is called. |
1357 if (temporary_file_manager_) | |
1358 temporary_file_manager_->UnregisterFilesForChild(child_id); | |
1383 } | 1359 } |
1384 | 1360 |
1385 void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id, | 1361 void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id, |
1386 int route_id) { | 1362 int route_id) { |
1387 // Since pending_requests_ is a map, we first build up a list of all of the | 1363 // Since pending_requests_ is a map, we first build up a list of all of the |
1388 // matching requests to be cancelled, and then we cancel them. Since there | 1364 // matching requests to be cancelled, and then we cancel them. Since there |
1389 // may be more than one request to cancel, we cannot simply hold onto the map | 1365 // may be more than one request to cancel, we cannot simply hold onto the map |
1390 // iterators found in the first loop. | 1366 // iterators found in the first loop. |
1391 | 1367 |
1392 // Find the global ID of all matching elements. | 1368 // Find the global ID of all matching elements. |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1974 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) | 1950 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) |
1975 && !policy->CanReadRawCookies(child_id)) { | 1951 && !policy->CanReadRawCookies(child_id)) { |
1976 VLOG(1) << "Denied unauthorized request for raw headers"; | 1952 VLOG(1) << "Denied unauthorized request for raw headers"; |
1977 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS; | 1953 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS; |
1978 } | 1954 } |
1979 | 1955 |
1980 return load_flags; | 1956 return load_flags; |
1981 } | 1957 } |
1982 | 1958 |
1983 } // namespace content | 1959 } // namespace content |
OLD | NEW |