| 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/renderer_host/resource_dispatcher_host.h" | 7 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
| 16 #include "base/debug/alias.h" | 16 #include "base/debug/alias.h" |
| 17 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
| 19 #include "base/message_loop.h" | 19 #include "base/message_loop.h" |
| 20 #include "base/metrics/histogram.h" | 20 #include "base/metrics/histogram.h" |
| 21 #include "base/shared_memory.h" | 21 #include "base/shared_memory.h" |
| 22 #include "base/stl_util.h" | 22 #include "base/stl_util.h" |
| 23 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 23 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 24 #include "content/browser/appcache/chrome_appcache_service.h" | 24 #include "content/browser/appcache/chrome_appcache_service.h" |
| 25 #include "content/browser/cert_store.h" | 25 #include "content/browser/cert_store.h" |
| 26 #include "content/browser/child_process_security_policy.h" | 26 #include "content/browser/child_process_security_policy_impl.h" |
| 27 #include "content/browser/chrome_blob_storage_context.h" | 27 #include "content/browser/chrome_blob_storage_context.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_file_manager.h" | 29 #include "content/browser/download/download_file_manager.h" |
| 30 #include "content/browser/download/download_resource_handler.h" | 30 #include "content/browser/download/download_resource_handler.h" |
| 31 #include "content/browser/download/save_file_manager.h" | 31 #include "content/browser/download/save_file_manager.h" |
| 32 #include "content/browser/download/save_file_resource_handler.h" | 32 #include "content/browser/download/save_file_resource_handler.h" |
| 33 #include "content/browser/plugin_service_impl.h" | 33 #include "content/browser/plugin_service_impl.h" |
| 34 #include "content/browser/renderer_host/async_resource_handler.h" | 34 #include "content/browser/renderer_host/async_resource_handler.h" |
| 35 #include "content/browser/renderer_host/buffered_resource_handler.h" | 35 #include "content/browser/renderer_host/buffered_resource_handler.h" |
| 36 #include "content/browser/renderer_host/cross_site_resource_handler.h" | 36 #include "content/browser/renderer_host/cross_site_resource_handler.h" |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 // Consults the RendererSecurity policy to determine whether the | 161 // Consults the RendererSecurity policy to determine whether the |
| 162 // ResourceDispatcherHost should service this request. A request might be | 162 // ResourceDispatcherHost should service this request. A request might be |
| 163 // disallowed if the renderer is not authorized to retrieve the request URL or | 163 // disallowed if the renderer is not authorized to retrieve the request URL or |
| 164 // if the renderer is attempting to upload an unauthorized file. | 164 // if the renderer is attempting to upload an unauthorized file. |
| 165 bool ShouldServiceRequest(content::ProcessType process_type, | 165 bool ShouldServiceRequest(content::ProcessType process_type, |
| 166 int child_id, | 166 int child_id, |
| 167 const ResourceHostMsg_Request& request_data) { | 167 const ResourceHostMsg_Request& request_data) { |
| 168 if (process_type == content::PROCESS_TYPE_PLUGIN) | 168 if (process_type == content::PROCESS_TYPE_PLUGIN) |
| 169 return true; | 169 return true; |
| 170 | 170 |
| 171 ChildProcessSecurityPolicy* policy = | 171 ChildProcessSecurityPolicyImpl* policy = |
| 172 ChildProcessSecurityPolicy::GetInstance(); | 172 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 173 | 173 |
| 174 // Check if the renderer is permitted to request the requested URL. | 174 // Check if the renderer is permitted to request the requested URL. |
| 175 if (!policy->CanRequestURL(child_id, request_data.url)) { | 175 if (!policy->CanRequestURL(child_id, request_data.url)) { |
| 176 VLOG(1) << "Denied unauthorized request for " | 176 VLOG(1) << "Denied unauthorized request for " |
| 177 << request_data.url.possibly_invalid_spec(); | 177 << request_data.url.possibly_invalid_spec(); |
| 178 return false; | 178 return false; |
| 179 } | 179 } |
| 180 | 180 |
| 181 // Check if the renderer is permitted to upload the requested files. | 181 // Check if the renderer is permitted to upload the requested files. |
| 182 if (request_data.upload_data) { | 182 if (request_data.upload_data) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 211 response->was_fetched_via_proxy = request->was_fetched_via_proxy(); | 211 response->was_fetched_via_proxy = request->was_fetched_via_proxy(); |
| 212 response->socket_address = request->GetSocketAddress(); | 212 response->socket_address = request->GetSocketAddress(); |
| 213 appcache::AppCacheInterceptor::GetExtraResponseInfo( | 213 appcache::AppCacheInterceptor::GetExtraResponseInfo( |
| 214 request, | 214 request, |
| 215 &response->appcache_id, | 215 &response->appcache_id, |
| 216 &response->appcache_manifest_url); | 216 &response->appcache_manifest_url); |
| 217 } | 217 } |
| 218 | 218 |
| 219 void RemoveDownloadFileFromChildSecurityPolicy(int child_id, | 219 void RemoveDownloadFileFromChildSecurityPolicy(int child_id, |
| 220 const FilePath& path) { | 220 const FilePath& path) { |
| 221 ChildProcessSecurityPolicy::GetInstance()->RevokeAllPermissionsForFile( | 221 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile( |
| 222 child_id, path); | 222 child_id, path); |
| 223 } | 223 } |
| 224 | 224 |
| 225 #if defined(OS_WIN) | 225 #if defined(OS_WIN) |
| 226 #pragma warning(disable: 4748) | 226 #pragma warning(disable: 4748) |
| 227 #pragma optimize("", off) | 227 #pragma optimize("", off) |
| 228 #endif | 228 #endif |
| 229 | 229 |
| 230 #if defined(OS_WIN) | 230 #if defined(OS_WIN) |
| 231 #pragma optimize("", on) | 231 #pragma optimize("", on) |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 load_flags |= net::LOAD_SUB_FRAME; | 613 load_flags |= net::LOAD_SUB_FRAME; |
| 614 } else if (request_data.resource_type == ResourceType::PREFETCH) { | 614 } else if (request_data.resource_type == ResourceType::PREFETCH) { |
| 615 load_flags |= (net::LOAD_PREFETCH | net::LOAD_DO_NOT_PROMPT_FOR_LOGIN); | 615 load_flags |= (net::LOAD_PREFETCH | net::LOAD_DO_NOT_PROMPT_FOR_LOGIN); |
| 616 } else if (request_data.resource_type == ResourceType::FAVICON) { | 616 } else if (request_data.resource_type == ResourceType::FAVICON) { |
| 617 load_flags |= net::LOAD_DO_NOT_PROMPT_FOR_LOGIN; | 617 load_flags |= net::LOAD_DO_NOT_PROMPT_FOR_LOGIN; |
| 618 } | 618 } |
| 619 | 619 |
| 620 if (sync_result) | 620 if (sync_result) |
| 621 load_flags |= net::LOAD_IGNORE_LIMITS; | 621 load_flags |= net::LOAD_IGNORE_LIMITS; |
| 622 | 622 |
| 623 ChildProcessSecurityPolicy* policy = | 623 ChildProcessSecurityPolicyImpl* policy = |
| 624 ChildProcessSecurityPolicy::GetInstance(); | 624 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 625 if (!policy->CanUseCookiesForOrigin(child_id, request_data.url)) { | 625 if (!policy->CanUseCookiesForOrigin(child_id, request_data.url)) { |
| 626 load_flags |= (net::LOAD_DO_NOT_SEND_COOKIES | | 626 load_flags |= (net::LOAD_DO_NOT_SEND_COOKIES | |
| 627 net::LOAD_DO_NOT_SEND_AUTH_DATA | | 627 net::LOAD_DO_NOT_SEND_AUTH_DATA | |
| 628 net::LOAD_DO_NOT_SAVE_COOKIES); | 628 net::LOAD_DO_NOT_SAVE_COOKIES); |
| 629 } | 629 } |
| 630 | 630 |
| 631 // Raw headers are sensitive, as they include Cookie/Set-Cookie, so only | 631 // Raw headers are sensitive, as they include Cookie/Set-Cookie, so only |
| 632 // allow requesting them if requester has ReadRawCookies permission. | 632 // allow requesting them if requester has ReadRawCookies permission. |
| 633 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) | 633 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) |
| 634 && !policy->CanReadRawCookies(child_id)) { | 634 && !policy->CanReadRawCookies(child_id)) { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 } | 767 } |
| 768 } | 768 } |
| 769 | 769 |
| 770 void ResourceDispatcherHost::OnDataDownloadedACK(int request_id) { | 770 void ResourceDispatcherHost::OnDataDownloadedACK(int request_id) { |
| 771 // TODO(michaeln): maybe throttle DataDownloaded messages | 771 // TODO(michaeln): maybe throttle DataDownloaded messages |
| 772 } | 772 } |
| 773 | 773 |
| 774 void ResourceDispatcherHost::RegisterDownloadedTempFile( | 774 void ResourceDispatcherHost::RegisterDownloadedTempFile( |
| 775 int child_id, int request_id, DeletableFileReference* reference) { | 775 int child_id, int request_id, DeletableFileReference* reference) { |
| 776 registered_temp_files_[child_id][request_id] = reference; | 776 registered_temp_files_[child_id][request_id] = reference; |
| 777 ChildProcessSecurityPolicy::GetInstance()->GrantReadFile( | 777 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( |
| 778 child_id, reference->path()); | 778 child_id, reference->path()); |
| 779 | 779 |
| 780 // When the temp file is deleted, revoke permissions that the renderer has | 780 // When the temp file is deleted, revoke permissions that the renderer has |
| 781 // to that file. This covers an edge case where the file is deleted and then | 781 // to that file. This covers an edge case where the file is deleted and then |
| 782 // the same name is re-used for some other purpose, we don't want the old | 782 // the same name is re-used for some other purpose, we don't want the old |
| 783 // renderer to still have access to it. | 783 // renderer to still have access to it. |
| 784 // | 784 // |
| 785 // We do this when the file is deleted because the renderer can take a blob | 785 // We do this when the file is deleted because the renderer can take a blob |
| 786 // reference to the temp file that outlives the url loaded that it was | 786 // reference to the temp file that outlives the url loaded that it was |
| 787 // loaded with to keep the file (and permissions) alive. | 787 // loaded with to keep the file (and permissions) alive. |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 // validating the entry if present. | 935 // validating the entry if present. |
| 936 if (request->get_upload() != NULL) | 936 if (request->get_upload() != NULL) |
| 937 extra_load_flags |= net::LOAD_ONLY_FROM_CACHE; | 937 extra_load_flags |= net::LOAD_ONLY_FROM_CACHE; |
| 938 else | 938 else |
| 939 extra_load_flags |= net::LOAD_PREFERRING_CACHE; | 939 extra_load_flags |= net::LOAD_PREFERRING_CACHE; |
| 940 } else { | 940 } else { |
| 941 extra_load_flags |= net::LOAD_DISABLE_CACHE; | 941 extra_load_flags |= net::LOAD_DISABLE_CACHE; |
| 942 } | 942 } |
| 943 request->set_load_flags(request->load_flags() | extra_load_flags); | 943 request->set_load_flags(request->load_flags() | extra_load_flags); |
| 944 // Check if the renderer is permitted to request the requested URL. | 944 // Check if the renderer is permitted to request the requested URL. |
| 945 if (!ChildProcessSecurityPolicy::GetInstance()-> | 945 if (!ChildProcessSecurityPolicyImpl::GetInstance()-> |
| 946 CanRequestURL(child_id, url)) { | 946 CanRequestURL(child_id, url)) { |
| 947 VLOG(1) << "Denied unauthorized download request for " | 947 VLOG(1) << "Denied unauthorized download request for " |
| 948 << url.possibly_invalid_spec(); | 948 << url.possibly_invalid_spec(); |
| 949 return net::ERR_ACCESS_DENIED; | 949 return net::ERR_ACCESS_DENIED; |
| 950 } | 950 } |
| 951 | 951 |
| 952 request_id_--; | 952 request_id_--; |
| 953 | 953 |
| 954 scoped_refptr<ResourceHandler> handler( | 954 scoped_refptr<ResourceHandler> handler( |
| 955 CreateResourceHandlerForDownload(request.get(), context, child_id, | 955 CreateResourceHandlerForDownload(request.get(), context, child_id, |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1315 | 1315 |
| 1316 void ResourceDispatcherHost::OnReceivedRedirect(net::URLRequest* request, | 1316 void ResourceDispatcherHost::OnReceivedRedirect(net::URLRequest* request, |
| 1317 const GURL& new_url, | 1317 const GURL& new_url, |
| 1318 bool* defer_redirect) { | 1318 bool* defer_redirect) { |
| 1319 VLOG(1) << "OnReceivedRedirect: " << request->url().spec(); | 1319 VLOG(1) << "OnReceivedRedirect: " << request->url().spec(); |
| 1320 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); | 1320 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); |
| 1321 | 1321 |
| 1322 DCHECK(request->status().is_success()); | 1322 DCHECK(request->status().is_success()); |
| 1323 | 1323 |
| 1324 if (info->process_type() != content::PROCESS_TYPE_PLUGIN && | 1324 if (info->process_type() != content::PROCESS_TYPE_PLUGIN && |
| 1325 !ChildProcessSecurityPolicy::GetInstance()-> | 1325 !ChildProcessSecurityPolicyImpl::GetInstance()-> |
| 1326 CanRequestURL(info->child_id(), new_url)) { | 1326 CanRequestURL(info->child_id(), new_url)) { |
| 1327 VLOG(1) << "Denied unauthorized request for " | 1327 VLOG(1) << "Denied unauthorized request for " |
| 1328 << new_url.possibly_invalid_spec(); | 1328 << new_url.possibly_invalid_spec(); |
| 1329 | 1329 |
| 1330 // Tell the renderer that this request was disallowed. | 1330 // Tell the renderer that this request was disallowed. |
| 1331 CancelRequestInternal(request, false); | 1331 CancelRequestInternal(request, false); |
| 1332 return; | 1332 return; |
| 1333 } | 1333 } |
| 1334 | 1334 |
| 1335 NotifyReceivedRedirect(request, info->child_id(), new_url); | 1335 NotifyReceivedRedirect(request, info->child_id(), new_url); |
| (...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2300 scoped_refptr<ResourceHandler> transferred_resource_handler( | 2300 scoped_refptr<ResourceHandler> transferred_resource_handler( |
| 2301 new DoomedResourceHandler(info->resource_handler())); | 2301 new DoomedResourceHandler(info->resource_handler())); |
| 2302 info->set_resource_handler(transferred_resource_handler.get()); | 2302 info->set_resource_handler(transferred_resource_handler.get()); |
| 2303 } | 2303 } |
| 2304 | 2304 |
| 2305 bool ResourceDispatcherHost::IsTransferredNavigation( | 2305 bool ResourceDispatcherHost::IsTransferredNavigation( |
| 2306 const content::GlobalRequestID& transferred_request_id) const { | 2306 const content::GlobalRequestID& transferred_request_id) const { |
| 2307 return transferred_navigations_.find(transferred_request_id) != | 2307 return transferred_navigations_.find(transferred_request_id) != |
| 2308 transferred_navigations_.end(); | 2308 transferred_navigations_.end(); |
| 2309 } | 2309 } |
| OLD | NEW |