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 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 base::MessageLoop::current()->PostTask( | 511 base::MessageLoop::current()->PostTask( |
510 FROM_HERE, | 512 FROM_HERE, |
511 base::Bind(&Job::OnHttpsProxyTunnelResponseCallback, | 513 base::Bind(&Job::OnHttpsProxyTunnelResponseCallback, |
512 ptr_factory_.GetWeakPtr(), | 514 ptr_factory_.GetWeakPtr(), |
513 *proxy_socket->GetConnectResponseInfo(), | 515 *proxy_socket->GetConnectResponseInfo(), |
514 proxy_socket->CreateConnectResponseStream())); | 516 proxy_socket->CreateConnectResponseStream())); |
515 return ERR_IO_PENDING; | 517 return ERR_IO_PENDING; |
516 } | 518 } |
517 | 519 |
518 case OK: | 520 case OK: |
| 521 job_status_ = STATUS_SUCCEEDED; |
| 522 MaybeMarkAlternateProtocolBroken(); |
519 next_state_ = STATE_DONE; | 523 next_state_ = STATE_DONE; |
520 if (new_spdy_session_.get()) { | 524 if (new_spdy_session_.get()) { |
521 base::MessageLoop::current()->PostTask( | 525 base::MessageLoop::current()->PostTask( |
522 FROM_HERE, | 526 FROM_HERE, |
523 base::Bind(&Job::OnNewSpdySessionReadyCallback, | 527 base::Bind(&Job::OnNewSpdySessionReadyCallback, |
524 ptr_factory_.GetWeakPtr())); | 528 ptr_factory_.GetWeakPtr())); |
525 } else if (stream_factory_->for_websockets_) { | 529 } else if (stream_factory_->for_websockets_) { |
526 DCHECK(websocket_stream_); | 530 DCHECK(websocket_stream_); |
527 base::MessageLoop::current()->PostTask( | 531 base::MessageLoop::current()->PostTask( |
528 FROM_HERE, | 532 FROM_HERE, |
529 base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, | 533 base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, |
530 ptr_factory_.GetWeakPtr())); | 534 ptr_factory_.GetWeakPtr())); |
531 } else { | 535 } else { |
532 DCHECK(stream_.get()); | 536 DCHECK(stream_.get()); |
533 base::MessageLoop::current()->PostTask( | 537 base::MessageLoop::current()->PostTask( |
534 FROM_HERE, | 538 FROM_HERE, |
535 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); | 539 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); |
536 } | 540 } |
537 return ERR_IO_PENDING; | 541 return ERR_IO_PENDING; |
538 | 542 |
539 default: | 543 default: |
| 544 if (job_status_ != STATUS_BROKEN) { |
| 545 DCHECK_EQ(STATUS_RUNNING, job_status_); |
| 546 job_status_ = STATUS_FAILED; |
| 547 MaybeMarkAlternateProtocolBroken(); |
| 548 } |
540 base::MessageLoop::current()->PostTask( | 549 base::MessageLoop::current()->PostTask( |
541 FROM_HERE, | 550 FROM_HERE, |
542 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), | 551 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), |
543 result)); | 552 result)); |
544 return ERR_IO_PENDING; | 553 return ERR_IO_PENDING; |
545 } | 554 } |
546 } | 555 } |
547 | 556 |
548 int HttpStreamFactoryImpl::Job::DoLoop(int result) { | 557 int HttpStreamFactoryImpl::Job::DoLoop(int result) { |
549 DCHECK_NE(next_state_, STATE_NONE); | 558 DCHECK_NE(next_state_, STATE_NONE); |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 | 990 |
982 if (using_quic_) { | 991 if (using_quic_) { |
983 if (result < 0) | 992 if (result < 0) |
984 return result; | 993 return result; |
985 stream_ = quic_request_.ReleaseStream(); | 994 stream_ = quic_request_.ReleaseStream(); |
986 next_state_ = STATE_NONE; | 995 next_state_ = STATE_NONE; |
987 return OK; | 996 return OK; |
988 } | 997 } |
989 | 998 |
990 if (!ssl_started && result < 0 && original_url_.get()) { | 999 if (!ssl_started && result < 0 && original_url_.get()) { |
991 HistogramBrokenAlternateProtocolLocation( | 1000 job_status_ = STATUS_BROKEN; |
992 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB); | 1001 MaybeMarkAlternateProtocolBroken(); |
993 // Mark the alternate protocol as broken and fallback. | |
994 session_->http_server_properties()->SetBrokenAlternateProtocol( | |
995 HostPortPair::FromURL(*original_url_)); | |
996 return result; | 1002 return result; |
997 } | 1003 } |
998 | 1004 |
999 if (result < 0 && !ssl_started) | 1005 if (result < 0 && !ssl_started) |
1000 return ReconsiderProxyAfterError(result); | 1006 return ReconsiderProxyAfterError(result); |
1001 establishing_tunnel_ = false; | 1007 establishing_tunnel_ = false; |
1002 | 1008 |
1003 if (connection_->socket()) { | 1009 if (connection_->socket()) { |
1004 LogHttpConnectedMetrics(*connection_); | 1010 LogHttpConnectedMetrics(*connection_); |
1005 | 1011 |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 } else if (original_url_) { | 1468 } else if (original_url_) { |
1463 // This job was the alternate protocol job, and hence won the race. | 1469 // This job was the alternate protocol job, and hence won the race. |
1464 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE); | 1470 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE); |
1465 } else { | 1471 } else { |
1466 // This job was the normal job, and hence the alternate protocol job lost | 1472 // This job was the normal job, and hence the alternate protocol job lost |
1467 // the race. | 1473 // the race. |
1468 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE); | 1474 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE); |
1469 } | 1475 } |
1470 } | 1476 } |
1471 | 1477 |
| 1478 void HttpStreamFactoryImpl::Job::MarkOtherJobComplete(const Job& job) { |
| 1479 DCHECK_EQ(STATUS_RUNNING, other_job_status_); |
| 1480 other_job_status_ = job.job_status_; |
| 1481 MaybeMarkAlternateProtocolBroken(); |
| 1482 } |
| 1483 |
1472 bool HttpStreamFactoryImpl::Job::IsRequestEligibleForPipelining() { | 1484 bool HttpStreamFactoryImpl::Job::IsRequestEligibleForPipelining() { |
1473 if (IsPreconnecting() || !request_) { | 1485 if (IsPreconnecting() || !request_) { |
1474 return false; | 1486 return false; |
1475 } | 1487 } |
1476 if (stream_factory_->for_websockets_) { | 1488 if (stream_factory_->for_websockets_) { |
1477 return false; | 1489 return false; |
1478 } | 1490 } |
1479 if (session_->force_http_pipelining()) { | 1491 if (session_->force_http_pipelining()) { |
1480 return true; | 1492 return true; |
1481 } | 1493 } |
1482 if (!session_->params().http_pipelining_enabled) { | 1494 if (!session_->params().http_pipelining_enabled) { |
1483 return false; | 1495 return false; |
1484 } | 1496 } |
1485 if (using_ssl_) { | 1497 if (using_ssl_) { |
1486 return false; | 1498 return false; |
1487 } | 1499 } |
1488 if (request_info_.method != "GET" && request_info_.method != "HEAD") { | 1500 if (request_info_.method != "GET" && request_info_.method != "HEAD") { |
1489 return false; | 1501 return false; |
1490 } | 1502 } |
1491 if (request_info_.load_flags & | 1503 if (request_info_.load_flags & |
1492 (net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME | net::LOAD_PREFETCH | | 1504 (net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME | net::LOAD_PREFETCH | |
1493 net::LOAD_IS_DOWNLOAD)) { | 1505 net::LOAD_IS_DOWNLOAD)) { |
1494 // Avoid pipelining resources that may be streamed for a long time. | 1506 // Avoid pipelining resources that may be streamed for a long time. |
1495 return false; | 1507 return false; |
1496 } | 1508 } |
1497 return stream_factory_->http_pipelined_host_pool_.IsKeyEligibleForPipelining( | 1509 return stream_factory_->http_pipelined_host_pool_.IsKeyEligibleForPipelining( |
1498 *http_pipelining_key_.get()); | 1510 *http_pipelining_key_.get()); |
1499 } | 1511 } |
1500 | 1512 |
| 1513 void HttpStreamFactoryImpl::Job::MaybeMarkAlternateProtocolBroken() { |
| 1514 if (job_status_ == STATUS_RUNNING || other_job_status_ == STATUS_RUNNING) |
| 1515 return; |
| 1516 |
| 1517 bool is_alternate_protocol_job = original_url_.get() != NULL; |
| 1518 if (is_alternate_protocol_job) { |
| 1519 if (job_status_ == STATUS_BROKEN && other_job_status_ == STATUS_SUCCEEDED) { |
| 1520 HistogramBrokenAlternateProtocolLocation( |
| 1521 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); |
| 1522 session_->http_server_properties()->SetBrokenAlternateProtocol( |
| 1523 HostPortPair::FromURL(*original_url_)); |
| 1524 } |
| 1525 return; |
| 1526 } |
| 1527 |
| 1528 if (job_status_ == STATUS_SUCCEEDED && other_job_status_ == STATUS_BROKEN) { |
| 1529 HistogramBrokenAlternateProtocolLocation( |
| 1530 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_MAIN); |
| 1531 session_->http_server_properties()->SetBrokenAlternateProtocol( |
| 1532 HostPortPair::FromURL(request_info_.url)); |
| 1533 } |
| 1534 } |
| 1535 |
1501 } // namespace net | 1536 } // namespace net |
OLD | NEW |