| 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 temporary_file_manager_->UnregisterDownloadedTempFile(filter_->child_id(), |
| 1191 request_id); |
| 1193 } | 1192 } |
| 1194 | 1193 |
| 1195 void ResourceDispatcherHostImpl::OnDataDownloadedACK(int request_id) { | 1194 void ResourceDispatcherHostImpl::OnDataDownloadedACK(int request_id) { |
| 1196 // TODO(michaeln): maybe throttle DataDownloaded messages | 1195 // TODO(michaeln): maybe throttle DataDownloaded messages |
| 1197 } | 1196 } |
| 1198 | 1197 |
| 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) { | 1198 bool ResourceDispatcherHostImpl::Send(IPC::Message* message) { |
| 1232 delete message; | 1199 delete message; |
| 1233 return false; | 1200 return false; |
| 1234 } | 1201 } |
| 1235 | 1202 |
| 1236 void ResourceDispatcherHostImpl::OnUploadProgressACK(int request_id) { | 1203 void ResourceDispatcherHostImpl::OnUploadProgressACK(int request_id) { |
| 1237 ResourceLoader* loader = GetLoader(filter_->child_id(), request_id); | 1204 ResourceLoader* loader = GetLoader(filter_->child_id(), request_id); |
| 1238 if (loader) | 1205 if (loader) |
| 1239 loader->OnUploadProgressACK(); | 1206 loader->OnUploadProgressACK(); |
| 1240 } | 1207 } |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1355 if (info->cross_site_handler()) | 1322 if (info->cross_site_handler()) |
| 1356 info->cross_site_handler()->ResumeResponse(); | 1323 info->cross_site_handler()->ResumeResponse(); |
| 1357 } | 1324 } |
| 1358 } | 1325 } |
| 1359 | 1326 |
| 1360 // The object died, so cancel and detach all requests associated with it except | 1327 // 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 | 1328 // for downloads and detachable resources, which belong to the browser process |
| 1362 // even if initiated via a renderer. | 1329 // even if initiated via a renderer. |
| 1363 void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) { | 1330 void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) { |
| 1364 CancelRequestsForRoute(child_id, -1 /* cancel all */); | 1331 CancelRequestsForRoute(child_id, -1 /* cancel all */); |
| 1365 registered_temp_files_.erase(child_id); | 1332 temporary_file_manager_->UnregisterFilesForChild(child_id); |
| 1366 } | 1333 } |
| 1367 | 1334 |
| 1368 void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id, | 1335 void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id, |
| 1369 int route_id) { | 1336 int route_id) { |
| 1370 // Since pending_requests_ is a map, we first build up a list of all of the | 1337 // 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 | 1338 // 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 | 1339 // may be more than one request to cancel, we cannot simply hold onto the map |
| 1373 // iterators found in the first loop. | 1340 // iterators found in the first loop. |
| 1374 | 1341 |
| 1375 // Find the global ID of all matching elements. | 1342 // Find the global ID of all matching elements. |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1958 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) | 1925 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) |
| 1959 && !policy->CanReadRawCookies(child_id)) { | 1926 && !policy->CanReadRawCookies(child_id)) { |
| 1960 VLOG(1) << "Denied unauthorized request for raw headers"; | 1927 VLOG(1) << "Denied unauthorized request for raw headers"; |
| 1961 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS; | 1928 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS; |
| 1962 } | 1929 } |
| 1963 | 1930 |
| 1964 return load_flags; | 1931 return load_flags; |
| 1965 } | 1932 } |
| 1966 | 1933 |
| 1967 } // namespace content | 1934 } // namespace content |
| OLD | NEW |