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 10 matching lines...) Expand all Loading... |
21 #include "net/http/http_pipelined_connection.h" | 21 #include "net/http/http_pipelined_connection.h" |
22 #include "net/http/http_pipelined_host.h" | 22 #include "net/http/http_pipelined_host.h" |
23 #include "net/http/http_pipelined_host_pool.h" | 23 #include "net/http/http_pipelined_host_pool.h" |
24 #include "net/http/http_pipelined_stream.h" | 24 #include "net/http/http_pipelined_stream.h" |
25 #include "net/http/http_proxy_client_socket.h" | 25 #include "net/http/http_proxy_client_socket.h" |
26 #include "net/http/http_proxy_client_socket_pool.h" | 26 #include "net/http/http_proxy_client_socket_pool.h" |
27 #include "net/http/http_request_info.h" | 27 #include "net/http/http_request_info.h" |
28 #include "net/http/http_server_properties.h" | 28 #include "net/http/http_server_properties.h" |
29 #include "net/http/http_stream_factory.h" | 29 #include "net/http/http_stream_factory.h" |
30 #include "net/http/http_stream_factory_impl_request.h" | 30 #include "net/http/http_stream_factory_impl_request.h" |
| 31 #include "net/quic/quic_http_stream.h" |
31 #include "net/socket/client_socket_handle.h" | 32 #include "net/socket/client_socket_handle.h" |
32 #include "net/socket/client_socket_pool.h" | 33 #include "net/socket/client_socket_pool.h" |
33 #include "net/socket/client_socket_pool_manager.h" | 34 #include "net/socket/client_socket_pool_manager.h" |
34 #include "net/socket/socks_client_socket_pool.h" | 35 #include "net/socket/socks_client_socket_pool.h" |
35 #include "net/socket/ssl_client_socket.h" | 36 #include "net/socket/ssl_client_socket.h" |
36 #include "net/socket/ssl_client_socket_pool.h" | 37 #include "net/socket/ssl_client_socket_pool.h" |
37 #include "net/spdy/spdy_http_stream.h" | 38 #include "net/spdy/spdy_http_stream.h" |
38 #include "net/spdy/spdy_session.h" | 39 #include "net/spdy/spdy_session.h" |
39 #include "net/spdy/spdy_session_pool.h" | 40 #include "net/spdy/spdy_session_pool.h" |
40 | 41 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 base::Bind(&Job::OnIOComplete, base::Unretained(this)))), | 83 base::Bind(&Job::OnIOComplete, base::Unretained(this)))), |
83 connection_(new ClientSocketHandle), | 84 connection_(new ClientSocketHandle), |
84 session_(session), | 85 session_(session), |
85 stream_factory_(stream_factory), | 86 stream_factory_(stream_factory), |
86 next_state_(STATE_NONE), | 87 next_state_(STATE_NONE), |
87 pac_request_(NULL), | 88 pac_request_(NULL), |
88 blocking_job_(NULL), | 89 blocking_job_(NULL), |
89 waiting_job_(NULL), | 90 waiting_job_(NULL), |
90 using_ssl_(false), | 91 using_ssl_(false), |
91 using_spdy_(false), | 92 using_spdy_(false), |
| 93 using_quic_(false), |
| 94 quic_request_(session_->quic_stream_factory()), |
92 force_spdy_always_(HttpStreamFactory::force_spdy_always()), | 95 force_spdy_always_(HttpStreamFactory::force_spdy_always()), |
93 force_spdy_over_ssl_(HttpStreamFactory::force_spdy_over_ssl()), | 96 force_spdy_over_ssl_(HttpStreamFactory::force_spdy_over_ssl()), |
94 spdy_certificate_error_(OK), | 97 spdy_certificate_error_(OK), |
95 establishing_tunnel_(false), | 98 establishing_tunnel_(false), |
96 was_npn_negotiated_(false), | 99 was_npn_negotiated_(false), |
97 protocol_negotiated_(kProtoUnknown), | 100 protocol_negotiated_(kProtoUnknown), |
98 num_streams_(0), | 101 num_streams_(0), |
99 spdy_session_direct_(false), | 102 spdy_session_direct_(false), |
100 existing_available_pipeline_(false), | 103 existing_available_pipeline_(false), |
101 ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)) { | 104 ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 next_state_ = STATE_RESTART_TUNNEL_AUTH; | 153 next_state_ = STATE_RESTART_TUNNEL_AUTH; |
151 stream_.reset(); | 154 stream_.reset(); |
152 return RunLoop(OK); | 155 return RunLoop(OK); |
153 } | 156 } |
154 | 157 |
155 LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { | 158 LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { |
156 switch (next_state_) { | 159 switch (next_state_) { |
157 case STATE_RESOLVE_PROXY_COMPLETE: | 160 case STATE_RESOLVE_PROXY_COMPLETE: |
158 return session_->proxy_service()->GetLoadState(pac_request_); | 161 return session_->proxy_service()->GetLoadState(pac_request_); |
159 case STATE_CREATE_STREAM_COMPLETE: | 162 case STATE_CREATE_STREAM_COMPLETE: |
160 return connection_->GetLoadState(); | 163 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); |
161 case STATE_INIT_CONNECTION_COMPLETE: | 164 case STATE_INIT_CONNECTION_COMPLETE: |
162 return LOAD_STATE_SENDING_REQUEST; | 165 return LOAD_STATE_SENDING_REQUEST; |
163 default: | 166 default: |
164 return LOAD_STATE_IDLE; | 167 return LOAD_STATE_IDLE; |
165 } | 168 } |
166 } | 169 } |
167 | 170 |
168 void HttpStreamFactoryImpl::Job::MarkAsAlternate(const GURL& original_url) { | 171 void HttpStreamFactoryImpl::Job::MarkAsAlternate(const GURL& original_url) { |
169 DCHECK(!original_url_.get()); | 172 DCHECK(!original_url_.get()); |
170 original_url_.reset(new GURL(original_url)); | 173 original_url_.reset(new GURL(original_url)); |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 bool HttpStreamFactoryImpl::Job::ShouldForceSpdySSL() const { | 634 bool HttpStreamFactoryImpl::Job::ShouldForceSpdySSL() const { |
632 bool rv = force_spdy_always_ && force_spdy_over_ssl_; | 635 bool rv = force_spdy_always_ && force_spdy_over_ssl_; |
633 return rv && !HttpStreamFactory::HasSpdyExclusion(origin_); | 636 return rv && !HttpStreamFactory::HasSpdyExclusion(origin_); |
634 } | 637 } |
635 | 638 |
636 bool HttpStreamFactoryImpl::Job::ShouldForceSpdyWithoutSSL() const { | 639 bool HttpStreamFactoryImpl::Job::ShouldForceSpdyWithoutSSL() const { |
637 bool rv = force_spdy_always_ && !force_spdy_over_ssl_; | 640 bool rv = force_spdy_always_ && !force_spdy_over_ssl_; |
638 return rv && !HttpStreamFactory::HasSpdyExclusion(origin_); | 641 return rv && !HttpStreamFactory::HasSpdyExclusion(origin_); |
639 } | 642 } |
640 | 643 |
| 644 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { |
| 645 return session_->params().origin_port_to_force_quic_on == origin_.port() |
| 646 && session_->params().origin_port_to_force_quic_on != 0 |
| 647 && proxy_info_.is_direct(); |
| 648 } |
| 649 |
641 int HttpStreamFactoryImpl::Job::DoWaitForJob() { | 650 int HttpStreamFactoryImpl::Job::DoWaitForJob() { |
642 DCHECK(blocking_job_); | 651 DCHECK(blocking_job_); |
643 next_state_ = STATE_WAIT_FOR_JOB_COMPLETE; | 652 next_state_ = STATE_WAIT_FOR_JOB_COMPLETE; |
644 return ERR_IO_PENDING; | 653 return ERR_IO_PENDING; |
645 } | 654 } |
646 | 655 |
647 int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) { | 656 int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) { |
648 DCHECK(!blocking_job_); | 657 DCHECK(!blocking_job_); |
649 DCHECK_EQ(OK, result); | 658 DCHECK_EQ(OK, result); |
650 next_state_ = STATE_INIT_CONNECTION; | 659 next_state_ = STATE_INIT_CONNECTION; |
651 return OK; | 660 return OK; |
652 } | 661 } |
653 | 662 |
654 int HttpStreamFactoryImpl::Job::DoInitConnection() { | 663 int HttpStreamFactoryImpl::Job::DoInitConnection() { |
655 DCHECK(!blocking_job_); | 664 DCHECK(!blocking_job_); |
656 DCHECK(!connection_->is_initialized()); | 665 DCHECK(!connection_->is_initialized()); |
657 DCHECK(proxy_info_.proxy_server().is_valid()); | 666 DCHECK(proxy_info_.proxy_server().is_valid()); |
658 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 667 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
659 | 668 |
660 using_ssl_ = request_info_.url.SchemeIs("https") || ShouldForceSpdySSL(); | 669 using_ssl_ = request_info_.url.SchemeIs("https") || ShouldForceSpdySSL(); |
661 using_spdy_ = false; | 670 using_spdy_ = false; |
662 | 671 |
| 672 if (ShouldForceQuic()) { |
| 673 next_state_ = STATE_CREATE_STREAM; |
| 674 using_quic_ = true; |
| 675 return OK; |
| 676 } |
| 677 |
663 // Check first if we have a spdy session for this group. If so, then go | 678 // Check first if we have a spdy session for this group. If so, then go |
664 // straight to using that. | 679 // straight to using that. |
665 HostPortProxyPair spdy_session_key = GetSpdySessionKey(); | 680 HostPortProxyPair spdy_session_key = GetSpdySessionKey(); |
666 scoped_refptr<SpdySession> spdy_session = | 681 scoped_refptr<SpdySession> spdy_session = |
667 session_->spdy_session_pool()->GetIfExists(spdy_session_key, net_log_); | 682 session_->spdy_session_pool()->GetIfExists(spdy_session_key, net_log_); |
668 if (spdy_session && CanUseExistingSpdySession()) { | 683 if (spdy_session && CanUseExistingSpdySession()) { |
669 // If we're preconnecting, but we already have a SpdySession, we don't | 684 // If we're preconnecting, but we already have a SpdySession, we don't |
670 // actually need to preconnect any sockets, so we're done. | 685 // actually need to preconnect any sockets, so we're done. |
671 if (IsPreconnecting()) | 686 if (IsPreconnecting()) |
672 return OK; | 687 return OK; |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 // This state indicates that the stream request is in a partially | 911 // This state indicates that the stream request is in a partially |
897 // completed state, and we've called back to the delegate for more | 912 // completed state, and we've called back to the delegate for more |
898 // information. | 913 // information. |
899 | 914 |
900 // We're always waiting here for the delegate to call us back. | 915 // We're always waiting here for the delegate to call us back. |
901 return ERR_IO_PENDING; | 916 return ERR_IO_PENDING; |
902 } | 917 } |
903 | 918 |
904 int HttpStreamFactoryImpl::Job::DoCreateStream() { | 919 int HttpStreamFactoryImpl::Job::DoCreateStream() { |
905 DCHECK(connection_->socket() || existing_spdy_session_ || | 920 DCHECK(connection_->socket() || existing_spdy_session_ || |
906 existing_available_pipeline_); | 921 existing_available_pipeline_ || using_quic_); |
907 | 922 |
908 next_state_ = STATE_CREATE_STREAM_COMPLETE; | 923 next_state_ = STATE_CREATE_STREAM_COMPLETE; |
909 | 924 |
910 // We only set the socket motivation if we're the first to use | 925 // We only set the socket motivation if we're the first to use |
911 // this socket. Is there a race for two SPDY requests? We really | 926 // this socket. Is there a race for two SPDY requests? We really |
912 // need to plumb this through to the connect level. | 927 // need to plumb this through to the connect level. |
913 if (connection_->socket() && !connection_->is_reused()) | 928 if (connection_->socket() && !connection_->is_reused()) |
914 SetSocketMotivation(); | 929 SetSocketMotivation(); |
915 | 930 |
916 const ProxyServer& proxy_server = proxy_info_.proxy_server(); | 931 const ProxyServer& proxy_server = proxy_info_.proxy_server(); |
917 | 932 |
| 933 if (using_quic_) { |
| 934 return quic_request_.Request(HostPortProxyPair(origin_, proxy_server), |
| 935 net_log_, io_callback_); |
| 936 } |
| 937 |
918 if (!using_spdy_) { | 938 if (!using_spdy_) { |
919 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && | 939 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && |
920 request_info_.url.SchemeIs("http"); | 940 request_info_.url.SchemeIs("http"); |
921 if (stream_factory_->http_pipelined_host_pool_. | 941 if (stream_factory_->http_pipelined_host_pool_. |
922 IsExistingPipelineAvailableForKey(*http_pipelining_key_.get())) { | 942 IsExistingPipelineAvailableForKey(*http_pipelining_key_.get())) { |
923 stream_.reset(stream_factory_->http_pipelined_host_pool_. | 943 stream_.reset(stream_factory_->http_pipelined_host_pool_. |
924 CreateStreamOnExistingPipeline( | 944 CreateStreamOnExistingPipeline( |
925 *http_pipelining_key_.get())); | 945 *http_pipelining_key_.get())); |
926 CHECK(stream_.get()); | 946 CHECK(stream_.get()); |
927 } else if (!using_proxy && IsRequestEligibleForPipelining()) { | 947 } else if (!using_proxy && IsRequestEligibleForPipelining()) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 | 1010 |
991 bool use_relative_url = direct || request_info_.url.SchemeIs("https"); | 1011 bool use_relative_url = direct || request_info_.url.SchemeIs("https"); |
992 stream_.reset(new SpdyHttpStream(spdy_session, use_relative_url)); | 1012 stream_.reset(new SpdyHttpStream(spdy_session, use_relative_url)); |
993 return OK; | 1013 return OK; |
994 } | 1014 } |
995 | 1015 |
996 int HttpStreamFactoryImpl::Job::DoCreateStreamComplete(int result) { | 1016 int HttpStreamFactoryImpl::Job::DoCreateStreamComplete(int result) { |
997 if (result < 0) | 1017 if (result < 0) |
998 return result; | 1018 return result; |
999 | 1019 |
| 1020 if (using_quic_) { |
| 1021 stream_ = quic_request_.ReleaseStream(); |
| 1022 } |
| 1023 |
1000 session_->proxy_service()->ReportSuccess(proxy_info_); | 1024 session_->proxy_service()->ReportSuccess(proxy_info_); |
1001 next_state_ = STATE_NONE; | 1025 next_state_ = STATE_NONE; |
1002 return OK; | 1026 return OK; |
1003 } | 1027 } |
1004 | 1028 |
1005 int HttpStreamFactoryImpl::Job::DoRestartTunnelAuth() { | 1029 int HttpStreamFactoryImpl::Job::DoRestartTunnelAuth() { |
1006 next_state_ = STATE_RESTART_TUNNEL_AUTH_COMPLETE; | 1030 next_state_ = STATE_RESTART_TUNNEL_AUTH_COMPLETE; |
1007 ProxyClientSocket* proxy_socket = | 1031 ProxyClientSocket* proxy_socket = |
1008 static_cast<ProxyClientSocket*>(connection_->socket()); | 1032 static_cast<ProxyClientSocket*>(connection_->socket()); |
1009 return proxy_socket->RestartWithAuth(io_callback_); | 1033 return proxy_socket->RestartWithAuth(io_callback_); |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1281 (net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME | net::LOAD_PREFETCH | | 1305 (net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME | net::LOAD_PREFETCH | |
1282 net::LOAD_IS_DOWNLOAD)) { | 1306 net::LOAD_IS_DOWNLOAD)) { |
1283 // Avoid pipelining resources that may be streamed for a long time. | 1307 // Avoid pipelining resources that may be streamed for a long time. |
1284 return false; | 1308 return false; |
1285 } | 1309 } |
1286 return stream_factory_->http_pipelined_host_pool_.IsKeyEligibleForPipelining( | 1310 return stream_factory_->http_pipelined_host_pool_.IsKeyEligibleForPipelining( |
1287 *http_pipelining_key_.get()); | 1311 *http_pipelining_key_.get()); |
1288 } | 1312 } |
1289 | 1313 |
1290 } // namespace net | 1314 } // namespace net |
OLD | NEW |