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 |