Chromium Code Reviews| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 555 int rv = RunLoop(OK); | 555 int rv = RunLoop(OK); |
| 556 DCHECK_EQ(ERR_IO_PENDING, rv); | 556 DCHECK_EQ(ERR_IO_PENDING, rv); |
| 557 return rv; | 557 return rv; |
| 558 } | 558 } |
| 559 | 559 |
| 560 int HttpStreamFactoryImpl::Job::DoStart() { | 560 int HttpStreamFactoryImpl::Job::DoStart() { |
| 561 int port = request_info_.url.EffectiveIntPort(); | 561 int port = request_info_.url.EffectiveIntPort(); |
| 562 origin_ = HostPortPair(request_info_.url.HostNoBrackets(), port); | 562 origin_ = HostPortPair(request_info_.url.HostNoBrackets(), port); |
| 563 origin_url_ = HttpStreamFactory::ApplyHostMappingRules( | 563 origin_url_ = HttpStreamFactory::ApplyHostMappingRules( |
| 564 request_info_.url, &origin_); | 564 request_info_.url, &origin_); |
| 565 http_pipelining_key_.reset(new HttpPipelinedHost::Key(origin_)); | |
| 565 | 566 |
| 566 net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_JOB, | 567 net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_JOB, |
| 567 HttpStreamJobParameters::Create(request_info_.url, | 568 HttpStreamJobParameters::Create(request_info_.url, |
| 568 origin_url_)); | 569 origin_url_)); |
| 569 | 570 |
| 570 // Don't connect to restricted ports. | 571 // Don't connect to restricted ports. |
| 571 if (!IsPortAllowedByDefault(port) && !IsPortAllowedByOverride(port)) { | 572 if (!IsPortAllowedByDefault(port) && !IsPortAllowedByOverride(port)) { |
| 572 if (waiting_job_) { | 573 if (waiting_job_) { |
| 573 waiting_job_->Resume(this); | 574 waiting_job_->Resume(this); |
| 574 waiting_job_ = NULL; | 575 waiting_job_ = NULL; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 next_state_ = STATE_CREATE_STREAM; | 680 next_state_ = STATE_CREATE_STREAM; |
| 680 existing_spdy_session_ = spdy_session; | 681 existing_spdy_session_ = spdy_session; |
| 681 return OK; | 682 return OK; |
| 682 } else if (request_ && (using_ssl_ || ShouldForceSpdyWithoutSSL())) { | 683 } else if (request_ && (using_ssl_ || ShouldForceSpdyWithoutSSL())) { |
| 683 // Update the spdy session key for the request that launched this job. | 684 // Update the spdy session key for the request that launched this job. |
| 684 request_->SetSpdySessionKey(spdy_session_key); | 685 request_->SetSpdySessionKey(spdy_session_key); |
| 685 } else if (IsRequestEligibleForPipelining()) { | 686 } else if (IsRequestEligibleForPipelining()) { |
| 686 // TODO(simonjam): With pipelining, we might be better off using fewer | 687 // TODO(simonjam): With pipelining, we might be better off using fewer |
| 687 // connections and thus should make fewer preconnections. Explore | 688 // connections and thus should make fewer preconnections. Explore |
| 688 // preconnecting fewer than the requested num_connections. | 689 // preconnecting fewer than the requested num_connections. |
| 690 // | |
| 691 // Separate note: A forced pipeline is always available if one exists for | |
| 692 // this key. This is different than normal pipelines, which may be | |
| 693 // unavailable or unusable. So, there is no need to worry about a race | |
| 694 // between when a pipeline becomes available and when this job blocks. | |
| 689 existing_available_pipeline_ = stream_factory_->http_pipelined_host_pool_. | 695 existing_available_pipeline_ = stream_factory_->http_pipelined_host_pool_. |
| 690 IsExistingPipelineAvailableForOrigin(origin_); | 696 IsExistingPipelineAvailableForKey(*http_pipelining_key_.get()); |
| 691 if (existing_available_pipeline_) { | 697 if (existing_available_pipeline_) { |
| 692 return OK; | 698 return OK; |
| 693 } else { | 699 } else { |
| 694 request_->SetHttpPipeliningKey(origin_); | 700 bool was_new_key = request_->SetHttpPipeliningKey( |
| 701 *http_pipelining_key_.get()); | |
| 702 if (!was_new_key && session_->force_http_pipelining()) { | |
| 703 return ERR_IO_PENDING; | |
|
mmenke
2012/03/01 16:50:30
I'm not sure this address's Will's concern about H
James Simonsen
2012/03/01 18:49:29
Any ideas?
The "right" thing to do would be to wr
mmenke
2012/03/01 19:10:09
I was thinking maybe a subclass...Not sure how wor
| |
| 704 } | |
| 695 } | 705 } |
| 696 } | 706 } |
| 697 | 707 |
| 698 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's | 708 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's |
| 699 // paused. | 709 // paused. |
| 700 | 710 |
| 701 if (waiting_job_) { | 711 if (waiting_job_) { |
| 702 waiting_job_->Resume(this); | 712 waiting_job_->Resume(this); |
| 703 waiting_job_ = NULL; | 713 waiting_job_ = NULL; |
| 704 } | 714 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 748 return OK; | 758 return OK; |
| 749 } | 759 } |
| 750 | 760 |
| 751 // TODO(willchan): Make this a bit more exact. Maybe there are recoverable | 761 // TODO(willchan): Make this a bit more exact. Maybe there are recoverable |
| 752 // errors, such as ignoring certificate errors for Alternate-Protocol. | 762 // errors, such as ignoring certificate errors for Alternate-Protocol. |
| 753 if (result < 0 && waiting_job_) { | 763 if (result < 0 && waiting_job_) { |
| 754 waiting_job_->Resume(this); | 764 waiting_job_->Resume(this); |
| 755 waiting_job_ = NULL; | 765 waiting_job_ = NULL; |
| 756 } | 766 } |
| 757 | 767 |
| 768 if (result < 0 && session_->force_http_pipelining()) { | |
| 769 stream_factory_->AbortPipelinedRequestsWithKey( | |
| 770 this, *http_pipelining_key_.get(), result, server_ssl_config_); | |
| 771 } | |
| 772 | |
| 758 // |result| may be the result of any of the stacked pools. The following | 773 // |result| may be the result of any of the stacked pools. The following |
| 759 // logic is used when determining how to interpret an error. | 774 // logic is used when determining how to interpret an error. |
| 760 // If |result| < 0: | 775 // If |result| < 0: |
| 761 // and connection_->socket() != NULL, then the SSL handshake ran and it | 776 // and connection_->socket() != NULL, then the SSL handshake ran and it |
| 762 // is a potentially recoverable error. | 777 // is a potentially recoverable error. |
| 763 // and connection_->socket == NULL and connection_->is_ssl_error() is true, | 778 // and connection_->socket == NULL and connection_->is_ssl_error() is true, |
| 764 // then the SSL handshake ran with an unrecoverable error. | 779 // then the SSL handshake ran with an unrecoverable error. |
| 765 // otherwise, the error came from one of the other pools. | 780 // otherwise, the error came from one of the other pools. |
| 766 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || | 781 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || |
| 767 connection_->is_ssl_error()); | 782 connection_->is_ssl_error()); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 880 // need to plumb this through to the connect level. | 895 // need to plumb this through to the connect level. |
| 881 if (connection_->socket() && !connection_->is_reused()) | 896 if (connection_->socket() && !connection_->is_reused()) |
| 882 SetSocketMotivation(); | 897 SetSocketMotivation(); |
| 883 | 898 |
| 884 const ProxyServer& proxy_server = proxy_info_.proxy_server(); | 899 const ProxyServer& proxy_server = proxy_info_.proxy_server(); |
| 885 | 900 |
| 886 if (!using_spdy_) { | 901 if (!using_spdy_) { |
| 887 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && | 902 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && |
| 888 request_info_.url.SchemeIs("http"); | 903 request_info_.url.SchemeIs("http"); |
| 889 // TODO(simonjam): Support proxies. | 904 // TODO(simonjam): Support proxies. |
| 890 if (existing_available_pipeline_) { | 905 if (stream_factory_->http_pipelined_host_pool_. |
| 906 IsExistingPipelineAvailableForKey(*http_pipelining_key_.get())) { | |
| 891 stream_.reset(stream_factory_->http_pipelined_host_pool_. | 907 stream_.reset(stream_factory_->http_pipelined_host_pool_. |
| 892 CreateStreamOnExistingPipeline(origin_)); | 908 CreateStreamOnExistingPipeline( |
| 909 *http_pipelining_key_.get())); | |
| 893 CHECK(stream_.get()); | 910 CHECK(stream_.get()); |
| 894 } else if (!using_proxy && IsRequestEligibleForPipelining()) { | 911 } else if (!using_proxy && IsRequestEligibleForPipelining()) { |
| 895 stream_.reset( | 912 stream_.reset( |
| 896 stream_factory_->http_pipelined_host_pool_.CreateStreamOnNewPipeline( | 913 stream_factory_->http_pipelined_host_pool_.CreateStreamOnNewPipeline( |
| 897 origin_, | 914 *http_pipelining_key_.get(), |
| 898 connection_.release(), | 915 connection_.release(), |
| 899 server_ssl_config_, | 916 server_ssl_config_, |
| 900 proxy_info_, | 917 proxy_info_, |
| 901 net_log_, | 918 net_log_, |
| 902 was_npn_negotiated_, | 919 was_npn_negotiated_, |
| 903 protocol_negotiated_)); | 920 protocol_negotiated_)); |
| 904 CHECK(stream_.get()); | 921 CHECK(stream_.get()); |
| 905 } else { | 922 } else { |
| 906 stream_.reset(new HttpBasicStream(connection_.release(), NULL, | 923 stream_.reset(new HttpBasicStream(connection_.release(), NULL, |
| 907 using_proxy)); | 924 using_proxy)); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1202 bool HttpStreamFactoryImpl::Job::IsPreconnecting() const { | 1219 bool HttpStreamFactoryImpl::Job::IsPreconnecting() const { |
| 1203 DCHECK_GE(num_streams_, 0); | 1220 DCHECK_GE(num_streams_, 0); |
| 1204 return num_streams_ > 0; | 1221 return num_streams_ > 0; |
| 1205 } | 1222 } |
| 1206 | 1223 |
| 1207 bool HttpStreamFactoryImpl::Job::IsOrphaned() const { | 1224 bool HttpStreamFactoryImpl::Job::IsOrphaned() const { |
| 1208 return !IsPreconnecting() && !request_; | 1225 return !IsPreconnecting() && !request_; |
| 1209 } | 1226 } |
| 1210 | 1227 |
| 1211 bool HttpStreamFactoryImpl::Job::IsRequestEligibleForPipelining() { | 1228 bool HttpStreamFactoryImpl::Job::IsRequestEligibleForPipelining() { |
| 1229 if (IsPreconnecting() || !request_) { | |
| 1230 return false; | |
| 1231 } | |
| 1232 if (session_->force_http_pipelining()) { | |
| 1233 return true; | |
| 1234 } | |
| 1212 if (!HttpStreamFactory::http_pipelining_enabled()) { | 1235 if (!HttpStreamFactory::http_pipelining_enabled()) { |
| 1213 return false; | 1236 return false; |
| 1214 } | 1237 } |
| 1215 if (IsPreconnecting() || !request_) { | |
| 1216 return false; | |
| 1217 } | |
| 1218 if (using_ssl_) { | 1238 if (using_ssl_) { |
| 1219 return false; | 1239 return false; |
| 1220 } | 1240 } |
| 1221 if (request_info_.method != "GET" && request_info_.method != "HEAD") { | 1241 if (request_info_.method != "GET" && request_info_.method != "HEAD") { |
| 1222 return false; | 1242 return false; |
| 1223 } | 1243 } |
| 1224 return stream_factory_->http_pipelined_host_pool_.IsHostEligibleForPipelining( | 1244 return stream_factory_->http_pipelined_host_pool_.IsKeyEligibleForPipelining( |
| 1225 origin_); | 1245 *http_pipelining_key_.get()); |
| 1226 } | 1246 } |
| 1227 | 1247 |
| 1228 } // namespace net | 1248 } // namespace net |
| OLD | NEW |