| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 ptr_factory_.GetWeakPtr())); | 532 ptr_factory_.GetWeakPtr())); |
| 533 } else { | 533 } else { |
| 534 DCHECK(stream_.get()); | 534 DCHECK(stream_.get()); |
| 535 base::MessageLoop::current()->PostTask( | 535 base::MessageLoop::current()->PostTask( |
| 536 FROM_HERE, | 536 FROM_HERE, |
| 537 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); | 537 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); |
| 538 } | 538 } |
| 539 return ERR_IO_PENDING; | 539 return ERR_IO_PENDING; |
| 540 | 540 |
| 541 default: | 541 default: |
| 542 DCHECK(result != ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN || |
| 543 IsSpdyAlternate()); |
| 542 if (job_status_ != STATUS_BROKEN) { | 544 if (job_status_ != STATUS_BROKEN) { |
| 543 DCHECK_EQ(STATUS_RUNNING, job_status_); | 545 DCHECK_EQ(STATUS_RUNNING, job_status_); |
| 544 job_status_ = STATUS_FAILED; | 546 job_status_ = STATUS_FAILED; |
| 547 // TODO(bnc): If (result == ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN), |
| 548 // then instead of marking alternative service broken, mark (origin, |
| 549 // alternative service) couple as invalid. |
| 545 MaybeMarkAlternativeServiceBroken(); | 550 MaybeMarkAlternativeServiceBroken(); |
| 546 } | 551 } |
| 547 base::MessageLoop::current()->PostTask( | 552 base::MessageLoop::current()->PostTask( |
| 548 FROM_HERE, | 553 FROM_HERE, |
| 549 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), | 554 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), |
| 550 result)); | 555 result)); |
| 551 return ERR_IO_PENDING; | 556 return ERR_IO_PENDING; |
| 552 } | 557 } |
| 553 } | 558 } |
| 554 | 559 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 } | 624 } |
| 620 | 625 |
| 621 int HttpStreamFactoryImpl::Job::DoStart() { | 626 int HttpStreamFactoryImpl::Job::DoStart() { |
| 622 if (IsAlternate()) { | 627 if (IsAlternate()) { |
| 623 server_ = alternative_service_.host_port_pair(); | 628 server_ = alternative_service_.host_port_pair(); |
| 624 } else { | 629 } else { |
| 625 server_ = HostPortPair::FromURL(request_info_.url); | 630 server_ = HostPortPair::FromURL(request_info_.url); |
| 626 } | 631 } |
| 627 origin_url_ = | 632 origin_url_ = |
| 628 stream_factory_->ApplyHostMappingRules(request_info_.url, &server_); | 633 stream_factory_->ApplyHostMappingRules(request_info_.url, &server_); |
| 634 valid_spdy_session_pool_.reset(new ValidSpdySessionPool( |
| 635 session_->spdy_session_pool(), origin_url_, IsSpdyAlternate())); |
| 629 | 636 |
| 630 net_log_.BeginEvent( | 637 net_log_.BeginEvent( |
| 631 NetLog::TYPE_HTTP_STREAM_JOB, | 638 NetLog::TYPE_HTTP_STREAM_JOB, |
| 632 base::Bind(&NetLogHttpStreamJobCallback, &request_info_.url, &origin_url_, | 639 base::Bind(&NetLogHttpStreamJobCallback, &request_info_.url, &origin_url_, |
| 633 &alternative_service_, priority_)); | 640 &alternative_service_, priority_)); |
| 634 | 641 |
| 635 // Don't connect to restricted ports. | 642 // Don't connect to restricted ports. |
| 636 bool is_port_allowed = IsPortAllowedByDefault(server_.port()); | 643 bool is_port_allowed = IsPortAllowedByDefault(server_.port()); |
| 637 if (request_info_.url.SchemeIs("ftp")) { | 644 if (request_info_.url.SchemeIs("ftp")) { |
| 638 // Never share connection with other jobs for FTP requests. | 645 // Never share connection with other jobs for FTP requests. |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 } | 805 } |
| 799 } | 806 } |
| 800 return rv; | 807 return rv; |
| 801 } | 808 } |
| 802 | 809 |
| 803 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 810 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| 804 | 811 |
| 805 // Check first if we have a spdy session for this group. If so, then go | 812 // Check first if we have a spdy session for this group. If so, then go |
| 806 // straight to using that. | 813 // straight to using that. |
| 807 if (CanUseExistingSpdySession()) { | 814 if (CanUseExistingSpdySession()) { |
| 808 base::WeakPtr<SpdySession> spdy_session = | 815 base::WeakPtr<SpdySession> spdy_session; |
| 809 session_->spdy_session_pool()->FindAvailableSession(spdy_session_key, | 816 int result = valid_spdy_session_pool_->FindAvailableSession( |
| 810 net_log_); | 817 spdy_session_key, net_log_, &spdy_session); |
| 818 if (result != OK) |
| 819 return result; |
| 811 if (spdy_session) { | 820 if (spdy_session) { |
| 812 // If we're preconnecting, but we already have a SpdySession, we don't | 821 // If we're preconnecting, but we already have a SpdySession, we don't |
| 813 // actually need to preconnect any sockets, so we're done. | 822 // actually need to preconnect any sockets, so we're done. |
| 814 if (IsPreconnecting()) | 823 if (IsPreconnecting()) |
| 815 return OK; | 824 return OK; |
| 816 using_spdy_ = true; | 825 using_spdy_ = true; |
| 817 next_state_ = STATE_CREATE_STREAM; | 826 next_state_ = STATE_CREATE_STREAM; |
| 818 existing_spdy_session_ = spdy_session; | 827 existing_spdy_session_ = spdy_session; |
| 819 return OK; | 828 return OK; |
| 820 } | 829 } |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 // puts the in progress HttpProxy socket into |connection_| in order to | 998 // puts the in progress HttpProxy socket into |connection_| in order to |
| 990 // complete the auth (or read the response body). The tunnel restart code | 999 // complete the auth (or read the response body). The tunnel restart code |
| 991 // is careful to remove it before returning control to the rest of this | 1000 // is careful to remove it before returning control to the rest of this |
| 992 // class. | 1001 // class. |
| 993 connection_.reset(connection_->release_pending_http_proxy_connection()); | 1002 connection_.reset(connection_->release_pending_http_proxy_connection()); |
| 994 return result; | 1003 return result; |
| 995 } | 1004 } |
| 996 | 1005 |
| 997 if (!ssl_started && result < 0 && IsAlternate()) { | 1006 if (!ssl_started && result < 0 && IsAlternate()) { |
| 998 job_status_ = STATUS_BROKEN; | 1007 job_status_ = STATUS_BROKEN; |
| 1008 // TODO(bnc): if (result == ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN), then |
| 1009 // instead of marking alternative service broken, mark (origin, alternative |
| 1010 // service) couple as invalid. |
| 999 MaybeMarkAlternativeServiceBroken(); | 1011 MaybeMarkAlternativeServiceBroken(); |
| 1000 return result; | 1012 return result; |
| 1001 } | 1013 } |
| 1002 | 1014 |
| 1003 if (using_quic_) { | 1015 if (using_quic_) { |
| 1004 if (result < 0) { | 1016 if (result < 0) { |
| 1005 job_status_ = STATUS_BROKEN; | 1017 job_status_ = STATUS_BROKEN; |
| 1006 MaybeMarkAlternativeServiceBroken(); | 1018 MaybeMarkAlternativeServiceBroken(); |
| 1007 return result; | 1019 return result; |
| 1008 } | 1020 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 // We picked up an existing session, so we don't need our socket. | 1123 // We picked up an existing session, so we don't need our socket. |
| 1112 if (connection_->socket()) | 1124 if (connection_->socket()) |
| 1113 connection_->socket()->Disconnect(); | 1125 connection_->socket()->Disconnect(); |
| 1114 connection_->Reset(); | 1126 connection_->Reset(); |
| 1115 | 1127 |
| 1116 int set_result = SetSpdyHttpStream(existing_spdy_session_, direct); | 1128 int set_result = SetSpdyHttpStream(existing_spdy_session_, direct); |
| 1117 existing_spdy_session_.reset(); | 1129 existing_spdy_session_.reset(); |
| 1118 return set_result; | 1130 return set_result; |
| 1119 } | 1131 } |
| 1120 | 1132 |
| 1121 SpdySessionPool* spdy_pool = session_->spdy_session_pool(); | |
| 1122 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 1133 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| 1123 base::WeakPtr<SpdySession> spdy_session = | 1134 base::WeakPtr<SpdySession> spdy_session; |
| 1124 spdy_pool->FindAvailableSession(spdy_session_key, net_log_); | 1135 int result = valid_spdy_session_pool_->FindAvailableSession( |
| 1125 | 1136 spdy_session_key, net_log_, &spdy_session); |
| 1137 if (result != OK) { |
| 1138 return result; |
| 1139 } |
| 1126 if (spdy_session) { | 1140 if (spdy_session) { |
| 1127 return SetSpdyHttpStream(spdy_session, direct); | 1141 return SetSpdyHttpStream(spdy_session, direct); |
| 1128 } | 1142 } |
| 1129 | 1143 |
| 1130 spdy_session = | 1144 result = valid_spdy_session_pool_->CreateAvailableSessionFromSocket( |
| 1131 spdy_pool->CreateAvailableSessionFromSocket(spdy_session_key, | 1145 spdy_session_key, connection_.Pass(), net_log_, spdy_certificate_error_, |
| 1132 connection_.Pass(), | 1146 using_ssl_, &spdy_session); |
| 1133 net_log_, | 1147 if (result != OK) { |
| 1134 spdy_certificate_error_, | 1148 return result; |
| 1135 using_ssl_); | 1149 } |
| 1150 |
| 1136 if (!spdy_session->HasAcceptableTransportSecurity()) { | 1151 if (!spdy_session->HasAcceptableTransportSecurity()) { |
| 1137 spdy_session->CloseSessionOnError( | 1152 spdy_session->CloseSessionOnError( |
| 1138 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, ""); | 1153 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, ""); |
| 1139 return ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY; | 1154 return ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY; |
| 1140 } | 1155 } |
| 1141 | 1156 |
| 1142 new_spdy_session_ = spdy_session; | 1157 new_spdy_session_ = spdy_session; |
| 1143 spdy_session_direct_ = direct; | 1158 spdy_session_direct_ = direct; |
| 1144 const HostPortPair& host_port_pair = spdy_session_key.host_port_pair(); | 1159 const HostPortPair& host_port_pair = spdy_session_key.host_port_pair(); |
| 1145 base::WeakPtr<HttpServerProperties> http_server_properties = | 1160 base::WeakPtr<HttpServerProperties> http_server_properties = |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1461 } | 1476 } |
| 1462 | 1477 |
| 1463 if (job_status_ == STATUS_SUCCEEDED && other_job_status_ == STATUS_BROKEN) { | 1478 if (job_status_ == STATUS_SUCCEEDED && other_job_status_ == STATUS_BROKEN) { |
| 1464 HistogramBrokenAlternateProtocolLocation( | 1479 HistogramBrokenAlternateProtocolLocation( |
| 1465 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_MAIN); | 1480 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_MAIN); |
| 1466 session_->http_server_properties()->MarkAlternativeServiceBroken( | 1481 session_->http_server_properties()->MarkAlternativeServiceBroken( |
| 1467 other_job_alternative_service_); | 1482 other_job_alternative_service_); |
| 1468 } | 1483 } |
| 1469 } | 1484 } |
| 1470 | 1485 |
| 1486 HttpStreamFactoryImpl::Job::ValidSpdySessionPool::ValidSpdySessionPool( |
| 1487 SpdySessionPool* spdy_session_pool, |
| 1488 GURL& origin_url, |
| 1489 bool is_spdy_alternate) |
| 1490 : spdy_session_pool_(spdy_session_pool), |
| 1491 origin_url_(origin_url), |
| 1492 is_spdy_alternate_(is_spdy_alternate) { |
| 1493 } |
| 1494 |
| 1495 int HttpStreamFactoryImpl::Job::ValidSpdySessionPool::FindAvailableSession( |
| 1496 const SpdySessionKey& key, |
| 1497 const BoundNetLog& net_log, |
| 1498 base::WeakPtr<SpdySession>* spdy_session) { |
| 1499 *spdy_session = spdy_session_pool_->FindAvailableSession(key, net_log); |
| 1500 return CheckAlternativeServiceValidityForOrigin(*spdy_session); |
| 1501 } |
| 1502 |
| 1503 int HttpStreamFactoryImpl::Job::ValidSpdySessionPool:: |
| 1504 CreateAvailableSessionFromSocket(const SpdySessionKey& key, |
| 1505 scoped_ptr<ClientSocketHandle> connection, |
| 1506 const BoundNetLog& net_log, |
| 1507 int certificate_error_code, |
| 1508 bool is_secure, |
| 1509 base::WeakPtr<SpdySession>* spdy_session) { |
| 1510 *spdy_session = spdy_session_pool_->CreateAvailableSessionFromSocket( |
| 1511 key, connection.Pass(), net_log, certificate_error_code, is_secure); |
| 1512 return CheckAlternativeServiceValidityForOrigin(*spdy_session); |
| 1513 } |
| 1514 |
| 1515 int HttpStreamFactoryImpl::Job::ValidSpdySessionPool:: |
| 1516 CheckAlternativeServiceValidityForOrigin( |
| 1517 base::WeakPtr<SpdySession> spdy_session) { |
| 1518 // For a SPDY alternate Job, server_.host() might be different than |
| 1519 // origin_url_.host(), therefore it needs to be verified that the former |
| 1520 // provides a certificate that is valid for the latter. |
| 1521 if (!is_spdy_alternate_ || !spdy_session || |
| 1522 spdy_session->VerifyDomainAuthentication(origin_url_.host())) { |
| 1523 return OK; |
| 1524 } |
| 1525 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; |
| 1526 } |
| 1527 |
| 1471 ClientSocketPoolManager::SocketGroupType | 1528 ClientSocketPoolManager::SocketGroupType |
| 1472 HttpStreamFactoryImpl::Job::GetSocketGroup() const { | 1529 HttpStreamFactoryImpl::Job::GetSocketGroup() const { |
| 1473 std::string scheme = origin_url_.scheme(); | 1530 std::string scheme = origin_url_.scheme(); |
| 1474 if (scheme == "https" || scheme == "wss" || IsSpdyAlternate()) | 1531 if (scheme == "https" || scheme == "wss" || IsSpdyAlternate()) |
| 1475 return ClientSocketPoolManager::SSL_GROUP; | 1532 return ClientSocketPoolManager::SSL_GROUP; |
| 1476 | 1533 |
| 1477 if (scheme == "ftp") | 1534 if (scheme == "ftp") |
| 1478 return ClientSocketPoolManager::FTP_GROUP; | 1535 return ClientSocketPoolManager::FTP_GROUP; |
| 1479 | 1536 |
| 1480 return ClientSocketPoolManager::NORMAL_GROUP; | 1537 return ClientSocketPoolManager::NORMAL_GROUP; |
| 1481 } | 1538 } |
| 1482 | 1539 |
| 1483 } // namespace net | 1540 } // namespace net |
| OLD | NEW |