| 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 <set> | 7 #include <set> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 if (target == HttpAuth::AUTH_NONE) { | 330 if (target == HttpAuth::AUTH_NONE) { |
| 331 NOTREACHED(); | 331 NOTREACHED(); |
| 332 return ERR_UNEXPECTED; | 332 return ERR_UNEXPECTED; |
| 333 } | 333 } |
| 334 pending_auth_target_ = HttpAuth::AUTH_NONE; | 334 pending_auth_target_ = HttpAuth::AUTH_NONE; |
| 335 | 335 |
| 336 auth_controllers_[target]->ResetAuth(username, password); | 336 auth_controllers_[target]->ResetAuth(username, password); |
| 337 | 337 |
| 338 if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) { | 338 if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) { |
| 339 DCHECK(establishing_tunnel_); | 339 DCHECK(establishing_tunnel_); |
| 340 next_state_ = STATE_RESTART_TUNNEL_AUTH; | 340 next_state_ = STATE_INIT_CONNECTION; |
| 341 auth_controllers_[target] = NULL; | |
| 342 ResetStateForRestart(); | 341 ResetStateForRestart(); |
| 343 } else { | 342 } else { |
| 344 PrepareForAuthRestart(target); | 343 PrepareForAuthRestart(target); |
| 345 } | 344 } |
| 346 | 345 |
| 347 DCHECK(user_callback_ == NULL); | 346 DCHECK(user_callback_ == NULL); |
| 348 int rv = DoLoop(OK); | 347 int rv = DoLoop(OK); |
| 349 if (rv == ERR_IO_PENDING) | 348 if (rv == ERR_IO_PENDING) |
| 350 user_callback_ = callback; | 349 user_callback_ = callback; |
| 351 | 350 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 case STATE_RESOLVE_PROXY_COMPLETE: | 531 case STATE_RESOLVE_PROXY_COMPLETE: |
| 533 rv = DoResolveProxyComplete(rv); | 532 rv = DoResolveProxyComplete(rv); |
| 534 break; | 533 break; |
| 535 case STATE_INIT_CONNECTION: | 534 case STATE_INIT_CONNECTION: |
| 536 DCHECK_EQ(OK, rv); | 535 DCHECK_EQ(OK, rv); |
| 537 rv = DoInitConnection(); | 536 rv = DoInitConnection(); |
| 538 break; | 537 break; |
| 539 case STATE_INIT_CONNECTION_COMPLETE: | 538 case STATE_INIT_CONNECTION_COMPLETE: |
| 540 rv = DoInitConnectionComplete(rv); | 539 rv = DoInitConnectionComplete(rv); |
| 541 break; | 540 break; |
| 542 case STATE_RESTART_TUNNEL_AUTH: | |
| 543 DCHECK_EQ(OK, rv); | |
| 544 rv = DoRestartTunnelAuth(); | |
| 545 break; | |
| 546 case STATE_RESTART_TUNNEL_AUTH_COMPLETE: | |
| 547 rv = DoRestartTunnelAuthComplete(rv); | |
| 548 break; | |
| 549 case STATE_GENERATE_PROXY_AUTH_TOKEN: | 541 case STATE_GENERATE_PROXY_AUTH_TOKEN: |
| 550 DCHECK_EQ(OK, rv); | 542 DCHECK_EQ(OK, rv); |
| 551 rv = DoGenerateProxyAuthToken(); | 543 rv = DoGenerateProxyAuthToken(); |
| 552 break; | 544 break; |
| 553 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: | 545 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: |
| 554 rv = DoGenerateProxyAuthTokenComplete(rv); | 546 rv = DoGenerateProxyAuthTokenComplete(rv); |
| 555 break; | 547 break; |
| 556 case STATE_GENERATE_SERVER_AUTH_TOKEN: | 548 case STATE_GENERATE_SERVER_AUTH_TOKEN: |
| 557 DCHECK_EQ(OK, rv); | 549 DCHECK_EQ(OK, rv); |
| 558 rv = DoGenerateServerAuthToken(); | 550 rv = DoGenerateServerAuthToken(); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 724 | 716 |
| 725 next_state_ = STATE_INIT_CONNECTION; | 717 next_state_ = STATE_INIT_CONNECTION; |
| 726 return OK; | 718 return OK; |
| 727 } | 719 } |
| 728 | 720 |
| 729 int HttpNetworkTransaction::DoInitConnection() { | 721 int HttpNetworkTransaction::DoInitConnection() { |
| 730 DCHECK(!connection_->is_initialized()); | 722 DCHECK(!connection_->is_initialized()); |
| 731 DCHECK(proxy_info_.proxy_server().is_valid()); | 723 DCHECK(proxy_info_.proxy_server().is_valid()); |
| 732 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 724 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
| 733 | 725 |
| 726 // Now that the proxy server has been resolved, create the auth_controllers_. |
| 727 for (int i = 0; i < HttpAuth::AUTH_NUM_TARGETS; i++) { |
| 728 HttpAuth::Target target = static_cast<HttpAuth::Target>(i); |
| 729 if (!auth_controllers_[target].get()) |
| 730 auth_controllers_[target] = new HttpAuthController(target, |
| 731 AuthURL(target), |
| 732 session_); |
| 733 } |
| 734 |
| 734 bool want_spdy_over_npn = alternate_protocol_mode_ == kUsingAlternateProtocol | 735 bool want_spdy_over_npn = alternate_protocol_mode_ == kUsingAlternateProtocol |
| 735 && alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_2; | 736 && alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_2; |
| 736 using_ssl_ = request_->url.SchemeIs("https") || | 737 using_ssl_ = request_->url.SchemeIs("https") || |
| 737 (want_spdy_without_npn_ && want_ssl_over_spdy_without_npn_) || | 738 (want_spdy_without_npn_ && want_ssl_over_spdy_without_npn_) || |
| 738 want_spdy_over_npn; | 739 want_spdy_over_npn; |
| 739 using_spdy_ = false; | 740 using_spdy_ = false; |
| 740 response_.was_fetched_via_proxy = !proxy_info_.is_direct(); | 741 response_.was_fetched_via_proxy = !proxy_info_.is_direct(); |
| 741 | 742 |
| 742 // Check first if we have a spdy session for this group. If so, then go | 743 // Check first if we have a spdy session for this group. If so, then go |
| 743 // straight to using that. | 744 // straight to using that. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 773 request_->referrer, | 774 request_->referrer, |
| 774 disable_resolver_cache); | 775 disable_resolver_cache); |
| 775 } else { | 776 } else { |
| 776 ProxyServer proxy_server = proxy_info_.proxy_server(); | 777 ProxyServer proxy_server = proxy_info_.proxy_server(); |
| 777 proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair())); | 778 proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair())); |
| 778 scoped_refptr<TCPSocketParams> proxy_tcp_params = | 779 scoped_refptr<TCPSocketParams> proxy_tcp_params = |
| 779 new TCPSocketParams(*proxy_host_port, request_->priority, | 780 new TCPSocketParams(*proxy_host_port, request_->priority, |
| 780 request_->referrer, disable_resolver_cache); | 781 request_->referrer, disable_resolver_cache); |
| 781 | 782 |
| 782 if (proxy_info_.is_http()) { | 783 if (proxy_info_.is_http()) { |
| 783 establishing_tunnel_ = using_ssl_; | 784 scoped_refptr<HttpAuthController> http_proxy_auth; |
| 785 if (using_ssl_) { |
| 786 http_proxy_auth = auth_controllers_[HttpAuth::AUTH_PROXY]; |
| 787 establishing_tunnel_ = true; |
| 788 } |
| 784 http_proxy_params = new HttpProxySocketParams(proxy_tcp_params, | 789 http_proxy_params = new HttpProxySocketParams(proxy_tcp_params, |
| 785 request_->url, endpoint_, | 790 request_->url, endpoint_, |
| 786 session_, using_ssl_); | 791 http_proxy_auth, |
| 792 using_ssl_); |
| 787 } else { | 793 } else { |
| 788 DCHECK(proxy_info_.is_socks()); | 794 DCHECK(proxy_info_.is_socks()); |
| 789 char socks_version; | 795 char socks_version; |
| 790 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5) | 796 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5) |
| 791 socks_version = '5'; | 797 socks_version = '5'; |
| 792 else | 798 else |
| 793 socks_version = '4'; | 799 socks_version = '4'; |
| 794 connection_group = | 800 connection_group = |
| 795 StringPrintf("socks%c/%s", socks_version, connection_group.c_str()); | 801 StringPrintf("socks%c/%s", socks_version, connection_group.c_str()); |
| 796 | 802 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 if(want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_) | 890 if(want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_) |
| 885 using_spdy_ = true; | 891 using_spdy_ = true; |
| 886 } | 892 } |
| 887 | 893 |
| 888 // We may be using spdy without SSL | 894 // We may be using spdy without SSL |
| 889 if(!want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_) | 895 if(!want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_) |
| 890 using_spdy_ = true; | 896 using_spdy_ = true; |
| 891 | 897 |
| 892 if (result == ERR_PROXY_AUTH_REQUESTED) { | 898 if (result == ERR_PROXY_AUTH_REQUESTED) { |
| 893 DCHECK(!ssl_started); | 899 DCHECK(!ssl_started); |
| 894 // Other state (i.e. |using_ssl_|) suggests that |connection_| will have an | 900 const HttpResponseInfo& tunnel_auth_response = |
| 895 // SSL socket, but there was an error before that could happened. This | 901 connection_->ssl_error_response_info(); |
| 896 // puts the in progress HttpProxy socket into |connection_| in order to | 902 |
| 897 // complete the auth. The tunnel restart code is carefully to remove it | 903 response_.headers = tunnel_auth_response.headers; |
| 898 // before returning control to the rest of this class. | 904 response_.auth_challenge = tunnel_auth_response.auth_challenge; |
| 899 connection_.reset(connection_->release_pending_http_proxy_connection()); | 905 headers_valid_ = true; |
| 900 return HandleTunnelAuthFailure(result); | 906 pending_auth_target_ = HttpAuth::AUTH_PROXY; |
| 907 return OK; |
| 901 } | 908 } |
| 902 | 909 |
| 903 if ((!ssl_started && result < 0 && | 910 if ((!ssl_started && result < 0 && |
| 904 alternate_protocol_mode_ == kUsingAlternateProtocol) || | 911 alternate_protocol_mode_ == kUsingAlternateProtocol) || |
| 905 result == ERR_NPN_NEGOTIATION_FAILED) { | 912 result == ERR_NPN_NEGOTIATION_FAILED) { |
| 906 // Mark the alternate protocol as broken and fallback. | 913 // Mark the alternate protocol as broken and fallback. |
| 907 MarkBrokenAlternateProtocolAndFallback(); | 914 MarkBrokenAlternateProtocolAndFallback(); |
| 908 return OK; | 915 return OK; |
| 909 } | 916 } |
| 910 | 917 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 if (using_spdy_) { | 977 if (using_spdy_) { |
| 971 UpdateConnectionTypeHistograms(CONNECTION_SPDY); | 978 UpdateConnectionTypeHistograms(CONNECTION_SPDY); |
| 972 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 | 979 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 |
| 973 next_state_ = STATE_SPDY_GET_STREAM; | 980 next_state_ = STATE_SPDY_GET_STREAM; |
| 974 } else { | 981 } else { |
| 975 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | 982 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
| 976 } | 983 } |
| 977 return OK; | 984 return OK; |
| 978 } | 985 } |
| 979 | 986 |
| 980 int HttpNetworkTransaction::DoRestartTunnelAuth() { | |
| 981 next_state_ = STATE_RESTART_TUNNEL_AUTH_COMPLETE; | |
| 982 HttpProxyClientSocket* http_proxy_socket = | |
| 983 static_cast<HttpProxyClientSocket*>(connection_->socket()); | |
| 984 return http_proxy_socket->RestartWithAuth(&io_callback_); | |
| 985 } | |
| 986 | |
| 987 int HttpNetworkTransaction::DoRestartTunnelAuthComplete(int result) { | |
| 988 if (result == ERR_PROXY_AUTH_REQUESTED) | |
| 989 return HandleTunnelAuthFailure(result); | |
| 990 | |
| 991 if (result == OK) { | |
| 992 // Now that we've got the HttpProxyClientSocket connected. We have | |
| 993 // to release it as an idle socket into the pool and start the connection | |
| 994 // process from the beginning. Trying to pass it in with the | |
| 995 // SSLSocketParams might cause a deadlock since params are dispatched | |
| 996 // interchangeably. This request won't necessarily get this http proxy | |
| 997 // socket, but there will be forward progress. | |
| 998 connection_->Reset(); | |
| 999 establishing_tunnel_ = false; | |
| 1000 next_state_ = STATE_INIT_CONNECTION; | |
| 1001 return OK; | |
| 1002 } | |
| 1003 | |
| 1004 return ReconsiderProxyAfterError(result); | |
| 1005 } | |
| 1006 | |
| 1007 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { | 987 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { |
| 1008 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; | 988 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; |
| 1009 if (!ShouldApplyProxyAuth()) | 989 if (!ShouldApplyProxyAuth()) |
| 1010 return OK; | 990 return OK; |
| 1011 HttpAuth::Target target = HttpAuth::AUTH_PROXY; | 991 return auth_controllers_[HttpAuth::AUTH_PROXY]->MaybeGenerateAuthToken( |
| 1012 if (!auth_controllers_[target].get()) | 992 request_, &io_callback_, net_log_); |
| 1013 auth_controllers_[target] = new HttpAuthController(target, AuthURL(target), | |
| 1014 session_); | |
| 1015 return auth_controllers_[target]->MaybeGenerateAuthToken(request_, | |
| 1016 &io_callback_, | |
| 1017 net_log_); | |
| 1018 } | 993 } |
| 1019 | 994 |
| 1020 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) { | 995 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) { |
| 1021 DCHECK_NE(ERR_IO_PENDING, rv); | 996 DCHECK_NE(ERR_IO_PENDING, rv); |
| 1022 if (rv == OK) | 997 if (rv == OK) |
| 1023 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN; | 998 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN; |
| 1024 return rv; | 999 return rv; |
| 1025 } | 1000 } |
| 1026 | 1001 |
| 1027 int HttpNetworkTransaction::DoGenerateServerAuthToken() { | 1002 int HttpNetworkTransaction::DoGenerateServerAuthToken() { |
| 1028 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE; | 1003 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE; |
| 1029 HttpAuth::Target target = HttpAuth::AUTH_SERVER; | |
| 1030 if (!auth_controllers_[target].get()) | |
| 1031 auth_controllers_[target] = new HttpAuthController(target, AuthURL(target), | |
| 1032 session_); | |
| 1033 if (!ShouldApplyServerAuth()) | 1004 if (!ShouldApplyServerAuth()) |
| 1034 return OK; | 1005 return OK; |
| 1035 return auth_controllers_[target]->MaybeGenerateAuthToken(request_, | 1006 return auth_controllers_[HttpAuth::AUTH_SERVER]->MaybeGenerateAuthToken( |
| 1036 &io_callback_, | 1007 request_, &io_callback_, net_log_); |
| 1037 net_log_); | |
| 1038 } | 1008 } |
| 1039 | 1009 |
| 1040 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) { | 1010 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) { |
| 1041 DCHECK_NE(ERR_IO_PENDING, rv); | 1011 DCHECK_NE(ERR_IO_PENDING, rv); |
| 1042 if (rv == OK) | 1012 if (rv == OK) |
| 1043 next_state_ = STATE_SEND_REQUEST; | 1013 next_state_ = STATE_SEND_REQUEST; |
| 1044 return rv; | 1014 return rv; |
| 1045 } | 1015 } |
| 1046 | 1016 |
| 1047 int HttpNetworkTransaction::DoSendRequest() { | 1017 int HttpNetworkTransaction::DoSendRequest() { |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1550 base::TimeDelta::FromMilliseconds(1), | 1520 base::TimeDelta::FromMilliseconds(1), |
| 1551 base::TimeDelta::FromMinutes(10), 100); | 1521 base::TimeDelta::FromMinutes(10), 100); |
| 1552 if (!reused_socket_) { | 1522 if (!reused_socket_) { |
| 1553 UMA_HISTOGRAM_CLIPPED_TIMES( | 1523 UMA_HISTOGRAM_CLIPPED_TIMES( |
| 1554 "Net.Transaction_Latency_Total_New_Connection_Under_10", | 1524 "Net.Transaction_Latency_Total_New_Connection_Under_10", |
| 1555 total_duration, base::TimeDelta::FromMilliseconds(1), | 1525 total_duration, base::TimeDelta::FromMilliseconds(1), |
| 1556 base::TimeDelta::FromMinutes(10), 100); | 1526 base::TimeDelta::FromMinutes(10), 100); |
| 1557 } | 1527 } |
| 1558 } | 1528 } |
| 1559 | 1529 |
| 1560 int HttpNetworkTransaction::HandleTunnelAuthFailure(int error) { | |
| 1561 DCHECK(establishing_tunnel_); | |
| 1562 DCHECK_EQ(ERR_PROXY_AUTH_REQUESTED, error); | |
| 1563 HttpProxyClientSocket* http_proxy_socket = | |
| 1564 static_cast<HttpProxyClientSocket*>(connection_->socket()); | |
| 1565 | |
| 1566 const HttpResponseInfo* tunnel_auth_response = | |
| 1567 http_proxy_socket->GetResponseInfo(); | |
| 1568 response_.headers = tunnel_auth_response->headers; | |
| 1569 response_.auth_challenge = tunnel_auth_response->auth_challenge; | |
| 1570 headers_valid_ = true; | |
| 1571 | |
| 1572 auth_controllers_[HttpAuth::AUTH_PROXY] = | |
| 1573 http_proxy_socket->auth_controller(); | |
| 1574 pending_auth_target_ = HttpAuth::AUTH_PROXY; | |
| 1575 return OK; | |
| 1576 } | |
| 1577 | |
| 1578 int HttpNetworkTransaction::HandleCertificateError(int error) { | 1530 int HttpNetworkTransaction::HandleCertificateError(int error) { |
| 1579 DCHECK(using_ssl_); | 1531 DCHECK(using_ssl_); |
| 1580 DCHECK(IsCertificateError(error)); | 1532 DCHECK(IsCertificateError(error)); |
| 1581 | 1533 |
| 1582 SSLClientSocket* ssl_socket = | 1534 SSLClientSocket* ssl_socket = |
| 1583 static_cast<SSLClientSocket*>(connection_->socket()); | 1535 static_cast<SSLClientSocket*>(connection_->socket()); |
| 1584 ssl_socket->GetSSLInfo(&response_.ssl_info); | 1536 ssl_socket->GetSSLInfo(&response_.ssl_info); |
| 1585 | 1537 |
| 1586 // Add the bad certificate to the set of allowed certificates in the | 1538 // Add the bad certificate to the set of allowed certificates in the |
| 1587 // SSL info object. This data structure will be consulted after calling | 1539 // SSL info object. This data structure will be consulted after calling |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1911 default: | 1863 default: |
| 1912 return priority; | 1864 return priority; |
| 1913 } | 1865 } |
| 1914 } | 1866 } |
| 1915 | 1867 |
| 1916 | 1868 |
| 1917 | 1869 |
| 1918 #undef STATE_CASE | 1870 #undef STATE_CASE |
| 1919 | 1871 |
| 1920 } // namespace net | 1872 } // namespace net |
| OLD | NEW |