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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 using_existing_quic_session_(false), | 101 using_existing_quic_session_(false), |
102 force_spdy_always_(HttpStreamFactory::force_spdy_always()), | 102 force_spdy_always_(HttpStreamFactory::force_spdy_always()), |
103 force_spdy_over_ssl_(HttpStreamFactory::force_spdy_over_ssl()), | 103 force_spdy_over_ssl_(HttpStreamFactory::force_spdy_over_ssl()), |
104 spdy_certificate_error_(OK), | 104 spdy_certificate_error_(OK), |
105 establishing_tunnel_(false), | 105 establishing_tunnel_(false), |
106 was_npn_negotiated_(false), | 106 was_npn_negotiated_(false), |
107 protocol_negotiated_(kProtoUnknown), | 107 protocol_negotiated_(kProtoUnknown), |
108 num_streams_(0), | 108 num_streams_(0), |
109 spdy_session_direct_(false), | 109 spdy_session_direct_(false), |
110 existing_available_pipeline_(false), | 110 existing_available_pipeline_(false), |
| 111 job_status_(STATUS_RUNNING), |
| 112 other_job_status_(STATUS_RUNNING), |
111 ptr_factory_(this) { | 113 ptr_factory_(this) { |
112 DCHECK(stream_factory); | 114 DCHECK(stream_factory); |
113 DCHECK(session); | 115 DCHECK(session); |
114 } | 116 } |
115 | 117 |
116 HttpStreamFactoryImpl::Job::~Job() { | 118 HttpStreamFactoryImpl::Job::~Job() { |
117 net_log_.EndEvent(NetLog::TYPE_HTTP_STREAM_JOB); | 119 net_log_.EndEvent(NetLog::TYPE_HTTP_STREAM_JOB); |
118 | 120 |
119 // When we're in a partially constructed state, waiting for the user to | 121 // When we're in a partially constructed state, waiting for the user to |
120 // provide certificate handling information or authentication, we can't reuse | 122 // provide certificate handling information or authentication, we can't reuse |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 base::MessageLoop::current()->PostTask( | 509 base::MessageLoop::current()->PostTask( |
508 FROM_HERE, | 510 FROM_HERE, |
509 base::Bind(&Job::OnHttpsProxyTunnelResponseCallback, | 511 base::Bind(&Job::OnHttpsProxyTunnelResponseCallback, |
510 ptr_factory_.GetWeakPtr(), | 512 ptr_factory_.GetWeakPtr(), |
511 *proxy_socket->GetConnectResponseInfo(), | 513 *proxy_socket->GetConnectResponseInfo(), |
512 proxy_socket->CreateConnectResponseStream())); | 514 proxy_socket->CreateConnectResponseStream())); |
513 return ERR_IO_PENDING; | 515 return ERR_IO_PENDING; |
514 } | 516 } |
515 | 517 |
516 case OK: | 518 case OK: |
| 519 job_status_ = STATUS_SUCCEEDED; |
| 520 MaybeMarkAlternateProtocolBroken(); |
517 next_state_ = STATE_DONE; | 521 next_state_ = STATE_DONE; |
518 if (new_spdy_session_.get()) { | 522 if (new_spdy_session_.get()) { |
519 base::MessageLoop::current()->PostTask( | 523 base::MessageLoop::current()->PostTask( |
520 FROM_HERE, | 524 FROM_HERE, |
521 base::Bind(&Job::OnNewSpdySessionReadyCallback, | 525 base::Bind(&Job::OnNewSpdySessionReadyCallback, |
522 ptr_factory_.GetWeakPtr())); | 526 ptr_factory_.GetWeakPtr())); |
523 } else if (stream_factory_->for_websockets_) { | 527 } else if (stream_factory_->for_websockets_) { |
524 DCHECK(websocket_stream_); | 528 DCHECK(websocket_stream_); |
525 base::MessageLoop::current()->PostTask( | 529 base::MessageLoop::current()->PostTask( |
526 FROM_HERE, | 530 FROM_HERE, |
527 base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, | 531 base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, |
528 ptr_factory_.GetWeakPtr())); | 532 ptr_factory_.GetWeakPtr())); |
529 } else { | 533 } else { |
530 DCHECK(stream_.get()); | 534 DCHECK(stream_.get()); |
531 base::MessageLoop::current()->PostTask( | 535 base::MessageLoop::current()->PostTask( |
532 FROM_HERE, | 536 FROM_HERE, |
533 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); | 537 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); |
534 } | 538 } |
535 return ERR_IO_PENDING; | 539 return ERR_IO_PENDING; |
536 | 540 |
537 default: | 541 default: |
| 542 if (job_status_ != STATUS_BROKEN) { |
| 543 DCHECK_EQ(STATUS_RUNNING, job_status_); |
| 544 job_status_ = STATUS_FAILED; |
| 545 MaybeMarkAlternateProtocolBroken(); |
| 546 } |
538 base::MessageLoop::current()->PostTask( | 547 base::MessageLoop::current()->PostTask( |
539 FROM_HERE, | 548 FROM_HERE, |
540 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), | 549 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), |
541 result)); | 550 result)); |
542 return ERR_IO_PENDING; | 551 return ERR_IO_PENDING; |
543 } | 552 } |
544 } | 553 } |
545 | 554 |
546 int HttpStreamFactoryImpl::Job::DoLoop(int result) { | 555 int HttpStreamFactoryImpl::Job::DoLoop(int result) { |
547 DCHECK_NE(next_state_, STATE_NONE); | 556 DCHECK_NE(next_state_, STATE_NONE); |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
971 // SSL socket, but there was an error before that could happen. This | 980 // SSL socket, but there was an error before that could happen. This |
972 // puts the in progress HttpProxy socket into |connection_| in order to | 981 // puts the in progress HttpProxy socket into |connection_| in order to |
973 // complete the auth (or read the response body). The tunnel restart code | 982 // complete the auth (or read the response body). The tunnel restart code |
974 // is careful to remove it before returning control to the rest of this | 983 // is careful to remove it before returning control to the rest of this |
975 // class. | 984 // class. |
976 connection_.reset(connection_->release_pending_http_proxy_connection()); | 985 connection_.reset(connection_->release_pending_http_proxy_connection()); |
977 return result; | 986 return result; |
978 } | 987 } |
979 | 988 |
980 if (!ssl_started && result < 0 && original_url_.get()) { | 989 if (!ssl_started && result < 0 && original_url_.get()) { |
981 HistogramBrokenAlternateProtocolLocation( | 990 job_status_ = STATUS_BROKEN; |
982 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB); | 991 MaybeMarkAlternateProtocolBroken(); |
983 // Mark the alternate protocol as broken and fallback. | |
984 session_->http_server_properties()->SetBrokenAlternateProtocol( | |
985 HostPortPair::FromURL(*original_url_)); | |
986 return result; | 992 return result; |
987 } | 993 } |
988 | 994 |
989 if (using_quic_) { | 995 if (using_quic_) { |
990 if (result < 0) | 996 if (result < 0) |
991 return result; | 997 return result; |
992 stream_ = quic_request_.ReleaseStream(); | 998 stream_ = quic_request_.ReleaseStream(); |
993 next_state_ = STATE_NONE; | 999 next_state_ = STATE_NONE; |
994 return OK; | 1000 return OK; |
995 } | 1001 } |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1460 } else if (original_url_) { | 1466 } else if (original_url_) { |
1461 // This job was the alternate protocol job, and hence won the race. | 1467 // This job was the alternate protocol job, and hence won the race. |
1462 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE); | 1468 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE); |
1463 } else { | 1469 } else { |
1464 // This job was the normal job, and hence the alternate protocol job lost | 1470 // This job was the normal job, and hence the alternate protocol job lost |
1465 // the race. | 1471 // the race. |
1466 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE); | 1472 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE); |
1467 } | 1473 } |
1468 } | 1474 } |
1469 | 1475 |
| 1476 void HttpStreamFactoryImpl::Job::MarkOtherJobComplete(const Job& job) { |
| 1477 DCHECK_EQ(STATUS_RUNNING, other_job_status_); |
| 1478 other_job_status_ = job.job_status_; |
| 1479 MaybeMarkAlternateProtocolBroken(); |
| 1480 } |
| 1481 |
1470 bool HttpStreamFactoryImpl::Job::IsRequestEligibleForPipelining() { | 1482 bool HttpStreamFactoryImpl::Job::IsRequestEligibleForPipelining() { |
1471 if (IsPreconnecting() || !request_) { | 1483 if (IsPreconnecting() || !request_) { |
1472 return false; | 1484 return false; |
1473 } | 1485 } |
1474 if (stream_factory_->for_websockets_) { | 1486 if (stream_factory_->for_websockets_) { |
1475 return false; | 1487 return false; |
1476 } | 1488 } |
1477 if (session_->force_http_pipelining()) { | 1489 if (session_->force_http_pipelining()) { |
1478 return true; | 1490 return true; |
1479 } | 1491 } |
1480 if (!session_->params().http_pipelining_enabled) { | 1492 if (!session_->params().http_pipelining_enabled) { |
1481 return false; | 1493 return false; |
1482 } | 1494 } |
1483 if (using_ssl_) { | 1495 if (using_ssl_) { |
1484 return false; | 1496 return false; |
1485 } | 1497 } |
1486 if (request_info_.method != "GET" && request_info_.method != "HEAD") { | 1498 if (request_info_.method != "GET" && request_info_.method != "HEAD") { |
1487 return false; | 1499 return false; |
1488 } | 1500 } |
1489 if (request_info_.load_flags & | 1501 if (request_info_.load_flags & |
1490 (net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME | net::LOAD_PREFETCH | | 1502 (net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME | net::LOAD_PREFETCH | |
1491 net::LOAD_IS_DOWNLOAD)) { | 1503 net::LOAD_IS_DOWNLOAD)) { |
1492 // Avoid pipelining resources that may be streamed for a long time. | 1504 // Avoid pipelining resources that may be streamed for a long time. |
1493 return false; | 1505 return false; |
1494 } | 1506 } |
1495 return stream_factory_->http_pipelined_host_pool_.IsKeyEligibleForPipelining( | 1507 return stream_factory_->http_pipelined_host_pool_.IsKeyEligibleForPipelining( |
1496 *http_pipelining_key_.get()); | 1508 *http_pipelining_key_.get()); |
1497 } | 1509 } |
1498 | 1510 |
| 1511 void HttpStreamFactoryImpl::Job::MaybeMarkAlternateProtocolBroken() { |
| 1512 if (job_status_ == STATUS_RUNNING || other_job_status_ == STATUS_RUNNING) |
| 1513 return; |
| 1514 |
| 1515 bool is_alternate_protocol_job = original_url_.get(); |
| 1516 if (is_alternate_protocol_job) { |
| 1517 if (job_status_ == STATUS_BROKEN && other_job_status_ == STATUS_SUCCEEDED) { |
| 1518 HistogramBrokenAlternateProtocolLocation( |
| 1519 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); |
| 1520 session_->http_server_properties()->SetBrokenAlternateProtocol( |
| 1521 HostPortPair::FromURL(*original_url_)); |
| 1522 } |
| 1523 return; |
| 1524 } |
| 1525 |
| 1526 if (job_status_ == STATUS_SUCCEEDED && other_job_status_ == STATUS_BROKEN) { |
| 1527 HistogramBrokenAlternateProtocolLocation( |
| 1528 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_MAIN); |
| 1529 session_->http_server_properties()->SetBrokenAlternateProtocol( |
| 1530 HostPortPair::FromURL(request_info_.url)); |
| 1531 } |
| 1532 } |
| 1533 |
1499 } // namespace net | 1534 } // namespace net |
OLD | NEW |