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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1141 handler.reset(new DetachableResourceHandler( | 1138 handler.reset(new DetachableResourceHandler( |
1142 request, | 1139 request, |
1143 base::TimeDelta::FromMilliseconds(kDefaultDetachableCancelDelayMs), | 1140 base::TimeDelta::FromMilliseconds(kDefaultDetachableCancelDelayMs), |
1144 handler.Pass())); | 1141 handler.Pass())); |
1145 } | 1142 } |
1146 } | 1143 } |
1147 | 1144 |
1148 // The RedirectToFileResourceHandler depends on being next in the chain. | 1145 // The RedirectToFileResourceHandler depends on being next in the chain. |
1149 if (request_data.download_to_file) { | 1146 if (request_data.download_to_file) { |
1150 handler.reset( | 1147 handler.reset( |
1151 new RedirectToFileResourceHandler(handler.Pass(), request, this)); | 1148 new RedirectToFileResourceHandler(handler.Pass(), request, |
| 1149 temporary_file_manager_.get())); |
1152 } | 1150 } |
1153 | 1151 |
1154 // Install a CrossSiteResourceHandler for all main frame requests. This will | 1152 // Install a CrossSiteResourceHandler for all main frame requests. This will |
1155 // let us check whether a transfer is required and pause for the unload | 1153 // let us check whether a transfer is required and pause for the unload |
1156 // handler either if so or if a cross-process navigation is already under way. | 1154 // handler either if so or if a cross-process navigation is already under way. |
1157 if (request_data.resource_type == ResourceType::MAIN_FRAME && | 1155 if (request_data.resource_type == ResourceType::MAIN_FRAME && |
1158 process_type == PROCESS_TYPE_RENDERER) { | 1156 process_type == PROCESS_TYPE_RENDERER) { |
1159 handler.reset(new CrossSiteResourceHandler(handler.Pass(), request)); | 1157 handler.reset(new CrossSiteResourceHandler(handler.Pass(), request)); |
1160 } | 1158 } |
1161 | 1159 |
(...skipping 20 matching lines...) Expand all Loading... |
1182 throttles.push_back( | 1180 throttles.push_back( |
1183 scheduler_->ScheduleRequest(child_id, route_id, request).release()); | 1181 scheduler_->ScheduleRequest(child_id, route_id, request).release()); |
1184 | 1182 |
1185 handler.reset( | 1183 handler.reset( |
1186 new ThrottlingResourceHandler(handler.Pass(), request, throttles.Pass())); | 1184 new ThrottlingResourceHandler(handler.Pass(), request, throttles.Pass())); |
1187 | 1185 |
1188 BeginRequestInternal(new_request.Pass(), handler.Pass()); | 1186 BeginRequestInternal(new_request.Pass(), handler.Pass()); |
1189 } | 1187 } |
1190 | 1188 |
1191 void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) { | 1189 void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) { |
1192 UnregisterDownloadedTempFile(filter_->child_id(), request_id); | 1190 if (temporary_file_manager_) { |
| 1191 temporary_file_manager_->UnregisterDownloadedTempFile(filter_->child_id(), |
| 1192 request_id); |
| 1193 } else { |
| 1194 // Can the RDH still receive messages after being shut down? |
| 1195 NOTREACHED(); |
| 1196 } |
1193 } | 1197 } |
1194 | 1198 |
1195 void ResourceDispatcherHostImpl::OnDataDownloadedACK(int request_id) { | 1199 void ResourceDispatcherHostImpl::OnDataDownloadedACK(int request_id) { |
1196 // TODO(michaeln): maybe throttle DataDownloaded messages | 1200 // TODO(michaeln): maybe throttle DataDownloaded messages |
1197 } | 1201 } |
1198 | 1202 |
1199 void ResourceDispatcherHostImpl::RegisterDownloadedTempFile( | |
1200 int child_id, int request_id, ShareableFileReference* reference) { | |
1201 registered_temp_files_[child_id][request_id] = reference; | |
1202 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( | |
1203 child_id, reference->path()); | |
1204 | |
1205 // When the temp file is deleted, revoke permissions that the renderer has | |
1206 // to that file. This covers an edge case where the file is deleted and then | |
1207 // the same name is re-used for some other purpose, we don't want the old | |
1208 // renderer to still have access to it. | |
1209 // | |
1210 // We do this when the file is deleted because the renderer can take a blob | |
1211 // reference to the temp file that outlives the url loaded that it was | |
1212 // loaded with to keep the file (and permissions) alive. | |
1213 reference->AddFinalReleaseCallback( | |
1214 base::Bind(&RemoveDownloadFileFromChildSecurityPolicy, | |
1215 child_id)); | |
1216 } | |
1217 | |
1218 void ResourceDispatcherHostImpl::UnregisterDownloadedTempFile( | |
1219 int child_id, int request_id) { | |
1220 DeletableFilesMap& map = registered_temp_files_[child_id]; | |
1221 DeletableFilesMap::iterator found = map.find(request_id); | |
1222 if (found == map.end()) | |
1223 return; | |
1224 | |
1225 map.erase(found); | |
1226 | |
1227 // Note that we don't remove the security bits here. This will be done | |
1228 // when all file refs are deleted (see RegisterDownloadedTempFile). | |
1229 } | |
1230 | |
1231 bool ResourceDispatcherHostImpl::Send(IPC::Message* message) { | 1203 bool ResourceDispatcherHostImpl::Send(IPC::Message* message) { |
1232 delete message; | 1204 delete message; |
1233 return false; | 1205 return false; |
1234 } | 1206 } |
1235 | 1207 |
1236 void ResourceDispatcherHostImpl::OnUploadProgressACK(int request_id) { | 1208 void ResourceDispatcherHostImpl::OnUploadProgressACK(int request_id) { |
1237 ResourceLoader* loader = GetLoader(filter_->child_id(), request_id); | 1209 ResourceLoader* loader = GetLoader(filter_->child_id(), request_id); |
1238 if (loader) | 1210 if (loader) |
1239 loader->OnUploadProgressACK(); | 1211 loader->OnUploadProgressACK(); |
1240 } | 1212 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1355 if (info->cross_site_handler()) | 1327 if (info->cross_site_handler()) |
1356 info->cross_site_handler()->ResumeResponse(); | 1328 info->cross_site_handler()->ResumeResponse(); |
1357 } | 1329 } |
1358 } | 1330 } |
1359 | 1331 |
1360 // The object died, so cancel and detach all requests associated with it except | 1332 // The object died, so cancel and detach all requests associated with it except |
1361 // for downloads and detachable resources, which belong to the browser process | 1333 // for downloads and detachable resources, which belong to the browser process |
1362 // even if initiated via a renderer. | 1334 // even if initiated via a renderer. |
1363 void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) { | 1335 void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) { |
1364 CancelRequestsForRoute(child_id, -1 /* cancel all */); | 1336 CancelRequestsForRoute(child_id, -1 /* cancel all */); |
1365 registered_temp_files_.erase(child_id); | 1337 // The RDH may already have been shutdown by the time this is called. |
| 1338 if (temporary_file_manager_) |
| 1339 temporary_file_manager_->UnregisterFilesForChild(child_id); |
1366 } | 1340 } |
1367 | 1341 |
1368 void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id, | 1342 void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id, |
1369 int route_id) { | 1343 int route_id) { |
1370 // Since pending_requests_ is a map, we first build up a list of all of the | 1344 // Since pending_requests_ is a map, we first build up a list of all of the |
1371 // matching requests to be cancelled, and then we cancel them. Since there | 1345 // matching requests to be cancelled, and then we cancel them. Since there |
1372 // may be more than one request to cancel, we cannot simply hold onto the map | 1346 // may be more than one request to cancel, we cannot simply hold onto the map |
1373 // iterators found in the first loop. | 1347 // iterators found in the first loop. |
1374 | 1348 |
1375 // Find the global ID of all matching elements. | 1349 // Find the global ID of all matching elements. |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1957 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) | 1931 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) |
1958 && !policy->CanReadRawCookies(child_id)) { | 1932 && !policy->CanReadRawCookies(child_id)) { |
1959 VLOG(1) << "Denied unauthorized request for raw headers"; | 1933 VLOG(1) << "Denied unauthorized request for raw headers"; |
1960 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS; | 1934 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS; |
1961 } | 1935 } |
1962 | 1936 |
1963 return load_flags; | 1937 return load_flags; |
1964 } | 1938 } |
1965 | 1939 |
1966 } // namespace content | 1940 } // namespace content |
OLD | NEW |