OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_network_transaction.h" | 5 #include "net/http/http_network_transaction.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/field_trial.h" | 8 #include "base/field_trial.h" |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/histogram.h" | 10 #include "base/histogram.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "net/http/http_proxy_client_socket_pool.h" | 33 #include "net/http/http_proxy_client_socket_pool.h" |
34 #include "net/http/http_request_headers.h" | 34 #include "net/http/http_request_headers.h" |
35 #include "net/http/http_request_info.h" | 35 #include "net/http/http_request_info.h" |
36 #include "net/http/http_response_headers.h" | 36 #include "net/http/http_response_headers.h" |
37 #include "net/http/http_response_info.h" | 37 #include "net/http/http_response_info.h" |
38 #include "net/http/http_util.h" | 38 #include "net/http/http_util.h" |
39 #include "net/http/url_security_manager.h" | 39 #include "net/http/url_security_manager.h" |
40 #include "net/socket/client_socket_factory.h" | 40 #include "net/socket/client_socket_factory.h" |
41 #include "net/socket/socks_client_socket_pool.h" | 41 #include "net/socket/socks_client_socket_pool.h" |
42 #include "net/socket/ssl_client_socket.h" | 42 #include "net/socket/ssl_client_socket.h" |
| 43 #include "net/socket/ssl_client_socket_pool.h" |
43 #include "net/socket/tcp_client_socket_pool.h" | 44 #include "net/socket/tcp_client_socket_pool.h" |
44 #include "net/spdy/spdy_http_stream.h" | 45 #include "net/spdy/spdy_http_stream.h" |
45 #include "net/spdy/spdy_session.h" | 46 #include "net/spdy/spdy_session.h" |
46 #include "net/spdy/spdy_session_pool.h" | 47 #include "net/spdy/spdy_session_pool.h" |
47 | 48 |
48 using base::Time; | 49 using base::Time; |
49 | 50 |
50 namespace net { | 51 namespace net { |
51 | 52 |
52 namespace { | 53 namespace { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 | 253 |
253 next_state_ = STATE_RESOLVE_PROXY; | 254 next_state_ = STATE_RESOLVE_PROXY; |
254 int rv = DoLoop(OK); | 255 int rv = DoLoop(OK); |
255 if (rv == ERR_IO_PENDING) | 256 if (rv == ERR_IO_PENDING) |
256 user_callback_ = callback; | 257 user_callback_ = callback; |
257 return rv; | 258 return rv; |
258 } | 259 } |
259 | 260 |
260 int HttpNetworkTransaction::RestartIgnoringLastError( | 261 int HttpNetworkTransaction::RestartIgnoringLastError( |
261 CompletionCallback* callback) { | 262 CompletionCallback* callback) { |
262 if (connection_->socket()->IsConnectedAndIdle()) { | 263 if (connection_->socket() && connection_->socket()->IsConnectedAndIdle()) { |
263 // TODO(wtc): Should we update any of the connection histograms that we | 264 // TODO(wtc): Should we update any of the connection histograms that we |
264 // update in DoSSLConnectComplete if |result| is OK? | 265 // update in DoSSLConnectComplete if |result| is OK? |
265 if (using_spdy_) { | 266 if (using_spdy_) { |
266 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 | 267 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 |
267 next_state_ = STATE_SPDY_SEND_REQUEST; | 268 next_state_ = STATE_SPDY_SEND_REQUEST; |
268 } else { | 269 } else { |
269 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | 270 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
270 } | 271 } |
271 } else { | 272 } else { |
272 connection_->socket()->Disconnect(); | 273 if (connection_->socket()) |
| 274 connection_->socket()->Disconnect(); |
273 connection_->Reset(); | 275 connection_->Reset(); |
274 next_state_ = STATE_INIT_CONNECTION; | 276 next_state_ = STATE_INIT_CONNECTION; |
275 } | 277 } |
276 int rv = DoLoop(OK); | 278 int rv = DoLoop(OK); |
277 if (rv == ERR_IO_PENDING) | 279 if (rv == ERR_IO_PENDING) |
278 user_callback_ = callback; | 280 user_callback_ = callback; |
279 return rv; | 281 return rv; |
280 } | 282 } |
281 | 283 |
282 int HttpNetworkTransaction::RestartWithCertificate( | 284 int HttpNetworkTransaction::RestartWithCertificate( |
(...skipping 23 matching lines...) Expand all Loading... |
306 if (target == HttpAuth::AUTH_NONE) { | 308 if (target == HttpAuth::AUTH_NONE) { |
307 NOTREACHED(); | 309 NOTREACHED(); |
308 return ERR_UNEXPECTED; | 310 return ERR_UNEXPECTED; |
309 } | 311 } |
310 pending_auth_target_ = HttpAuth::AUTH_NONE; | 312 pending_auth_target_ = HttpAuth::AUTH_NONE; |
311 | 313 |
312 auth_controllers_[target]->ResetAuth(username, password); | 314 auth_controllers_[target]->ResetAuth(username, password); |
313 | 315 |
314 if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) { | 316 if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) { |
315 DCHECK(establishing_tunnel_); | 317 DCHECK(establishing_tunnel_); |
| 318 next_state_ = STATE_INIT_CONNECTION; |
316 ResetStateForRestart(); | 319 ResetStateForRestart(); |
317 next_state_ = STATE_TUNNEL_RESTART_WITH_AUTH; | |
318 } else { | 320 } else { |
319 PrepareForAuthRestart(target); | 321 PrepareForAuthRestart(target); |
320 } | 322 } |
321 | 323 |
322 DCHECK(user_callback_ == NULL); | 324 DCHECK(user_callback_ == NULL); |
323 int rv = DoLoop(OK); | 325 int rv = DoLoop(OK); |
324 if (rv == ERR_IO_PENDING) | 326 if (rv == ERR_IO_PENDING) |
325 user_callback_ = callback; | 327 user_callback_ = callback; |
326 | 328 |
327 return rv; | 329 return rv; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 ResetStateForRestart(); | 371 ResetStateForRestart(); |
370 } | 372 } |
371 | 373 |
372 int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, | 374 int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, |
373 CompletionCallback* callback) { | 375 CompletionCallback* callback) { |
374 DCHECK(buf); | 376 DCHECK(buf); |
375 DCHECK_LT(0, buf_len); | 377 DCHECK_LT(0, buf_len); |
376 | 378 |
377 State next_state = STATE_NONE; | 379 State next_state = STATE_NONE; |
378 | 380 |
379 // Are we using SPDY or HTTP? | |
380 if (using_spdy_) { | |
381 DCHECK(!http_stream_.get()); | |
382 DCHECK(spdy_http_stream_->GetResponseInfo()->headers); | |
383 next_state = STATE_SPDY_READ_BODY; | |
384 } else { | |
385 DCHECK(!spdy_http_stream_.get()); | |
386 next_state = STATE_READ_BODY; | |
387 | |
388 if (!connection_->is_initialized()) | |
389 return 0; // connection_->has been reset. Treat like EOF. | |
390 } | |
391 | |
392 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); | 381 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); |
393 DCHECK(headers.get()); | 382 if (headers_valid_ && headers.get() && establishing_tunnel_) { |
394 if (establishing_tunnel_) { | |
395 // We're trying to read the body of the response but we're still trying | 383 // We're trying to read the body of the response but we're still trying |
396 // to establish an SSL tunnel through the proxy. We can't read these | 384 // to establish an SSL tunnel through the proxy. We can't read these |
397 // bytes when establishing a tunnel because they might be controlled by | 385 // bytes when establishing a tunnel because they might be controlled by |
398 // an active network attacker. We don't worry about this for HTTP | 386 // an active network attacker. We don't worry about this for HTTP |
399 // because an active network attacker can already control HTTP sessions. | 387 // because an active network attacker can already control HTTP sessions. |
400 // We reach this case when the user cancels a 407 proxy auth prompt. | 388 // We reach this case when the user cancels a 407 proxy auth prompt. |
401 // See http://crbug.com/8473. | 389 // See http://crbug.com/8473. |
402 DCHECK(proxy_info_.is_http()); | 390 DCHECK(proxy_info_.is_http()); |
403 DCHECK_EQ(headers->response_code(), 407); | 391 DCHECK_EQ(headers->response_code(), 407); |
404 LOG(WARNING) << "Blocked proxy response with status " | 392 LOG(WARNING) << "Blocked proxy response with status " |
405 << headers->response_code() << " to CONNECT request for " | 393 << headers->response_code() << " to CONNECT request for " |
406 << GetHostAndPort(request_->url) << "."; | 394 << GetHostAndPort(request_->url) << "."; |
407 return ERR_TUNNEL_CONNECTION_FAILED; | 395 return ERR_TUNNEL_CONNECTION_FAILED; |
408 } | 396 } |
409 | 397 |
| 398 // Are we using SPDY or HTTP? |
| 399 if (using_spdy_) { |
| 400 DCHECK(!http_stream_.get()); |
| 401 DCHECK(spdy_http_stream_->GetResponseInfo()->headers); |
| 402 next_state = STATE_SPDY_READ_BODY; |
| 403 } else { |
| 404 DCHECK(!spdy_http_stream_.get()); |
| 405 next_state = STATE_READ_BODY; |
| 406 |
| 407 if (!connection_->is_initialized()) |
| 408 return 0; // |*connection_| has been reset. Treat like EOF. |
| 409 } |
| 410 |
410 read_buf_ = buf; | 411 read_buf_ = buf; |
411 read_buf_len_ = buf_len; | 412 read_buf_len_ = buf_len; |
412 | 413 |
413 next_state_ = next_state; | 414 next_state_ = next_state; |
414 int rv = DoLoop(OK); | 415 int rv = DoLoop(OK); |
415 if (rv == ERR_IO_PENDING) | 416 if (rv == ERR_IO_PENDING) |
416 user_callback_ = callback; | 417 user_callback_ = callback; |
417 return rv; | 418 return rv; |
418 } | 419 } |
419 | 420 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 case STATE_RESOLVE_PROXY_COMPLETE: | 510 case STATE_RESOLVE_PROXY_COMPLETE: |
510 rv = DoResolveProxyComplete(rv); | 511 rv = DoResolveProxyComplete(rv); |
511 break; | 512 break; |
512 case STATE_INIT_CONNECTION: | 513 case STATE_INIT_CONNECTION: |
513 DCHECK_EQ(OK, rv); | 514 DCHECK_EQ(OK, rv); |
514 rv = DoInitConnection(); | 515 rv = DoInitConnection(); |
515 break; | 516 break; |
516 case STATE_INIT_CONNECTION_COMPLETE: | 517 case STATE_INIT_CONNECTION_COMPLETE: |
517 rv = DoInitConnectionComplete(rv); | 518 rv = DoInitConnectionComplete(rv); |
518 break; | 519 break; |
519 case STATE_TUNNEL_RESTART_WITH_AUTH: | |
520 DCHECK_EQ(OK, rv); | |
521 rv = DoTunnelRestartWithAuth(); | |
522 break; | |
523 case STATE_SSL_CONNECT: | |
524 DCHECK_EQ(OK, rv); | |
525 rv = DoSSLConnect(); | |
526 break; | |
527 case STATE_SSL_CONNECT_COMPLETE: | |
528 rv = DoSSLConnectComplete(rv); | |
529 break; | |
530 case STATE_GENERATE_PROXY_AUTH_TOKEN: | 520 case STATE_GENERATE_PROXY_AUTH_TOKEN: |
531 DCHECK_EQ(OK, rv); | 521 DCHECK_EQ(OK, rv); |
532 rv = DoGenerateProxyAuthToken(); | 522 rv = DoGenerateProxyAuthToken(); |
533 break; | 523 break; |
534 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: | 524 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: |
535 rv = DoGenerateProxyAuthTokenComplete(rv); | 525 rv = DoGenerateProxyAuthTokenComplete(rv); |
536 break; | 526 break; |
537 case STATE_GENERATE_SERVER_AUTH_TOKEN: | 527 case STATE_GENERATE_SERVER_AUTH_TOKEN: |
538 DCHECK_EQ(OK, rv); | 528 DCHECK_EQ(OK, rv); |
539 rv = DoGenerateServerAuthToken(); | 529 rv = DoGenerateServerAuthToken(); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 return ERR_NO_SUPPORTED_PROXIES; | 684 return ERR_NO_SUPPORTED_PROXIES; |
695 } | 685 } |
696 | 686 |
697 next_state_ = STATE_INIT_CONNECTION; | 687 next_state_ = STATE_INIT_CONNECTION; |
698 return OK; | 688 return OK; |
699 } | 689 } |
700 | 690 |
701 int HttpNetworkTransaction::DoInitConnection() { | 691 int HttpNetworkTransaction::DoInitConnection() { |
702 DCHECK(!connection_->is_initialized()); | 692 DCHECK(!connection_->is_initialized()); |
703 DCHECK(proxy_info_.proxy_server().is_valid()); | 693 DCHECK(proxy_info_.proxy_server().is_valid()); |
| 694 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
704 | 695 |
705 // Now that the proxy server has been resolved, create the auth_controllers_. | 696 // Now that the proxy server has been resolved, create the auth_controllers_. |
706 for (int i = 0; i < HttpAuth::AUTH_NUM_TARGETS; i++) { | 697 for (int i = 0; i < HttpAuth::AUTH_NUM_TARGETS; i++) { |
707 HttpAuth::Target target = static_cast<HttpAuth::Target>(i); | 698 HttpAuth::Target target = static_cast<HttpAuth::Target>(i); |
708 if (!auth_controllers_[target].get()) | 699 if (!auth_controllers_[target].get()) |
709 auth_controllers_[target] = new HttpAuthController(target, | 700 auth_controllers_[target] = new HttpAuthController(target, |
710 AuthURL(target), | 701 AuthURL(target), |
711 session_); | 702 session_); |
712 } | 703 } |
713 | 704 |
714 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 705 bool want_spdy = alternate_protocol_mode_ == kUsingAlternateProtocol |
715 | 706 && alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_1; |
716 using_ssl_ = request_->url.SchemeIs("https") || | 707 using_ssl_ = request_->url.SchemeIs("https") || want_spdy; |
717 (alternate_protocol_mode_ == kUsingAlternateProtocol && | |
718 alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_1); | |
719 | |
720 using_spdy_ = false; | 708 using_spdy_ = false; |
721 | 709 response_.was_fetched_via_proxy = !proxy_info_.is_direct(); |
722 // Build the string used to uniquely identify connections of this type. | |
723 // Determine the host and port to connect to. | |
724 std::string connection_group; | |
725 | 710 |
726 // Use the fixed testing ports if they've been provided. | 711 // Use the fixed testing ports if they've been provided. |
727 if (using_ssl_) { | 712 if (using_ssl_) { |
728 if (session_->fixed_https_port() != 0) | 713 if (session_->fixed_https_port() != 0) |
729 endpoint_.port = session_->fixed_https_port(); | 714 endpoint_.port = session_->fixed_https_port(); |
730 } else if (session_->fixed_http_port() != 0) { | 715 } else if (session_->fixed_http_port() != 0) { |
731 endpoint_.port = session_->fixed_http_port(); | 716 endpoint_.port = session_->fixed_http_port(); |
732 } | 717 } |
733 | 718 |
734 response_.was_fetched_via_proxy = !proxy_info_.is_direct(); | |
735 | |
736 // Check first if we have a spdy session for this group. If so, then go | 719 // Check first if we have a spdy session for this group. If so, then go |
737 // straight to using that. | 720 // straight to using that. |
738 if (session_->spdy_session_pool()->HasSession(endpoint_)) { | 721 if (session_->spdy_session_pool()->HasSession(endpoint_)) { |
739 using_spdy_ = true; | 722 using_spdy_ = true; |
740 reused_socket_ = true; | 723 reused_socket_ = true; |
| 724 next_state_ = STATE_SPDY_SEND_REQUEST; |
741 return OK; | 725 return OK; |
742 } | 726 } |
743 | 727 |
744 connection_group = endpoint_.ToString(); | 728 // Build the string used to uniquely identify connections of this type. |
| 729 // Determine the host and port to connect to. |
| 730 std::string connection_group = endpoint_.ToString(); |
745 DCHECK(!connection_group.empty()); | 731 DCHECK(!connection_group.empty()); |
746 | 732 |
747 if (using_ssl_) | 733 if (using_ssl_) |
748 connection_group = StringPrintf("ssl/%s", connection_group.c_str()); | 734 connection_group = StringPrintf("ssl/%s", connection_group.c_str()); |
749 | 735 |
750 // If the user is refreshing the page, bypass the host cache. | 736 // If the user is refreshing the page, bypass the host cache. |
751 bool disable_resolver_cache = request_->load_flags & LOAD_BYPASS_CACHE || | 737 bool disable_resolver_cache = request_->load_flags & LOAD_BYPASS_CACHE || |
752 request_->load_flags & LOAD_VALIDATE_CACHE || | 738 request_->load_flags & LOAD_VALIDATE_CACHE || |
753 request_->load_flags & LOAD_DISABLE_CACHE; | 739 request_->load_flags & LOAD_DISABLE_CACHE; |
754 | 740 |
755 int rv; | 741 // Build up the connection parameters. |
756 if (!proxy_info_.is_direct()) { | 742 scoped_refptr<TCPSocketParams> tcp_params; |
| 743 scoped_refptr<HttpProxySocketParams> http_proxy_params; |
| 744 scoped_refptr<SOCKSSocketParams> socks_params; |
| 745 scoped_ptr<HostPortPair> proxy_host_port; |
| 746 |
| 747 if (proxy_info_.is_direct()) { |
| 748 tcp_params = new TCPSocketParams(endpoint_, request_->priority, |
| 749 request_->referrer, |
| 750 disable_resolver_cache); |
| 751 } else { |
757 ProxyServer proxy_server = proxy_info_.proxy_server(); | 752 ProxyServer proxy_server = proxy_info_.proxy_server(); |
758 HostPortPair proxy_host_port_pair(proxy_server.HostNoBrackets(), | 753 proxy_host_port.reset(new HostPortPair(proxy_server.HostNoBrackets(), |
759 proxy_server.port()); | 754 proxy_server.port())); |
760 | 755 scoped_refptr<TCPSocketParams> proxy_tcp_params = |
761 scoped_refptr<TCPSocketParams> tcp_params = | 756 new TCPSocketParams(*proxy_host_port, request_->priority, |
762 new TCPSocketParams(proxy_host_port_pair, request_->priority, | |
763 request_->referrer, disable_resolver_cache); | 757 request_->referrer, disable_resolver_cache); |
764 | 758 |
765 if (proxy_info_.is_socks()) { | 759 if (proxy_info_.is_http()) { |
766 const char* socks_version; | |
767 bool socks_v5; | |
768 if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5) { | |
769 socks_version = "5"; | |
770 socks_v5 = true; | |
771 } else { | |
772 socks_version = "4"; | |
773 socks_v5 = false; | |
774 } | |
775 | |
776 connection_group = | |
777 StringPrintf("socks%s/%s", socks_version, connection_group.c_str()); | |
778 | |
779 scoped_refptr<SOCKSSocketParams> socks_params = | |
780 new SOCKSSocketParams(tcp_params, socks_v5, endpoint_, | |
781 request_->priority, request_->referrer); | |
782 | |
783 rv = connection_->Init( | |
784 connection_group, socks_params, request_->priority, | |
785 &io_callback_, | |
786 session_->GetSocketPoolForSOCKSProxy(proxy_host_port_pair), net_log_); | |
787 } else { | |
788 DCHECK(proxy_info_.is_http()); | |
789 scoped_refptr<HttpAuthController> http_proxy_auth; | 760 scoped_refptr<HttpAuthController> http_proxy_auth; |
790 if (using_ssl_) { | 761 if (using_ssl_) { |
791 http_proxy_auth = auth_controllers_[HttpAuth::AUTH_PROXY]; | 762 http_proxy_auth = auth_controllers_[HttpAuth::AUTH_PROXY]; |
792 establishing_tunnel_ = true; | 763 establishing_tunnel_ = true; |
793 } | 764 } |
| 765 http_proxy_params = new HttpProxySocketParams(proxy_tcp_params, |
| 766 request_->url, endpoint_, |
| 767 http_proxy_auth, |
| 768 using_ssl_); |
| 769 } else { |
| 770 DCHECK(proxy_info_.is_socks()); |
| 771 char socks_version; |
| 772 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5) |
| 773 socks_version = '5'; |
| 774 else |
| 775 socks_version = '4'; |
| 776 connection_group = |
| 777 StringPrintf("socks%c/%s", socks_version, connection_group.c_str()); |
794 | 778 |
795 scoped_refptr<HttpProxySocketParams> http_proxy_params = | 779 socks_params = new SOCKSSocketParams(proxy_tcp_params, |
796 new HttpProxySocketParams(tcp_params, request_->url, endpoint_, | 780 socks_version == '5', |
797 http_proxy_auth, using_ssl_); | 781 endpoint_, |
| 782 request_->priority, |
| 783 request_->referrer); |
| 784 } |
| 785 } |
798 | 786 |
799 rv = connection_->Init(connection_group, http_proxy_params, | 787 // Deal with SSL - which layers on top of any given proxy. |
800 request_->priority, &io_callback_, | 788 if (using_ssl_) { |
801 session_->GetSocketPoolForHTTPProxy( | 789 if (ContainsKey(*g_tls_intolerant_servers, GetHostAndPort(request_->url))) { |
802 proxy_host_port_pair), | 790 LOG(WARNING) << "Falling back to SSLv3 because host is TLS intolerant: " |
803 net_log_); | 791 << GetHostAndPort(request_->url); |
| 792 ssl_config_.tls1_enabled = false; |
804 } | 793 } |
805 } else { | 794 |
806 scoped_refptr<TCPSocketParams> tcp_params = | 795 int load_flags = request_->load_flags; |
807 new TCPSocketParams(endpoint_, request_->priority, request_->referrer, | 796 if (g_ignore_certificate_errors) |
808 disable_resolver_cache); | 797 load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; |
809 rv = connection_->Init(connection_group, tcp_params, request_->priority, | 798 if (request_->load_flags & LOAD_VERIFY_EV_CERT) |
| 799 ssl_config_.verify_ev_cert = true; |
| 800 |
| 801 scoped_refptr<SSLSocketParams> ssl_params = |
| 802 new SSLSocketParams(tcp_params, http_proxy_params, socks_params, |
| 803 proxy_info_.proxy_server().scheme(), |
| 804 request_->url.HostNoBrackets(), ssl_config_, |
| 805 load_flags, want_spdy); |
| 806 |
| 807 scoped_refptr<SSLClientSocketPool> ssl_pool; |
| 808 if (proxy_info_.is_direct()) |
| 809 ssl_pool = session_->ssl_socket_pool(); |
| 810 else |
| 811 ssl_pool = session_->GetSocketPoolForSSLWithProxy(*proxy_host_port); |
| 812 |
| 813 return connection_->Init(connection_group, ssl_params, request_->priority, |
| 814 &io_callback_, ssl_pool, net_log_); |
| 815 } |
| 816 |
| 817 // Finally, get the connection started. |
| 818 if (proxy_info_.is_http()) { |
| 819 return connection_->Init( |
| 820 connection_group, http_proxy_params, request_->priority, &io_callback_, |
| 821 session_->GetSocketPoolForHTTPProxy(*proxy_host_port), net_log_); |
| 822 } |
| 823 |
| 824 if (proxy_info_.is_socks()) { |
| 825 return connection_->Init( |
| 826 connection_group, socks_params, request_->priority, &io_callback_, |
| 827 session_->GetSocketPoolForSOCKSProxy(*proxy_host_port), net_log_); |
| 828 } |
| 829 |
| 830 DCHECK(proxy_info_.is_direct()); |
| 831 return connection_->Init(connection_group, tcp_params, request_->priority, |
810 &io_callback_, session_->tcp_socket_pool(), | 832 &io_callback_, session_->tcp_socket_pool(), |
811 net_log_); | 833 net_log_); |
812 } | |
813 | |
814 return rv; | |
815 } | 834 } |
816 | 835 |
817 int HttpNetworkTransaction::DoInitConnectionComplete(int result) { | 836 int HttpNetworkTransaction::DoInitConnectionComplete(int result) { |
818 if (result < 0) { | 837 // |result| may be the result of any of the stacked pools. The following |
819 if (result == ERR_RETRY_CONNECTION) { | 838 // logic is used when determining how to interpret an error. |
820 DCHECK(establishing_tunnel_); | 839 // If |result| < 0: |
821 next_state_ = STATE_INIT_CONNECTION; | 840 // and connection_->socket() != NULL, then the SSL handshake ran and it |
822 connection_->socket()->Disconnect(); | 841 // is a potentially recoverable error. |
823 connection_->Reset(); | 842 // and connection_->socket == NULL and connection_->is_ssl_error() is true, |
824 return OK; | 843 // then the SSL handshake ran with an unrecoverable error. |
| 844 // otherwise, the error came from one of the other pools. |
| 845 bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || |
| 846 connection_->is_ssl_error()); |
| 847 |
| 848 if (ssl_started && (result == OK || IsCertificateError(result))) { |
| 849 SSLClientSocket* ssl_socket = |
| 850 static_cast<SSLClientSocket*>(connection_->socket()); |
| 851 if (ssl_socket->wasNpnNegotiated()) { |
| 852 response_.was_npn_negotiated = true; |
| 853 std::string proto; |
| 854 ssl_socket->GetNextProto(&proto); |
| 855 if (SSLClientSocket::NextProtoFromString(proto) == |
| 856 SSLClientSocket::kProtoSPDY1) |
| 857 using_spdy_ = true; |
825 } | 858 } |
826 | |
827 if (result == ERR_PROXY_AUTH_REQUESTED) { | |
828 DCHECK(establishing_tunnel_); | |
829 HttpProxyClientSocket* tunnel_socket = | |
830 static_cast<HttpProxyClientSocket*>(connection_->socket()); | |
831 DCHECK(tunnel_socket); | |
832 DCHECK(!tunnel_socket->IsConnected()); | |
833 const HttpResponseInfo* auth_response = tunnel_socket->GetResponseInfo(); | |
834 | |
835 response_.headers = auth_response->headers; | |
836 headers_valid_ = true; | |
837 response_.auth_challenge = auth_response->auth_challenge; | |
838 pending_auth_target_ = HttpAuth::AUTH_PROXY; | |
839 return OK; | |
840 } | |
841 | |
842 if (alternate_protocol_mode_ == kUsingAlternateProtocol) { | |
843 // Mark the alternate protocol as broken and fallback. | |
844 MarkBrokenAlternateProtocolAndFallback(); | |
845 return OK; | |
846 } | |
847 | |
848 return ReconsiderProxyAfterError(result); | |
849 } | 859 } |
850 | 860 |
851 DCHECK_EQ(OK, result); | 861 if (result == ERR_PROXY_AUTH_REQUESTED) { |
852 if (establishing_tunnel_) { | 862 DCHECK(!ssl_started); |
853 DCHECK(connection_->socket()->IsConnected()); | 863 const HttpResponseInfo& tunnel_auth_response = |
854 establishing_tunnel_ = false; | 864 connection_->tunnel_auth_response_info(); |
855 } | |
856 | 865 |
857 if (using_spdy_) { | 866 response_.headers = tunnel_auth_response.headers; |
858 DCHECK(!connection_->is_initialized()); | 867 response_.auth_challenge = tunnel_auth_response.auth_challenge; |
859 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 | 868 headers_valid_ = true; |
860 next_state_ = STATE_SPDY_SEND_REQUEST; | 869 pending_auth_target_ = HttpAuth::AUTH_PROXY; |
861 return OK; | 870 return OK; |
862 } | 871 } |
863 | 872 |
864 LogHttpConnectedMetrics(*connection_); | 873 if ((!ssl_started && result < 0 && |
865 | 874 alternate_protocol_mode_ == kUsingAlternateProtocol) || |
866 // Set the reused_socket_ flag to indicate that we are using a keep-alive | 875 result == ERR_NPN_NEGOTIATION_FAILED) { |
867 // connection. This flag is used to handle errors that occur while we are | 876 // Mark the alternate protocol as broken and fallback. |
868 // trying to reuse a keep-alive connection. | |
869 reused_socket_ = connection_->is_reused(); | |
870 if (reused_socket_) { | |
871 if (using_ssl_) { | |
872 SSLClientSocket* ssl_socket = | |
873 reinterpret_cast<SSLClientSocket*>(connection_->socket()); | |
874 response_.was_npn_negotiated = ssl_socket->wasNpnNegotiated(); | |
875 } | |
876 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | |
877 } else { | |
878 // Now we have a TCP connected socket. Perform other connection setup as | |
879 // needed. | |
880 UpdateConnectionTypeHistograms(CONNECTION_HTTP); | |
881 if (using_ssl_) | |
882 next_state_ = STATE_SSL_CONNECT; | |
883 else | |
884 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | |
885 } | |
886 | |
887 return OK; | |
888 } | |
889 | |
890 int HttpNetworkTransaction::DoTunnelRestartWithAuth() { | |
891 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | |
892 HttpProxyClientSocket* tunnel_socket = | |
893 reinterpret_cast<HttpProxyClientSocket*>(connection_->socket()); | |
894 | |
895 return tunnel_socket->RestartWithAuth(&io_callback_); | |
896 } | |
897 | |
898 int HttpNetworkTransaction::DoSSLConnect() { | |
899 next_state_ = STATE_SSL_CONNECT_COMPLETE; | |
900 | |
901 if (ContainsKey(*g_tls_intolerant_servers, GetHostAndPort(request_->url))) { | |
902 LOG(WARNING) << "Falling back to SSLv3 because host is TLS intolerant: " | |
903 << GetHostAndPort(request_->url); | |
904 ssl_config_.tls1_enabled = false; | |
905 } | |
906 | |
907 if (request_->load_flags & LOAD_VERIFY_EV_CERT) | |
908 ssl_config_.verify_ev_cert = true; | |
909 | |
910 ssl_connect_start_time_ = base::TimeTicks::Now(); | |
911 | |
912 // Add a SSL socket on top of our existing transport socket. | |
913 ClientSocket* s = connection_->release_socket(); | |
914 s = session_->socket_factory()->CreateSSLClientSocket( | |
915 s, request_->url.HostNoBrackets(), ssl_config_); | |
916 connection_->set_socket(s); | |
917 return connection_->socket()->Connect(&io_callback_); | |
918 } | |
919 | |
920 int HttpNetworkTransaction::DoSSLConnectComplete(int result) { | |
921 SSLClientSocket* ssl_socket = | |
922 reinterpret_cast<SSLClientSocket*>(connection_->socket()); | |
923 | |
924 SSLClientSocket::NextProtoStatus status = | |
925 SSLClientSocket::kNextProtoUnsupported; | |
926 std::string proto; | |
927 // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket | |
928 // that hasn't had SSL_ImportFD called on it. If we get a certificate error | |
929 // here, then we know that we called SSL_ImportFD. | |
930 if (result == OK || IsCertificateError(result)) | |
931 status = ssl_socket->GetNextProto(&proto); | |
932 | |
933 if (status == SSLClientSocket::kNextProtoNegotiated) { | |
934 ssl_socket->setWasNpnNegotiated(true); | |
935 response_.was_npn_negotiated = true; | |
936 if (SSLClientSocket::NextProtoFromString(proto) == | |
937 SSLClientSocket::kProtoSPDY1) { | |
938 using_spdy_ = true; | |
939 } | |
940 } | |
941 | |
942 if (alternate_protocol_mode_ == kUsingAlternateProtocol && | |
943 alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_1 && | |
944 !using_spdy_) { | |
945 // We tried using the NPN_SPDY_1 alternate protocol, but failed, so we | |
946 // fallback. | |
947 MarkBrokenAlternateProtocolAndFallback(); | 877 MarkBrokenAlternateProtocolAndFallback(); |
948 return OK; | 878 return OK; |
949 } | 879 } |
950 | 880 |
| 881 if (result < 0 && !ssl_started) |
| 882 return ReconsiderProxyAfterError(result); |
| 883 establishing_tunnel_ = false; |
| 884 |
| 885 if (connection_->socket()) { |
| 886 LogHttpConnectedMetrics(*connection_); |
| 887 |
| 888 // Set the reused_socket_ flag to indicate that we are using a keep-alive |
| 889 // connection. This flag is used to handle errors that occur while we are |
| 890 // trying to reuse a keep-alive connection. |
| 891 reused_socket_ = connection_->is_reused(); |
| 892 // TODO(vandebo) should we exclude SPDY in the following if? |
| 893 if (!reused_socket_) |
| 894 UpdateConnectionTypeHistograms(CONNECTION_HTTP); |
| 895 |
| 896 if (!using_ssl_) { |
| 897 DCHECK_EQ(OK, result); |
| 898 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
| 899 return result; |
| 900 } |
| 901 } |
| 902 |
| 903 // Handle SSL errors below. |
| 904 DCHECK(using_ssl_); |
| 905 DCHECK(ssl_started); |
951 if (IsCertificateError(result)) { | 906 if (IsCertificateError(result)) { |
952 if (using_spdy_ && request_->url.SchemeIs("http")) { | 907 if (using_spdy_ && request_->url.SchemeIs("http")) { |
953 // We ignore certificate errors for http over spdy. | 908 // We ignore certificate errors for http over spdy. |
954 spdy_certificate_error_ = result; | 909 spdy_certificate_error_ = result; |
955 result = OK; | 910 result = OK; |
956 } else { | 911 } else { |
957 result = HandleCertificateError(result); | 912 result = HandleCertificateError(result); |
958 if (result == OK && !connection_->socket()->IsConnectedAndIdle()) { | 913 if (result == OK && !connection_->socket()->IsConnectedAndIdle()) { |
959 connection_->socket()->Disconnect(); | 914 connection_->socket()->Disconnect(); |
960 connection_->Reset(); | 915 connection_->Reset(); |
961 next_state_ = STATE_INIT_CONNECTION; | 916 next_state_ = STATE_INIT_CONNECTION; |
962 return result; | 917 return result; |
963 } | 918 } |
964 } | 919 } |
965 } | 920 } |
966 | 921 |
967 if (result == OK) { | 922 if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) |
968 DCHECK(ssl_connect_start_time_ != base::TimeTicks()); | 923 return HandleCertificateRequest(result); |
969 base::TimeDelta connect_duration = | 924 if (result < 0) |
970 base::TimeTicks::Now() - ssl_connect_start_time_; | 925 return HandleSSLHandshakeError(result); |
971 | 926 |
972 if (using_spdy_) { | 927 if (using_spdy_) { |
973 UMA_HISTOGRAM_CUSTOM_TIMES("Net.SpdyConnectionLatency", | 928 UpdateConnectionTypeHistograms(CONNECTION_SPDY); |
974 connect_duration, | 929 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 |
975 base::TimeDelta::FromMilliseconds(1), | 930 next_state_ = STATE_SPDY_SEND_REQUEST; |
976 base::TimeDelta::FromMinutes(10), | |
977 100); | |
978 | |
979 UpdateConnectionTypeHistograms(CONNECTION_SPDY); | |
980 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 | |
981 next_state_ = STATE_SPDY_SEND_REQUEST; | |
982 } else { | |
983 UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency", | |
984 connect_duration, | |
985 base::TimeDelta::FromMilliseconds(1), | |
986 base::TimeDelta::FromMinutes(10), | |
987 100); | |
988 | |
989 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | |
990 } | |
991 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | |
992 result = HandleCertificateRequest(result); | |
993 } else { | 931 } else { |
994 result = HandleSSLHandshakeError(result); | 932 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
995 } | 933 } |
996 return result; | 934 return OK; |
997 } | 935 } |
998 | 936 |
999 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { | 937 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { |
1000 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; | 938 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; |
1001 if (!ShouldApplyProxyAuth()) | 939 if (!ShouldApplyProxyAuth()) |
1002 return OK; | 940 return OK; |
1003 return auth_controllers_[HttpAuth::AUTH_PROXY]->MaybeGenerateAuthToken( | 941 return auth_controllers_[HttpAuth::AUTH_PROXY]->MaybeGenerateAuthToken( |
1004 request_, &io_callback_, net_log_); | 942 request_, &io_callback_, net_log_); |
1005 } | 943 } |
1006 | 944 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1184 ProcessAlternateProtocol(*response_.headers, | 1122 ProcessAlternateProtocol(*response_.headers, |
1185 endpoint_, | 1123 endpoint_, |
1186 session_->mutable_alternate_protocols()); | 1124 session_->mutable_alternate_protocols()); |
1187 | 1125 |
1188 int rv = HandleAuthChallenge(); | 1126 int rv = HandleAuthChallenge(); |
1189 if (rv != OK) | 1127 if (rv != OK) |
1190 return rv; | 1128 return rv; |
1191 | 1129 |
1192 if (using_ssl_) { | 1130 if (using_ssl_) { |
1193 SSLClientSocket* ssl_socket = | 1131 SSLClientSocket* ssl_socket = |
1194 reinterpret_cast<SSLClientSocket*>(connection_->socket()); | 1132 static_cast<SSLClientSocket*>(connection_->socket()); |
1195 ssl_socket->GetSSLInfo(&response_.ssl_info); | 1133 ssl_socket->GetSSLInfo(&response_.ssl_info); |
1196 } | 1134 } |
1197 | 1135 |
1198 headers_valid_ = true; | 1136 headers_valid_ = true; |
1199 return OK; | 1137 return OK; |
1200 } | 1138 } |
1201 | 1139 |
1202 int HttpNetworkTransaction::DoReadBody() { | 1140 int HttpNetworkTransaction::DoReadBody() { |
1203 DCHECK(read_buf_); | 1141 DCHECK(read_buf_); |
1204 DCHECK_GT(read_buf_len_, 0); | 1142 DCHECK_GT(read_buf_len_, 0); |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1527 total_duration, base::TimeDelta::FromMilliseconds(1), | 1465 total_duration, base::TimeDelta::FromMilliseconds(1), |
1528 base::TimeDelta::FromMinutes(10), 100); | 1466 base::TimeDelta::FromMinutes(10), 100); |
1529 } | 1467 } |
1530 } | 1468 } |
1531 | 1469 |
1532 int HttpNetworkTransaction::HandleCertificateError(int error) { | 1470 int HttpNetworkTransaction::HandleCertificateError(int error) { |
1533 DCHECK(using_ssl_); | 1471 DCHECK(using_ssl_); |
1534 DCHECK(IsCertificateError(error)); | 1472 DCHECK(IsCertificateError(error)); |
1535 | 1473 |
1536 SSLClientSocket* ssl_socket = | 1474 SSLClientSocket* ssl_socket = |
1537 reinterpret_cast<SSLClientSocket*>(connection_->socket()); | 1475 static_cast<SSLClientSocket*>(connection_->socket()); |
1538 ssl_socket->GetSSLInfo(&response_.ssl_info); | 1476 ssl_socket->GetSSLInfo(&response_.ssl_info); |
1539 | 1477 |
1540 // Add the bad certificate to the set of allowed certificates in the | 1478 // Add the bad certificate to the set of allowed certificates in the |
1541 // SSL info object. This data structure will be consulted after calling | 1479 // SSL info object. This data structure will be consulted after calling |
1542 // RestartIgnoringLastError(). And the user will be asked interactively | 1480 // RestartIgnoringLastError(). And the user will be asked interactively |
1543 // before RestartIgnoringLastError() is ever called. | 1481 // before RestartIgnoringLastError() is ever called. |
1544 SSLConfig::CertAndStatus bad_cert; | 1482 SSLConfig::CertAndStatus bad_cert; |
1545 bad_cert.cert = response_.ssl_info.cert; | 1483 bad_cert.cert = response_.ssl_info.cert; |
1546 bad_cert.cert_status = response_.ssl_info.cert_status; | 1484 bad_cert.cert_status = response_.ssl_info.cert_status; |
1547 ssl_config_.allowed_bad_certs.push_back(bad_cert); | 1485 ssl_config_.allowed_bad_certs.push_back(bad_cert); |
1548 | 1486 |
| 1487 int load_flags = request_->load_flags; |
1549 if (g_ignore_certificate_errors) | 1488 if (g_ignore_certificate_errors) |
| 1489 load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; |
| 1490 if (ssl_socket->IgnoreCertError(error, load_flags)) |
1550 return OK; | 1491 return OK; |
1551 | |
1552 const int kCertFlags = LOAD_IGNORE_CERT_COMMON_NAME_INVALID | | |
1553 LOAD_IGNORE_CERT_DATE_INVALID | | |
1554 LOAD_IGNORE_CERT_AUTHORITY_INVALID | | |
1555 LOAD_IGNORE_CERT_WRONG_USAGE; | |
1556 if (request_->load_flags & kCertFlags) { | |
1557 switch (error) { | |
1558 case ERR_CERT_COMMON_NAME_INVALID: | |
1559 if (request_->load_flags & LOAD_IGNORE_CERT_COMMON_NAME_INVALID) | |
1560 error = OK; | |
1561 break; | |
1562 case ERR_CERT_DATE_INVALID: | |
1563 if (request_->load_flags & LOAD_IGNORE_CERT_DATE_INVALID) | |
1564 error = OK; | |
1565 break; | |
1566 case ERR_CERT_AUTHORITY_INVALID: | |
1567 if (request_->load_flags & LOAD_IGNORE_CERT_AUTHORITY_INVALID) | |
1568 error = OK; | |
1569 break; | |
1570 } | |
1571 } | |
1572 return error; | 1492 return error; |
1573 } | 1493 } |
1574 | 1494 |
1575 int HttpNetworkTransaction::HandleCertificateRequest(int error) { | 1495 int HttpNetworkTransaction::HandleCertificateRequest(int error) { |
1576 // Assert that the socket did not send a client certificate. | 1496 // Assert that the socket did not send a client certificate. |
1577 // Note: If we got a reused socket, it was created with some other | 1497 // Note: If we got a reused socket, it was created with some other |
1578 // transaction's ssl_config_, so we need to disable this assertion. We can | 1498 // transaction's ssl_config_, so we need to disable this assertion. We can |
1579 // get a certificate request on a reused socket when the server requested | 1499 // get a certificate request on a reused socket when the server requested |
1580 // renegotiation (rehandshake). | 1500 // renegotiation (rehandshake). |
1581 // TODO(wtc): add a GetSSLParams method to SSLClientSocket so we can query | 1501 // TODO(wtc): add a GetSSLParams method to SSLClientSocket so we can query |
1582 // the SSL parameters it was created with and get rid of the reused_socket_ | 1502 // the SSL parameters it was created with and get rid of the reused_socket_ |
1583 // test. | 1503 // test. |
1584 DCHECK(reused_socket_ || !ssl_config_.send_client_cert); | 1504 DCHECK(reused_socket_ || !ssl_config_.send_client_cert); |
1585 | 1505 |
1586 response_.cert_request_info = new SSLCertRequestInfo; | 1506 response_.cert_request_info = new SSLCertRequestInfo; |
1587 SSLClientSocket* ssl_socket = | 1507 SSLClientSocket* ssl_socket = |
1588 reinterpret_cast<SSLClientSocket*>(connection_->socket()); | 1508 static_cast<SSLClientSocket*>(connection_->socket()); |
1589 ssl_socket->GetSSLCertRequestInfo(response_.cert_request_info); | 1509 ssl_socket->GetSSLCertRequestInfo(response_.cert_request_info); |
1590 | 1510 |
1591 // Close the connection while the user is selecting a certificate to send | 1511 // Close the connection while the user is selecting a certificate to send |
1592 // to the server. | 1512 // to the server. |
1593 connection_->socket()->Disconnect(); | 1513 connection_->socket()->Disconnect(); |
1594 connection_->Reset(); | 1514 connection_->Reset(); |
1595 | 1515 |
1596 // If the user selected one of the certificate in client_certs for this | 1516 // If the user selected one of the certificate in client_certs for this |
1597 // server before, use it automatically. | 1517 // server before, use it automatically. |
1598 X509Certificate* client_cert = session_->ssl_client_auth_cache()-> | 1518 X509Certificate* client_cert = session_->ssl_client_auth_cache()-> |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1683 // This automatically prevents an infinite resend loop because we'll run | 1603 // This automatically prevents an infinite resend loop because we'll run |
1684 // out of the cached keep-alive connections eventually. | 1604 // out of the cached keep-alive connections eventually. |
1685 if (!connection_->ShouldResendFailedRequest(error) || | 1605 if (!connection_->ShouldResendFailedRequest(error) || |
1686 GetResponseHeaders()) { // We have received some response headers. | 1606 GetResponseHeaders()) { // We have received some response headers. |
1687 return false; | 1607 return false; |
1688 } | 1608 } |
1689 return true; | 1609 return true; |
1690 } | 1610 } |
1691 | 1611 |
1692 void HttpNetworkTransaction::ResetConnectionAndRequestForResend() { | 1612 void HttpNetworkTransaction::ResetConnectionAndRequestForResend() { |
1693 connection_->socket()->Disconnect(); | 1613 if (connection_->socket()) |
| 1614 connection_->socket()->Disconnect(); |
1694 connection_->Reset(); | 1615 connection_->Reset(); |
1695 // We need to clear request_headers_ because it contains the real request | 1616 // We need to clear request_headers_ because it contains the real request |
1696 // headers, but we may need to resend the CONNECT request first to recreate | 1617 // headers, but we may need to resend the CONNECT request first to recreate |
1697 // the SSL tunnel. | 1618 // the SSL tunnel. |
| 1619 |
1698 request_headers_.clear(); | 1620 request_headers_.clear(); |
1699 next_state_ = STATE_INIT_CONNECTION; // Resend the request. | 1621 next_state_ = STATE_INIT_CONNECTION; // Resend the request. |
1700 } | 1622 } |
1701 | 1623 |
1702 int HttpNetworkTransaction::ReconsiderProxyAfterError(int error) { | 1624 int HttpNetworkTransaction::ReconsiderProxyAfterError(int error) { |
1703 DCHECK(!pac_request_); | 1625 DCHECK(!pac_request_); |
1704 | 1626 |
1705 // A failure to resolve the hostname or any error related to establishing a | 1627 // A failure to resolve the hostname or any error related to establishing a |
1706 // TCP connection could be grounds for trying a new proxy configuration. | 1628 // TCP connection could be grounds for trying a new proxy configuration. |
1707 // | 1629 // |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1866 default: | 1788 default: |
1867 description = StringPrintf("Unknown state 0x%08X (%u)", state, state); | 1789 description = StringPrintf("Unknown state 0x%08X (%u)", state, state); |
1868 break; | 1790 break; |
1869 } | 1791 } |
1870 return description; | 1792 return description; |
1871 } | 1793 } |
1872 | 1794 |
1873 #undef STATE_CASE | 1795 #undef STATE_CASE |
1874 | 1796 |
1875 } // namespace net | 1797 } // namespace net |
OLD | NEW |