Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: net/http/http_stream_factory_impl.cc

Issue 1540463003: Change the interface of GetAlternativeServicesFor, always return the best Alt-Svc entry. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: change hanging_data_ to vector Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http/http_stream_factory_impl.h ('k') | net/http/http_stream_factory_impl_job.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 RequestPriority priority, 113 RequestPriority priority,
114 const SSLConfig& server_ssl_config, 114 const SSLConfig& server_ssl_config,
115 const SSLConfig& proxy_ssl_config, 115 const SSLConfig& proxy_ssl_config,
116 HttpStreamRequest::Delegate* delegate, 116 HttpStreamRequest::Delegate* delegate,
117 WebSocketHandshakeStreamBase::CreateHelper* 117 WebSocketHandshakeStreamBase::CreateHelper*
118 websocket_handshake_stream_create_helper, 118 websocket_handshake_stream_create_helper,
119 const BoundNetLog& net_log) { 119 const BoundNetLog& net_log) {
120 Request* request = new Request(request_info.url, this, delegate, 120 Request* request = new Request(request_info.url, this, delegate,
121 websocket_handshake_stream_create_helper, 121 websocket_handshake_stream_create_helper,
122 net_log, Request::HTTP_STREAM); 122 net_log, Request::HTTP_STREAM);
123 HostPortPair server = HostPortPair::FromURL(request_info.url);
124 GURL origin_url = ApplyHostMappingRules(request_info.url, &server);
125
123 Job* job = new Job(this, session_, request_info, priority, server_ssl_config, 126 Job* job = new Job(this, session_, request_info, priority, server_ssl_config,
124 proxy_ssl_config, net_log.net_log()); 127 proxy_ssl_config, server, origin_url, net_log.net_log());
125 request->AttachJob(job); 128 request->AttachJob(job);
126 129
127 const AlternativeServiceVector alternative_service_vector = 130 const AlternativeService alternative_service =
128 GetAlternativeServicesFor(request_info.url, delegate); 131 GetAlternativeServiceFor(request_info, delegate);
129 132
130 if (!alternative_service_vector.empty()) { 133 if (alternative_service.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) {
mef 2016/01/08 16:03:10 Should this code be also applied to HttpStreamFact
131 // TODO(bnc): Pass on multiple alternative services to Job.
132 const AlternativeService& alternative_service =
133 alternative_service_vector[0];
134 // Never share connection with other jobs for FTP requests. 134 // Never share connection with other jobs for FTP requests.
135 DVLOG(1) << "Selected alternative service (host: "
136 << alternative_service.host_port_pair().host()
137 << " port: " << alternative_service.host_port_pair().port() << ")";
138
135 DCHECK(!request_info.url.SchemeIs("ftp")); 139 DCHECK(!request_info.url.SchemeIs("ftp"));
140 HostPortPair server = alternative_service.host_port_pair();
141 GURL origin_url = ApplyHostMappingRules(request_info.url, &server);
136 142
137 Job* alternative_job = 143 Job* alternative_job =
138 new Job(this, session_, request_info, priority, server_ssl_config, 144 new Job(this, session_, request_info, priority, server_ssl_config,
139 proxy_ssl_config, alternative_service, net_log.net_log()); 145 proxy_ssl_config, server, origin_url, alternative_service,
146 net_log.net_log());
140 request->AttachJob(alternative_job); 147 request->AttachJob(alternative_job);
141 148
142 job->WaitFor(alternative_job); 149 job->WaitFor(alternative_job);
143 // Make sure to wait until we call WaitFor(), before starting 150 // Make sure to wait until we call WaitFor(), before starting
144 // |alternative_job|, otherwise |alternative_job| will not notify |job| 151 // |alternative_job|, otherwise |alternative_job| will not notify |job|
145 // appropriately. 152 // appropriately.
146 alternative_job->Start(request); 153 alternative_job->Start(request);
147 } 154 }
148 155
149 // Even if |alternative_job| has already finished, it will not have notified 156 // Even if |alternative_job| has already finished, it will not have notified
150 // the request yet, since we defer that to the next iteration of the 157 // the request yet, since we defer that to the next iteration of the
151 // MessageLoop, so starting |job| is always safe. 158 // MessageLoop, so starting |job| is always safe.
152 job->Start(request); 159 job->Start(request);
153 return request; 160 return request;
154 } 161 }
155 162
156 void HttpStreamFactoryImpl::PreconnectStreams( 163 void HttpStreamFactoryImpl::PreconnectStreams(
157 int num_streams, 164 int num_streams,
158 const HttpRequestInfo& request_info, 165 const HttpRequestInfo& request_info,
159 const SSLConfig& server_ssl_config, 166 const SSLConfig& server_ssl_config,
160 const SSLConfig& proxy_ssl_config) { 167 const SSLConfig& proxy_ssl_config) {
161 DCHECK(!for_websockets_); 168 DCHECK(!for_websockets_);
162 AlternativeService alternative_service; 169 AlternativeService alternative_service =
163 AlternativeServiceVector alternative_service_vector = 170 GetAlternativeServiceFor(request_info, nullptr);
164 GetAlternativeServicesFor(request_info.url, nullptr); 171 HostPortPair server;
165 if (!alternative_service_vector.empty()) { 172 if (alternative_service.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) {
166 // TODO(bnc): Pass on multiple alternative services to Job. 173 server = alternative_service.host_port_pair();
167 alternative_service = alternative_service_vector[0];
168 if (session_->params().quic_disable_preconnect_if_0rtt && 174 if (session_->params().quic_disable_preconnect_if_0rtt &&
169 alternative_service.protocol == QUIC && 175 alternative_service.protocol == QUIC &&
170 session_->quic_stream_factory()->ZeroRTTEnabledFor(QuicServerId( 176 session_->quic_stream_factory()->ZeroRTTEnabledFor(QuicServerId(
171 alternative_service.host_port_pair(), request_info.privacy_mode))) { 177 alternative_service.host_port_pair(), request_info.privacy_mode))) {
172 return; 178 return;
173 } 179 }
180 } else {
181 server = HostPortPair::FromURL(request_info.url);
174 } 182 }
175 183 GURL origin_url = ApplyHostMappingRules(request_info.url, &server);
176 // Due to how the socket pools handle priorities and idle sockets, only IDLE 184 // Due to how the socket pools handle priorities and idle sockets, only IDLE
177 // priority currently makes sense for preconnects. The priority for 185 // priority currently makes sense for preconnects. The priority for
178 // preconnects is currently ignored (see RequestSocketsForPool()), but could 186 // preconnects is currently ignored (see RequestSocketsForPool()), but could
179 // be used at some point for proxy resolution or something. 187 // be used at some point for proxy resolution or something.
180 Job* job = 188 Job* job = new Job(this, session_, request_info, IDLE, server_ssl_config,
181 new Job(this, session_, request_info, IDLE, server_ssl_config, 189 proxy_ssl_config, server, origin_url, alternative_service,
182 proxy_ssl_config, alternative_service, session_->net_log()); 190 session_->net_log());
183 preconnect_job_set_.insert(job); 191 preconnect_job_set_.insert(job);
184 job->Preconnect(num_streams); 192 job->Preconnect(num_streams);
185 } 193 }
186 194
187 const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const { 195 const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const {
188 return session_->params().host_mapping_rules; 196 return session_->params().host_mapping_rules;
189 } 197 }
190 198
191 AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor( 199 AlternativeService HttpStreamFactoryImpl::GetAlternativeServiceFor(
192 const GURL& original_url, 200 const HttpRequestInfo& request_info,
193 HttpStreamRequest::Delegate* delegate) { 201 HttpStreamRequest::Delegate* delegate) {
202 GURL original_url = request_info.url;
203
194 if (original_url.SchemeIs("ftp")) 204 if (original_url.SchemeIs("ftp"))
195 return AlternativeServiceVector(); 205 return AlternativeService();
196 206
197 HostPortPair origin = HostPortPair::FromURL(original_url); 207 HostPortPair origin = HostPortPair::FromURL(original_url);
198 HttpServerProperties& http_server_properties = 208 HttpServerProperties& http_server_properties =
199 *session_->http_server_properties(); 209 *session_->http_server_properties();
200 const AlternativeServiceVector alternative_service_vector = 210 const AlternativeServiceVector alternative_service_vector =
201 http_server_properties.GetAlternativeServices(origin); 211 http_server_properties.GetAlternativeServices(origin);
202 if (alternative_service_vector.empty()) 212 if (alternative_service_vector.empty())
203 return AlternativeServiceVector(); 213 return AlternativeService();
204 214
205 bool quic_advertised = false; 215 bool quic_advertised = false;
206 bool quic_all_broken = true; 216 bool quic_all_broken = true;
207 217
208 const bool enable_different_host = 218 const bool enable_different_host =
209 session_->params().use_alternative_services; 219 session_->params().use_alternative_services;
210 220
211 AlternativeServiceVector enabled_alternative_service_vector; 221 // First Alt-Svc that is not marked as broken.
222 AlternativeService first_alternative_service;
223
212 for (const AlternativeService& alternative_service : 224 for (const AlternativeService& alternative_service :
213 alternative_service_vector) { 225 alternative_service_vector) {
214 DCHECK(IsAlternateProtocolValid(alternative_service.protocol)); 226 DCHECK(IsAlternateProtocolValid(alternative_service.protocol));
215 if (!quic_advertised && alternative_service.protocol == QUIC) 227 if (!quic_advertised && alternative_service.protocol == QUIC)
216 quic_advertised = true; 228 quic_advertised = true;
217 if (http_server_properties.IsAlternativeServiceBroken( 229 if (http_server_properties.IsAlternativeServiceBroken(
218 alternative_service)) { 230 alternative_service)) {
219 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN); 231 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN);
220 continue; 232 continue;
221 } 233 }
(...skipping 15 matching lines...) Expand all
237 249
238 origin.set_port(alternative_service.port); 250 origin.set_port(alternative_service.port);
239 if (alternative_service.protocol >= NPN_SPDY_MINIMUM_VERSION && 251 if (alternative_service.protocol >= NPN_SPDY_MINIMUM_VERSION &&
240 alternative_service.protocol <= NPN_SPDY_MAXIMUM_VERSION) { 252 alternative_service.protocol <= NPN_SPDY_MAXIMUM_VERSION) {
241 if (!HttpStreamFactory::spdy_enabled()) 253 if (!HttpStreamFactory::spdy_enabled())
242 continue; 254 continue;
243 255
244 if (session_->HasSpdyExclusion(origin)) 256 if (session_->HasSpdyExclusion(origin))
245 continue; 257 continue;
246 258
247 enabled_alternative_service_vector.push_back(alternative_service); 259 // Cache this entry if we don't have a non-broken Alt-Svc yet.
260 if (first_alternative_service.protocol ==
261 UNINITIALIZED_ALTERNATE_PROTOCOL)
262 first_alternative_service = alternative_service;
248 continue; 263 continue;
249 } 264 }
250 265
251 DCHECK_EQ(QUIC, alternative_service.protocol); 266 DCHECK_EQ(QUIC, alternative_service.protocol);
252 quic_all_broken = false; 267 quic_all_broken = false;
253 if (!session_->params().enable_quic) 268 if (!session_->params().enable_quic)
254 continue; 269 continue;
255 270
256 if (session_->quic_stream_factory()->IsQuicDisabled(origin.port())) 271 if (session_->quic_stream_factory()->IsQuicDisabled(origin.port()))
257 continue; 272 continue;
258 273
259 if (!original_url.SchemeIs("https")) 274 if (!original_url.SchemeIs("https"))
260 continue; 275 continue;
261 276
262 enabled_alternative_service_vector.push_back(alternative_service); 277 // Check whether there's an existing session to use for this QUIC Alt-Svc.
278 HostPortPair destination = alternative_service.host_port_pair();
279 std::string origin_host =
280 ApplyHostMappingRules(request_info.url, &destination).host();
281 QuicServerId server_id(destination, request_info.privacy_mode);
282 if (session_->quic_stream_factory()->CanUseExistingSession(
283 server_id, request_info.privacy_mode, origin_host))
284 return alternative_service;
285
286 // Cache this entry if we don't have a non-broken Alt-Svc yet.
287 if (first_alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL)
288 first_alternative_service = alternative_service;
263 } 289 }
290
291 // Ask delegate to mark QUIC as broken for the origin.
264 if (quic_advertised && quic_all_broken && delegate != nullptr) 292 if (quic_advertised && quic_all_broken && delegate != nullptr)
265 delegate->OnQuicBroken(); 293 delegate->OnQuicBroken();
266 return enabled_alternative_service_vector; 294
295 return first_alternative_service;
267 } 296 }
268 297
269 void HttpStreamFactoryImpl::OrphanJob(Job* job, const Request* request) { 298 void HttpStreamFactoryImpl::OrphanJob(Job* job, const Request* request) {
270 DCHECK(ContainsKey(request_map_, job)); 299 DCHECK(ContainsKey(request_map_, job));
271 DCHECK_EQ(request_map_[job], request); 300 DCHECK_EQ(request_map_[job], request);
272 DCHECK(!ContainsKey(orphaned_job_set_, job)); 301 DCHECK(!ContainsKey(orphaned_job_set_, job));
273 302
274 request_map_.erase(job); 303 request_map_.erase(job);
275 304
276 orphaned_job_set_.insert(job); 305 orphaned_job_set_.insert(job);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 delete job; 357 delete job;
329 } 358 }
330 359
331 void HttpStreamFactoryImpl::OnPreconnectsComplete(const Job* job) { 360 void HttpStreamFactoryImpl::OnPreconnectsComplete(const Job* job) {
332 preconnect_job_set_.erase(job); 361 preconnect_job_set_.erase(job);
333 delete job; 362 delete job;
334 OnPreconnectsCompleteInternal(); 363 OnPreconnectsCompleteInternal();
335 } 364 }
336 365
337 } // namespace net 366 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_stream_factory_impl.h ('k') | net/http/http_stream_factory_impl_job.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698