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 |