| 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 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 server_ssl_config_(server_ssl_config), | 184 server_ssl_config_(server_ssl_config), |
| 185 proxy_ssl_config_(proxy_ssl_config), | 185 proxy_ssl_config_(proxy_ssl_config), |
| 186 net_log_(BoundNetLog::Make(net_log, NetLogSourceType::HTTP_STREAM_JOB)), | 186 net_log_(BoundNetLog::Make(net_log, NetLogSourceType::HTTP_STREAM_JOB)), |
| 187 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), | 187 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), |
| 188 connection_(new ClientSocketHandle), | 188 connection_(new ClientSocketHandle), |
| 189 session_(session), | 189 session_(session), |
| 190 next_state_(STATE_NONE), | 190 next_state_(STATE_NONE), |
| 191 pac_request_(NULL), | 191 pac_request_(NULL), |
| 192 destination_(destination), | 192 destination_(destination), |
| 193 origin_url_(origin_url), | 193 origin_url_(origin_url), |
| 194 alternative_broken_(false), |
| 194 alternative_service_(alternative_service), | 195 alternative_service_(alternative_service), |
| 195 delegate_(delegate), | 196 delegate_(delegate), |
| 196 alternative_proxy_server_(alternative_proxy_server), | 197 alternative_proxy_server_(alternative_proxy_server), |
| 197 job_type_(job_type), | 198 job_type_(job_type), |
| 198 using_ssl_(false), | 199 using_ssl_(false), |
| 199 using_spdy_(false), | 200 using_spdy_(false), |
| 200 using_quic_(false), | 201 using_quic_(false), |
| 201 quic_request_(session_->quic_stream_factory()), | 202 quic_request_(session_->quic_stream_factory()), |
| 202 using_existing_quic_session_(false), | 203 using_existing_quic_session_(false), |
| 203 spdy_certificate_error_(OK), | 204 spdy_certificate_error_(OK), |
| 204 establishing_tunnel_(false), | 205 establishing_tunnel_(false), |
| 205 was_npn_negotiated_(false), | 206 was_npn_negotiated_(false), |
| 206 negotiated_protocol_(kProtoUnknown), | 207 negotiated_protocol_(kProtoUnknown), |
| 207 num_streams_(0), | 208 num_streams_(0), |
| 208 spdy_session_direct_(false), | 209 spdy_session_direct_(false), |
| 209 job_status_(STATUS_RUNNING), | |
| 210 other_job_status_(STATUS_RUNNING), | |
| 211 stream_type_(HttpStreamRequest::BIDIRECTIONAL_STREAM), | 210 stream_type_(HttpStreamRequest::BIDIRECTIONAL_STREAM), |
| 212 ptr_factory_(this) { | 211 ptr_factory_(this) { |
| 213 DCHECK(session); | 212 DCHECK(session); |
| 214 // The job can't have alternative service and alternative proxy server set at | 213 // The job can't have alternative service and alternative proxy server set at |
| 215 // the same time since alternative services are used for requests that are | 214 // the same time since alternative services are used for requests that are |
| 216 // fetched directly, while the alternative proxy server is used for requests | 215 // fetched directly, while the alternative proxy server is used for requests |
| 217 // that should be fetched using proxy. | 216 // that should be fetched using proxy. |
| 218 DCHECK(alternative_service_.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL || | 217 DCHECK(alternative_service_.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL || |
| 219 !alternative_proxy_server_.is_valid()); | 218 !alternative_proxy_server_.is_valid()); |
| 220 DCHECK(!alternative_proxy_server_.is_valid() || | 219 DCHECK(!alternative_proxy_server_.is_valid() || |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 static_cast<ProxyClientSocket*>(connection_->socket()); | 573 static_cast<ProxyClientSocket*>(connection_->socket()); |
| 575 base::ThreadTaskRunnerHandle::Get()->PostTask( | 574 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 576 FROM_HERE, base::Bind(&Job::OnHttpsProxyTunnelResponseCallback, | 575 FROM_HERE, base::Bind(&Job::OnHttpsProxyTunnelResponseCallback, |
| 577 ptr_factory_.GetWeakPtr(), | 576 ptr_factory_.GetWeakPtr(), |
| 578 *proxy_socket->GetConnectResponseInfo(), | 577 *proxy_socket->GetConnectResponseInfo(), |
| 579 proxy_socket->CreateConnectResponseStream())); | 578 proxy_socket->CreateConnectResponseStream())); |
| 580 return ERR_IO_PENDING; | 579 return ERR_IO_PENDING; |
| 581 } | 580 } |
| 582 | 581 |
| 583 case OK: | 582 case OK: |
| 584 job_status_ = STATUS_SUCCEEDED; | |
| 585 MaybeMarkAlternativeServiceBroken(); | |
| 586 next_state_ = STATE_DONE; | 583 next_state_ = STATE_DONE; |
| 587 if (new_spdy_session_.get()) { | 584 if (new_spdy_session_.get()) { |
| 588 base::ThreadTaskRunnerHandle::Get()->PostTask( | 585 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 589 FROM_HERE, base::Bind(&Job::OnNewSpdySessionReadyCallback, | 586 FROM_HERE, base::Bind(&Job::OnNewSpdySessionReadyCallback, |
| 590 ptr_factory_.GetWeakPtr())); | 587 ptr_factory_.GetWeakPtr())); |
| 591 } else if (delegate_->for_websockets()) { | 588 } else if (delegate_->for_websockets()) { |
| 592 DCHECK(websocket_stream_); | 589 DCHECK(websocket_stream_); |
| 593 base::ThreadTaskRunnerHandle::Get()->PostTask( | 590 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 594 FROM_HERE, base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, | 591 FROM_HERE, base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, |
| 595 ptr_factory_.GetWeakPtr())); | 592 ptr_factory_.GetWeakPtr())); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 606 } | 603 } |
| 607 } else { | 604 } else { |
| 608 DCHECK(stream_.get()); | 605 DCHECK(stream_.get()); |
| 609 base::ThreadTaskRunnerHandle::Get()->PostTask( | 606 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 610 FROM_HERE, | 607 FROM_HERE, |
| 611 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); | 608 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); |
| 612 } | 609 } |
| 613 return ERR_IO_PENDING; | 610 return ERR_IO_PENDING; |
| 614 | 611 |
| 615 default: | 612 default: |
| 616 if (job_status_ != STATUS_BROKEN) { | 613 // Notify job controlelr that alternative proxy server is broken. |
| 617 DCHECK_EQ(STATUS_RUNNING, job_status_); | 614 if (alternative_proxy_server_.is_valid()) |
| 618 job_status_ = STATUS_FAILED; | 615 alternative_broken_ = true; |
| 619 MaybeMarkAlternativeServiceBroken(); | |
| 620 } | |
| 621 base::ThreadTaskRunnerHandle::Get()->PostTask( | 616 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 622 FROM_HERE, base::Bind(&Job::OnStreamFailedCallback, | 617 FROM_HERE, base::Bind(&Job::OnStreamFailedCallback, |
| 623 ptr_factory_.GetWeakPtr(), result)); | 618 ptr_factory_.GetWeakPtr(), result)); |
| 624 return ERR_IO_PENDING; | 619 return ERR_IO_PENDING; |
| 625 } | 620 } |
| 626 } | 621 } |
| 627 | 622 |
| 628 int HttpStreamFactoryImpl::Job::DoLoop(int result) { | 623 int HttpStreamFactoryImpl::Job::DoLoop(int result) { |
| 629 DCHECK_NE(next_state_, STATE_NONE); | 624 DCHECK_NE(next_state_, STATE_NONE); |
| 630 int rv = result; | 625 int rv = result; |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1058 connection_.reset(connection_->release_pending_http_proxy_connection()); | 1053 connection_.reset(connection_->release_pending_http_proxy_connection()); |
| 1059 return result; | 1054 return result; |
| 1060 } | 1055 } |
| 1061 | 1056 |
| 1062 if (proxy_info_.is_quic() && using_quic_ && result < 0) { | 1057 if (proxy_info_.is_quic() && using_quic_ && result < 0) { |
| 1063 using_quic_ = false; | 1058 using_quic_ = false; |
| 1064 return ReconsiderProxyAfterError(result); | 1059 return ReconsiderProxyAfterError(result); |
| 1065 } | 1060 } |
| 1066 | 1061 |
| 1067 if (IsSpdyAlternative() && !using_spdy_) { | 1062 if (IsSpdyAlternative() && !using_spdy_) { |
| 1068 job_status_ = STATUS_BROKEN; | 1063 alternative_broken_ = true; |
| 1069 MaybeMarkAlternativeServiceBroken(); | |
| 1070 return ERR_NPN_NEGOTIATION_FAILED; | 1064 return ERR_NPN_NEGOTIATION_FAILED; |
| 1071 } | 1065 } |
| 1072 | 1066 |
| 1073 if (!ssl_started && result < 0 && | 1067 if (!ssl_started && result < 0 && |
| 1074 (IsSpdyAlternative() || IsQuicAlternative())) { | 1068 (IsSpdyAlternative() || IsQuicAlternative())) { |
| 1075 job_status_ = STATUS_BROKEN; | 1069 alternative_broken_ = true; |
| 1076 MaybeMarkAlternativeServiceBroken(); | |
| 1077 return result; | 1070 return result; |
| 1078 } | 1071 } |
| 1079 | 1072 |
| 1080 if (using_quic_) { | 1073 if (using_quic_) { |
| 1081 if (result < 0) { | 1074 if (result < 0) { |
| 1082 job_status_ = STATUS_BROKEN; | 1075 alternative_broken_ = true; |
| 1083 MaybeMarkAlternativeServiceBroken(); | |
| 1084 return result; | 1076 return result; |
| 1085 } | 1077 } |
| 1086 if (stream_type_ == HttpStreamRequest::BIDIRECTIONAL_STREAM) { | 1078 if (stream_type_ == HttpStreamRequest::BIDIRECTIONAL_STREAM) { |
| 1087 bidirectional_stream_impl_ = | 1079 bidirectional_stream_impl_ = |
| 1088 quic_request_.CreateBidirectionalStreamImpl(); | 1080 quic_request_.CreateBidirectionalStreamImpl(); |
| 1089 if (!bidirectional_stream_impl_) { | 1081 if (!bidirectional_stream_impl_) { |
| 1090 // Quic session is closed before stream can be created. | 1082 // Quic session is closed before stream can be created. |
| 1091 return ERR_CONNECTION_CLOSED; | 1083 return ERR_CONNECTION_CLOSED; |
| 1092 } | 1084 } |
| 1093 } else { | 1085 } else { |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1513 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_NO_RACE); | 1505 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_NO_RACE); |
| 1514 } else if (IsSpdyAlternative() || IsQuicAlternative()) { | 1506 } else if (IsSpdyAlternative() || IsQuicAlternative()) { |
| 1515 // This Job was the alternative Job, and hence won the race. | 1507 // This Job was the alternative Job, and hence won the race. |
| 1516 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE); | 1508 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE); |
| 1517 } else { | 1509 } else { |
| 1518 // This Job was the normal Job, and hence the alternative Job lost the race. | 1510 // This Job was the normal Job, and hence the alternative Job lost the race. |
| 1519 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE); | 1511 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE); |
| 1520 } | 1512 } |
| 1521 } | 1513 } |
| 1522 | 1514 |
| 1523 void HttpStreamFactoryImpl::Job::MarkOtherJobComplete(const Job& job) { | |
| 1524 DCHECK_EQ(STATUS_RUNNING, other_job_status_); | |
| 1525 DCHECK(!other_job_alternative_proxy_server_.is_valid()); | |
| 1526 | |
| 1527 other_job_status_ = job.job_status_; | |
| 1528 other_job_alternative_service_ = job.alternative_service_; | |
| 1529 other_job_alternative_proxy_server_ = job.alternative_proxy_server_; | |
| 1530 | |
| 1531 // At most one job can have a valid |alternative_proxy_server_|. | |
| 1532 DCHECK(!alternative_proxy_server_.is_valid() || | |
| 1533 !other_job_alternative_proxy_server_.is_valid()); | |
| 1534 | |
| 1535 MaybeMarkAlternativeServiceBroken(); | |
| 1536 } | |
| 1537 | |
| 1538 void HttpStreamFactoryImpl::Job::MaybeMarkAlternativeServiceBroken() { | |
| 1539 // At least one job should not be an alternative job. | |
| 1540 DCHECK(alternative_service_.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL || | |
| 1541 other_job_alternative_service_.protocol == | |
| 1542 UNINITIALIZED_ALTERNATE_PROTOCOL); | |
| 1543 | |
| 1544 if (job_status_ == STATUS_RUNNING || other_job_status_ == STATUS_RUNNING) | |
| 1545 return; | |
| 1546 | |
| 1547 MaybeNotifyAlternativeProxyServerBroken(); | |
| 1548 | |
| 1549 if (IsSpdyAlternative() || IsQuicAlternative()) { | |
| 1550 if (job_status_ == STATUS_BROKEN && other_job_status_ == STATUS_SUCCEEDED) { | |
| 1551 HistogramBrokenAlternateProtocolLocation( | |
| 1552 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); | |
| 1553 session_->http_server_properties()->MarkAlternativeServiceBroken( | |
| 1554 alternative_service_); | |
| 1555 } | |
| 1556 return; | |
| 1557 } | |
| 1558 | |
| 1559 session_->quic_stream_factory()->OnTcpJobCompleted(job_status_ == | |
| 1560 STATUS_SUCCEEDED); | |
| 1561 if (job_status_ == STATUS_SUCCEEDED && other_job_status_ == STATUS_BROKEN) { | |
| 1562 HistogramBrokenAlternateProtocolLocation( | |
| 1563 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_MAIN); | |
| 1564 session_->http_server_properties()->MarkAlternativeServiceBroken( | |
| 1565 other_job_alternative_service_); | |
| 1566 } | |
| 1567 } | |
| 1568 | |
| 1569 void HttpStreamFactoryImpl::Job::MaybeNotifyAlternativeProxyServerBroken() | |
| 1570 const { | |
| 1571 if (!alternative_proxy_server_.is_valid() && | |
| 1572 !other_job_alternative_proxy_server_.is_valid()) { | |
| 1573 // Neither of the two jobs used an alternative proxy server. | |
| 1574 return; | |
| 1575 } | |
| 1576 | |
| 1577 // Neither this job, nor the other job should have used the alternative | |
| 1578 // service. | |
| 1579 DCHECK_EQ(UNINITIALIZED_ALTERNATE_PROTOCOL, alternative_service_.protocol); | |
| 1580 DCHECK_EQ(UNINITIALIZED_ALTERNATE_PROTOCOL, | |
| 1581 other_job_alternative_service_.protocol); | |
| 1582 | |
| 1583 ProxyDelegate* proxy_delegate = session_->params().proxy_delegate; | |
| 1584 if (!proxy_delegate) | |
| 1585 return; | |
| 1586 | |
| 1587 if (alternative_proxy_server_.is_valid()) { | |
| 1588 // |this| connected to the alternative proxy server. | |
| 1589 if ((job_status_ == STATUS_BROKEN || job_status_ == STATUS_FAILED) && | |
| 1590 other_job_status_ == STATUS_SUCCEEDED) { | |
| 1591 // Notify ProxyDelegate. | |
| 1592 proxy_delegate->OnAlternativeProxyBroken(alternative_proxy_server_); | |
| 1593 } | |
| 1594 return; | |
| 1595 } | |
| 1596 | |
| 1597 if (other_job_alternative_proxy_server_.is_valid()) { | |
| 1598 // Other job connected to the alternative proxy server. | |
| 1599 if (job_status_ == STATUS_SUCCEEDED && | |
| 1600 (other_job_status_ == STATUS_BROKEN || | |
| 1601 other_job_status_ == STATUS_FAILED)) { | |
| 1602 // Notify ProxyDelegate. | |
| 1603 proxy_delegate->OnAlternativeProxyBroken( | |
| 1604 other_job_alternative_proxy_server_); | |
| 1605 } | |
| 1606 return; | |
| 1607 } | |
| 1608 } | |
| 1609 | |
| 1610 ClientSocketPoolManager::SocketGroupType | 1515 ClientSocketPoolManager::SocketGroupType |
| 1611 HttpStreamFactoryImpl::Job::GetSocketGroup() const { | 1516 HttpStreamFactoryImpl::Job::GetSocketGroup() const { |
| 1612 std::string scheme = origin_url_.scheme(); | 1517 std::string scheme = origin_url_.scheme(); |
| 1613 if (scheme == "https" || scheme == "wss" || IsSpdyAlternative()) | 1518 if (scheme == "https" || scheme == "wss" || IsSpdyAlternative()) |
| 1614 return ClientSocketPoolManager::SSL_GROUP; | 1519 return ClientSocketPoolManager::SSL_GROUP; |
| 1615 | 1520 |
| 1616 if (scheme == "ftp") | 1521 if (scheme == "ftp") |
| 1617 return ClientSocketPoolManager::FTP_GROUP; | 1522 return ClientSocketPoolManager::FTP_GROUP; |
| 1618 | 1523 |
| 1619 return ClientSocketPoolManager::NORMAL_GROUP; | 1524 return ClientSocketPoolManager::NORMAL_GROUP; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1631 | 1536 |
| 1632 ConnectionAttempts socket_attempts = connection_->connection_attempts(); | 1537 ConnectionAttempts socket_attempts = connection_->connection_attempts(); |
| 1633 if (connection_->socket()) { | 1538 if (connection_->socket()) { |
| 1634 connection_->socket()->GetConnectionAttempts(&socket_attempts); | 1539 connection_->socket()->GetConnectionAttempts(&socket_attempts); |
| 1635 } | 1540 } |
| 1636 | 1541 |
| 1637 delegate_->AddConnectionAttemptsToRequest(this, socket_attempts); | 1542 delegate_->AddConnectionAttemptsToRequest(this, socket_attempts); |
| 1638 } | 1543 } |
| 1639 | 1544 |
| 1640 } // namespace net | 1545 } // namespace net |
| OLD | NEW |