Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 11 #include "base/values.h" | 11 #include "base/values.h" |
| 12 #include "build/build_config.h" | 12 #include "build/build_config.h" |
| 13 #include "net/base/connection_type_histograms.h" | 13 #include "net/base/connection_type_histograms.h" |
| 14 #include "net/base/net_log.h" | 14 #include "net/base/net_log.h" |
| 15 #include "net/base/net_util.h" | 15 #include "net/base/net_util.h" |
| 16 #include "net/base/ssl_cert_request_info.h" | 16 #include "net/base/ssl_cert_request_info.h" |
| 17 #include "net/http/http_basic_stream.h" | 17 #include "net/http/http_basic_stream.h" |
| 18 #include "net/http/http_network_session.h" | 18 #include "net/http/http_network_session.h" |
| 19 #include "net/http/http_pipelined_connection.h" | |
| 20 #include "net/http/http_pipelined_host.h" | |
| 21 #include "net/http/http_pipelined_host_pool.h" | |
| 22 #include "net/http/http_pipelined_stream.h" | |
| 19 #include "net/http/http_proxy_client_socket.h" | 23 #include "net/http/http_proxy_client_socket.h" |
| 20 #include "net/http/http_proxy_client_socket_pool.h" | 24 #include "net/http/http_proxy_client_socket_pool.h" |
| 21 #include "net/http/http_request_info.h" | 25 #include "net/http/http_request_info.h" |
| 26 #include "net/http/http_stream_factory.h" | |
| 22 #include "net/http/http_stream_factory_impl_request.h" | 27 #include "net/http/http_stream_factory_impl_request.h" |
| 23 #include "net/socket/client_socket_handle.h" | 28 #include "net/socket/client_socket_handle.h" |
| 24 #include "net/socket/client_socket_pool.h" | 29 #include "net/socket/client_socket_pool.h" |
| 25 #include "net/socket/socks_client_socket_pool.h" | 30 #include "net/socket/socks_client_socket_pool.h" |
| 26 #include "net/socket/ssl_client_socket.h" | 31 #include "net/socket/ssl_client_socket.h" |
| 27 #include "net/socket/ssl_client_socket_pool.h" | 32 #include "net/socket/ssl_client_socket_pool.h" |
| 28 #include "net/spdy/spdy_http_stream.h" | 33 #include "net/spdy/spdy_http_stream.h" |
| 29 #include "net/spdy/spdy_session.h" | 34 #include "net/spdy/spdy_session.h" |
| 30 #include "net/spdy/spdy_session_pool.h" | 35 #include "net/spdy/spdy_session_pool.h" |
| 31 | 36 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 dependent_job_(NULL), | 83 dependent_job_(NULL), |
| 79 using_ssl_(false), | 84 using_ssl_(false), |
| 80 using_spdy_(false), | 85 using_spdy_(false), |
| 81 force_spdy_always_(HttpStreamFactory::force_spdy_always()), | 86 force_spdy_always_(HttpStreamFactory::force_spdy_always()), |
| 82 force_spdy_over_ssl_(HttpStreamFactory::force_spdy_over_ssl()), | 87 force_spdy_over_ssl_(HttpStreamFactory::force_spdy_over_ssl()), |
| 83 spdy_certificate_error_(OK), | 88 spdy_certificate_error_(OK), |
| 84 establishing_tunnel_(false), | 89 establishing_tunnel_(false), |
| 85 was_npn_negotiated_(false), | 90 was_npn_negotiated_(false), |
| 86 num_streams_(0), | 91 num_streams_(0), |
| 87 spdy_session_direct_(false), | 92 spdy_session_direct_(false), |
| 93 existing_available_pipeline_(NULL), | |
| 88 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { | 94 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
| 89 DCHECK(stream_factory); | 95 DCHECK(stream_factory); |
| 90 DCHECK(session); | 96 DCHECK(session); |
| 91 } | 97 } |
| 92 | 98 |
| 93 HttpStreamFactoryImpl::Job::~Job() { | 99 HttpStreamFactoryImpl::Job::~Job() { |
| 94 net_log_.EndEvent(NetLog::TYPE_HTTP_STREAM_JOB, NULL); | 100 net_log_.EndEvent(NetLog::TYPE_HTTP_STREAM_JOB, NULL); |
| 95 | 101 |
| 96 // When we're in a partially constructed state, waiting for the user to | 102 // When we're in a partially constructed state, waiting for the user to |
| 97 // provide certificate handling information or authentication, we can't reuse | 103 // provide certificate handling information or authentication, we can't reuse |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 573 // actually need to preconnect any sockets, so we're done. | 579 // actually need to preconnect any sockets, so we're done. |
| 574 if (IsPreconnecting()) | 580 if (IsPreconnecting()) |
| 575 return OK; | 581 return OK; |
| 576 using_spdy_ = true; | 582 using_spdy_ = true; |
| 577 next_state_ = STATE_CREATE_STREAM; | 583 next_state_ = STATE_CREATE_STREAM; |
| 578 existing_spdy_session_ = spdy_session; | 584 existing_spdy_session_ = spdy_session; |
| 579 return OK; | 585 return OK; |
| 580 } else if (request_ && (using_ssl_ || ShouldForceSpdyWithoutSSL())) { | 586 } else if (request_ && (using_ssl_ || ShouldForceSpdyWithoutSSL())) { |
| 581 // Update the spdy session key for the request that launched this job. | 587 // Update the spdy session key for the request that launched this job. |
| 582 request_->SetSpdySessionKey(spdy_session_key); | 588 request_->SetSpdySessionKey(spdy_session_key); |
| 589 } else if (IsRequestEligibleForPipelining()) { | |
|
willchan no longer on Chromium
2011/09/03 01:11:06
If we're preconnecting, you may want to choose thi
James Simonsen
2011/09/07 21:20:10
Done.
Yeah, that's an interesting topic. It might
| |
| 590 HttpPipelinedHost* host = session_->http_pipelined_host_pool()-> | |
| 591 GetPipelinedHostIfExists(origin_); | |
| 592 if (host) { | |
| 593 HttpPipelinedConnection* connection = host->FindAvailablePipeline(); | |
| 594 if (connection) { | |
| 595 next_state_ = STATE_CREATE_STREAM; | |
| 596 existing_available_pipeline_ = connection; | |
| 597 return OK; | |
| 598 } | |
| 599 } | |
| 600 request_->SetHttpPipeliningKey(origin_); | |
| 583 } | 601 } |
| 584 | 602 |
| 585 // OK, there's no available SPDY session. Let |dependent_job_| resume if it's | 603 // OK, there's no available SPDY session. Let |dependent_job_| resume if it's |
| 586 // paused. | 604 // paused. |
| 587 | 605 |
| 588 if (dependent_job_) { | 606 if (dependent_job_) { |
| 589 dependent_job_->Resume(this); | 607 dependent_job_->Resume(this); |
| 590 dependent_job_ = NULL; | 608 dependent_job_ = NULL; |
| 591 } | 609 } |
| 592 | 610 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 750 int HttpStreamFactoryImpl::Job::DoWaitingUserAction(int result) { | 768 int HttpStreamFactoryImpl::Job::DoWaitingUserAction(int result) { |
| 751 // This state indicates that the stream request is in a partially | 769 // This state indicates that the stream request is in a partially |
| 752 // completed state, and we've called back to the delegate for more | 770 // completed state, and we've called back to the delegate for more |
| 753 // information. | 771 // information. |
| 754 | 772 |
| 755 // We're always waiting here for the delegate to call us back. | 773 // We're always waiting here for the delegate to call us back. |
| 756 return ERR_IO_PENDING; | 774 return ERR_IO_PENDING; |
| 757 } | 775 } |
| 758 | 776 |
| 759 int HttpStreamFactoryImpl::Job::DoCreateStream() { | 777 int HttpStreamFactoryImpl::Job::DoCreateStream() { |
| 760 if (!connection_->socket() && !existing_spdy_session_) | 778 if (!connection_->socket() && !existing_spdy_session_ && |
| 779 !existing_available_pipeline_) | |
| 761 HACKCrashHereToDebug80095(); | 780 HACKCrashHereToDebug80095(); |
| 762 | 781 |
| 782 DCHECK(connection_->socket() || existing_spdy_session_ || | |
| 783 existing_available_pipeline_); | |
| 784 | |
| 763 next_state_ = STATE_CREATE_STREAM_COMPLETE; | 785 next_state_ = STATE_CREATE_STREAM_COMPLETE; |
| 764 | 786 |
| 765 // We only set the socket motivation if we're the first to use | 787 // We only set the socket motivation if we're the first to use |
| 766 // this socket. Is there a race for two SPDY requests? We really | 788 // this socket. Is there a race for two SPDY requests? We really |
| 767 // need to plumb this through to the connect level. | 789 // need to plumb this through to the connect level. |
| 768 if (connection_->socket() && !connection_->is_reused()) | 790 if (connection_->socket() && !connection_->is_reused()) |
| 769 SetSocketMotivation(); | 791 SetSocketMotivation(); |
| 770 | 792 |
| 771 const ProxyServer& proxy_server = proxy_info_.proxy_server(); | 793 const ProxyServer& proxy_server = proxy_info_.proxy_server(); |
| 772 | 794 |
| 773 if (!using_spdy_) { | 795 if (!using_spdy_) { |
| 774 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && | 796 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && |
| 775 request_info_.url.SchemeIs("http"); | 797 request_info_.url.SchemeIs("http"); |
| 776 stream_.reset(new HttpBasicStream(connection_.release(), NULL, | 798 // TODO(simonjam): Support proxies. |
| 777 using_proxy)); | 799 if (existing_available_pipeline_) { |
| 800 stream_.reset(existing_available_pipeline_->CreateNewStream()); | |
| 801 } else if (!using_proxy && IsRequestEligibleForPipelining()) { | |
| 802 HttpPipelinedConnection* pipeline = session_->http_pipelined_host_pool()-> | |
| 803 GetOrCreatePipelinedHost(origin_)->CreateNewPipeline( | |
| 804 connection_.release(), | |
| 805 ssl_config_, | |
| 806 proxy_info_, | |
| 807 net_log_, | |
| 808 was_npn_negotiated_); | |
| 809 stream_.reset(pipeline->CreateNewStream()); | |
| 810 } else { | |
| 811 stream_.reset(new HttpBasicStream(connection_.release(), NULL, | |
| 812 using_proxy)); | |
| 813 } | |
| 778 return OK; | 814 return OK; |
| 779 } | 815 } |
| 780 | 816 |
| 781 CHECK(!stream_.get()); | 817 CHECK(!stream_.get()); |
| 782 | 818 |
| 783 if (!connection_->socket() && !existing_spdy_session_) | 819 if (!connection_->socket() && !existing_spdy_session_) |
| 784 HACKCrashHereToDebug80095(); | 820 HACKCrashHereToDebug80095(); |
| 785 | 821 |
| 786 bool direct = true; | 822 bool direct = true; |
| 787 HostPortProxyPair pair(origin_, proxy_server); | 823 HostPortProxyPair pair(origin_, proxy_server); |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1072 | 1108 |
| 1073 bool HttpStreamFactoryImpl::Job::IsPreconnecting() const { | 1109 bool HttpStreamFactoryImpl::Job::IsPreconnecting() const { |
| 1074 DCHECK_GE(num_streams_, 0); | 1110 DCHECK_GE(num_streams_, 0); |
| 1075 return num_streams_ > 0; | 1111 return num_streams_ > 0; |
| 1076 } | 1112 } |
| 1077 | 1113 |
| 1078 bool HttpStreamFactoryImpl::Job::IsOrphaned() const { | 1114 bool HttpStreamFactoryImpl::Job::IsOrphaned() const { |
| 1079 return !IsPreconnecting() && !request_; | 1115 return !IsPreconnecting() && !request_; |
| 1080 } | 1116 } |
| 1081 | 1117 |
| 1118 bool HttpStreamFactoryImpl::Job::IsRequestEligibleForPipelining() const { | |
| 1119 if (!HttpStreamFactory::http_pipelining_enabled()) { | |
| 1120 return false; | |
| 1121 } | |
| 1122 if (IsPreconnecting() || !request_) { | |
| 1123 return false; | |
| 1124 } | |
| 1125 if (using_ssl_) { | |
| 1126 return false; | |
| 1127 } | |
| 1128 return request_info_.method == "GET" || request_info_.method == "HEAD"; | |
| 1129 } | |
| 1130 | |
| 1082 #if defined(OS_WIN) | 1131 #if defined(OS_WIN) |
| 1083 #pragma warning (disable: 4748) | 1132 #pragma warning (disable: 4748) |
| 1084 #pragma optimize( "", off ) | 1133 #pragma optimize( "", off ) |
| 1085 #endif | 1134 #endif |
| 1086 | 1135 |
| 1087 void HttpStreamFactoryImpl::Job::HACKCrashHereToDebug80095() { | 1136 void HttpStreamFactoryImpl::Job::HACKCrashHereToDebug80095() { |
| 1088 // If we enter this code path, then we'll cause a crash later in | 1137 // If we enter this code path, then we'll cause a crash later in |
| 1089 // DoCreateStream(). Crash now and figure out what happened: | 1138 // DoCreateStream(). Crash now and figure out what happened: |
| 1090 // http://crbug.com/80095. | 1139 // http://crbug.com/80095. |
| 1091 GURL url = original_url_.get() ? *original_url_ : request_info_.url; | 1140 GURL url = original_url_.get() ? *original_url_ : request_info_.url; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1116 << (using_spdy ? "true\n" : "false\n"); | 1165 << (using_spdy ? "true\n" : "false\n"); |
| 1117 } | 1166 } |
| 1118 } | 1167 } |
| 1119 | 1168 |
| 1120 #if defined(OS_WIN) | 1169 #if defined(OS_WIN) |
| 1121 #pragma optimize( "", on ) | 1170 #pragma optimize( "", on ) |
| 1122 #pragma warning (default: 4748) | 1171 #pragma warning (default: 4748) |
| 1123 #endif | 1172 #endif |
| 1124 | 1173 |
| 1125 } // namespace net | 1174 } // namespace net |
| OLD | NEW |