| 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 |