| OLD | NEW |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 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 #include "net/http/http_stream_factory_impl_job_controller.h" | 5 #include "net/http/http_stream_factory_impl_job_controller.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 | 760 |
| 761 int HttpStreamFactoryImpl::JobController::DoCreateJobs() { | 761 int HttpStreamFactoryImpl::JobController::DoCreateJobs() { |
| 762 DCHECK(!main_job_); | 762 DCHECK(!main_job_); |
| 763 DCHECK(!alternative_job_); | 763 DCHECK(!alternative_job_); |
| 764 | 764 |
| 765 HostPortPair destination(HostPortPair::FromURL(request_info_.url)); | 765 HostPortPair destination(HostPortPair::FromURL(request_info_.url)); |
| 766 GURL origin_url = ApplyHostMappingRules(request_info_.url, &destination); | 766 GURL origin_url = ApplyHostMappingRules(request_info_.url, &destination); |
| 767 | 767 |
| 768 // Create an alternative job if alternative service is set up for this domain. | 768 // Create an alternative job if alternative service is set up for this domain. |
| 769 const AlternativeService alternative_service = | 769 const AlternativeService alternative_service = |
| 770 GetAlternativeServiceFor(request_info_, delegate_, stream_type_); | 770 GetAlternativeServiceInfoFor(request_info_, delegate_, stream_type_) |
| 771 .alternative_service; |
| 771 | 772 |
| 772 if (is_preconnect_) { | 773 if (is_preconnect_) { |
| 773 // Due to how the socket pools handle priorities and idle sockets, only IDLE | 774 // Due to how the socket pools handle priorities and idle sockets, only IDLE |
| 774 // priority currently makes sense for preconnects. The priority for | 775 // priority currently makes sense for preconnects. The priority for |
| 775 // preconnects is currently ignored (see RequestSocketsForPool()), but could | 776 // preconnects is currently ignored (see RequestSocketsForPool()), but could |
| 776 // be used at some point for proxy resolution or something. | 777 // be used at some point for proxy resolution or something. |
| 777 main_job_.reset(job_factory_->CreateAltSvcJob( | 778 main_job_.reset(job_factory_->CreateAltSvcJob( |
| 778 this, PRECONNECT, session_, request_info_, IDLE, proxy_info_, | 779 this, PRECONNECT, session_, request_info_, IDLE, proxy_info_, |
| 779 server_ssl_config_, proxy_ssl_config_, destination, origin_url, | 780 server_ssl_config_, proxy_ssl_config_, destination, origin_url, |
| 780 alternative_service, enable_ip_based_pooling_, session_->net_log())); | 781 alternative_service, enable_ip_based_pooling_, session_->net_log())); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 url::Replacements<char> replacements; | 999 url::Replacements<char> replacements; |
| 999 const std::string port_str = base::UintToString(endpoint->port()); | 1000 const std::string port_str = base::UintToString(endpoint->port()); |
| 1000 replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size())); | 1001 replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size())); |
| 1001 replacements.SetHost(endpoint->host().c_str(), | 1002 replacements.SetHost(endpoint->host().c_str(), |
| 1002 url::Component(0, endpoint->host().size())); | 1003 url::Component(0, endpoint->host().size())); |
| 1003 return url.ReplaceComponents(replacements); | 1004 return url.ReplaceComponents(replacements); |
| 1004 } | 1005 } |
| 1005 return url; | 1006 return url; |
| 1006 } | 1007 } |
| 1007 | 1008 |
| 1008 AlternativeService | 1009 AlternativeServiceInfo |
| 1009 HttpStreamFactoryImpl::JobController::GetAlternativeServiceFor( | 1010 HttpStreamFactoryImpl::JobController::GetAlternativeServiceInfoFor( |
| 1010 const HttpRequestInfo& request_info, | 1011 const HttpRequestInfo& request_info, |
| 1011 HttpStreamRequest::Delegate* delegate, | 1012 HttpStreamRequest::Delegate* delegate, |
| 1012 HttpStreamRequest::StreamType stream_type) { | 1013 HttpStreamRequest::StreamType stream_type) { |
| 1013 if (!enable_alternative_services_) | 1014 if (!enable_alternative_services_) |
| 1014 return AlternativeService(); | 1015 return AlternativeServiceInfo(); |
| 1015 | 1016 |
| 1016 AlternativeService alternative_service = | 1017 AlternativeServiceInfo alternative_service_info = |
| 1017 GetAlternativeServiceForInternal(request_info, delegate, stream_type); | 1018 GetAlternativeServiceInfoInternal(request_info, delegate, stream_type); |
| 1018 AlternativeServiceType type; | 1019 AlternativeServiceType type; |
| 1019 if (alternative_service.protocol == kProtoUnknown) { | 1020 if (alternative_service_info.alternative_service.protocol == kProtoUnknown) { |
| 1020 type = NO_ALTERNATIVE_SERVICE; | 1021 type = NO_ALTERNATIVE_SERVICE; |
| 1021 } else if (alternative_service.protocol == kProtoQUIC) { | 1022 } else if (alternative_service_info.alternative_service.protocol == |
| 1022 if (request_info.url.host_piece() == alternative_service.host) { | 1023 kProtoQUIC) { |
| 1024 if (request_info.url.host_piece() == |
| 1025 alternative_service_info.alternative_service.host) { |
| 1023 type = QUIC_SAME_DESTINATION; | 1026 type = QUIC_SAME_DESTINATION; |
| 1024 } else { | 1027 } else { |
| 1025 type = QUIC_DIFFERENT_DESTINATION; | 1028 type = QUIC_DIFFERENT_DESTINATION; |
| 1026 } | 1029 } |
| 1027 } else { | 1030 } else { |
| 1028 if (request_info.url.host_piece() == alternative_service.host) { | 1031 if (request_info.url.host_piece() == |
| 1032 alternative_service_info.alternative_service.host) { |
| 1029 type = NOT_QUIC_SAME_DESTINATION; | 1033 type = NOT_QUIC_SAME_DESTINATION; |
| 1030 } else { | 1034 } else { |
| 1031 type = NOT_QUIC_DIFFERENT_DESTINATION; | 1035 type = NOT_QUIC_DIFFERENT_DESTINATION; |
| 1032 } | 1036 } |
| 1033 } | 1037 } |
| 1034 UMA_HISTOGRAM_ENUMERATION("Net.AlternativeServiceTypeForRequest", type, | 1038 UMA_HISTOGRAM_ENUMERATION("Net.AlternativeServiceTypeForRequest", type, |
| 1035 MAX_ALTERNATIVE_SERVICE_TYPE); | 1039 MAX_ALTERNATIVE_SERVICE_TYPE); |
| 1036 return alternative_service; | 1040 return alternative_service_info; |
| 1037 } | 1041 } |
| 1038 | 1042 |
| 1039 AlternativeService | 1043 AlternativeServiceInfo |
| 1040 HttpStreamFactoryImpl::JobController::GetAlternativeServiceForInternal( | 1044 HttpStreamFactoryImpl::JobController::GetAlternativeServiceInfoInternal( |
| 1041 const HttpRequestInfo& request_info, | 1045 const HttpRequestInfo& request_info, |
| 1042 HttpStreamRequest::Delegate* delegate, | 1046 HttpStreamRequest::Delegate* delegate, |
| 1043 HttpStreamRequest::StreamType stream_type) { | 1047 HttpStreamRequest::StreamType stream_type) { |
| 1044 GURL original_url = request_info.url; | 1048 GURL original_url = request_info.url; |
| 1045 | 1049 |
| 1046 if (!original_url.SchemeIs(url::kHttpsScheme)) | 1050 if (!original_url.SchemeIs(url::kHttpsScheme)) |
| 1047 return AlternativeService(); | 1051 return AlternativeServiceInfo(); |
| 1048 | 1052 |
| 1049 url::SchemeHostPort origin(original_url); | 1053 url::SchemeHostPort origin(original_url); |
| 1050 HttpServerProperties& http_server_properties = | 1054 HttpServerProperties& http_server_properties = |
| 1051 *session_->http_server_properties(); | 1055 *session_->http_server_properties(); |
| 1052 const AlternativeServiceVector alternative_service_vector = | 1056 const AlternativeServiceInfoVector alternative_service_info_vector = |
| 1053 http_server_properties.GetAlternativeServices(origin); | 1057 http_server_properties.GetAlternativeServiceInfos(origin); |
| 1054 if (alternative_service_vector.empty()) | 1058 if (alternative_service_info_vector.empty()) |
| 1055 return AlternativeService(); | 1059 return AlternativeServiceInfo(); |
| 1056 | 1060 |
| 1057 bool quic_advertised = false; | 1061 bool quic_advertised = false; |
| 1058 bool quic_all_broken = true; | 1062 bool quic_all_broken = true; |
| 1059 | 1063 |
| 1060 // First Alt-Svc that is not marked as broken. | 1064 // First alternative service that is not marked as broken. |
| 1061 AlternativeService first_alternative_service; | 1065 AlternativeServiceInfo first_alternative_service_info; |
| 1062 | 1066 |
| 1063 for (const AlternativeService& alternative_service : | 1067 for (const AlternativeServiceInfo& alternative_service_info : |
| 1064 alternative_service_vector) { | 1068 alternative_service_info_vector) { |
| 1065 DCHECK(IsAlternateProtocolValid(alternative_service.protocol)); | 1069 DCHECK(IsAlternateProtocolValid( |
| 1066 if (!quic_advertised && alternative_service.protocol == kProtoQUIC) | 1070 alternative_service_info.alternative_service.protocol)); |
| 1071 if (!quic_advertised && |
| 1072 alternative_service_info.alternative_service.protocol == kProtoQUIC) |
| 1067 quic_advertised = true; | 1073 quic_advertised = true; |
| 1068 if (http_server_properties.IsAlternativeServiceBroken( | 1074 if (http_server_properties.IsAlternativeServiceBroken( |
| 1069 alternative_service)) { | 1075 alternative_service_info.alternative_service)) { |
| 1070 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN, false); | 1076 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN, false); |
| 1071 continue; | 1077 continue; |
| 1072 } | 1078 } |
| 1073 | 1079 |
| 1074 // Some shared unix systems may have user home directories (like | 1080 // Some shared unix systems may have user home directories (like |
| 1075 // http://foo.com/~mike) which allow users to emit headers. This is a bad | 1081 // http://foo.com/~mike) which allow users to emit headers. This is a bad |
| 1076 // idea already, but with Alternate-Protocol, it provides the ability for a | 1082 // idea already, but with Alternate-Protocol, it provides the ability for a |
| 1077 // single user on a multi-user system to hijack the alternate protocol. | 1083 // single user on a multi-user system to hijack the alternate protocol. |
| 1078 // These systems also enforce ports <1024 as restricted ports. So don't | 1084 // These systems also enforce ports <1024 as restricted ports. So don't |
| 1079 // allow protocol upgrades to user-controllable ports. | 1085 // allow protocol upgrades to user-controllable ports. |
| 1080 const int kUnrestrictedPort = 1024; | 1086 const int kUnrestrictedPort = 1024; |
| 1081 if (!session_->params().enable_user_alternate_protocol_ports && | 1087 if (!session_->params().enable_user_alternate_protocol_ports && |
| 1082 (alternative_service.port >= kUnrestrictedPort && | 1088 (alternative_service_info.alternative_service.port >= |
| 1089 kUnrestrictedPort && |
| 1083 origin.port() < kUnrestrictedPort)) | 1090 origin.port() < kUnrestrictedPort)) |
| 1084 continue; | 1091 continue; |
| 1085 | 1092 |
| 1086 if (alternative_service.protocol == kProtoHTTP2) { | 1093 if (alternative_service_info.alternative_service.protocol == kProtoHTTP2) { |
| 1087 if (!session_->params().enable_http2_alternative_service) | 1094 if (!session_->params().enable_http2_alternative_service) |
| 1088 continue; | 1095 continue; |
| 1089 | 1096 |
| 1090 // Cache this entry if we don't have a non-broken Alt-Svc yet. | 1097 // Cache this entry if we don't have a non-broken Alt-Svc yet. |
| 1091 if (first_alternative_service.protocol == kProtoUnknown) | 1098 if (first_alternative_service_info.alternative_service.protocol == |
| 1092 first_alternative_service = alternative_service; | 1099 kProtoUnknown) |
| 1100 first_alternative_service_info = alternative_service_info; |
| 1093 continue; | 1101 continue; |
| 1094 } | 1102 } |
| 1095 | 1103 |
| 1096 DCHECK_EQ(kProtoQUIC, alternative_service.protocol); | 1104 DCHECK_EQ(kProtoQUIC, |
| 1105 alternative_service_info.alternative_service.protocol); |
| 1097 quic_all_broken = false; | 1106 quic_all_broken = false; |
| 1098 if (!session_->IsQuicEnabled()) | 1107 if (!session_->IsQuicEnabled()) |
| 1099 continue; | 1108 continue; |
| 1100 | 1109 |
| 1101 if (stream_type == HttpStreamRequest::BIDIRECTIONAL_STREAM && | 1110 if (stream_type == HttpStreamRequest::BIDIRECTIONAL_STREAM && |
| 1102 session_->params().quic_disable_bidirectional_streams) { | 1111 session_->params().quic_disable_bidirectional_streams) { |
| 1103 continue; | 1112 continue; |
| 1104 } | 1113 } |
| 1105 | 1114 |
| 1106 if (!original_url.SchemeIs(url::kHttpsScheme)) | 1115 if (!original_url.SchemeIs(url::kHttpsScheme)) |
| 1107 continue; | 1116 continue; |
| 1108 | 1117 |
| 1109 // Check whether there is an existing QUIC session to use for this origin. | 1118 // Check whether there is an existing QUIC session to use for this origin. |
| 1110 HostPortPair mapped_origin(origin.host(), origin.port()); | 1119 HostPortPair mapped_origin(origin.host(), origin.port()); |
| 1111 ignore_result(ApplyHostMappingRules(original_url, &mapped_origin)); | 1120 ignore_result(ApplyHostMappingRules(original_url, &mapped_origin)); |
| 1112 QuicServerId server_id(mapped_origin, request_info.privacy_mode); | 1121 QuicServerId server_id(mapped_origin, request_info.privacy_mode); |
| 1113 | 1122 |
| 1114 HostPortPair destination(alternative_service.host_port_pair()); | 1123 HostPortPair destination( |
| 1124 alternative_service_info.alternative_service.host_port_pair()); |
| 1115 ignore_result(ApplyHostMappingRules(original_url, &destination)); | 1125 ignore_result(ApplyHostMappingRules(original_url, &destination)); |
| 1116 | 1126 |
| 1117 if (session_->quic_stream_factory()->CanUseExistingSession(server_id, | 1127 if (session_->quic_stream_factory()->CanUseExistingSession(server_id, |
| 1118 destination)) { | 1128 destination)) { |
| 1119 return alternative_service; | 1129 return alternative_service_info; |
| 1120 } | 1130 } |
| 1121 | 1131 |
| 1122 // Cache this entry if we don't have a non-broken Alt-Svc yet. | 1132 // Cache this entry if we don't have a non-broken Alt-Svc yet. |
| 1123 if (first_alternative_service.protocol == kProtoUnknown) | 1133 if (first_alternative_service_info.alternative_service.protocol == |
| 1124 first_alternative_service = alternative_service; | 1134 kProtoUnknown) |
| 1135 first_alternative_service_info = alternative_service_info; |
| 1125 } | 1136 } |
| 1126 | 1137 |
| 1127 // Ask delegate to mark QUIC as broken for the origin. | 1138 // Ask delegate to mark QUIC as broken for the origin. |
| 1128 if (quic_advertised && quic_all_broken && delegate != nullptr) | 1139 if (quic_advertised && quic_all_broken && delegate != nullptr) |
| 1129 delegate->OnQuicBroken(); | 1140 delegate->OnQuicBroken(); |
| 1130 | 1141 |
| 1131 return first_alternative_service; | 1142 return first_alternative_service_info; |
| 1132 } | 1143 } |
| 1133 | 1144 |
| 1134 bool HttpStreamFactoryImpl::JobController:: | 1145 bool HttpStreamFactoryImpl::JobController:: |
| 1135 ShouldCreateAlternativeProxyServerJob( | 1146 ShouldCreateAlternativeProxyServerJob( |
| 1136 const ProxyInfo& proxy_info, | 1147 const ProxyInfo& proxy_info, |
| 1137 const GURL& url, | 1148 const GURL& url, |
| 1138 ProxyServer* alternative_proxy_server) const { | 1149 ProxyServer* alternative_proxy_server) const { |
| 1139 DCHECK(!alternative_proxy_server->is_valid()); | 1150 DCHECK(!alternative_proxy_server->is_valid()); |
| 1140 | 1151 |
| 1141 if (!enable_alternative_services_) | 1152 if (!enable_alternative_services_) |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 // If ReconsiderProxyAfterError() failed synchronously, it means | 1267 // If ReconsiderProxyAfterError() failed synchronously, it means |
| 1257 // there was nothing left to fall-back to, so fail the transaction | 1268 // there was nothing left to fall-back to, so fail the transaction |
| 1258 // with the last connection error we got. | 1269 // with the last connection error we got. |
| 1259 // TODO(eroman): This is a confusing contract, make it more obvious. | 1270 // TODO(eroman): This is a confusing contract, make it more obvious. |
| 1260 rv = error; | 1271 rv = error; |
| 1261 } | 1272 } |
| 1262 return rv; | 1273 return rv; |
| 1263 } | 1274 } |
| 1264 | 1275 |
| 1265 } // namespace net | 1276 } // namespace net |
| OLD | NEW |