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_job.h" | 5 #include "net/http/http_stream_factory_impl_job.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 request_->OnStreamReady(this, server_ssl_config_, proxy_info_, | 291 request_->OnStreamReady(this, server_ssl_config_, proxy_info_, |
292 stream_.release()); | 292 stream_.release()); |
293 } | 293 } |
294 // |this| may be deleted after this call. | 294 // |this| may be deleted after this call. |
295 } | 295 } |
296 | 296 |
297 void HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback() { | 297 void HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback() { |
298 DCHECK(!stream_.get()); | 298 DCHECK(!stream_.get()); |
299 DCHECK(!IsPreconnecting()); | 299 DCHECK(!IsPreconnecting()); |
300 DCHECK(using_spdy()); | 300 DCHECK(using_spdy()); |
301 DCHECK(new_spdy_session_); | 301 DCHECK(new_spdy_session_.get()); |
302 scoped_refptr<SpdySession> spdy_session = new_spdy_session_; | 302 scoped_refptr<SpdySession> spdy_session = new_spdy_session_; |
303 new_spdy_session_ = NULL; | 303 new_spdy_session_ = NULL; |
304 if (IsOrphaned()) { | 304 if (IsOrphaned()) { |
305 stream_factory_->OnSpdySessionReady( | 305 stream_factory_->OnSpdySessionReady( |
306 spdy_session, spdy_session_direct_, server_ssl_config_, proxy_info_, | 306 spdy_session, spdy_session_direct_, server_ssl_config_, proxy_info_, |
307 was_npn_negotiated(), protocol_negotiated(), using_spdy(), net_log_); | 307 was_npn_negotiated(), protocol_negotiated(), using_spdy(), net_log_); |
308 stream_factory_->OnOrphanedJobComplete(this); | 308 stream_factory_->OnOrphanedJobComplete(this); |
309 } else { | 309 } else { |
310 request_->OnSpdySessionReady(this, spdy_session, spdy_session_direct_); | 310 request_->OnSpdySessionReady(this, spdy_session, spdy_session_direct_); |
311 } | 311 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 if (IsOrphaned()) | 360 if (IsOrphaned()) |
361 stream_factory_->OnOrphanedJobComplete(this); | 361 stream_factory_->OnOrphanedJobComplete(this); |
362 else | 362 else |
363 request_->OnHttpsProxyTunnelResponse( | 363 request_->OnHttpsProxyTunnelResponse( |
364 this, response_info, server_ssl_config_, proxy_info_, stream); | 364 this, response_info, server_ssl_config_, proxy_info_, stream); |
365 // |this| may be deleted after this call. | 365 // |this| may be deleted after this call. |
366 } | 366 } |
367 | 367 |
368 void HttpStreamFactoryImpl::Job::OnPreconnectsComplete() { | 368 void HttpStreamFactoryImpl::Job::OnPreconnectsComplete() { |
369 DCHECK(!request_); | 369 DCHECK(!request_); |
370 if (new_spdy_session_) { | 370 if (new_spdy_session_.get()) { |
371 stream_factory_->OnSpdySessionReady( | 371 stream_factory_->OnSpdySessionReady(new_spdy_session_, |
372 new_spdy_session_, spdy_session_direct_, server_ssl_config_, | 372 spdy_session_direct_, |
373 proxy_info_, was_npn_negotiated(), protocol_negotiated(), using_spdy(), | 373 server_ssl_config_, |
374 net_log_); | 374 proxy_info_, |
| 375 was_npn_negotiated(), |
| 376 protocol_negotiated(), |
| 377 using_spdy(), |
| 378 net_log_); |
375 } | 379 } |
376 stream_factory_->OnPreconnectsComplete(this); | 380 stream_factory_->OnPreconnectsComplete(this); |
377 // |this| may be deleted after this call. | 381 // |this| may be deleted after this call. |
378 } | 382 } |
379 | 383 |
380 // static | 384 // static |
381 int HttpStreamFactoryImpl::Job::OnHostResolution( | 385 int HttpStreamFactoryImpl::Job::OnHostResolution( |
382 SpdySessionPool* spdy_session_pool, | 386 SpdySessionPool* spdy_session_pool, |
383 const SpdySessionKey& spdy_session_key, | 387 const SpdySessionKey& spdy_session_key, |
384 const AddressList& addresses, | 388 const AddressList& addresses, |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 base::Bind( | 477 base::Bind( |
474 &HttpStreamFactoryImpl::Job::OnHttpsProxyTunnelResponseCallback, | 478 &HttpStreamFactoryImpl::Job::OnHttpsProxyTunnelResponseCallback, |
475 ptr_factory_.GetWeakPtr(), | 479 ptr_factory_.GetWeakPtr(), |
476 *proxy_socket->GetConnectResponseInfo(), | 480 *proxy_socket->GetConnectResponseInfo(), |
477 proxy_socket->CreateConnectResponseStream())); | 481 proxy_socket->CreateConnectResponseStream())); |
478 return ERR_IO_PENDING; | 482 return ERR_IO_PENDING; |
479 } | 483 } |
480 | 484 |
481 case OK: | 485 case OK: |
482 next_state_ = STATE_DONE; | 486 next_state_ = STATE_DONE; |
483 if (new_spdy_session_) { | 487 if (new_spdy_session_.get()) { |
484 base::MessageLoop::current()->PostTask( | 488 base::MessageLoop::current()->PostTask( |
485 FROM_HERE, | 489 FROM_HERE, |
486 base::Bind( | 490 base::Bind(&HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback, |
487 &HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback, | 491 ptr_factory_.GetWeakPtr())); |
488 ptr_factory_.GetWeakPtr())); | |
489 } else { | 492 } else { |
490 base::MessageLoop::current()->PostTask( | 493 base::MessageLoop::current()->PostTask( |
491 FROM_HERE, | 494 FROM_HERE, |
492 base::Bind( | 495 base::Bind( |
493 &HttpStreamFactoryImpl::Job::OnStreamReadyCallback, | 496 &HttpStreamFactoryImpl::Job::OnStreamReadyCallback, |
494 ptr_factory_.GetWeakPtr())); | 497 ptr_factory_.GetWeakPtr())); |
495 } | 498 } |
496 return ERR_IO_PENDING; | 499 return ERR_IO_PENDING; |
497 | 500 |
498 default: | 501 default: |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 const ProxyServer& proxy_server = proxy_info_.proxy_server(); | 706 const ProxyServer& proxy_server = proxy_info_.proxy_server(); |
704 return quic_request_.Request(HostPortProxyPair(origin_, proxy_server), | 707 return quic_request_.Request(HostPortProxyPair(origin_, proxy_server), |
705 net_log_, io_callback_); | 708 net_log_, io_callback_); |
706 } | 709 } |
707 | 710 |
708 // Check first if we have a spdy session for this group. If so, then go | 711 // Check first if we have a spdy session for this group. If so, then go |
709 // straight to using that. | 712 // straight to using that. |
710 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 713 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
711 scoped_refptr<SpdySession> spdy_session = | 714 scoped_refptr<SpdySession> spdy_session = |
712 session_->spdy_session_pool()->GetIfExists(spdy_session_key, net_log_); | 715 session_->spdy_session_pool()->GetIfExists(spdy_session_key, net_log_); |
713 if (spdy_session && CanUseExistingSpdySession()) { | 716 if (spdy_session.get() && CanUseExistingSpdySession()) { |
714 // If we're preconnecting, but we already have a SpdySession, we don't | 717 // If we're preconnecting, but we already have a SpdySession, we don't |
715 // actually need to preconnect any sockets, so we're done. | 718 // actually need to preconnect any sockets, so we're done. |
716 if (IsPreconnecting()) | 719 if (IsPreconnecting()) |
717 return OK; | 720 return OK; |
718 using_spdy_ = true; | 721 using_spdy_ = true; |
719 next_state_ = STATE_CREATE_STREAM; | 722 next_state_ = STATE_CREATE_STREAM; |
720 existing_spdy_session_ = spdy_session; | 723 existing_spdy_session_ = spdy_session; |
721 return OK; | 724 return OK; |
722 } else if (request_ && (using_ssl_ || ShouldForceSpdyWithoutSSL())) { | 725 } else if (request_ && (using_ssl_ || ShouldForceSpdyWithoutSSL())) { |
723 // Update the spdy session key for the request that launched this job. | 726 // Update the spdy session key for the request that launched this job. |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 DCHECK_EQ(OK, result); | 811 DCHECK_EQ(OK, result); |
809 return OK; | 812 return OK; |
810 } | 813 } |
811 | 814 |
812 if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { | 815 if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { |
813 // We found a SPDY connection after resolving the host. This is | 816 // We found a SPDY connection after resolving the host. This is |
814 // probably an IP pooled connection. | 817 // probably an IP pooled connection. |
815 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 818 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
816 existing_spdy_session_ = | 819 existing_spdy_session_ = |
817 session_->spdy_session_pool()->GetIfExists(spdy_session_key, net_log_); | 820 session_->spdy_session_pool()->GetIfExists(spdy_session_key, net_log_); |
818 if (existing_spdy_session_) { | 821 if (existing_spdy_session_.get()) { |
819 using_spdy_ = true; | 822 using_spdy_ = true; |
820 next_state_ = STATE_CREATE_STREAM; | 823 next_state_ = STATE_CREATE_STREAM; |
821 } else { | 824 } else { |
822 // It is possible that the spdy session no longer exists. | 825 // It is possible that the spdy session no longer exists. |
823 ReturnToStateInitConnection(true /* close connection */); | 826 ReturnToStateInitConnection(true /* close connection */); |
824 } | 827 } |
825 return OK; | 828 return OK; |
826 } | 829 } |
827 | 830 |
828 // TODO(willchan): Make this a bit more exact. Maybe there are recoverable | 831 // TODO(willchan): Make this a bit more exact. Maybe there are recoverable |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
954 int HttpStreamFactoryImpl::Job::DoWaitingUserAction(int result) { | 957 int HttpStreamFactoryImpl::Job::DoWaitingUserAction(int result) { |
955 // This state indicates that the stream request is in a partially | 958 // This state indicates that the stream request is in a partially |
956 // completed state, and we've called back to the delegate for more | 959 // completed state, and we've called back to the delegate for more |
957 // information. | 960 // information. |
958 | 961 |
959 // We're always waiting here for the delegate to call us back. | 962 // We're always waiting here for the delegate to call us back. |
960 return ERR_IO_PENDING; | 963 return ERR_IO_PENDING; |
961 } | 964 } |
962 | 965 |
963 int HttpStreamFactoryImpl::Job::DoCreateStream() { | 966 int HttpStreamFactoryImpl::Job::DoCreateStream() { |
964 DCHECK(connection_->socket() || existing_spdy_session_ || | 967 DCHECK(connection_->socket() || existing_spdy_session_.get() || |
965 existing_available_pipeline_ || using_quic_); | 968 existing_available_pipeline_ || using_quic_); |
966 | 969 |
967 next_state_ = STATE_CREATE_STREAM_COMPLETE; | 970 next_state_ = STATE_CREATE_STREAM_COMPLETE; |
968 | 971 |
969 // We only set the socket motivation if we're the first to use | 972 // We only set the socket motivation if we're the first to use |
970 // this socket. Is there a race for two SPDY requests? We really | 973 // this socket. Is there a race for two SPDY requests? We really |
971 // need to plumb this through to the connect level. | 974 // need to plumb this through to the connect level. |
972 if (connection_->socket() && !connection_->is_reused()) | 975 if (connection_->socket() && !connection_->is_reused()) |
973 SetSocketMotivation(); | 976 SetSocketMotivation(); |
974 | 977 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 // If we don't have a direct SPDY session, and we're using an HTTPS | 1015 // If we don't have a direct SPDY session, and we're using an HTTPS |
1013 // proxy, then we might have a SPDY session to the proxy. | 1016 // proxy, then we might have a SPDY session to the proxy. |
1014 // We never use privacy mode for connection to proxy server. | 1017 // We never use privacy mode for connection to proxy server. |
1015 spdy_session_key = SpdySessionKey(proxy_server.host_port_pair(), | 1018 spdy_session_key = SpdySessionKey(proxy_server.host_port_pair(), |
1016 ProxyServer::Direct(), | 1019 ProxyServer::Direct(), |
1017 kPrivacyModeDisabled); | 1020 kPrivacyModeDisabled); |
1018 direct = false; | 1021 direct = false; |
1019 } | 1022 } |
1020 | 1023 |
1021 scoped_refptr<SpdySession> spdy_session; | 1024 scoped_refptr<SpdySession> spdy_session; |
1022 if (existing_spdy_session_) { | 1025 if (existing_spdy_session_.get()) { |
1023 // We picked up an existing session, so we don't need our socket. | 1026 // We picked up an existing session, so we don't need our socket. |
1024 if (connection_->socket()) | 1027 if (connection_->socket()) |
1025 connection_->socket()->Disconnect(); | 1028 connection_->socket()->Disconnect(); |
1026 connection_->Reset(); | 1029 connection_->Reset(); |
1027 spdy_session.swap(existing_spdy_session_); | 1030 spdy_session.swap(existing_spdy_session_); |
1028 } else { | 1031 } else { |
1029 SpdySessionPool* spdy_pool = session_->spdy_session_pool(); | 1032 SpdySessionPool* spdy_pool = session_->spdy_session_pool(); |
1030 spdy_session = spdy_pool->GetIfExists(spdy_session_key, net_log_); | 1033 spdy_session = spdy_pool->GetIfExists(spdy_session_key, net_log_); |
1031 if (!spdy_session) { | 1034 if (!spdy_session.get()) { |
1032 int error = spdy_pool->GetSpdySessionFromSocket( | 1035 int error = spdy_pool->GetSpdySessionFromSocket(spdy_session_key, |
1033 spdy_session_key, connection_.release(), net_log_, | 1036 connection_.release(), |
1034 spdy_certificate_error_, &new_spdy_session_, using_ssl_); | 1037 net_log_, |
| 1038 spdy_certificate_error_, |
| 1039 &new_spdy_session_, |
| 1040 using_ssl_); |
1035 if (error != OK) | 1041 if (error != OK) |
1036 return error; | 1042 return error; |
1037 const HostPortPair& host_port_pair = spdy_session_key.host_port_pair(); | 1043 const HostPortPair& host_port_pair = spdy_session_key.host_port_pair(); |
1038 HttpServerProperties* http_server_properties = | 1044 HttpServerProperties* http_server_properties = |
1039 session_->http_server_properties(); | 1045 session_->http_server_properties(); |
1040 if (http_server_properties) | 1046 if (http_server_properties) |
1041 http_server_properties->SetSupportsSpdy(host_port_pair, true); | 1047 http_server_properties->SetSupportsSpdy(host_port_pair, true); |
1042 spdy_session_direct_ = direct; | 1048 spdy_session_direct_ = direct; |
1043 return OK; | 1049 return OK; |
1044 } | 1050 } |
1045 } | 1051 } |
1046 | 1052 |
1047 if (spdy_session->IsClosed()) | 1053 if (spdy_session->IsClosed()) |
1048 return ERR_CONNECTION_CLOSED; | 1054 return ERR_CONNECTION_CLOSED; |
1049 | 1055 |
1050 // TODO(willchan): Delete this code, because eventually, the | 1056 // TODO(willchan): Delete this code, because eventually, the |
1051 // HttpStreamFactoryImpl will be creating all the SpdyHttpStreams, since it | 1057 // HttpStreamFactoryImpl will be creating all the SpdyHttpStreams, since it |
1052 // will know when SpdySessions become available. | 1058 // will know when SpdySessions become available. |
1053 | 1059 |
1054 bool use_relative_url = direct || request_info_.url.SchemeIs("https"); | 1060 bool use_relative_url = direct || request_info_.url.SchemeIs("https"); |
1055 stream_.reset(new SpdyHttpStream(spdy_session, use_relative_url)); | 1061 stream_.reset(new SpdyHttpStream(spdy_session.get(), use_relative_url)); |
1056 return OK; | 1062 return OK; |
1057 } | 1063 } |
1058 | 1064 |
1059 int HttpStreamFactoryImpl::Job::DoCreateStreamComplete(int result) { | 1065 int HttpStreamFactoryImpl::Job::DoCreateStreamComplete(int result) { |
1060 if (result < 0) | 1066 if (result < 0) |
1061 return result; | 1067 return result; |
1062 | 1068 |
1063 session_->proxy_service()->ReportSuccess(proxy_info_); | 1069 session_->proxy_service()->ReportSuccess(proxy_info_); |
1064 next_state_ = STATE_NONE; | 1070 next_state_ = STATE_NONE; |
1065 return OK; | 1071 return OK; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1278 | 1284 |
1279 // Add the bad certificate to the set of allowed certificates in the | 1285 // Add the bad certificate to the set of allowed certificates in the |
1280 // SSL config object. This data structure will be consulted after calling | 1286 // SSL config object. This data structure will be consulted after calling |
1281 // RestartIgnoringLastError(). And the user will be asked interactively | 1287 // RestartIgnoringLastError(). And the user will be asked interactively |
1282 // before RestartIgnoringLastError() is ever called. | 1288 // before RestartIgnoringLastError() is ever called. |
1283 SSLConfig::CertAndStatus bad_cert; | 1289 SSLConfig::CertAndStatus bad_cert; |
1284 | 1290 |
1285 // |ssl_info_.cert| may be NULL if we failed to create | 1291 // |ssl_info_.cert| may be NULL if we failed to create |
1286 // X509Certificate for whatever reason, but normally it shouldn't | 1292 // X509Certificate for whatever reason, but normally it shouldn't |
1287 // happen, unless this code is used inside sandbox. | 1293 // happen, unless this code is used inside sandbox. |
1288 if (ssl_info_.cert == NULL || | 1294 if (ssl_info_.cert.get() == NULL || |
1289 !X509Certificate::GetDEREncoded(ssl_info_.cert->os_cert_handle(), | 1295 !X509Certificate::GetDEREncoded(ssl_info_.cert->os_cert_handle(), |
1290 &bad_cert.der_cert)) { | 1296 &bad_cert.der_cert)) { |
1291 return error; | 1297 return error; |
1292 } | 1298 } |
1293 bad_cert.cert_status = ssl_info_.cert_status; | 1299 bad_cert.cert_status = ssl_info_.cert_status; |
1294 server_ssl_config_.allowed_bad_certs.push_back(bad_cert); | 1300 server_ssl_config_.allowed_bad_certs.push_back(bad_cert); |
1295 | 1301 |
1296 int load_flags = request_info_.load_flags; | 1302 int load_flags = request_info_.load_flags; |
1297 if (session_->params().ignore_certificate_errors) | 1303 if (session_->params().ignore_certificate_errors) |
1298 load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; | 1304 load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1369 (net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME | net::LOAD_PREFETCH | | 1375 (net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME | net::LOAD_PREFETCH | |
1370 net::LOAD_IS_DOWNLOAD)) { | 1376 net::LOAD_IS_DOWNLOAD)) { |
1371 // Avoid pipelining resources that may be streamed for a long time. | 1377 // Avoid pipelining resources that may be streamed for a long time. |
1372 return false; | 1378 return false; |
1373 } | 1379 } |
1374 return stream_factory_->http_pipelined_host_pool_.IsKeyEligibleForPipelining( | 1380 return stream_factory_->http_pipelined_host_pool_.IsKeyEligibleForPipelining( |
1375 *http_pipelining_key_.get()); | 1381 *http_pipelining_key_.get()); |
1376 } | 1382 } |
1377 | 1383 |
1378 } // namespace net | 1384 } // namespace net |
OLD | NEW |