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 <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "net/http/http_proxy_client_socket.h" | 33 #include "net/http/http_proxy_client_socket.h" |
34 #include "net/http/http_proxy_client_socket_pool.h" | 34 #include "net/http/http_proxy_client_socket_pool.h" |
35 #include "net/http/http_request_info.h" | 35 #include "net/http/http_request_info.h" |
36 #include "net/http/http_server_properties.h" | 36 #include "net/http/http_server_properties.h" |
37 #include "net/http/http_stream_factory.h" | 37 #include "net/http/http_stream_factory.h" |
38 #include "net/http/http_stream_factory_impl_request.h" | 38 #include "net/http/http_stream_factory_impl_request.h" |
39 #include "net/log/net_log_capture_mode.h" | 39 #include "net/log/net_log_capture_mode.h" |
40 #include "net/log/net_log_event_type.h" | 40 #include "net/log/net_log_event_type.h" |
41 #include "net/log/net_log_source.h" | 41 #include "net/log/net_log_source.h" |
42 #include "net/log/net_log_source_type.h" | 42 #include "net/log/net_log_source_type.h" |
43 #include "net/quic/chromium/quic_http_stream.h" | |
44 #include "net/socket/client_socket_handle.h" | 43 #include "net/socket/client_socket_handle.h" |
45 #include "net/socket/client_socket_pool.h" | 44 #include "net/socket/client_socket_pool.h" |
46 #include "net/socket/client_socket_pool_manager.h" | 45 #include "net/socket/client_socket_pool_manager.h" |
47 #include "net/socket/socks_client_socket_pool.h" | 46 #include "net/socket/socks_client_socket_pool.h" |
48 #include "net/socket/ssl_client_socket.h" | 47 #include "net/socket/ssl_client_socket.h" |
49 #include "net/socket/ssl_client_socket_pool.h" | 48 #include "net/socket/ssl_client_socket_pool.h" |
50 #include "net/socket/stream_socket.h" | 49 #include "net/socket/stream_socket.h" |
51 #include "net/spdy/chromium/bidirectional_stream_spdy_impl.h" | 50 #include "net/spdy/chromium/bidirectional_stream_spdy_impl.h" |
52 #include "net/spdy/chromium/spdy_http_stream.h" | 51 #include "net/spdy/chromium/spdy_http_stream.h" |
53 #include "net/spdy/chromium/spdy_session.h" | 52 #include "net/spdy/chromium/spdy_session.h" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 // stream. | 141 // stream. |
143 std::unique_ptr<base::Value> NetLogHttpStreamProtoCallback( | 142 std::unique_ptr<base::Value> NetLogHttpStreamProtoCallback( |
144 NextProto negotiated_protocol, | 143 NextProto negotiated_protocol, |
145 NetLogCaptureMode /* capture_mode */) { | 144 NetLogCaptureMode /* capture_mode */) { |
146 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 145 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
147 | 146 |
148 dict->SetString("proto", NextProtoToString(negotiated_protocol)); | 147 dict->SetString("proto", NextProtoToString(negotiated_protocol)); |
149 return std::move(dict); | 148 return std::move(dict); |
150 } | 149 } |
151 | 150 |
152 // Returns parameters associated with the proxy resolution. | |
153 std::unique_ptr<base::Value> NetLogHttpStreamJobProxyServerResolved( | |
154 const ProxyServer& proxy_server, | |
155 NetLogCaptureMode /* capture_mode */) { | |
156 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | |
157 | |
158 dict->SetString("proxy_server", proxy_server.is_valid() | |
159 ? proxy_server.ToPacString() | |
160 : std::string()); | |
161 return std::move(dict); | |
162 } | |
163 | |
164 HttpStreamFactoryImpl::Job::Job(Delegate* delegate, | 151 HttpStreamFactoryImpl::Job::Job(Delegate* delegate, |
165 JobType job_type, | 152 JobType job_type, |
166 HttpNetworkSession* session, | 153 HttpNetworkSession* session, |
167 const HttpRequestInfo& request_info, | 154 const HttpRequestInfo& request_info, |
168 RequestPriority priority, | 155 RequestPriority priority, |
| 156 ProxyInfo proxy_info, |
169 const SSLConfig& server_ssl_config, | 157 const SSLConfig& server_ssl_config, |
170 const SSLConfig& proxy_ssl_config, | 158 const SSLConfig& proxy_ssl_config, |
171 HostPortPair destination, | 159 HostPortPair destination, |
172 GURL origin_url, | 160 GURL origin_url, |
173 bool enable_ip_based_pooling, | 161 bool enable_ip_based_pooling, |
174 NetLog* net_log) | 162 NetLog* net_log) |
175 : Job(delegate, | 163 : Job(delegate, |
176 job_type, | 164 job_type, |
177 session, | 165 session, |
178 request_info, | 166 request_info, |
179 priority, | 167 priority, |
| 168 proxy_info, |
180 server_ssl_config, | 169 server_ssl_config, |
181 proxy_ssl_config, | 170 proxy_ssl_config, |
182 destination, | 171 destination, |
183 origin_url, | 172 origin_url, |
184 AlternativeService(), | 173 AlternativeService(), |
185 ProxyServer(), | 174 ProxyServer(), |
186 enable_ip_based_pooling, | 175 enable_ip_based_pooling, |
187 net_log) {} | 176 net_log) {} |
188 | 177 |
189 HttpStreamFactoryImpl::Job::Job(Delegate* delegate, | 178 HttpStreamFactoryImpl::Job::Job(Delegate* delegate, |
190 JobType job_type, | 179 JobType job_type, |
191 HttpNetworkSession* session, | 180 HttpNetworkSession* session, |
192 const HttpRequestInfo& request_info, | 181 const HttpRequestInfo& request_info, |
193 RequestPriority priority, | 182 RequestPriority priority, |
| 183 ProxyInfo proxy_info, |
194 const SSLConfig& server_ssl_config, | 184 const SSLConfig& server_ssl_config, |
195 const SSLConfig& proxy_ssl_config, | 185 const SSLConfig& proxy_ssl_config, |
196 HostPortPair destination, | 186 HostPortPair destination, |
197 GURL origin_url, | 187 GURL origin_url, |
198 AlternativeService alternative_service, | 188 AlternativeService alternative_service, |
199 const ProxyServer& alternative_proxy_server, | 189 const ProxyServer& alternative_proxy_server, |
200 bool enable_ip_based_pooling, | 190 bool enable_ip_based_pooling, |
201 NetLog* net_log) | 191 NetLog* net_log) |
202 : request_info_(request_info), | 192 : request_info_(request_info), |
203 priority_(priority), | 193 priority_(priority), |
| 194 proxy_info_(proxy_info), |
204 server_ssl_config_(server_ssl_config), | 195 server_ssl_config_(server_ssl_config), |
205 proxy_ssl_config_(proxy_ssl_config), | 196 proxy_ssl_config_(proxy_ssl_config), |
206 net_log_( | 197 net_log_( |
207 NetLogWithSource::Make(net_log, NetLogSourceType::HTTP_STREAM_JOB)), | 198 NetLogWithSource::Make(net_log, NetLogSourceType::HTTP_STREAM_JOB)), |
208 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), | 199 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), |
209 connection_(new ClientSocketHandle), | 200 connection_(new ClientSocketHandle), |
210 session_(session), | 201 session_(session), |
211 state_(STATE_NONE), | 202 state_(STATE_NONE), |
212 next_state_(STATE_NONE), | 203 next_state_(STATE_NONE), |
213 pac_request_(NULL), | |
214 destination_(destination), | 204 destination_(destination), |
215 origin_url_(origin_url), | 205 origin_url_(origin_url), |
216 alternative_service_(alternative_service), | 206 alternative_service_(alternative_service), |
217 alternative_proxy_server_(alternative_proxy_server), | 207 alternative_proxy_server_(alternative_proxy_server), |
218 enable_ip_based_pooling_(enable_ip_based_pooling), | 208 enable_ip_based_pooling_(enable_ip_based_pooling), |
219 delegate_(delegate), | 209 delegate_(delegate), |
220 job_type_(job_type), | 210 job_type_(job_type), |
221 using_ssl_(origin_url_.SchemeIs(url::kHttpsScheme) || | 211 using_ssl_(origin_url_.SchemeIs(url::kHttpsScheme) || |
222 origin_url_.SchemeIs(url::kWssScheme)), | 212 origin_url_.SchemeIs(url::kWssScheme)), |
223 using_spdy_(false), | 213 using_spdy_(false), |
224 using_quic_(false), | 214 using_quic_(false), |
225 quic_request_(session_->quic_stream_factory(), | 215 reconsider_proxy_(false), |
226 session_->http_server_properties()), | 216 quic_request_(session_->quic_stream_factory()->CreateStreamRequest()), |
227 using_existing_quic_session_(false), | 217 using_existing_quic_session_(false), |
228 establishing_tunnel_(false), | 218 establishing_tunnel_(false), |
229 was_alpn_negotiated_(false), | 219 was_alpn_negotiated_(false), |
230 negotiated_protocol_(kProtoUnknown), | 220 negotiated_protocol_(kProtoUnknown), |
231 num_streams_(0), | 221 num_streams_(0), |
232 spdy_session_direct_(false), | 222 spdy_session_direct_(false), |
233 stream_type_(HttpStreamRequest::BIDIRECTIONAL_STREAM), | 223 stream_type_(HttpStreamRequest::BIDIRECTIONAL_STREAM), |
234 ptr_factory_(this) { | 224 ptr_factory_(this) { |
235 DCHECK(session); | 225 DCHECK(session); |
236 // The job can't have alternative service and alternative proxy server set at | 226 // The job can't have alternative service and alternative proxy server set at |
(...skipping 27 matching lines...) Expand all Loading... |
264 net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB); | 254 net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB); |
265 | 255 |
266 // When we're in a partially constructed state, waiting for the user to | 256 // When we're in a partially constructed state, waiting for the user to |
267 // provide certificate handling information or authentication, we can't reuse | 257 // provide certificate handling information or authentication, we can't reuse |
268 // this stream at all. | 258 // this stream at all. |
269 if (next_state_ == STATE_WAITING_USER_ACTION) { | 259 if (next_state_ == STATE_WAITING_USER_ACTION) { |
270 connection_->socket()->Disconnect(); | 260 connection_->socket()->Disconnect(); |
271 connection_.reset(); | 261 connection_.reset(); |
272 } | 262 } |
273 | 263 |
274 if (pac_request_) | |
275 session_->proxy_service()->CancelPacRequest(pac_request_); | |
276 | |
277 // The stream could be in a partial state. It is not reusable. | 264 // The stream could be in a partial state. It is not reusable. |
278 if (stream_.get() && next_state_ != STATE_DONE) | 265 if (stream_.get() && next_state_ != STATE_DONE) |
279 stream_->Close(true /* not reusable */); | 266 stream_->Close(true /* not reusable */); |
280 } | 267 } |
281 | 268 |
282 void HttpStreamFactoryImpl::Job::Start( | 269 void HttpStreamFactoryImpl::Job::Start( |
283 HttpStreamRequest::StreamType stream_type) { | 270 HttpStreamRequest::StreamType stream_type) { |
284 stream_type_ = stream_type; | 271 stream_type_ = stream_type; |
285 StartInternal(); | 272 StartInternal(); |
286 } | 273 } |
(...skipping 24 matching lines...) Expand all Loading... |
311 int HttpStreamFactoryImpl::Job::RestartTunnelWithProxyAuth() { | 298 int HttpStreamFactoryImpl::Job::RestartTunnelWithProxyAuth() { |
312 DCHECK(establishing_tunnel_); | 299 DCHECK(establishing_tunnel_); |
313 next_state_ = STATE_RESTART_TUNNEL_AUTH; | 300 next_state_ = STATE_RESTART_TUNNEL_AUTH; |
314 stream_.reset(); | 301 stream_.reset(); |
315 RunLoop(OK); | 302 RunLoop(OK); |
316 return ERR_IO_PENDING; | 303 return ERR_IO_PENDING; |
317 } | 304 } |
318 | 305 |
319 LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { | 306 LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { |
320 switch (next_state_) { | 307 switch (next_state_) { |
321 case STATE_RESOLVE_PROXY_COMPLETE: | |
322 return session_->proxy_service()->GetLoadState(pac_request_); | |
323 case STATE_INIT_CONNECTION_COMPLETE: | 308 case STATE_INIT_CONNECTION_COMPLETE: |
324 case STATE_CREATE_STREAM_COMPLETE: | 309 case STATE_CREATE_STREAM_COMPLETE: |
325 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); | 310 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); |
326 default: | 311 default: |
327 return LOAD_STATE_IDLE; | 312 return LOAD_STATE_IDLE; |
328 } | 313 } |
329 } | 314 } |
330 | 315 |
331 void HttpStreamFactoryImpl::Job::Resume() { | 316 void HttpStreamFactoryImpl::Job::Resume() { |
332 DCHECK_EQ(job_type_, MAIN); | 317 DCHECK_EQ(job_type_, MAIN); |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 do { | 666 do { |
682 State state = next_state_; | 667 State state = next_state_; |
683 // Added to investigate crbug.com/711721. | 668 // Added to investigate crbug.com/711721. |
684 state_ = state; | 669 state_ = state; |
685 next_state_ = STATE_NONE; | 670 next_state_ = STATE_NONE; |
686 switch (state) { | 671 switch (state) { |
687 case STATE_START: | 672 case STATE_START: |
688 DCHECK_EQ(OK, rv); | 673 DCHECK_EQ(OK, rv); |
689 rv = DoStart(); | 674 rv = DoStart(); |
690 break; | 675 break; |
691 case STATE_RESOLVE_PROXY: | |
692 DCHECK_EQ(OK, rv); | |
693 rv = DoResolveProxy(); | |
694 break; | |
695 case STATE_RESOLVE_PROXY_COMPLETE: | |
696 rv = DoResolveProxyComplete(rv); | |
697 break; | |
698 case STATE_WAIT: | 676 case STATE_WAIT: |
699 DCHECK_EQ(OK, rv); | 677 DCHECK_EQ(OK, rv); |
700 rv = DoWait(); | 678 rv = DoWait(); |
701 break; | 679 break; |
702 case STATE_WAIT_COMPLETE: | 680 case STATE_WAIT_COMPLETE: |
703 rv = DoWaitComplete(rv); | 681 rv = DoWaitComplete(rv); |
704 break; | 682 break; |
705 case STATE_INIT_CONNECTION: | 683 case STATE_INIT_CONNECTION: |
706 DCHECK_EQ(OK, rv); | 684 DCHECK_EQ(OK, rv); |
707 rv = DoInitConnection(); | 685 rv = DoInitConnection(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 net_log->AddEvent(NetLogEventType::HTTP_STREAM_REQUEST_STARTED_JOB, | 732 net_log->AddEvent(NetLogEventType::HTTP_STREAM_REQUEST_STARTED_JOB, |
755 net_log_.source().ToEventParametersCallback()); | 733 net_log_.source().ToEventParametersCallback()); |
756 } | 734 } |
757 | 735 |
758 // Don't connect to restricted ports. | 736 // Don't connect to restricted ports. |
759 if (!IsPortAllowedForScheme(destination_.port(), | 737 if (!IsPortAllowedForScheme(destination_.port(), |
760 request_info_.url.scheme())) { | 738 request_info_.url.scheme())) { |
761 return ERR_UNSAFE_PORT; | 739 return ERR_UNSAFE_PORT; |
762 } | 740 } |
763 | 741 |
764 next_state_ = STATE_RESOLVE_PROXY; | 742 next_state_ = STATE_WAIT; |
765 return OK; | 743 return OK; |
766 } | 744 } |
767 | 745 |
768 int HttpStreamFactoryImpl::Job::DoResolveProxy() { | |
769 DCHECK(!pac_request_); | |
770 DCHECK(session_); | |
771 | |
772 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; | |
773 | |
774 if (request_info_.load_flags & LOAD_BYPASS_PROXY) { | |
775 proxy_info_.UseDirect(); | |
776 return OK; | |
777 } | |
778 | |
779 // If an alternative proxy server was provided, use that. | |
780 if (alternative_proxy_server_.is_valid()) { | |
781 proxy_info_.UseProxyServer(alternative_proxy_server_); | |
782 return OK; | |
783 } | |
784 | |
785 return session_->proxy_service()->ResolveProxy( | |
786 origin_url_, request_info_.method, &proxy_info_, io_callback_, | |
787 &pac_request_, session_->params().proxy_delegate, net_log_); | |
788 } | |
789 | |
790 int HttpStreamFactoryImpl::Job::DoResolveProxyComplete(int result) { | |
791 pac_request_ = NULL; | |
792 | |
793 net_log_.AddEvent( | |
794 NetLogEventType::HTTP_STREAM_JOB_PROXY_SERVER_RESOLVED, | |
795 base::Bind( | |
796 &NetLogHttpStreamJobProxyServerResolved, | |
797 proxy_info_.is_empty() ? ProxyServer() : proxy_info_.proxy_server())); | |
798 | |
799 if (result == OK) { | |
800 // Remove unsupported proxies from the list. | |
801 int supported_proxies = | |
802 ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP | | |
803 ProxyServer::SCHEME_HTTPS | ProxyServer::SCHEME_SOCKS4 | | |
804 ProxyServer::SCHEME_SOCKS5; | |
805 | |
806 if (session_->IsQuicEnabled()) | |
807 supported_proxies |= ProxyServer::SCHEME_QUIC; | |
808 | |
809 proxy_info_.RemoveProxiesWithoutScheme(supported_proxies); | |
810 | |
811 if (proxy_info_.is_empty()) { | |
812 // No proxies/direct to choose from. This happens when we don't support | |
813 // any of the proxies in the returned list. | |
814 result = ERR_NO_SUPPORTED_PROXIES; | |
815 } else if (using_quic_ && | |
816 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { | |
817 // QUIC can not be spoken to non-QUIC proxies. This error should not be | |
818 // user visible, because the non-alternative Job should be resumed. | |
819 result = ERR_NO_SUPPORTED_PROXIES; | |
820 } | |
821 } | |
822 | |
823 if (result != OK) { | |
824 return result; | |
825 } | |
826 | |
827 next_state_ = STATE_WAIT; | |
828 | |
829 delegate_->OnResolveProxyComplete(this, request_info_, priority_, | |
830 server_ssl_config_, proxy_ssl_config_, | |
831 stream_type_); | |
832 | |
833 return OK; | |
834 } | |
835 | |
836 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { | 746 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { |
837 return session_->IsQuicEnabled() && | 747 return session_->IsQuicEnabled() && |
838 (base::ContainsKey(session_->params().origins_to_force_quic_on, | 748 (base::ContainsKey(session_->params().origins_to_force_quic_on, |
839 HostPortPair()) || | 749 HostPortPair()) || |
840 base::ContainsKey(session_->params().origins_to_force_quic_on, | 750 base::ContainsKey(session_->params().origins_to_force_quic_on, |
841 destination_)) && | 751 destination_)) && |
842 proxy_info_.is_direct() && origin_url_.SchemeIs(url::kHttpsScheme); | 752 proxy_info_.is_direct() && origin_url_.SchemeIs(url::kHttpsScheme); |
843 } | 753 } |
844 | 754 |
845 int HttpStreamFactoryImpl::Job::DoWait() { | 755 int HttpStreamFactoryImpl::Job::DoWait() { |
(...skipping 22 matching lines...) Expand all Loading... |
868 | 778 |
869 return result; | 779 return result; |
870 } | 780 } |
871 | 781 |
872 int HttpStreamFactoryImpl::Job::DoInitConnectionImpl() { | 782 int HttpStreamFactoryImpl::Job::DoInitConnectionImpl() { |
873 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. | 783 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. |
874 tracked_objects::ScopedTracker tracking_profile( | 784 tracked_objects::ScopedTracker tracking_profile( |
875 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 785 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
876 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); | 786 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); |
877 DCHECK(!connection_->is_initialized()); | 787 DCHECK(!connection_->is_initialized()); |
| 788 |
| 789 if (proxy_info_.is_empty()) { |
| 790 // No proxies/direct to choose from. This happens when we don't support |
| 791 // any of the proxies in the returned list. |
| 792 return ERR_NO_SUPPORTED_PROXIES; |
| 793 } else if (using_quic_ && |
| 794 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { |
| 795 // QUIC can not be spoken to non-QUIC proxies. This error should not be |
| 796 // user visible, because the non-alternative Job should be resumed. |
| 797 return ERR_NO_SUPPORTED_PROXIES; |
| 798 } |
| 799 |
878 DCHECK(proxy_info_.proxy_server().is_valid()); | 800 DCHECK(proxy_info_.proxy_server().is_valid()); |
879 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 801 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
880 | 802 |
881 if (delegate_->OnInitConnection(proxy_info_)) { | 803 if (delegate_->OnInitConnection(proxy_info_)) { |
882 // Return since the connection initialization can be skipped. | 804 // Return since the connection initialization can be skipped. |
883 return OK; | 805 return OK; |
884 } | 806 } |
885 | 807 |
886 using_spdy_ = false; | 808 using_spdy_ = false; |
887 | 809 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 url = url.ReplaceComponents(replacements); | 854 url = url.ReplaceComponents(replacements); |
933 } else { | 855 } else { |
934 DCHECK(using_ssl_); | 856 DCHECK(using_ssl_); |
935 // The certificate of a QUIC alternative server is expected to be valid | 857 // The certificate of a QUIC alternative server is expected to be valid |
936 // for the origin of the request (in addition to being valid for the | 858 // for the origin of the request (in addition to being valid for the |
937 // server itself). | 859 // server itself). |
938 destination = destination_; | 860 destination = destination_; |
939 ssl_config = &server_ssl_config_; | 861 ssl_config = &server_ssl_config_; |
940 } | 862 } |
941 int rv = | 863 int rv = |
942 quic_request_.Request(destination, request_info_.privacy_mode, | 864 quic_request_->Request(destination, request_info_.privacy_mode, |
943 ssl_config->GetCertVerifyFlags(), url, | 865 ssl_config->GetCertVerifyFlags(), url, |
944 request_info_.method, net_log_, io_callback_); | 866 request_info_.method, net_log_, io_callback_); |
945 if (rv == OK) { | 867 if (rv == OK) { |
946 using_existing_quic_session_ = true; | 868 using_existing_quic_session_ = true; |
947 } else { | 869 } else { |
948 // There's no available QUIC session. Inform the delegate how long to | 870 // There's no available QUIC session. Inform the delegate how long to |
949 // delay the main job. | 871 // delay the main job. |
950 if (rv == ERR_IO_PENDING) { | 872 if (rv == ERR_IO_PENDING) { |
951 delegate_->MaybeSetWaitTimeForMainJob( | 873 delegate_->MaybeSetWaitTimeForMainJob( |
952 quic_request_.GetTimeDelayForWaitingJob()); | 874 quic_request_->GetTimeDelayForWaitingJob()); |
953 } | 875 } |
954 } | 876 } |
955 return rv; | 877 return rv; |
956 } | 878 } |
957 | 879 |
958 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 880 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
959 | 881 |
960 // Check first if we have a spdy session for this group. If so, then go | 882 // Check first if we have a spdy session for this group. If so, then go |
961 // straight to using that. | 883 // straight to using that. |
962 if (CanUseExistingSpdySession()) { | 884 if (CanUseExistingSpdySession()) { |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1122 if (!ssl_started && result < 0 && | 1044 if (!ssl_started && result < 0 && |
1123 (IsSpdyAlternative() || IsQuicAlternative())) | 1045 (IsSpdyAlternative() || IsQuicAlternative())) |
1124 return result; | 1046 return result; |
1125 | 1047 |
1126 if (using_quic_) { | 1048 if (using_quic_) { |
1127 if (result < 0) | 1049 if (result < 0) |
1128 return result; | 1050 return result; |
1129 | 1051 |
1130 if (stream_type_ == HttpStreamRequest::BIDIRECTIONAL_STREAM) { | 1052 if (stream_type_ == HttpStreamRequest::BIDIRECTIONAL_STREAM) { |
1131 bidirectional_stream_impl_ = | 1053 bidirectional_stream_impl_ = |
1132 quic_request_.CreateBidirectionalStreamImpl(); | 1054 quic_request_->CreateBidirectionalStreamImpl(); |
1133 if (!bidirectional_stream_impl_) { | 1055 if (!bidirectional_stream_impl_) { |
1134 // Quic session is closed before stream can be created. | 1056 // Quic session is closed before stream can be created. |
1135 return ERR_CONNECTION_CLOSED; | 1057 return ERR_CONNECTION_CLOSED; |
1136 } | 1058 } |
1137 } else { | 1059 } else { |
1138 stream_ = quic_request_.CreateStream(); | 1060 stream_ = quic_request_->CreateStream(); |
1139 if (!stream_) { | 1061 if (!stream_) { |
1140 // Quic session is closed before stream can be created. | 1062 // Quic session is closed before stream can be created. |
1141 return ERR_CONNECTION_CLOSED; | 1063 return ERR_CONNECTION_CLOSED; |
1142 } | 1064 } |
1143 } | 1065 } |
1144 next_state_ = STATE_NONE; | 1066 next_state_ = STATE_NONE; |
1145 return OK; | 1067 return OK; |
1146 } | 1068 } |
1147 | 1069 |
1148 if (result < 0 && !ssl_started) | 1070 if (result < 0 && !ssl_started) |
1149 return ReconsiderProxyAfterError(result); | 1071 return ReconsiderProxyAfterError(result); |
| 1072 |
1150 establishing_tunnel_ = false; | 1073 establishing_tunnel_ = false; |
1151 | 1074 |
1152 // Handle SSL errors below. | 1075 // Handle SSL errors below. |
1153 if (using_ssl_) { | 1076 if (using_ssl_) { |
1154 DCHECK(ssl_started); | 1077 DCHECK(ssl_started); |
1155 if (IsCertificateError(result)) { | 1078 if (IsCertificateError(result)) { |
1156 result = HandleCertificateError(result); | 1079 result = HandleCertificateError(result); |
1157 if (result == OK && !connection_->socket()->IsConnectedAndIdle()) { | 1080 if (result == OK && !connection_->socket()->IsConnectedAndIdle()) { |
1158 ReturnToStateInitConnection(true /* close connection */); | 1081 ReturnToStateInitConnection(true /* close connection */); |
1159 return result; | 1082 return result; |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1406 } | 1329 } |
1407 | 1330 |
1408 if (request_info_.load_flags & LOAD_VERIFY_EV_CERT) | 1331 if (request_info_.load_flags & LOAD_VERIFY_EV_CERT) |
1409 ssl_config->verify_ev_cert = true; | 1332 ssl_config->verify_ev_cert = true; |
1410 | 1333 |
1411 // Disable Channel ID if privacy mode is enabled. | 1334 // Disable Channel ID if privacy mode is enabled. |
1412 if (request_info_.privacy_mode == PRIVACY_MODE_ENABLED) | 1335 if (request_info_.privacy_mode == PRIVACY_MODE_ENABLED) |
1413 ssl_config->channel_id_enabled = false; | 1336 ssl_config->channel_id_enabled = false; |
1414 } | 1337 } |
1415 | 1338 |
1416 | |
1417 int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) { | 1339 int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) { |
1418 DCHECK(!pac_request_); | |
1419 DCHECK(session_); | |
1420 | |
1421 // A failure to resolve the hostname or any error related to establishing a | |
1422 // TCP connection could be grounds for trying a new proxy configuration. | |
1423 // | |
1424 // Why do this when a hostname cannot be resolved? Some URLs only make sense | |
1425 // to proxy servers. The hostname in those URLs might fail to resolve if we | |
1426 // are still using a non-proxy config. We need to check if a proxy config | |
1427 // now exists that corresponds to a proxy server that could load the URL. | |
1428 // | |
1429 switch (error) { | 1340 switch (error) { |
1430 case ERR_PROXY_CONNECTION_FAILED: | 1341 case ERR_PROXY_CONNECTION_FAILED: |
1431 case ERR_NAME_NOT_RESOLVED: | 1342 case ERR_NAME_NOT_RESOLVED: |
1432 case ERR_INTERNET_DISCONNECTED: | 1343 case ERR_INTERNET_DISCONNECTED: |
1433 case ERR_ADDRESS_UNREACHABLE: | 1344 case ERR_ADDRESS_UNREACHABLE: |
1434 case ERR_CONNECTION_CLOSED: | 1345 case ERR_CONNECTION_CLOSED: |
1435 case ERR_CONNECTION_TIMED_OUT: | 1346 case ERR_CONNECTION_TIMED_OUT: |
1436 case ERR_CONNECTION_RESET: | 1347 case ERR_CONNECTION_RESET: |
1437 case ERR_CONNECTION_REFUSED: | 1348 case ERR_CONNECTION_REFUSED: |
1438 case ERR_CONNECTION_ABORTED: | 1349 case ERR_CONNECTION_ABORTED: |
(...skipping 18 matching lines...) Expand all Loading... |
1457 // | 1368 // |
1458 // Note that if the host resolving was done by the SOCKS5 proxy, we can't | 1369 // Note that if the host resolving was done by the SOCKS5 proxy, we can't |
1459 // differentiate between a proxy-side "host not found" versus a proxy-side | 1370 // differentiate between a proxy-side "host not found" versus a proxy-side |
1460 // "address unreachable" error, and will report both of these failures as | 1371 // "address unreachable" error, and will report both of these failures as |
1461 // ERR_ADDRESS_UNREACHABLE. | 1372 // ERR_ADDRESS_UNREACHABLE. |
1462 return ERR_ADDRESS_UNREACHABLE; | 1373 return ERR_ADDRESS_UNREACHABLE; |
1463 default: | 1374 default: |
1464 return error; | 1375 return error; |
1465 } | 1376 } |
1466 | 1377 |
1467 // Do not bypass non-QUIC proxy on ERR_MSG_TOO_BIG. | |
1468 if (!proxy_info_.is_quic() && error == ERR_MSG_TOO_BIG) | |
1469 return error; | |
1470 | |
1471 if (request_info_.load_flags & LOAD_BYPASS_PROXY) | |
1472 return error; | |
1473 | |
1474 // Alternative proxy server job should not use fallback proxies, and instead | 1378 // Alternative proxy server job should not use fallback proxies, and instead |
1475 // return. This would resume the main job (if possible) which may try the | 1379 // return. This would resume the main job (if possible) which may try the |
1476 // fallback proxies. | 1380 // fallback proxies. |
1477 if (alternative_proxy_server_.is_valid()) { | 1381 if (job_type() == ALTERNATIVE && alternative_proxy_server().is_valid()) { |
1478 DCHECK_EQ(STATE_NONE, next_state_); | 1382 DCHECK_EQ(STATE_NONE, next_state_); |
1479 return error; | 1383 return error; |
1480 } | 1384 } |
1481 | 1385 |
1482 if (proxy_info_.is_https() && proxy_ssl_config_.send_client_cert) { | 1386 reconsider_proxy_ = true; |
1483 session_->ssl_client_auth_cache()->Remove( | 1387 return error; |
1484 proxy_info_.proxy_server().host_port_pair()); | |
1485 } | |
1486 | |
1487 int rv = session_->proxy_service()->ReconsiderProxyAfterError( | |
1488 request_info_.url, request_info_.method, error, &proxy_info_, | |
1489 io_callback_, &pac_request_, session_->params().proxy_delegate, net_log_); | |
1490 if (rv == OK || rv == ERR_IO_PENDING) { | |
1491 // If the error was during connection setup, there is no socket to | |
1492 // disconnect. | |
1493 if (connection_->socket()) | |
1494 connection_->socket()->Disconnect(); | |
1495 connection_->Reset(); | |
1496 delegate_->RemoveRequestFromSpdySessionRequestMapForJob(this); | |
1497 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; | |
1498 } else { | |
1499 // If ReconsiderProxyAfterError() failed synchronously, it means | |
1500 // there was nothing left to fall-back to, so fail the transaction | |
1501 // with the last connection error we got. | |
1502 // TODO(eroman): This is a confusing contract, make it more obvious. | |
1503 rv = error; | |
1504 } | |
1505 | |
1506 return rv; | |
1507 } | 1388 } |
1508 | 1389 |
1509 int HttpStreamFactoryImpl::Job::HandleCertificateError(int error) { | 1390 int HttpStreamFactoryImpl::Job::HandleCertificateError(int error) { |
1510 DCHECK(using_ssl_); | 1391 DCHECK(using_ssl_); |
1511 DCHECK(IsCertificateError(error)); | 1392 DCHECK(IsCertificateError(error)); |
1512 | 1393 |
1513 SSLClientSocket* ssl_socket = | 1394 SSLClientSocket* ssl_socket = |
1514 static_cast<SSLClientSocket*>(connection_->socket()); | 1395 static_cast<SSLClientSocket*>(connection_->socket()); |
1515 ssl_socket->GetSSLInfo(&ssl_info_); | 1396 ssl_socket->GetSSLInfo(&ssl_info_); |
1516 | 1397 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1559 | 1440 |
1560 ConnectionAttempts socket_attempts = connection_->connection_attempts(); | 1441 ConnectionAttempts socket_attempts = connection_->connection_attempts(); |
1561 if (connection_->socket()) { | 1442 if (connection_->socket()) { |
1562 connection_->socket()->GetConnectionAttempts(&socket_attempts); | 1443 connection_->socket()->GetConnectionAttempts(&socket_attempts); |
1563 } | 1444 } |
1564 | 1445 |
1565 delegate_->AddConnectionAttemptsToRequest(this, socket_attempts); | 1446 delegate_->AddConnectionAttemptsToRequest(this, socket_attempts); |
1566 } | 1447 } |
1567 | 1448 |
1568 } // namespace net | 1449 } // namespace net |
OLD | NEW |