Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: net/http/http_stream_factory_impl_job.cc

Issue 7289006: Basic HTTP pipelining support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added about:flags entry Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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-inl.h" 8 #include "base/stl_util-inl.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
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
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()) {
mmenke 2011/08/03 21:09:39 Looks to me like you're implicitly not using pipel
James Simonsen 2011/08/05 01:39:00 Done.
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
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(new HttpPipelinedStream(existing_available_pipeline_));
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(new HttpPipelinedStream(pipeline));
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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 1102
1067 bool HttpStreamFactoryImpl::Job::IsPreconnecting() const { 1103 bool HttpStreamFactoryImpl::Job::IsPreconnecting() const {
1068 DCHECK_GE(num_streams_, 0); 1104 DCHECK_GE(num_streams_, 0);
1069 return num_streams_ > 0; 1105 return num_streams_ > 0;
1070 } 1106 }
1071 1107
1072 bool HttpStreamFactoryImpl::Job::IsOrphaned() const { 1108 bool HttpStreamFactoryImpl::Job::IsOrphaned() const {
1073 return !IsPreconnecting() && !request_; 1109 return !IsPreconnecting() && !request_;
1074 } 1110 }
1075 1111
1112 bool HttpStreamFactoryImpl::Job::IsRequestEligibleForPipelining() const {
1113 if (!HttpStreamFactory::http_pipelining_enabled()) {
1114 return false;
1115 }
1116 if (IsPreconnecting() || !request_) {
1117 return false;
1118 }
1119 return request_info_.method == "GET" || request_info_.method == "HEAD";
1120 }
1121
1076 #if defined(OS_WIN) 1122 #if defined(OS_WIN)
1077 #pragma warning (disable: 4748) 1123 #pragma warning (disable: 4748)
1078 #pragma optimize( "", off ) 1124 #pragma optimize( "", off )
1079 #endif 1125 #endif
1080 1126
1081 void HttpStreamFactoryImpl::Job::HACKCrashHereToDebug80095() { 1127 void HttpStreamFactoryImpl::Job::HACKCrashHereToDebug80095() {
1082 // If we enter this code path, then we'll cause a crash later in 1128 // If we enter this code path, then we'll cause a crash later in
1083 // DoCreateStream(). Crash now and figure out what happened: 1129 // DoCreateStream(). Crash now and figure out what happened:
1084 // http://crbug.com/80095. 1130 // http://crbug.com/80095.
1085 GURL url = original_url_.get() ? *original_url_ : request_info_.url; 1131 GURL url = original_url_.get() ? *original_url_ : request_info_.url;
(...skipping 24 matching lines...) Expand all
1110 << (using_spdy ? "true\n" : "false\n"); 1156 << (using_spdy ? "true\n" : "false\n");
1111 } 1157 }
1112 } 1158 }
1113 1159
1114 #if defined(OS_WIN) 1160 #if defined(OS_WIN)
1115 #pragma optimize( "", on ) 1161 #pragma optimize( "", on )
1116 #pragma warning (default: 4748) 1162 #pragma warning (default: 4748)
1117 #endif 1163 #endif
1118 1164
1119 } // namespace net 1165 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698