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( |
| 566 origin_, (request_info_.load_flags & LOAD_FORCE_HTTP_PIPELINING) != 0)); |
565 | 567 |
566 net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_JOB, | 568 net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_JOB, |
567 HttpStreamJobParameters::Create(request_info_.url, | 569 HttpStreamJobParameters::Create(request_info_.url, |
568 origin_url_)); | 570 origin_url_)); |
569 | 571 |
570 // Don't connect to restricted ports. | 572 // Don't connect to restricted ports. |
571 if (!IsPortAllowedByDefault(port) && !IsPortAllowedByOverride(port)) { | 573 if (!IsPortAllowedByDefault(port) && !IsPortAllowedByOverride(port)) { |
572 if (waiting_job_) { | 574 if (waiting_job_) { |
573 waiting_job_->Resume(this); | 575 waiting_job_->Resume(this); |
574 waiting_job_ = NULL; | 576 waiting_job_ = NULL; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 existing_spdy_session_ = spdy_session; | 682 existing_spdy_session_ = spdy_session; |
681 return OK; | 683 return OK; |
682 } else if (request_ && (using_ssl_ || ShouldForceSpdyWithoutSSL())) { | 684 } else if (request_ && (using_ssl_ || ShouldForceSpdyWithoutSSL())) { |
683 // Update the spdy session key for the request that launched this job. | 685 // Update the spdy session key for the request that launched this job. |
684 request_->SetSpdySessionKey(spdy_session_key); | 686 request_->SetSpdySessionKey(spdy_session_key); |
685 } else if (IsRequestEligibleForPipelining()) { | 687 } else if (IsRequestEligibleForPipelining()) { |
686 // TODO(simonjam): With pipelining, we might be better off using fewer | 688 // TODO(simonjam): With pipelining, we might be better off using fewer |
687 // connections and thus should make fewer preconnections. Explore | 689 // connections and thus should make fewer preconnections. Explore |
688 // preconnecting fewer than the requested num_connections. | 690 // preconnecting fewer than the requested num_connections. |
689 existing_available_pipeline_ = stream_factory_->http_pipelined_host_pool_. | 691 existing_available_pipeline_ = stream_factory_->http_pipelined_host_pool_. |
690 IsExistingPipelineAvailableForOrigin(origin_); | 692 IsExistingPipelineAvailableForKey(*http_pipelining_key_.get()); |
691 if (existing_available_pipeline_) { | 693 if (existing_available_pipeline_) { |
692 return OK; | 694 return OK; |
693 } else { | 695 } else { |
694 request_->SetHttpPipeliningKey(origin_); | 696 bool was_new_key = request_->SetHttpPipeliningKey( |
| 697 *http_pipelining_key_.get()); |
| 698 if (!was_new_key && http_pipelining_key_->force_pipelining()) { |
| 699 return ERR_IO_PENDING; |
| 700 } |
695 } | 701 } |
696 } | 702 } |
697 | 703 |
698 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's | 704 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's |
699 // paused. | 705 // paused. |
700 | 706 |
701 if (waiting_job_) { | 707 if (waiting_job_) { |
702 waiting_job_->Resume(this); | 708 waiting_job_->Resume(this); |
703 waiting_job_ = NULL; | 709 waiting_job_ = NULL; |
704 } | 710 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 return OK; | 754 return OK; |
749 } | 755 } |
750 | 756 |
751 // TODO(willchan): Make this a bit more exact. Maybe there are recoverable | 757 // TODO(willchan): Make this a bit more exact. Maybe there are recoverable |
752 // errors, such as ignoring certificate errors for Alternate-Protocol. | 758 // errors, such as ignoring certificate errors for Alternate-Protocol. |
753 if (result < 0 && waiting_job_) { | 759 if (result < 0 && waiting_job_) { |
754 waiting_job_->Resume(this); | 760 waiting_job_->Resume(this); |
755 waiting_job_ = NULL; | 761 waiting_job_ = NULL; |
756 } | 762 } |
757 | 763 |
| 764 if (result < 0 && http_pipelining_key_->force_pipelining()) { |
| 765 stream_factory_->AbortPipelinedRequestsWithKey( |
| 766 this, *http_pipelining_key_.get(), result, server_ssl_config_); |
| 767 } |
| 768 |
758 // |result| may be the result of any of the stacked pools. The following | 769 // |result| may be the result of any of the stacked pools. The following |
759 // logic is used when determining how to interpret an error. | 770 // logic is used when determining how to interpret an error. |
760 // If |result| < 0: | 771 // If |result| < 0: |
761 // and connection_->socket() != NULL, then the SSL handshake ran and it | 772 // and connection_->socket() != NULL, then the SSL handshake ran and it |
762 // is a potentially recoverable error. | 773 // is a potentially recoverable error. |
763 // and connection_->socket == NULL and connection_->is_ssl_error() is true, | 774 // and connection_->socket == NULL and connection_->is_ssl_error() is true, |
764 // then the SSL handshake ran with an unrecoverable error. | 775 // then the SSL handshake ran with an unrecoverable error. |
765 // otherwise, the error came from one of the other pools. | 776 // otherwise, the error came from one of the other pools. |
766 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || | 777 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || |
767 connection_->is_ssl_error()); | 778 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. | 891 // need to plumb this through to the connect level. |
881 if (connection_->socket() && !connection_->is_reused()) | 892 if (connection_->socket() && !connection_->is_reused()) |
882 SetSocketMotivation(); | 893 SetSocketMotivation(); |
883 | 894 |
884 const ProxyServer& proxy_server = proxy_info_.proxy_server(); | 895 const ProxyServer& proxy_server = proxy_info_.proxy_server(); |
885 | 896 |
886 if (!using_spdy_) { | 897 if (!using_spdy_) { |
887 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && | 898 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && |
888 request_info_.url.SchemeIs("http"); | 899 request_info_.url.SchemeIs("http"); |
889 // TODO(simonjam): Support proxies. | 900 // TODO(simonjam): Support proxies. |
890 if (existing_available_pipeline_) { | 901 if (stream_factory_->http_pipelined_host_pool_. |
| 902 IsExistingPipelineAvailableForKey(*http_pipelining_key_.get())) { |
891 stream_.reset(stream_factory_->http_pipelined_host_pool_. | 903 stream_.reset(stream_factory_->http_pipelined_host_pool_. |
892 CreateStreamOnExistingPipeline(origin_)); | 904 CreateStreamOnExistingPipeline( |
| 905 *http_pipelining_key_.get())); |
893 CHECK(stream_.get()); | 906 CHECK(stream_.get()); |
894 } else if (!using_proxy && IsRequestEligibleForPipelining()) { | 907 } else if (!using_proxy && IsRequestEligibleForPipelining()) { |
895 stream_.reset( | 908 stream_.reset( |
896 stream_factory_->http_pipelined_host_pool_.CreateStreamOnNewPipeline( | 909 stream_factory_->http_pipelined_host_pool_.CreateStreamOnNewPipeline( |
897 origin_, | 910 *http_pipelining_key_.get(), |
898 connection_.release(), | 911 connection_.release(), |
899 server_ssl_config_, | 912 server_ssl_config_, |
900 proxy_info_, | 913 proxy_info_, |
901 net_log_, | 914 net_log_, |
902 was_npn_negotiated_, | 915 was_npn_negotiated_, |
903 protocol_negotiated_)); | 916 protocol_negotiated_)); |
904 CHECK(stream_.get()); | 917 CHECK(stream_.get()); |
905 } else { | 918 } else { |
906 stream_.reset(new HttpBasicStream(connection_.release(), NULL, | 919 stream_.reset(new HttpBasicStream(connection_.release(), NULL, |
907 using_proxy)); | 920 using_proxy)); |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1202 bool HttpStreamFactoryImpl::Job::IsPreconnecting() const { | 1215 bool HttpStreamFactoryImpl::Job::IsPreconnecting() const { |
1203 DCHECK_GE(num_streams_, 0); | 1216 DCHECK_GE(num_streams_, 0); |
1204 return num_streams_ > 0; | 1217 return num_streams_ > 0; |
1205 } | 1218 } |
1206 | 1219 |
1207 bool HttpStreamFactoryImpl::Job::IsOrphaned() const { | 1220 bool HttpStreamFactoryImpl::Job::IsOrphaned() const { |
1208 return !IsPreconnecting() && !request_; | 1221 return !IsPreconnecting() && !request_; |
1209 } | 1222 } |
1210 | 1223 |
1211 bool HttpStreamFactoryImpl::Job::IsRequestEligibleForPipelining() { | 1224 bool HttpStreamFactoryImpl::Job::IsRequestEligibleForPipelining() { |
| 1225 if (IsPreconnecting() || !request_) { |
| 1226 return false; |
| 1227 } |
| 1228 if (http_pipelining_key_->force_pipelining()) { |
| 1229 return true; |
| 1230 } |
1212 if (!HttpStreamFactory::http_pipelining_enabled()) { | 1231 if (!HttpStreamFactory::http_pipelining_enabled()) { |
1213 return false; | 1232 return false; |
1214 } | 1233 } |
1215 if (IsPreconnecting() || !request_) { | |
1216 return false; | |
1217 } | |
1218 if (using_ssl_) { | 1234 if (using_ssl_) { |
1219 return false; | 1235 return false; |
1220 } | 1236 } |
1221 if (request_info_.method != "GET" && request_info_.method != "HEAD") { | 1237 if (request_info_.method != "GET" && request_info_.method != "HEAD") { |
1222 return false; | 1238 return false; |
1223 } | 1239 } |
1224 return stream_factory_->http_pipelined_host_pool_.IsHostEligibleForPipelining( | 1240 return stream_factory_->http_pipelined_host_pool_.IsKeyEligibleForPipelining( |
1225 origin_); | 1241 *http_pipelining_key_.get()); |
1226 } | 1242 } |
1227 | 1243 |
1228 } // namespace net | 1244 } // namespace net |
OLD | NEW |