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

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

Issue 6684019: Reland rest of r77399. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « net/http/http_stream_factory_impl_job.h ('k') | net/http/http_stream_factory_impl_request.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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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.h" 5 #include "net/http/http_stream_factory_impl_job.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/stl_util-inl.h" 8 #include "base/stl_util-inl.h"
9 #include "base/string_number_conversions.h"
10 #include "base/string_util.h" 9 #include "base/string_util.h"
11 #include "base/stringprintf.h" 10 #include "base/stringprintf.h"
12 #include "base/values.h" 11 #include "base/values.h"
13 #include "net/base/connection_type_histograms.h" 12 #include "net/base/connection_type_histograms.h"
14 #include "net/base/net_log.h" 13 #include "net/base/net_log.h"
15 #include "net/base/net_util.h" 14 #include "net/base/net_util.h"
16 #include "net/base/ssl_cert_request_info.h" 15 #include "net/base/ssl_cert_request_info.h"
17 #include "net/http/http_basic_stream.h" 16 #include "net/http/http_basic_stream.h"
18 #include "net/http/http_network_session.h" 17 #include "net/http/http_network_session.h"
19 #include "net/http/http_proxy_client_socket.h" 18 #include "net/http/http_proxy_client_socket.h"
20 #include "net/http/http_proxy_client_socket_pool.h" 19 #include "net/http/http_proxy_client_socket_pool.h"
21 #include "net/http/http_request_info.h" 20 #include "net/http/http_request_info.h"
22 #include "net/http/http_stream_factory_impl_request.h" 21 #include "net/http/http_stream_factory_impl_request.h"
23 #include "net/socket/client_socket_handle.h" 22 #include "net/socket/client_socket_handle.h"
24 #include "net/socket/client_socket_pool.h" 23 #include "net/socket/client_socket_pool.h"
25 #include "net/socket/socks_client_socket_pool.h" 24 #include "net/socket/socks_client_socket_pool.h"
26 #include "net/socket/ssl_client_socket.h" 25 #include "net/socket/ssl_client_socket.h"
27 #include "net/socket/ssl_client_socket_pool.h" 26 #include "net/socket/ssl_client_socket_pool.h"
28 #include "net/socket/tcp_client_socket_pool.h" 27 #include "net/socket/tcp_client_socket_pool.h"
29 #include "net/spdy/spdy_http_stream.h" 28 #include "net/spdy/spdy_http_stream.h"
30 #include "net/spdy/spdy_session.h" 29 #include "net/spdy/spdy_session.h"
31 #include "net/spdy/spdy_session_pool.h" 30 #include "net/spdy/spdy_session_pool.h"
32 31
33 namespace net { 32 namespace net {
34 33
35 namespace { 34 namespace {
36 35
37 GURL UpgradeUrlToHttps(const GURL& original_url) {
38 GURL::Replacements replacements;
39 // new_sheme and new_port need to be in scope here because GURL::Replacements
40 // references the memory contained by them directly.
41 const std::string new_scheme = "https";
42 const std::string new_port = base::IntToString(443);
43 replacements.SetSchemeStr(new_scheme);
44 replacements.SetPortStr(new_port);
45 return original_url.ReplaceComponents(replacements);
46 }
47
48 } // namespace 36 } // namespace
49 37
50 HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory, 38 HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory,
51 HttpNetworkSession* session) 39 HttpNetworkSession* session,
40 const HttpRequestInfo& request_info,
41 const SSLConfig& ssl_config,
42 const BoundNetLog& net_log)
52 : request_(NULL), 43 : request_(NULL),
44 request_info_(request_info),
45 ssl_config_(ssl_config),
46 net_log_(BoundNetLog::Make(net_log.net_log(),
47 NetLog::SOURCE_HTTP_STREAM_JOB)),
53 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_(this, &Job::OnIOComplete)), 48 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_(this, &Job::OnIOComplete)),
54 connection_(new ClientSocketHandle), 49 connection_(new ClientSocketHandle),
55 session_(session), 50 session_(session),
56 stream_factory_(stream_factory), 51 stream_factory_(stream_factory),
57 next_state_(STATE_NONE), 52 next_state_(STATE_NONE),
58 pac_request_(NULL), 53 pac_request_(NULL),
54 blocking_job_(NULL),
55 dependent_job_(NULL),
59 using_ssl_(false), 56 using_ssl_(false),
60 using_spdy_(false), 57 using_spdy_(false),
61 force_spdy_always_(HttpStreamFactory::force_spdy_always()), 58 force_spdy_always_(HttpStreamFactory::force_spdy_always()),
62 force_spdy_over_ssl_(HttpStreamFactory::force_spdy_over_ssl()), 59 force_spdy_over_ssl_(HttpStreamFactory::force_spdy_over_ssl()),
63 spdy_certificate_error_(OK), 60 spdy_certificate_error_(OK),
64 alternate_protocol_(HttpAlternateProtocols::UNINITIALIZED),
65 establishing_tunnel_(false), 61 establishing_tunnel_(false),
66 was_alternate_protocol_available_(false),
67 was_npn_negotiated_(false), 62 was_npn_negotiated_(false),
68 num_streams_(0), 63 num_streams_(0),
69 spdy_session_direct_(false), 64 spdy_session_direct_(false),
70 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { 65 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
71 DCHECK(stream_factory); 66 DCHECK(stream_factory);
72 DCHECK(session); 67 DCHECK(session);
73 if (HttpStreamFactory::use_alternate_protocols())
74 alternate_protocol_mode_ = kUnspecified;
75 else
76 alternate_protocol_mode_ = kDoNotUseAlternateProtocol;
77 } 68 }
78 69
79 HttpStreamFactoryImpl::Job::~Job() { 70 HttpStreamFactoryImpl::Job::~Job() {
80 net_log_.EndEvent(NetLog::TYPE_HTTP_STREAM_JOB, NULL); 71 net_log_.EndEvent(NetLog::TYPE_HTTP_STREAM_JOB, NULL);
81 72
82 // When we're in a partially constructed state, waiting for the user to 73 // When we're in a partially constructed state, waiting for the user to
83 // provide certificate handling information or authentication, we can't reuse 74 // provide certificate handling information or authentication, we can't reuse
84 // this stream at all. 75 // this stream at all.
85 if (next_state_ == STATE_WAITING_USER_ACTION) { 76 if (next_state_ == STATE_WAITING_USER_ACTION) {
86 connection_->socket()->Disconnect(); 77 connection_->socket()->Disconnect();
87 connection_.reset(); 78 connection_.reset();
88 } 79 }
89 80
90 if (pac_request_) 81 if (pac_request_)
91 session_->proxy_service()->CancelPacRequest(pac_request_); 82 session_->proxy_service()->CancelPacRequest(pac_request_);
92 83
93 // The stream could be in a partial state. It is not reusable. 84 // The stream could be in a partial state. It is not reusable.
94 if (stream_.get() && next_state_ != STATE_DONE) 85 if (stream_.get() && next_state_ != STATE_DONE)
95 stream_->Close(true /* not reusable */); 86 stream_->Close(true /* not reusable */);
96 } 87 }
97 88
98 void HttpStreamFactoryImpl::Job::Start(Request* request, 89 void HttpStreamFactoryImpl::Job::Start(Request* request) {
99 const HttpRequestInfo& request_info,
100 const SSLConfig& ssl_config,
101 const BoundNetLog& net_log) {
102 DCHECK(request); 90 DCHECK(request);
103 request_ = request; 91 request_ = request;
104 StartInternal(request_info, ssl_config, net_log); 92 StartInternal();
105 } 93 }
106 94
107 int HttpStreamFactoryImpl::Job::Preconnect(int num_streams, 95 int HttpStreamFactoryImpl::Job::Preconnect(int num_streams) {
108 const HttpRequestInfo& request_info,
109 const SSLConfig& ssl_config,
110 const BoundNetLog& net_log) {
111 DCHECK_GT(num_streams, 0); 96 DCHECK_GT(num_streams, 0);
112 num_streams_ = num_streams; 97 num_streams_ = num_streams;
113 return StartInternal(request_info, ssl_config, net_log); 98 return StartInternal();
114 } 99 }
115 100
116 int HttpStreamFactoryImpl::Job::RestartTunnelWithProxyAuth( 101 int HttpStreamFactoryImpl::Job::RestartTunnelWithProxyAuth(
117 const string16& username, const string16& password) { 102 const string16& username, const string16& password) {
118 DCHECK(establishing_tunnel_); 103 DCHECK(establishing_tunnel_);
119 next_state_ = STATE_RESTART_TUNNEL_AUTH; 104 next_state_ = STATE_RESTART_TUNNEL_AUTH;
120 stream_.reset(); 105 stream_.reset();
121 return RunLoop(OK); 106 return RunLoop(OK);
122 } 107 }
123 108
124 LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { 109 LoadState HttpStreamFactoryImpl::Job::GetLoadState() const {
125 switch (next_state_) { 110 switch (next_state_) {
126 case STATE_RESOLVE_PROXY_COMPLETE: 111 case STATE_RESOLVE_PROXY_COMPLETE:
127 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; 112 return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
128 case STATE_CREATE_STREAM_COMPLETE: 113 case STATE_CREATE_STREAM_COMPLETE:
129 return connection_->GetLoadState(); 114 return connection_->GetLoadState();
130 case STATE_INIT_CONNECTION_COMPLETE: 115 case STATE_INIT_CONNECTION_COMPLETE:
131 return LOAD_STATE_SENDING_REQUEST; 116 return LOAD_STATE_SENDING_REQUEST;
132 default: 117 default:
133 return LOAD_STATE_IDLE; 118 return LOAD_STATE_IDLE;
134 } 119 }
135 } 120 }
136 121
122 void HttpStreamFactoryImpl::Job::MarkAsAlternate(const GURL& original_url) {
123 DCHECK(!original_url_.get());
124 original_url_.reset(new GURL(original_url));
125 }
126
127 void HttpStreamFactoryImpl::Job::WaitFor(Job* job) {
128 DCHECK_EQ(STATE_NONE, next_state_);
129 DCHECK_EQ(STATE_NONE, job->next_state_);
130 DCHECK(!blocking_job_);
131 DCHECK(!job->dependent_job_);
132 blocking_job_ = job;
133 job->dependent_job_ = this;
134 }
135
136 void HttpStreamFactoryImpl::Job::Resume(Job* job) {
137 DCHECK_EQ(blocking_job_, job);
138 blocking_job_ = NULL;
139
140 // We know we're blocked if the next_state_ is STATE_WAIT_FOR_JOB_COMPLETE.
141 // Unblock |this|.
142 if (next_state_ == STATE_WAIT_FOR_JOB_COMPLETE) {
143 MessageLoop::current()->PostTask(
144 FROM_HERE,
145 method_factory_.NewRunnableMethod(
146 &HttpStreamFactoryImpl::Job::OnIOComplete, OK));
147 }
148 }
149
137 void HttpStreamFactoryImpl::Job::Orphan(const Request* request) { 150 void HttpStreamFactoryImpl::Job::Orphan(const Request* request) {
138 DCHECK_EQ(request_, request); 151 DCHECK_EQ(request_, request);
139 request_ = NULL; 152 request_ = NULL;
140 } 153 // We've been orphaned, but there's a job we're blocked on. Don't bother
141 154 // racing, just cancel ourself.
142 bool HttpStreamFactoryImpl::Job::was_alternate_protocol_available() const { 155 if (blocking_job_) {
143 return was_alternate_protocol_available_; 156 DCHECK(blocking_job_->dependent_job_);
157 blocking_job_->dependent_job_ = NULL;
158 blocking_job_ = NULL;
159 stream_factory_->OnOrphanedJobComplete(this);
160 }
144 } 161 }
145 162
146 bool HttpStreamFactoryImpl::Job::was_npn_negotiated() const { 163 bool HttpStreamFactoryImpl::Job::was_npn_negotiated() const {
147 return was_npn_negotiated_; 164 return was_npn_negotiated_;
148 } 165 }
149 166
150 bool HttpStreamFactoryImpl::Job::using_spdy() const { 167 bool HttpStreamFactoryImpl::Job::using_spdy() const {
151 return using_spdy_; 168 return using_spdy_;
152 } 169 }
153 170
(...skipping 13 matching lines...) Expand all
167 static_cast<SSLClientSocket*>(connection_->socket()); 184 static_cast<SSLClientSocket*>(connection_->socket());
168 ssl_socket->GetSSLInfo(&ssl_info_); 185 ssl_socket->GetSSLInfo(&ssl_info_);
169 } 186 }
170 187
171 void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() { 188 void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() {
172 DCHECK(stream_.get()); 189 DCHECK(stream_.get());
173 DCHECK(!IsPreconnecting()); 190 DCHECK(!IsPreconnecting());
174 if (IsOrphaned()) { 191 if (IsOrphaned()) {
175 stream_factory_->OnOrphanedJobComplete(this); 192 stream_factory_->OnOrphanedJobComplete(this);
176 } else { 193 } else {
177 request_->Complete(was_alternate_protocol_available(), 194 request_->Complete(was_npn_negotiated(),
178 was_npn_negotiated(),
179 using_spdy(), 195 using_spdy(),
180 net_log_.source()); 196 net_log_.source());
181 request_->OnStreamReady(this, ssl_config_, proxy_info_, stream_.release()); 197 request_->OnStreamReady(this, ssl_config_, proxy_info_, stream_.release());
182 } 198 }
183 // |this| may be deleted after this call. 199 // |this| may be deleted after this call.
184 } 200 }
185 201
186 void HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback() { 202 void HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback() {
187 DCHECK(!stream_.get()); 203 DCHECK(!stream_.get());
188 DCHECK(!IsPreconnecting()); 204 DCHECK(!IsPreconnecting());
189 DCHECK(using_spdy()); 205 DCHECK(using_spdy());
190 DCHECK(new_spdy_session_); 206 DCHECK(new_spdy_session_);
191 scoped_refptr<SpdySession> spdy_session = new_spdy_session_; 207 scoped_refptr<SpdySession> spdy_session = new_spdy_session_;
192 new_spdy_session_ = NULL; 208 new_spdy_session_ = NULL;
193 if (IsOrphaned()) { 209 if (IsOrphaned()) {
194 stream_factory_->OnSpdySessionReady( 210 stream_factory_->OnSpdySessionReady(
195 spdy_session, spdy_session_direct_, ssl_config_, proxy_info_, 211 spdy_session, spdy_session_direct_, ssl_config_, proxy_info_,
196 was_alternate_protocol_available(), was_npn_negotiated(), 212 was_npn_negotiated(), using_spdy(), net_log_.source());
197 using_spdy(), net_log_.source());
198 stream_factory_->OnOrphanedJobComplete(this); 213 stream_factory_->OnOrphanedJobComplete(this);
199 } else { 214 } else {
200 request_->OnSpdySessionReady(this, spdy_session, spdy_session_direct_); 215 request_->OnSpdySessionReady(this, spdy_session, spdy_session_direct_);
201 } 216 }
202 // |this| may be deleted after this call. 217 // |this| may be deleted after this call.
203 } 218 }
204 219
205 void HttpStreamFactoryImpl::Job::OnStreamFailedCallback(int result) { 220 void HttpStreamFactoryImpl::Job::OnStreamFailedCallback(int result) {
206 DCHECK(!IsPreconnecting()); 221 DCHECK(!IsPreconnecting());
207 if (IsOrphaned()) 222 if (IsOrphaned())
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 request_->OnHttpsProxyTunnelResponse( 268 request_->OnHttpsProxyTunnelResponse(
254 this, response_info, ssl_config_, proxy_info_, stream); 269 this, response_info, ssl_config_, proxy_info_, stream);
255 // |this| may be deleted after this call. 270 // |this| may be deleted after this call.
256 } 271 }
257 272
258 void HttpStreamFactoryImpl::Job::OnPreconnectsComplete() { 273 void HttpStreamFactoryImpl::Job::OnPreconnectsComplete() {
259 DCHECK(!request_); 274 DCHECK(!request_);
260 if (new_spdy_session_) { 275 if (new_spdy_session_) {
261 stream_factory_->OnSpdySessionReady( 276 stream_factory_->OnSpdySessionReady(
262 new_spdy_session_, spdy_session_direct_, ssl_config_, 277 new_spdy_session_, spdy_session_direct_, ssl_config_,
263 proxy_info_, was_alternate_protocol_available(), 278 proxy_info_, was_npn_negotiated(), using_spdy(), net_log_.source());
264 was_npn_negotiated(), using_spdy(), net_log_.source());
265 } 279 }
266 stream_factory_->OnPreconnectsComplete(this); 280 stream_factory_->OnPreconnectsComplete(this);
267 // |this| may be deleted after this call. 281 // |this| may be deleted after this call.
268 } 282 }
269 283
270 void HttpStreamFactoryImpl::Job::OnIOComplete(int result) { 284 void HttpStreamFactoryImpl::Job::OnIOComplete(int result) {
271 RunLoop(result); 285 RunLoop(result);
272 } 286 }
273 287
274 int HttpStreamFactoryImpl::Job::RunLoop(int result) { 288 int HttpStreamFactoryImpl::Job::RunLoop(int result) {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 State state = next_state_; 392 State state = next_state_;
379 next_state_ = STATE_NONE; 393 next_state_ = STATE_NONE;
380 switch (state) { 394 switch (state) {
381 case STATE_RESOLVE_PROXY: 395 case STATE_RESOLVE_PROXY:
382 DCHECK_EQ(OK, rv); 396 DCHECK_EQ(OK, rv);
383 rv = DoResolveProxy(); 397 rv = DoResolveProxy();
384 break; 398 break;
385 case STATE_RESOLVE_PROXY_COMPLETE: 399 case STATE_RESOLVE_PROXY_COMPLETE:
386 rv = DoResolveProxyComplete(rv); 400 rv = DoResolveProxyComplete(rv);
387 break; 401 break;
402 case STATE_WAIT_FOR_JOB:
403 DCHECK_EQ(OK, rv);
404 rv = DoWaitForJob();
405 break;
406 case STATE_WAIT_FOR_JOB_COMPLETE:
407 rv = DoWaitForJobComplete(rv);
408 break;
388 case STATE_INIT_CONNECTION: 409 case STATE_INIT_CONNECTION:
389 DCHECK_EQ(OK, rv); 410 DCHECK_EQ(OK, rv);
390 rv = DoInitConnection(); 411 rv = DoInitConnection();
391 break; 412 break;
392 case STATE_INIT_CONNECTION_COMPLETE: 413 case STATE_INIT_CONNECTION_COMPLETE:
393 rv = DoInitConnectionComplete(rv); 414 rv = DoInitConnectionComplete(rv);
394 break; 415 break;
395 case STATE_WAITING_USER_ACTION: 416 case STATE_WAITING_USER_ACTION:
396 rv = DoWaitingUserAction(rv); 417 rv = DoWaitingUserAction(rv);
397 break; 418 break;
(...skipping 13 matching lines...) Expand all
411 break; 432 break;
412 default: 433 default:
413 NOTREACHED() << "bad state"; 434 NOTREACHED() << "bad state";
414 rv = ERR_FAILED; 435 rv = ERR_FAILED;
415 break; 436 break;
416 } 437 }
417 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 438 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
418 return rv; 439 return rv;
419 } 440 }
420 441
421 int HttpStreamFactoryImpl::Job::StartInternal( 442 int HttpStreamFactoryImpl::Job::StartInternal() {
422 const HttpRequestInfo& request_info,
423 const SSLConfig& ssl_config,
424 const BoundNetLog& net_log) {
425 CHECK_EQ(STATE_NONE, next_state_); 443 CHECK_EQ(STATE_NONE, next_state_);
426 request_info_ = request_info;
427 ssl_config_ = ssl_config;
428 net_log_ = BoundNetLog::Make(net_log.net_log(),
429 NetLog::SOURCE_HTTP_STREAM_JOB);
430 net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_JOB, 444 net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_JOB,
431 make_scoped_refptr(new NetLogStringParameter( 445 make_scoped_refptr(new NetLogStringParameter(
432 "url", request_info.url.GetOrigin().spec()))); 446 "url", request_info_.url.GetOrigin().spec())));
433 next_state_ = STATE_RESOLVE_PROXY; 447 next_state_ = STATE_RESOLVE_PROXY;
434 int rv = RunLoop(OK); 448 int rv = RunLoop(OK);
435 DCHECK_EQ(ERR_IO_PENDING, rv); 449 DCHECK_EQ(ERR_IO_PENDING, rv);
436 return rv; 450 return rv;
437 } 451 }
438 452
439 int HttpStreamFactoryImpl::Job::DoResolveProxy() { 453 int HttpStreamFactoryImpl::Job::DoResolveProxy() {
440 DCHECK(!pac_request_); 454 DCHECK(!pac_request_);
441 455
442 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; 456 next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
443 457
444 // |endpoint_| indicates the final destination endpoint. 458 origin_ = HostPortPair(request_info_.url.HostNoBrackets(),
445 endpoint_ = HostPortPair(request_info_.url.HostNoBrackets(), 459 request_info_.url.EffectiveIntPort());
446 request_info_.url.EffectiveIntPort());
447
448 // Extra URL we might be attempting to resolve to.
449 GURL alternate_endpoint_url = request_info_.url;
450
451 // Tracks whether we are using |request_.url| or |alternate_endpoint_url|.
452 const GURL *curr_endpoint_url = &request_info_.url;
453
454 alternate_endpoint_url =
455 HttpStreamFactory::ApplyHostMappingRules(
456 alternate_endpoint_url, &endpoint_);
457
458 const HttpAlternateProtocols& alternate_protocols =
459 session_->alternate_protocols();
460 if (HttpStreamFactory::spdy_enabled() &&
461 alternate_protocols.HasAlternateProtocolFor(endpoint_)) {
462 was_alternate_protocol_available_ = true;
463 if (alternate_protocol_mode_ == kUnspecified) {
464 HttpAlternateProtocols::PortProtocolPair alternate =
465 alternate_protocols.GetAlternateProtocolFor(endpoint_);
466 if (alternate.protocol != HttpAlternateProtocols::BROKEN) {
467 DCHECK_LE(HttpAlternateProtocols::NPN_SPDY_1, alternate.protocol);
468 DCHECK_GT(HttpAlternateProtocols::NUM_ALTERNATE_PROTOCOLS,
469 alternate.protocol);
470 endpoint_.set_port(alternate.port);
471 alternate_protocol_ = alternate.protocol;
472 alternate_protocol_mode_ = kUsingAlternateProtocol;
473 alternate_endpoint_url = UpgradeUrlToHttps(*curr_endpoint_url);
474 curr_endpoint_url = &alternate_endpoint_url;
475 }
476 }
477 }
478 460
479 if (request_info_.load_flags & LOAD_BYPASS_PROXY) { 461 if (request_info_.load_flags & LOAD_BYPASS_PROXY) {
480 proxy_info_.UseDirect(); 462 proxy_info_.UseDirect();
481 return OK; 463 return OK;
482 } 464 }
483 465
484 return session_->proxy_service()->ResolveProxy( 466 return session_->proxy_service()->ResolveProxy(
485 *curr_endpoint_url, &proxy_info_, &io_callback_, &pac_request_, 467 request_info_.url, &proxy_info_, &io_callback_, &pac_request_,
486 net_log_); 468 net_log_);
487 } 469 }
488 470
489 int HttpStreamFactoryImpl::Job::DoResolveProxyComplete(int result) { 471 int HttpStreamFactoryImpl::Job::DoResolveProxyComplete(int result) {
490 pac_request_ = NULL; 472 pac_request_ = NULL;
491 473
492 if (result != OK) 474 if (result == OK) {
493 return result; 475 // Remove unsupported proxies from the list.
476 proxy_info_.RemoveProxiesWithoutScheme(
477 ProxyServer::SCHEME_DIRECT |
478 ProxyServer::SCHEME_HTTP | ProxyServer::SCHEME_HTTPS |
479 ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5);
494 480
495 // TODO(mbelshe): consider retrying ResolveProxy if we came here via use of 481 if (proxy_info_.is_empty()) {
496 // AlternateProtocol. 482 // No proxies/direct to choose from. This happens when we don't support
497 483 // any of the proxies in the returned list.
498 // Remove unsupported proxies from the list. 484 result = ERR_NO_SUPPORTED_PROXIES;
499 proxy_info_.RemoveProxiesWithoutScheme( 485 }
500 ProxyServer::SCHEME_DIRECT |
501 ProxyServer::SCHEME_HTTP | ProxyServer::SCHEME_HTTPS |
502 ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5);
503
504 if (proxy_info_.is_empty()) {
505 // No proxies/direct to choose from. This happens when we don't support any
506 // of the proxies in the returned list.
507 return ERR_NO_SUPPORTED_PROXIES;
508 } 486 }
509 487
488 if (result != OK) {
489 if (dependent_job_)
490 dependent_job_->Resume(this);
491 return result;
492 }
493
494 if (blocking_job_)
495 next_state_ = STATE_WAIT_FOR_JOB;
496 else
497 next_state_ = STATE_INIT_CONNECTION;
498 return OK;
499 }
500
501 bool HttpStreamFactoryImpl::Job::ShouldForceSpdySSL() const {
502 return force_spdy_always_ && force_spdy_over_ssl_;
503 }
504
505 bool HttpStreamFactoryImpl::Job::ShouldForceSpdyWithoutSSL() const {
506 return force_spdy_always_ && !force_spdy_over_ssl_;
507 }
508
509 int HttpStreamFactoryImpl::Job::DoWaitForJob() {
510 DCHECK(blocking_job_);
511 next_state_ = STATE_WAIT_FOR_JOB_COMPLETE;
512 return ERR_IO_PENDING;
513 }
514
515 int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) {
516 DCHECK(!blocking_job_);
517 DCHECK_EQ(OK, result);
510 next_state_ = STATE_INIT_CONNECTION; 518 next_state_ = STATE_INIT_CONNECTION;
511 return OK; 519 return OK;
512 } 520 }
513 521
514 static bool HasSpdyExclusion(const HostPortPair& endpoint) {
515 std::list<HostPortPair>* exclusions =
516 HttpStreamFactory::forced_spdy_exclusions();
517 if (!exclusions)
518 return false;
519
520 std::list<HostPortPair>::const_iterator it;
521 for (it = exclusions->begin(); it != exclusions->end(); it++)
522 if (it->Equals(endpoint))
523 return true;
524 return false;
525 }
526
527 bool HttpStreamFactoryImpl::Job::ShouldForceSpdySSL() {
528 bool rv = force_spdy_always_ && force_spdy_over_ssl_;
529 return rv && !HasSpdyExclusion(endpoint_);
530 }
531
532 bool HttpStreamFactoryImpl::Job::ShouldForceSpdyWithoutSSL() {
533 bool rv = force_spdy_always_ && !force_spdy_over_ssl_;
534 return rv && !HasSpdyExclusion(endpoint_);
535 }
536
537 int HttpStreamFactoryImpl::Job::DoInitConnection() { 522 int HttpStreamFactoryImpl::Job::DoInitConnection() {
523 DCHECK(!blocking_job_);
538 DCHECK(!connection_->is_initialized()); 524 DCHECK(!connection_->is_initialized());
539 DCHECK(proxy_info_.proxy_server().is_valid()); 525 DCHECK(proxy_info_.proxy_server().is_valid());
540 next_state_ = STATE_INIT_CONNECTION_COMPLETE; 526 next_state_ = STATE_INIT_CONNECTION_COMPLETE;
541 527
542 bool want_spdy_over_npn = 528 using_ssl_ = request_info_.url.SchemeIs("https") || ShouldForceSpdySSL();
543 alternate_protocol_mode_ == kUsingAlternateProtocol &&
544 alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_2;
545 using_ssl_ = request_info_.url.SchemeIs("https") ||
546 ShouldForceSpdySSL() || want_spdy_over_npn;
547 using_spdy_ = false; 529 using_spdy_ = false;
548 530
549 // If spdy has been turned off on-the-fly, then there may be SpdySessions 531 // Check first if we have a spdy session for this group. If so, then go
550 // still active. But don't use them unless spdy is currently on. 532 // straight to using that.
551 if (HttpStreamFactory::spdy_enabled() && !HasSpdyExclusion(endpoint_)) { 533 HostPortProxyPair spdy_session_key;
552 // Check first if we have a spdy session for this group. If so, then go 534 if (IsHttpsProxyAndHttpUrl()) {
553 // straight to using that. 535 spdy_session_key =
554 HostPortProxyPair spdy_session_key; 536 HostPortProxyPair(proxy_info_.proxy_server().host_port_pair(),
555 if (IsHttpsProxyAndHttpUrl()) { 537 ProxyServer::Direct());
556 spdy_session_key = 538 } else {
557 HostPortProxyPair(proxy_info_.proxy_server().host_port_pair(), 539 spdy_session_key = HostPortProxyPair(origin_, proxy_info_.proxy_server());
558 ProxyServer::Direct()); 540 }
559 } else { 541 if (session_->spdy_session_pool()->HasSession(spdy_session_key)) {
560 spdy_session_key = 542 // If we're preconnecting, but we already have a SpdySession, we don't
561 HostPortProxyPair(endpoint_, proxy_info_.proxy_server()); 543 // actually need to preconnect any sockets, so we're done.
562 } 544 if (IsPreconnecting())
563 if (session_->spdy_session_pool()->HasSession(spdy_session_key)) {
564 // If we're preconnecting, but we already have a SpdySession, we don't
565 // actually need to preconnect any sockets, so we're done.
566 if (IsPreconnecting())
567 return OK;
568 using_spdy_ = true;
569 next_state_ = STATE_CREATE_STREAM;
570 return OK; 545 return OK;
571 } else if (request_) { 546 using_spdy_ = true;
572 // Update the spdy session key for the request that launched this job. 547 next_state_ = STATE_CREATE_STREAM;
573 request_->SetSpdySessionKey(spdy_session_key); 548 return OK;
574 } 549 } else if (request_ && (using_ssl_ || ShouldForceSpdyWithoutSSL())) {
550 // Update the spdy session key for the request that launched this job.
551 request_->SetSpdySessionKey(spdy_session_key);
552 }
553
554 // OK, there's no available SPDY session. Let |dependent_job_| resume if it's
555 // paused.
556
557 if (dependent_job_) {
558 dependent_job_->Resume(this);
559 dependent_job_ = NULL;
575 } 560 }
576 561
577 // Build the string used to uniquely identify connections of this type. 562 // Build the string used to uniquely identify connections of this type.
578 // Determine the host and port to connect to. 563 // Determine the host and port to connect to.
579 std::string connection_group = endpoint_.ToString(); 564 std::string connection_group = origin_.ToString();
580 DCHECK(!connection_group.empty()); 565 DCHECK(!connection_group.empty());
581 566
582 if (using_ssl_) 567 if (using_ssl_)
583 connection_group = base::StringPrintf("ssl/%s", connection_group.c_str()); 568 connection_group = base::StringPrintf("ssl/%s", connection_group.c_str());
584 569
585 // If the user is refreshing the page, bypass the host cache. 570 // If the user is refreshing the page, bypass the host cache.
586 bool disable_resolver_cache = 571 bool disable_resolver_cache =
587 request_info_.load_flags & LOAD_BYPASS_CACHE || 572 request_info_.load_flags & LOAD_BYPASS_CACHE ||
588 request_info_.load_flags & LOAD_VALIDATE_CACHE || 573 request_info_.load_flags & LOAD_VALIDATE_CACHE ||
589 request_info_.load_flags & LOAD_DISABLE_CACHE; 574 request_info_.load_flags & LOAD_DISABLE_CACHE;
590 575
591 // Build up the connection parameters. 576 // Build up the connection parameters.
592 scoped_refptr<TCPSocketParams> tcp_params; 577 scoped_refptr<TCPSocketParams> tcp_params;
593 scoped_refptr<HttpProxySocketParams> http_proxy_params; 578 scoped_refptr<HttpProxySocketParams> http_proxy_params;
594 scoped_refptr<SOCKSSocketParams> socks_params; 579 scoped_refptr<SOCKSSocketParams> socks_params;
595 scoped_ptr<HostPortPair> proxy_host_port; 580 scoped_ptr<HostPortPair> proxy_host_port;
596 581
597 if (proxy_info_.is_direct()) { 582 if (proxy_info_.is_direct()) {
598 tcp_params = new TCPSocketParams(endpoint_, request_info_.priority, 583 tcp_params = new TCPSocketParams(origin_, request_info_.priority,
599 request_info_.referrer, 584 request_info_.referrer,
600 disable_resolver_cache); 585 disable_resolver_cache);
601 } else { 586 } else {
602 ProxyServer proxy_server = proxy_info_.proxy_server(); 587 ProxyServer proxy_server = proxy_info_.proxy_server();
603 proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair())); 588 proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair()));
604 scoped_refptr<TCPSocketParams> proxy_tcp_params( 589 scoped_refptr<TCPSocketParams> proxy_tcp_params(
605 new TCPSocketParams(*proxy_host_port, request_info_.priority, 590 new TCPSocketParams(*proxy_host_port, request_info_.priority,
606 request_info_.referrer, disable_resolver_cache)); 591 request_info_.referrer, disable_resolver_cache));
607 592
608 if (proxy_info_.is_http() || proxy_info_.is_https()) { 593 if (proxy_info_.is_http() || proxy_info_.is_https()) {
609 GURL authentication_url = request_info_.url;
610 if (using_ssl_ && !authentication_url.SchemeIs("https")) {
611 // If a proxy tunnel connection needs to be established due to
612 // an Alternate-Protocol, the URL needs to be changed to indicate
613 // https or digest authentication attempts will fail.
614 // For example, suppose the initial request was for
615 // "http://www.example.com/index.html". If this is an SSL
616 // upgrade due to alternate protocol, the digest authorization
617 // should have a uri="www.example.com:443" field rather than a
618 // "/index.html" entry, even though the original request URL has not
619 // changed.
620 authentication_url = UpgradeUrlToHttps(authentication_url);
621 }
622 establishing_tunnel_ = using_ssl_; 594 establishing_tunnel_ = using_ssl_;
623 std::string user_agent; 595 std::string user_agent;
624 request_info_.extra_headers.GetHeader(HttpRequestHeaders::kUserAgent, 596 request_info_.extra_headers.GetHeader(HttpRequestHeaders::kUserAgent,
625 &user_agent); 597 &user_agent);
626 scoped_refptr<SSLSocketParams> ssl_params; 598 scoped_refptr<SSLSocketParams> ssl_params;
627 if (proxy_info_.is_https()) { 599 if (proxy_info_.is_https()) {
628 // Set ssl_params, and unset proxy_tcp_params 600 // Set ssl_params, and unset proxy_tcp_params
629 ssl_params = GenerateSSLParams(proxy_tcp_params, NULL, NULL, 601 ssl_params = GenerateSSLParams(proxy_tcp_params, NULL, NULL,
630 ProxyServer::SCHEME_DIRECT, 602 ProxyServer::SCHEME_DIRECT,
631 *proxy_host_port.get(), 603 *proxy_host_port.get(),
632 want_spdy_over_npn); 604 original_url_.get() ? true : false);
633 proxy_tcp_params = NULL; 605 proxy_tcp_params = NULL;
634 } 606 }
635 607
636 http_proxy_params = 608 http_proxy_params =
637 new HttpProxySocketParams(proxy_tcp_params, 609 new HttpProxySocketParams(proxy_tcp_params,
638 ssl_params, 610 ssl_params,
639 authentication_url, 611 request_info_.url,
640 user_agent, 612 user_agent,
641 endpoint_, 613 origin_,
642 session_->http_auth_cache(), 614 session_->http_auth_cache(),
643 session_->http_auth_handler_factory(), 615 session_->http_auth_handler_factory(),
644 session_->spdy_session_pool(), 616 session_->spdy_session_pool(),
645 using_ssl_); 617 using_ssl_);
646 } else { 618 } else {
647 DCHECK(proxy_info_.is_socks()); 619 DCHECK(proxy_info_.is_socks());
648 char socks_version; 620 char socks_version;
649 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5) 621 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5)
650 socks_version = '5'; 622 socks_version = '5';
651 else 623 else
652 socks_version = '4'; 624 socks_version = '4';
653 connection_group = base::StringPrintf( 625 connection_group = base::StringPrintf(
654 "socks%c/%s", socks_version, connection_group.c_str()); 626 "socks%c/%s", socks_version, connection_group.c_str());
655 627
656 socks_params = new SOCKSSocketParams(proxy_tcp_params, 628 socks_params = new SOCKSSocketParams(proxy_tcp_params,
657 socks_version == '5', 629 socks_version == '5',
658 endpoint_, 630 origin_,
659 request_info_.priority, 631 request_info_.priority,
660 request_info_.referrer); 632 request_info_.referrer);
661 } 633 }
662 } 634 }
663 635
664 // Deal with SSL - which layers on top of any given proxy. 636 // Deal with SSL - which layers on top of any given proxy.
665 if (using_ssl_) { 637 if (using_ssl_) {
666 scoped_refptr<SSLSocketParams> ssl_params = 638 scoped_refptr<SSLSocketParams> ssl_params =
667 GenerateSSLParams(tcp_params, http_proxy_params, socks_params, 639 GenerateSSLParams(tcp_params, http_proxy_params, socks_params,
668 proxy_info_.proxy_server().scheme(), 640 proxy_info_.proxy_server().scheme(),
669 HostPortPair::FromURL(request_info_.url), 641 origin_, original_url_.get() ? true : false);
670 want_spdy_over_npn);
671 SSLClientSocketPool* ssl_pool = NULL; 642 SSLClientSocketPool* ssl_pool = NULL;
672 if (proxy_info_.is_direct()) 643 if (proxy_info_.is_direct())
673 ssl_pool = session_->ssl_socket_pool(); 644 ssl_pool = session_->ssl_socket_pool();
674 else 645 else
675 ssl_pool = session_->GetSocketPoolForSSLWithProxy(*proxy_host_port); 646 ssl_pool = session_->GetSocketPoolForSSLWithProxy(*proxy_host_port);
676 647
677 if (IsPreconnecting()) { 648 if (IsPreconnecting()) {
678 RequestSocketsForPool(ssl_pool, connection_group, ssl_params, 649 RequestSocketsForPool(ssl_pool, connection_group, ssl_params,
679 num_streams_, net_log_); 650 num_streams_, net_log_);
680 return OK; 651 return OK;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 request_info_.priority, &io_callback_, 698 request_info_.priority, &io_callback_,
728 pool, net_log_); 699 pool, net_log_);
729 } 700 }
730 701
731 int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { 702 int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
732 if (IsPreconnecting()) { 703 if (IsPreconnecting()) {
733 DCHECK_EQ(OK, result); 704 DCHECK_EQ(OK, result);
734 return OK; 705 return OK;
735 } 706 }
736 707
708 // TODO(willchan): Make this a bit more exact. Maybe there are recoverable
709 // errors, such as ignoring certificate errors for Alternate-Protocol.
710 if (result < 0 && dependent_job_) {
711 dependent_job_->Resume(this);
712 dependent_job_ = NULL;
713 }
714
737 // |result| may be the result of any of the stacked pools. The following 715 // |result| may be the result of any of the stacked pools. The following
738 // logic is used when determining how to interpret an error. 716 // logic is used when determining how to interpret an error.
739 // If |result| < 0: 717 // If |result| < 0:
740 // and connection_->socket() != NULL, then the SSL handshake ran and it 718 // and connection_->socket() != NULL, then the SSL handshake ran and it
741 // is a potentially recoverable error. 719 // is a potentially recoverable error.
742 // and connection_->socket == NULL and connection_->is_ssl_error() is true, 720 // and connection_->socket == NULL and connection_->is_ssl_error() is true,
743 // then the SSL handshake ran with an unrecoverable error. 721 // then the SSL handshake ran with an unrecoverable error.
744 // otherwise, the error came from one of the other pools. 722 // otherwise, the error came from one of the other pools.
745 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || 723 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() ||
746 connection_->is_ssl_error()); 724 connection_->is_ssl_error());
(...skipping 28 matching lines...) Expand all
775 // Other state (i.e. |using_ssl_|) suggests that |connection_| will have an 753 // Other state (i.e. |using_ssl_|) suggests that |connection_| will have an
776 // SSL socket, but there was an error before that could happen. This 754 // SSL socket, but there was an error before that could happen. This
777 // puts the in progress HttpProxy socket into |connection_| in order to 755 // puts the in progress HttpProxy socket into |connection_| in order to
778 // complete the auth (or read the response body). The tunnel restart code 756 // complete the auth (or read the response body). The tunnel restart code
779 // is careful to remove it before returning control to the rest of this 757 // is careful to remove it before returning control to the rest of this
780 // class. 758 // class.
781 connection_.reset(connection_->release_pending_http_proxy_connection()); 759 connection_.reset(connection_->release_pending_http_proxy_connection());
782 return result; 760 return result;
783 } 761 }
784 762
785 if ((!ssl_started && result < 0 && 763 if (!ssl_started && result < 0 && original_url_.get()) {
786 alternate_protocol_mode_ == kUsingAlternateProtocol) ||
787 result == ERR_NPN_NEGOTIATION_FAILED) {
788 // Mark the alternate protocol as broken and fallback. 764 // Mark the alternate protocol as broken and fallback.
789 MarkBrokenAlternateProtocolAndFallback(); 765 session_->mutable_alternate_protocols()->MarkBrokenAlternateProtocolFor(
790 return OK; 766 HostPortPair::FromURL(*original_url_));
767 return result;
791 } 768 }
792 769
793 if (result < 0 && !ssl_started) 770 if (result < 0 && !ssl_started)
794 return ReconsiderProxyAfterError(result); 771 return ReconsiderProxyAfterError(result);
795 establishing_tunnel_ = false; 772 establishing_tunnel_ = false;
796 773
797 if (connection_->socket()) { 774 if (connection_->socket()) {
798 LogHttpConnectedMetrics(*connection_); 775 LogHttpConnectedMetrics(*connection_);
799 776
800 // We officially have a new connection. Record the type. 777 // We officially have a new connection. Record the type.
801 if (!connection_->is_reused()) { 778 if (!connection_->is_reused()) {
802 ConnectionType type = using_spdy_ ? CONNECTION_SPDY : CONNECTION_HTTP; 779 ConnectionType type = using_spdy_ ? CONNECTION_SPDY : CONNECTION_HTTP;
803 UpdateConnectionTypeHistograms(type); 780 UpdateConnectionTypeHistograms(type);
804 } 781 }
805 } 782 }
806 783
807 // Handle SSL errors below. 784 // Handle SSL errors below.
808 if (using_ssl_) { 785 if (using_ssl_) {
809 DCHECK(ssl_started); 786 DCHECK(ssl_started);
810 if (IsCertificateError(result)) { 787 if (IsCertificateError(result)) {
811 if (using_spdy_ && request_info_.url.SchemeIs("http")) { 788 if (using_spdy_ && original_url_.get() &&
789 original_url_->SchemeIs("http")) {
812 // We ignore certificate errors for http over spdy. 790 // We ignore certificate errors for http over spdy.
813 spdy_certificate_error_ = result; 791 spdy_certificate_error_ = result;
814 result = OK; 792 result = OK;
815 } else { 793 } else {
816 result = HandleCertificateError(result); 794 result = HandleCertificateError(result);
817 if (result == OK && !connection_->socket()->IsConnectedAndIdle()) { 795 if (result == OK && !connection_->socket()->IsConnectedAndIdle()) {
818 ReturnToStateInitConnection(true /* close connection */); 796 ReturnToStateInitConnection(true /* close connection */);
819 return result; 797 return result;
820 } 798 }
821 } 799 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 using_proxy)); 833 using_proxy));
856 return OK; 834 return OK;
857 } 835 }
858 836
859 CHECK(!stream_.get()); 837 CHECK(!stream_.get());
860 838
861 bool direct = true; 839 bool direct = true;
862 SpdySessionPool* spdy_pool = session_->spdy_session_pool(); 840 SpdySessionPool* spdy_pool = session_->spdy_session_pool();
863 scoped_refptr<SpdySession> spdy_session; 841 scoped_refptr<SpdySession> spdy_session;
864 842
865 HostPortProxyPair pair(endpoint_, proxy_server); 843 HostPortProxyPair pair(origin_, proxy_server);
866 if (spdy_pool->HasSession(pair)) { 844 if (spdy_pool->HasSession(pair)) {
867 // We have a SPDY session to the origin server. This might be a direct 845 // We have a SPDY session to the origin server. This might be a direct
868 // connection, or it might be a SPDY session through an HTTP or HTTPS proxy. 846 // connection, or it might be a SPDY session through an HTTP or HTTPS proxy.
869 spdy_session = spdy_pool->Get(pair, net_log_); 847 spdy_session = spdy_pool->Get(pair, net_log_);
870 } else if (IsHttpsProxyAndHttpUrl()) { 848 } else if (IsHttpsProxyAndHttpUrl()) {
871 // If we don't have a direct SPDY session, and we're using an HTTPS 849 // If we don't have a direct SPDY session, and we're using an HTTPS
872 // proxy, then we might have a SPDY session to the proxy. 850 // proxy, then we might have a SPDY session to the proxy.
873 pair = HostPortProxyPair(proxy_server.host_port_pair(), 851 pair = HostPortProxyPair(proxy_server.host_port_pair(),
874 ProxyServer::Direct()); 852 ProxyServer::Direct());
875 if (spdy_pool->HasSession(pair)) { 853 if (spdy_pool->HasSession(pair)) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 937
960 void HttpStreamFactoryImpl::Job::SetSocketMotivation() { 938 void HttpStreamFactoryImpl::Job::SetSocketMotivation() {
961 if (request_info_.motivation == HttpRequestInfo::PRECONNECT_MOTIVATED) 939 if (request_info_.motivation == HttpRequestInfo::PRECONNECT_MOTIVATED)
962 connection_->socket()->SetSubresourceSpeculation(); 940 connection_->socket()->SetSubresourceSpeculation();
963 else if (request_info_.motivation == HttpRequestInfo::OMNIBOX_MOTIVATED) 941 else if (request_info_.motivation == HttpRequestInfo::OMNIBOX_MOTIVATED)
964 connection_->socket()->SetOmniboxSpeculation(); 942 connection_->socket()->SetOmniboxSpeculation();
965 // TODO(mbelshe): Add other motivations (like EARLY_LOAD_MOTIVATED). 943 // TODO(mbelshe): Add other motivations (like EARLY_LOAD_MOTIVATED).
966 } 944 }
967 945
968 bool HttpStreamFactoryImpl::Job::IsHttpsProxyAndHttpUrl() { 946 bool HttpStreamFactoryImpl::Job::IsHttpsProxyAndHttpUrl() {
969 return proxy_info_.is_https() && request_info_.url.SchemeIs("http"); 947 if (!proxy_info_.is_https())
948 return false;
949 if (original_url_.get()) {
950 // We currently only support Alternate-Protocol where the original scheme
951 // is http.
952 DCHECK(original_url_->SchemeIs("http"));
953 return original_url_->SchemeIs("http");
954 }
955 return request_info_.url.SchemeIs("http");
970 } 956 }
971 957
972 // Returns a newly create SSLSocketParams, and sets several 958 // Returns a newly create SSLSocketParams, and sets several
973 // fields of ssl_config_. 959 // fields of ssl_config_.
974 scoped_refptr<SSLSocketParams> HttpStreamFactoryImpl::Job::GenerateSSLParams( 960 scoped_refptr<SSLSocketParams> HttpStreamFactoryImpl::Job::GenerateSSLParams(
975 scoped_refptr<TCPSocketParams> tcp_params, 961 scoped_refptr<TCPSocketParams> tcp_params,
976 scoped_refptr<HttpProxySocketParams> http_proxy_params, 962 scoped_refptr<HttpProxySocketParams> http_proxy_params,
977 scoped_refptr<SOCKSSocketParams> socks_params, 963 scoped_refptr<SOCKSSocketParams> socks_params,
978 ProxyServer::Scheme proxy_scheme, 964 ProxyServer::Scheme proxy_scheme,
979 const HostPortPair& host_and_port, 965 const HostPortPair& origin_server,
980 bool want_spdy_over_npn) { 966 bool want_spdy_over_npn) {
981 967
982 if (stream_factory_->IsTLSIntolerantServer(request_info_.url)) { 968 if (stream_factory_->IsTLSIntolerantServer(origin_server)) {
983 LOG(WARNING) << "Falling back to SSLv3 because host is TLS intolerant: " 969 LOG(WARNING) << "Falling back to SSLv3 because host is TLS intolerant: "
984 << GetHostAndPort(request_info_.url); 970 << origin_server.ToString();
985 ssl_config_.ssl3_fallback = true; 971 ssl_config_.ssl3_fallback = true;
986 ssl_config_.tls1_enabled = false; 972 ssl_config_.tls1_enabled = false;
987 } 973 }
988 974
989 if (proxy_info_.is_https() && ssl_config_.send_client_cert) { 975 if (proxy_info_.is_https() && ssl_config_.send_client_cert) {
990 // When connecting through an HTTPS proxy, disable TLS False Start so 976 // When connecting through an HTTPS proxy, disable TLS False Start so
991 // that client authentication errors can be distinguished between those 977 // that client authentication errors can be distinguished between those
992 // originating from the proxy server (ERR_PROXY_CONNECTION_FAILED) and 978 // originating from the proxy server (ERR_PROXY_CONNECTION_FAILED) and
993 // those originating from the endpoint (ERR_SSL_PROTOCOL_ERROR / 979 // those originating from the endpoint (ERR_SSL_PROTOCOL_ERROR /
994 // ERR_BAD_SSL_CLIENT_AUTH_CERT). 980 // ERR_BAD_SSL_CLIENT_AUTH_CERT).
(...skipping 12 matching lines...) Expand all
1007 if (request_info_.load_flags & LOAD_VERIFY_EV_CERT) 993 if (request_info_.load_flags & LOAD_VERIFY_EV_CERT)
1008 ssl_config_.verify_ev_cert = true; 994 ssl_config_.verify_ev_cert = true;
1009 995
1010 if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_HTTP || 996 if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_HTTP ||
1011 proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_HTTPS) { 997 proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_HTTPS) {
1012 ssl_config_.mitm_proxies_allowed = true; 998 ssl_config_.mitm_proxies_allowed = true;
1013 } 999 }
1014 1000
1015 scoped_refptr<SSLSocketParams> ssl_params( 1001 scoped_refptr<SSLSocketParams> ssl_params(
1016 new SSLSocketParams(tcp_params, socks_params, http_proxy_params, 1002 new SSLSocketParams(tcp_params, socks_params, http_proxy_params,
1017 proxy_scheme, host_and_port, 1003 proxy_scheme, origin_server,
1018 ssl_config_, load_flags, 1004 ssl_config_, load_flags,
1019 ShouldForceSpdySSL(), 1005 ShouldForceSpdySSL(),
1020 want_spdy_over_npn)); 1006 want_spdy_over_npn));
1021 1007
1022 return ssl_params; 1008 return ssl_params;
1023 } 1009 }
1024 1010
1025 1011
1026 void HttpStreamFactoryImpl::Job::MarkBrokenAlternateProtocolAndFallback() {
1027 // We have to:
1028 // * Reset the endpoint to be the unmodified URL specified destination.
1029 // * Mark the endpoint as broken so we don't try again.
1030 // * Set the alternate protocol mode to kDoNotUseAlternateProtocol so we
1031 // ignore future Alternate-Protocol headers from the HostPortPair.
1032 // * Reset the connection and go back to STATE_INIT_CONNECTION.
1033
1034 endpoint_ = HostPortPair(request_info_.url.HostNoBrackets(),
1035 request_info_.url.EffectiveIntPort());
1036
1037 session_->mutable_alternate_protocols()->MarkBrokenAlternateProtocolFor(
1038 endpoint_);
1039
1040 alternate_protocol_mode_ = kDoNotUseAlternateProtocol;
1041 ReturnToStateInitConnection(false /* close connection */);
1042 }
1043
1044 int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) { 1012 int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) {
1045 DCHECK(!pac_request_); 1013 DCHECK(!pac_request_);
1046 1014
1047 // A failure to resolve the hostname or any error related to establishing a 1015 // A failure to resolve the hostname or any error related to establishing a
1048 // TCP connection could be grounds for trying a new proxy configuration. 1016 // TCP connection could be grounds for trying a new proxy configuration.
1049 // 1017 //
1050 // Why do this when a hostname cannot be resolved? Some URLs only make sense 1018 // Why do this when a hostname cannot be resolved? Some URLs only make sense
1051 // to proxy servers. The hostname in those URLs might fail to resolve if we 1019 // to proxy servers. The hostname in those URLs might fail to resolve if we
1052 // are still using a non-proxy config. We need to check if a proxy config 1020 // are still using a non-proxy config. We need to check if a proxy config
1053 // now exists that corresponds to a proxy server that could load the URL. 1021 // now exists that corresponds to a proxy server that could load the URL.
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 bool HttpStreamFactoryImpl::Job::IsPreconnecting() const { 1146 bool HttpStreamFactoryImpl::Job::IsPreconnecting() const {
1179 DCHECK_GE(num_streams_, 0); 1147 DCHECK_GE(num_streams_, 0);
1180 return num_streams_ > 0; 1148 return num_streams_ > 0;
1181 } 1149 }
1182 1150
1183 bool HttpStreamFactoryImpl::Job::IsOrphaned() const { 1151 bool HttpStreamFactoryImpl::Job::IsOrphaned() const {
1184 return !IsPreconnecting() && !request_; 1152 return !IsPreconnecting() && !request_;
1185 } 1153 }
1186 1154
1187 } // namespace net 1155 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_stream_factory_impl_job.h ('k') | net/http/http_stream_factory_impl_request.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698