Chromium Code Reviews| 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 #include "net/http/http_stream_factory_impl.h" | 5 #include "net/http/http_stream_factory_impl.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 const BoundNetLog& net_log) { | 87 const BoundNetLog& net_log) { |
| 88 Request* request = new Request(request_info.url, | 88 Request* request = new Request(request_info.url, |
| 89 this, | 89 this, |
| 90 delegate, | 90 delegate, |
| 91 websocket_handshake_stream_create_helper, | 91 websocket_handshake_stream_create_helper, |
| 92 net_log); | 92 net_log); |
| 93 Job* job = new Job(this, session_, request_info, priority, server_ssl_config, | 93 Job* job = new Job(this, session_, request_info, priority, server_ssl_config, |
| 94 proxy_ssl_config, net_log.net_log()); | 94 proxy_ssl_config, net_log.net_log()); |
| 95 request->AttachJob(job); | 95 request->AttachJob(job); |
| 96 | 96 |
| 97 const AlternativeServiceVector alternative_service_vector = | 97 const AlternativeService alternative_service = |
| 98 GetAlternativeServicesFor(request_info.url, delegate); | 98 GetAlternativeServiceFor(request_info, delegate); |
| 99 | 99 |
| 100 if (!alternative_service_vector.empty()) { | 100 if (alternative_service.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) { |
| 101 // TODO(bnc): Pass on multiple alternative services to Job. | |
| 102 const AlternativeService& alternative_service = | |
| 103 alternative_service_vector[0]; | |
| 104 // Never share connection with other jobs for FTP requests. | 101 // Never share connection with other jobs for FTP requests. |
| 105 DCHECK(!request_info.url.SchemeIs("ftp")); | 102 DCHECK(!request_info.url.SchemeIs("ftp")); |
| 106 | 103 |
| 107 Job* alternative_job = | 104 Job* alternative_job = |
| 108 new Job(this, session_, request_info, priority, server_ssl_config, | 105 new Job(this, session_, request_info, priority, server_ssl_config, |
| 109 proxy_ssl_config, alternative_service, net_log.net_log()); | 106 proxy_ssl_config, alternative_service, net_log.net_log()); |
| 110 request->AttachJob(alternative_job); | 107 request->AttachJob(alternative_job); |
| 111 | 108 |
| 112 job->WaitFor(alternative_job); | 109 job->WaitFor(alternative_job); |
| 113 // Make sure to wait until we call WaitFor(), before starting | 110 // Make sure to wait until we call WaitFor(), before starting |
| 114 // |alternative_job|, otherwise |alternative_job| will not notify |job| | 111 // |alternative_job|, otherwise |alternative_job| will not notify |job| |
| 115 // appropriately. | 112 // appropriately. |
| 116 alternative_job->Start(request); | 113 alternative_job->Start(request); |
| 117 } | 114 } |
| 118 | 115 |
| 119 // Even if |alternative_job| has already finished, it will not have notified | 116 // Even if |alternative_job| has already finished, it will not have notified |
| 120 // the request yet, since we defer that to the next iteration of the | 117 // the request yet, since we defer that to the next iteration of the |
| 121 // MessageLoop, so starting |job| is always safe. | 118 // MessageLoop, so starting |job| is always safe. |
| 122 job->Start(request); | 119 job->Start(request); |
| 123 return request; | 120 return request; |
| 124 } | 121 } |
| 125 | 122 |
| 126 void HttpStreamFactoryImpl::PreconnectStreams( | 123 void HttpStreamFactoryImpl::PreconnectStreams( |
| 127 int num_streams, | 124 int num_streams, |
| 128 const HttpRequestInfo& request_info, | 125 const HttpRequestInfo& request_info, |
| 129 const SSLConfig& server_ssl_config, | 126 const SSLConfig& server_ssl_config, |
| 130 const SSLConfig& proxy_ssl_config) { | 127 const SSLConfig& proxy_ssl_config) { |
| 131 DCHECK(!for_websockets_); | 128 DCHECK(!for_websockets_); |
| 132 AlternativeService alternative_service; | 129 AlternativeService alternative_service = |
| 133 AlternativeServiceVector alternative_service_vector = | 130 GetAlternativeServiceFor(request_info, nullptr); |
| 134 GetAlternativeServicesFor(request_info.url, nullptr); | 131 if (alternative_service.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) { |
| 135 if (!alternative_service_vector.empty()) { | |
| 136 // TODO(bnc): Pass on multiple alternative services to Job. | |
| 137 alternative_service = alternative_service_vector[0]; | |
| 138 if (session_->params().quic_disable_preconnect_if_0rtt && | 132 if (session_->params().quic_disable_preconnect_if_0rtt && |
| 139 alternative_service.protocol == QUIC && | 133 alternative_service.protocol == QUIC && |
| 140 session_->quic_stream_factory()->ZeroRTTEnabledFor(QuicServerId( | 134 session_->quic_stream_factory()->ZeroRTTEnabledFor(QuicServerId( |
| 141 alternative_service.host_port_pair(), request_info.privacy_mode))) { | 135 alternative_service.host_port_pair(), request_info.privacy_mode))) { |
| 142 return; | 136 return; |
| 143 } | 137 } |
| 144 } | 138 } |
| 145 | 139 |
| 146 // Due to how the socket pools handle priorities and idle sockets, only IDLE | 140 // Due to how the socket pools handle priorities and idle sockets, only IDLE |
| 147 // priority currently makes sense for preconnects. The priority for | 141 // priority currently makes sense for preconnects. The priority for |
| 148 // preconnects is currently ignored (see RequestSocketsForPool()), but could | 142 // preconnects is currently ignored (see RequestSocketsForPool()), but could |
| 149 // be used at some point for proxy resolution or something. | 143 // be used at some point for proxy resolution or something. |
| 150 Job* job = | 144 Job* job = |
| 151 new Job(this, session_, request_info, IDLE, server_ssl_config, | 145 new Job(this, session_, request_info, IDLE, server_ssl_config, |
| 152 proxy_ssl_config, alternative_service, session_->net_log()); | 146 proxy_ssl_config, alternative_service, session_->net_log()); |
| 153 preconnect_job_set_.insert(job); | 147 preconnect_job_set_.insert(job); |
| 154 job->Preconnect(num_streams); | 148 job->Preconnect(num_streams); |
| 155 } | 149 } |
| 156 | 150 |
| 157 const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const { | 151 const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const { |
| 158 return session_->params().host_mapping_rules; | 152 return session_->params().host_mapping_rules; |
| 159 } | 153 } |
| 160 | 154 |
| 161 AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor( | 155 AlternativeService HttpStreamFactoryImpl::GetAlternativeServiceFor( |
| 162 const GURL& original_url, | 156 const HttpRequestInfo& request_info, |
| 163 HttpStreamRequest::Delegate* delegate) { | 157 HttpStreamRequest::Delegate* delegate) { |
| 158 GURL original_url = request_info.url; | |
| 159 | |
| 164 if (original_url.SchemeIs("ftp")) | 160 if (original_url.SchemeIs("ftp")) |
| 165 return AlternativeServiceVector(); | 161 return AlternativeService(); |
| 166 | 162 |
| 167 HostPortPair origin = HostPortPair::FromURL(original_url); | 163 HostPortPair origin = HostPortPair::FromURL(original_url); |
| 168 HttpServerProperties& http_server_properties = | 164 HttpServerProperties& http_server_properties = |
| 169 *session_->http_server_properties(); | 165 *session_->http_server_properties(); |
| 170 const AlternativeServiceVector alternative_service_vector = | 166 const AlternativeServiceVector alternative_service_vector = |
| 171 http_server_properties.GetAlternativeServices(origin); | 167 http_server_properties.GetAlternativeServices(origin); |
| 172 if (alternative_service_vector.empty()) | 168 if (alternative_service_vector.empty()) |
| 173 return AlternativeServiceVector(); | 169 return AlternativeService(); |
| 174 | 170 |
| 175 bool quic_advertised = false; | 171 bool quic_advertised = false; |
| 176 bool quic_all_broken = true; | 172 bool quic_all_broken = true; |
| 177 | 173 |
| 178 const bool enable_different_host = | 174 const bool enable_different_host = |
| 179 session_->params().use_alternative_services; | 175 session_->params().use_alternative_services; |
| 180 | 176 |
| 181 AlternativeServiceVector enabled_alternative_service_vector; | 177 AlternativeService preferred_alternative_service; |
| 178 AlternativeService candidate_alternative_service; | |
| 182 for (const AlternativeService& alternative_service : | 179 for (const AlternativeService& alternative_service : |
| 183 alternative_service_vector) { | 180 alternative_service_vector) { |
| 184 DCHECK(IsAlternateProtocolValid(alternative_service.protocol)); | 181 DCHECK(IsAlternateProtocolValid(alternative_service.protocol)); |
| 185 if (!quic_advertised && alternative_service.protocol == QUIC) | 182 if (!quic_advertised && alternative_service.protocol == QUIC) |
| 186 quic_advertised = true; | 183 quic_advertised = true; |
| 187 if (http_server_properties.IsAlternativeServiceBroken( | 184 if (http_server_properties.IsAlternativeServiceBroken( |
| 188 alternative_service)) { | 185 alternative_service)) { |
| 189 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN); | 186 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN); |
| 190 continue; | 187 continue; |
| 191 } | 188 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 207 | 204 |
| 208 origin.set_port(alternative_service.port); | 205 origin.set_port(alternative_service.port); |
| 209 if (alternative_service.protocol >= NPN_SPDY_MINIMUM_VERSION && | 206 if (alternative_service.protocol >= NPN_SPDY_MINIMUM_VERSION && |
| 210 alternative_service.protocol <= NPN_SPDY_MAXIMUM_VERSION) { | 207 alternative_service.protocol <= NPN_SPDY_MAXIMUM_VERSION) { |
| 211 if (!HttpStreamFactory::spdy_enabled()) | 208 if (!HttpStreamFactory::spdy_enabled()) |
| 212 continue; | 209 continue; |
| 213 | 210 |
| 214 if (session_->HasSpdyExclusion(origin)) | 211 if (session_->HasSpdyExclusion(origin)) |
| 215 continue; | 212 continue; |
| 216 | 213 |
| 217 enabled_alternative_service_vector.push_back(alternative_service); | 214 // enabled_alternative_service_vector.push_back(alternative_service); |
| 215 // Cache the first entry if no preferred Alt-Svc selected yet. | |
| 216 if (candidate_alternative_service.protocol == | |
| 217 UNINITIALIZED_ALTERNATE_PROTOCOL && | |
| 218 preferred_alternative_service.protocol == | |
| 219 UNINITIALIZED_ALTERNATE_PROTOCOL) { | |
| 220 candidate_alternative_service = alternative_service; | |
| 221 } | |
| 218 continue; | 222 continue; |
| 219 } | 223 } |
| 220 | 224 |
| 221 DCHECK_EQ(QUIC, alternative_service.protocol); | 225 DCHECK_EQ(QUIC, alternative_service.protocol); |
| 222 quic_all_broken = false; | 226 quic_all_broken = false; |
| 223 if (!session_->params().enable_quic) | 227 if (!session_->params().enable_quic) |
| 224 continue; | 228 continue; |
| 225 | 229 |
| 226 if (session_->quic_stream_factory()->IsQuicDisabled(origin.port())) | 230 if (session_->quic_stream_factory()->IsQuicDisabled(origin.port())) |
| 227 continue; | 231 continue; |
| 228 | 232 |
| 229 if (!original_url.SchemeIs("https")) | 233 if (!original_url.SchemeIs("https")) |
| 230 continue; | 234 continue; |
| 231 | 235 |
| 232 enabled_alternative_service_vector.push_back(alternative_service); | 236 if (preferred_alternative_service.protocol == |
| 237 UNINITIALIZED_ALTERNATE_PROTOCOL) { | |
| 238 // Check to see whether there's an active session to pool for this QUIC | |
| 239 // alternative service. | |
| 240 HostPortPair destination = alternative_service.host_port_pair(); | |
| 241 StringPiece origin_host = | |
| 242 ApplyHostMappingRules(request_info.url, &destination).host(); | |
|
Ryan Hamilton
2015/12/18 17:52:51
Are you sure this is correct? It may well be, but
Zhongyi Shi
2015/12/18 21:59:29
I still leave the origin_host calculation here, bu
| |
| 243 if (session_->quic_stream_factory()->CanPool( | |
| 244 destination, request_info.privacy_mode, origin_host)) | |
| 245 preferred_alternative_service = alternative_service; | |
|
Ryan Hamilton
2015/12/18 17:52:51
I'm not sure that I understand the dance here with
Zhongyi Shi
2015/12/18 17:57:23
Candidate is the first entry of the list. While pr
Ryan Hamilton
2015/12/18 19:52:59
Are you specifically thinking about the call to de
Zhongyi Shi
2015/12/18 21:59:29
Ah, thanks for pointing this out! If we are able t
| |
| 246 } | |
| 247 // enabled_alternative_service_vector.push_back(alternative_service); | |
| 248 if (candidate_alternative_service.protocol == | |
| 249 UNINITIALIZED_ALTERNATE_PROTOCOL && | |
| 250 preferred_alternative_service.protocol == | |
| 251 UNINITIALIZED_ALTERNATE_PROTOCOL) { | |
| 252 candidate_alternative_service = alternative_service; | |
| 253 } | |
| 233 } | 254 } |
| 234 if (quic_advertised && quic_all_broken && delegate != nullptr) | 255 if (quic_advertised && quic_all_broken && delegate != nullptr) |
| 235 delegate->OnQuicBroken(); | 256 delegate->OnQuicBroken(); |
| 236 return enabled_alternative_service_vector; | 257 if (preferred_alternative_service.protocol == |
| 258 UNINITIALIZED_ALTERNATE_PROTOCOL) | |
| 259 return candidate_alternative_service; | |
| 260 return preferred_alternative_service; | |
| 237 } | 261 } |
| 238 | 262 |
| 239 void HttpStreamFactoryImpl::OrphanJob(Job* job, const Request* request) { | 263 void HttpStreamFactoryImpl::OrphanJob(Job* job, const Request* request) { |
| 240 DCHECK(ContainsKey(request_map_, job)); | 264 DCHECK(ContainsKey(request_map_, job)); |
| 241 DCHECK_EQ(request_map_[job], request); | 265 DCHECK_EQ(request_map_[job], request); |
| 242 DCHECK(!ContainsKey(orphaned_job_set_, job)); | 266 DCHECK(!ContainsKey(orphaned_job_set_, job)); |
| 243 | 267 |
| 244 request_map_.erase(job); | 268 request_map_.erase(job); |
| 245 | 269 |
| 246 orphaned_job_set_.insert(job); | 270 orphaned_job_set_.insert(job); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 delete job; | 316 delete job; |
| 293 } | 317 } |
| 294 | 318 |
| 295 void HttpStreamFactoryImpl::OnPreconnectsComplete(const Job* job) { | 319 void HttpStreamFactoryImpl::OnPreconnectsComplete(const Job* job) { |
| 296 preconnect_job_set_.erase(job); | 320 preconnect_job_set_.erase(job); |
| 297 delete job; | 321 delete job; |
| 298 OnPreconnectsCompleteInternal(); | 322 OnPreconnectsCompleteInternal(); |
| 299 } | 323 } |
| 300 | 324 |
| 301 } // namespace net | 325 } // namespace net |
| OLD | NEW |