| 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 <algorithm> | 9 #include <algorithm> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 // use. Arbitrarily chosen. | 129 // use. Arbitrarily chosen. |
| 130 const double kMaxRequestsPerProcessRatio = 0.45; | 130 const double kMaxRequestsPerProcessRatio = 0.45; |
| 131 | 131 |
| 132 // TODO(jkarlin): The value is high to reduce the chance of the detachable | 132 // TODO(jkarlin): The value is high to reduce the chance of the detachable |
| 133 // request timing out, forcing a blocked second request to open a new connection | 133 // request timing out, forcing a blocked second request to open a new connection |
| 134 // and start over. Reduce this value once we have a better idea of what it | 134 // and start over. Reduce this value once we have a better idea of what it |
| 135 // should be and once we stop blocking multiple simultaneous requests for the | 135 // should be and once we stop blocking multiple simultaneous requests for the |
| 136 // same resource (see bugs 46104 and 31014). | 136 // same resource (see bugs 46104 and 31014). |
| 137 const int kDefaultDetachableCancelDelayMs = 30000; | 137 const int kDefaultDetachableCancelDelayMs = 30000; |
| 138 | 138 |
| 139 bool IsDetachableResourceType(ResourceType::Type type) { | 139 bool IsDetachableResourceType(ResourceType type) { |
| 140 switch (type) { | 140 switch (type) { |
| 141 case ResourceType::PREFETCH: | 141 case RESOURCE_TYPE_PREFETCH: |
| 142 case ResourceType::PING: | 142 case RESOURCE_TYPE_PING: |
| 143 return true; | 143 return true; |
| 144 default: | 144 default: |
| 145 return false; | 145 return false; |
| 146 } | 146 } |
| 147 } | 147 } |
| 148 | 148 |
| 149 // Aborts a request before an URLRequest has actually been created. | 149 // Aborts a request before an URLRequest has actually been created. |
| 150 void AbortRequestBeforeItStarts(ResourceMessageFilter* filter, | 150 void AbortRequestBeforeItStarts(ResourceMessageFilter* filter, |
| 151 IPC::Message* sync_result, | 151 IPC::Message* sync_result, |
| 152 int request_id) { | 152 int request_id) { |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 return delegate_->CreateLoginDelegate(auth_info, loader->request()); | 670 return delegate_->CreateLoginDelegate(auth_info, loader->request()); |
| 671 } | 671 } |
| 672 | 672 |
| 673 bool ResourceDispatcherHostImpl::HandleExternalProtocol(ResourceLoader* loader, | 673 bool ResourceDispatcherHostImpl::HandleExternalProtocol(ResourceLoader* loader, |
| 674 const GURL& url) { | 674 const GURL& url) { |
| 675 if (!delegate_) | 675 if (!delegate_) |
| 676 return false; | 676 return false; |
| 677 | 677 |
| 678 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); | 678 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); |
| 679 | 679 |
| 680 if (!ResourceType::IsFrame(info->GetResourceType())) | 680 if (!IsResourceTypeFrame(info->GetResourceType())) |
| 681 return false; | 681 return false; |
| 682 | 682 |
| 683 const net::URLRequestJobFactory* job_factory = | 683 const net::URLRequestJobFactory* job_factory = |
| 684 info->GetContext()->GetRequestContext()->job_factory(); | 684 info->GetContext()->GetRequestContext()->job_factory(); |
| 685 if (job_factory->IsHandledURL(url)) | 685 if (job_factory->IsHandledURL(url)) |
| 686 return false; | 686 return false; |
| 687 | 687 |
| 688 return delegate_->HandleExternalProtocol( | 688 return delegate_->HandleExternalProtocol( |
| 689 url, info->GetChildID(), info->GetRouteID()); | 689 url, info->GetChildID(), info->GetRouteID()); |
| 690 } | 690 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 BrowserThread::UI, FROM_HERE, | 740 BrowserThread::UI, FROM_HERE, |
| 741 base::Bind( | 741 base::Bind( |
| 742 &NotifyResponseOnUI, | 742 &NotifyResponseOnUI, |
| 743 render_process_id, render_frame_host, base::Passed(&detail))); | 743 render_process_id, render_frame_host, base::Passed(&detail))); |
| 744 } | 744 } |
| 745 | 745 |
| 746 void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) { | 746 void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) { |
| 747 ResourceRequestInfo* info = loader->GetRequestInfo(); | 747 ResourceRequestInfo* info = loader->GetRequestInfo(); |
| 748 | 748 |
| 749 // Record final result of all resource loads. | 749 // Record final result of all resource loads. |
| 750 if (info->GetResourceType() == ResourceType::MAIN_FRAME) { | 750 if (info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME) { |
| 751 // This enumeration has "3" appended to its name to distinguish it from | 751 // This enumeration has "3" appended to its name to distinguish it from |
| 752 // older versions. | 752 // older versions. |
| 753 UMA_HISTOGRAM_SPARSE_SLOWLY( | 753 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 754 "Net.ErrorCodesForMainFrame3", | 754 "Net.ErrorCodesForMainFrame3", |
| 755 -loader->request()->status().error()); | 755 -loader->request()->status().error()); |
| 756 | 756 |
| 757 if (loader->request()->url().SchemeIsSecure()) { | 757 if (loader->request()->url().SchemeIsSecure()) { |
| 758 if (loader->request()->url().host() == "www.google.com") { | 758 if (loader->request()->url().host() == "www.google.com") { |
| 759 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.ErrorCodesForHTTPSGoogleMainFrame2", | 759 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.ErrorCodesForHTTPSGoogleMainFrame2", |
| 760 -loader->request()->status().error()); | 760 -loader->request()->status().error()); |
| 761 } | 761 } |
| 762 | 762 |
| 763 int num_valid_scts = std::count_if( | 763 int num_valid_scts = std::count_if( |
| 764 loader->request()->ssl_info().signed_certificate_timestamps.begin(), | 764 loader->request()->ssl_info().signed_certificate_timestamps.begin(), |
| 765 loader->request()->ssl_info().signed_certificate_timestamps.end(), | 765 loader->request()->ssl_info().signed_certificate_timestamps.end(), |
| 766 IsValidatedSCT); | 766 IsValidatedSCT); |
| 767 UMA_HISTOGRAM_COUNTS_100( | 767 UMA_HISTOGRAM_COUNTS_100( |
| 768 "Net.CertificateTransparency.MainFrameValidSCTCount", num_valid_scts); | 768 "Net.CertificateTransparency.MainFrameValidSCTCount", num_valid_scts); |
| 769 } | 769 } |
| 770 } else { | 770 } else { |
| 771 if (info->GetResourceType() == ResourceType::IMAGE) { | 771 if (info->GetResourceType() == RESOURCE_TYPE_IMAGE) { |
| 772 UMA_HISTOGRAM_SPARSE_SLOWLY( | 772 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 773 "Net.ErrorCodesForImages", | 773 "Net.ErrorCodesForImages", |
| 774 -loader->request()->status().error()); | 774 -loader->request()->status().error()); |
| 775 } | 775 } |
| 776 // This enumeration has "2" appended to distinguish it from older versions. | 776 // This enumeration has "2" appended to distinguish it from older versions. |
| 777 UMA_HISTOGRAM_SPARSE_SLOWLY( | 777 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 778 "Net.ErrorCodesForSubresources2", | 778 "Net.ErrorCodesForSubresources2", |
| 779 -loader->request()->status().error()); | 779 -loader->request()->status().error()); |
| 780 } | 780 } |
| 781 | 781 |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 if (request_data.request_body.get()) { | 1057 if (request_data.request_body.get()) { |
| 1058 new_request->set_upload(UploadDataStreamBuilder::Build( | 1058 new_request->set_upload(UploadDataStreamBuilder::Build( |
| 1059 request_data.request_body.get(), | 1059 request_data.request_body.get(), |
| 1060 GetBlobStorageContext(filter_), | 1060 GetBlobStorageContext(filter_), |
| 1061 filter_->file_system_context(), | 1061 filter_->file_system_context(), |
| 1062 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE) | 1062 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE) |
| 1063 .get())); | 1063 .get())); |
| 1064 } | 1064 } |
| 1065 | 1065 |
| 1066 bool allow_download = request_data.allow_download && | 1066 bool allow_download = request_data.allow_download && |
| 1067 ResourceType::IsFrame(request_data.resource_type); | 1067 IsResourceTypeFrame(request_data.resource_type); |
| 1068 | 1068 |
| 1069 // Make extra info and read footer (contains request ID). | 1069 // Make extra info and read footer (contains request ID). |
| 1070 ResourceRequestInfoImpl* extra_info = | 1070 ResourceRequestInfoImpl* extra_info = |
| 1071 new ResourceRequestInfoImpl( | 1071 new ResourceRequestInfoImpl( |
| 1072 process_type, | 1072 process_type, |
| 1073 child_id, | 1073 child_id, |
| 1074 route_id, | 1074 route_id, |
| 1075 request_data.origin_pid, | 1075 request_data.origin_pid, |
| 1076 request_id, | 1076 request_id, |
| 1077 request_data.render_frame_id, | 1077 request_data.render_frame_id, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1160 handler.reset(new DetachableResourceHandler( | 1160 handler.reset(new DetachableResourceHandler( |
| 1161 request, | 1161 request, |
| 1162 base::TimeDelta::FromMilliseconds(kDefaultDetachableCancelDelayMs), | 1162 base::TimeDelta::FromMilliseconds(kDefaultDetachableCancelDelayMs), |
| 1163 handler.Pass())); | 1163 handler.Pass())); |
| 1164 } | 1164 } |
| 1165 | 1165 |
| 1166 // Install a CrossSiteResourceHandler for all main frame requests. This will | 1166 // Install a CrossSiteResourceHandler for all main frame requests. This will |
| 1167 // let us check whether a transfer is required and pause for the unload | 1167 // let us check whether a transfer is required and pause for the unload |
| 1168 // handler either if so or if a cross-process navigation is already under way. | 1168 // handler either if so or if a cross-process navigation is already under way. |
| 1169 bool is_swappable_navigation = | 1169 bool is_swappable_navigation = |
| 1170 request_data.resource_type == ResourceType::MAIN_FRAME; | 1170 request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME; |
| 1171 // If we are using --site-per-process, install it for subframes as well. | 1171 // If we are using --site-per-process, install it for subframes as well. |
| 1172 if (!is_swappable_navigation && | 1172 if (!is_swappable_navigation && |
| 1173 CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | 1173 CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { |
| 1174 is_swappable_navigation = | 1174 is_swappable_navigation = |
| 1175 request_data.resource_type == ResourceType::SUB_FRAME; | 1175 request_data.resource_type == RESOURCE_TYPE_SUB_FRAME; |
| 1176 } | 1176 } |
| 1177 if (is_swappable_navigation && process_type == PROCESS_TYPE_RENDERER) | 1177 if (is_swappable_navigation && process_type == PROCESS_TYPE_RENDERER) |
| 1178 handler.reset(new CrossSiteResourceHandler(handler.Pass(), request)); | 1178 handler.reset(new CrossSiteResourceHandler(handler.Pass(), request)); |
| 1179 | 1179 |
| 1180 // Insert a buffered event handler before the actual one. | 1180 // Insert a buffered event handler before the actual one. |
| 1181 handler.reset( | 1181 handler.reset( |
| 1182 new BufferedResourceHandler(handler.Pass(), this, request)); | 1182 new BufferedResourceHandler(handler.Pass(), this, request)); |
| 1183 | 1183 |
| 1184 ScopedVector<ResourceThrottle> throttles; | 1184 ScopedVector<ResourceThrottle> throttles; |
| 1185 if (delegate_) { | 1185 if (delegate_) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 return new ResourceRequestInfoImpl( | 1291 return new ResourceRequestInfoImpl( |
| 1292 PROCESS_TYPE_RENDERER, | 1292 PROCESS_TYPE_RENDERER, |
| 1293 child_id, | 1293 child_id, |
| 1294 route_id, | 1294 route_id, |
| 1295 0, | 1295 0, |
| 1296 request_id_, | 1296 request_id_, |
| 1297 MSG_ROUTING_NONE, // render_frame_id | 1297 MSG_ROUTING_NONE, // render_frame_id |
| 1298 false, // is_main_frame | 1298 false, // is_main_frame |
| 1299 false, // parent_is_main_frame | 1299 false, // parent_is_main_frame |
| 1300 -1, // parent_render_frame_id | 1300 -1, // parent_render_frame_id |
| 1301 ResourceType::SUB_RESOURCE, | 1301 RESOURCE_TYPE_SUB_RESOURCE, |
| 1302 PAGE_TRANSITION_LINK, | 1302 PAGE_TRANSITION_LINK, |
| 1303 false, // should_replace_current_entry | 1303 false, // should_replace_current_entry |
| 1304 download, // is_download | 1304 download, // is_download |
| 1305 false, // is_stream | 1305 false, // is_stream |
| 1306 download, // allow_download | 1306 download, // allow_download |
| 1307 false, // has_user_gesture | 1307 false, // has_user_gesture |
| 1308 blink::WebReferrerPolicyDefault, | 1308 blink::WebReferrerPolicyDefault, |
| 1309 blink::WebPageVisibilityStateVisible, | 1309 blink::WebPageVisibilityStateVisible, |
| 1310 context, | 1310 context, |
| 1311 base::WeakPtr<ResourceMessageFilter>(), // filter | 1311 base::WeakPtr<ResourceMessageFilter>(), // filter |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1935 const ResourceHostMsg_Request& request_data, | 1935 const ResourceHostMsg_Request& request_data, |
| 1936 int child_id, | 1936 int child_id, |
| 1937 bool is_sync_load) { | 1937 bool is_sync_load) { |
| 1938 int load_flags = request_data.load_flags; | 1938 int load_flags = request_data.load_flags; |
| 1939 | 1939 |
| 1940 // Although EV status is irrelevant to sub-frames and sub-resources, we have | 1940 // Although EV status is irrelevant to sub-frames and sub-resources, we have |
| 1941 // to perform EV certificate verification on all resources because an HTTP | 1941 // to perform EV certificate verification on all resources because an HTTP |
| 1942 // keep-alive connection created to load a sub-frame or a sub-resource could | 1942 // keep-alive connection created to load a sub-frame or a sub-resource could |
| 1943 // be reused to load a main frame. | 1943 // be reused to load a main frame. |
| 1944 load_flags |= net::LOAD_VERIFY_EV_CERT; | 1944 load_flags |= net::LOAD_VERIFY_EV_CERT; |
| 1945 if (request_data.resource_type == ResourceType::MAIN_FRAME) { | 1945 if (request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME) { |
| 1946 load_flags |= net::LOAD_MAIN_FRAME; | 1946 load_flags |= net::LOAD_MAIN_FRAME; |
| 1947 } else if (request_data.resource_type == ResourceType::SUB_FRAME) { | 1947 } else if (request_data.resource_type == RESOURCE_TYPE_SUB_FRAME) { |
| 1948 load_flags |= net::LOAD_SUB_FRAME; | 1948 load_flags |= net::LOAD_SUB_FRAME; |
| 1949 } else if (request_data.resource_type == ResourceType::PREFETCH) { | 1949 } else if (request_data.resource_type == RESOURCE_TYPE_PREFETCH) { |
| 1950 load_flags |= (net::LOAD_PREFETCH | net::LOAD_DO_NOT_PROMPT_FOR_LOGIN); | 1950 load_flags |= (net::LOAD_PREFETCH | net::LOAD_DO_NOT_PROMPT_FOR_LOGIN); |
| 1951 } else if (request_data.resource_type == ResourceType::FAVICON) { | 1951 } else if (request_data.resource_type == RESOURCE_TYPE_FAVICON) { |
| 1952 load_flags |= net::LOAD_DO_NOT_PROMPT_FOR_LOGIN; | 1952 load_flags |= net::LOAD_DO_NOT_PROMPT_FOR_LOGIN; |
| 1953 } else if (request_data.resource_type == ResourceType::IMAGE) { | 1953 } else if (request_data.resource_type == RESOURCE_TYPE_IMAGE) { |
| 1954 // Prevent third-party image content from prompting for login, as this | 1954 // Prevent third-party image content from prompting for login, as this |
| 1955 // is often a scam to extract credentials for another domain from the user. | 1955 // is often a scam to extract credentials for another domain from the user. |
| 1956 // Only block image loads, as the attack applies largely to the "src" | 1956 // Only block image loads, as the attack applies largely to the "src" |
| 1957 // property of the <img> tag. It is common for web properties to allow | 1957 // property of the <img> tag. It is common for web properties to allow |
| 1958 // untrusted values for <img src>; this is considered a fair thing for an | 1958 // untrusted values for <img src>; this is considered a fair thing for an |
| 1959 // HTML sanitizer to do. Conversely, any HTML sanitizer that didn't | 1959 // HTML sanitizer to do. Conversely, any HTML sanitizer that didn't |
| 1960 // filter sources for <script>, <link>, <embed>, <object>, <iframe> tags | 1960 // filter sources for <script>, <link>, <embed>, <object>, <iframe> tags |
| 1961 // would be considered vulnerable in and of itself. | 1961 // would be considered vulnerable in and of itself. |
| 1962 HttpAuthRelationType relation_type = HttpAuthRelationTypeOf( | 1962 HttpAuthRelationType relation_type = HttpAuthRelationTypeOf( |
| 1963 request_data.url, request_data.first_party_for_cookies); | 1963 request_data.url, request_data.first_party_for_cookies); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1981 // Raw headers are sensitive, as they include Cookie/Set-Cookie, so only | 1981 // Raw headers are sensitive, as they include Cookie/Set-Cookie, so only |
| 1982 // allow requesting them if requester has ReadRawCookies permission. | 1982 // allow requesting them if requester has ReadRawCookies permission. |
| 1983 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) | 1983 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) |
| 1984 && !policy->CanReadRawCookies(child_id)) { | 1984 && !policy->CanReadRawCookies(child_id)) { |
| 1985 VLOG(1) << "Denied unauthorized request for raw headers"; | 1985 VLOG(1) << "Denied unauthorized request for raw headers"; |
| 1986 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS; | 1986 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS; |
| 1987 } | 1987 } |
| 1988 | 1988 |
| 1989 // Add a flag to selectively bypass the data reduction proxy if the resource | 1989 // Add a flag to selectively bypass the data reduction proxy if the resource |
| 1990 // type is not an image. | 1990 // type is not an image. |
| 1991 if (request_data.resource_type != ResourceType::IMAGE) | 1991 if (request_data.resource_type != RESOURCE_TYPE_IMAGE) |
| 1992 load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY; | 1992 load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY; |
| 1993 | 1993 |
| 1994 return load_flags; | 1994 return load_flags; |
| 1995 } | 1995 } |
| 1996 | 1996 |
| 1997 } // namespace content | 1997 } // namespace content |
| OLD | NEW |