Chromium Code Reviews| 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 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 if (target == HttpAuth::AUTH_NONE) { | 325 if (target == HttpAuth::AUTH_NONE) { |
| 326 NOTREACHED(); | 326 NOTREACHED(); |
| 327 return ERR_UNEXPECTED; | 327 return ERR_UNEXPECTED; |
| 328 } | 328 } |
| 329 pending_auth_target_ = HttpAuth::AUTH_NONE; | 329 pending_auth_target_ = HttpAuth::AUTH_NONE; |
| 330 | 330 |
| 331 auth_controllers_[target]->ResetAuth(username, password); | 331 auth_controllers_[target]->ResetAuth(username, password); |
| 332 | 332 |
| 333 if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) { | 333 if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) { |
| 334 DCHECK(establishing_tunnel_); | 334 DCHECK(establishing_tunnel_); |
| 335 next_state_ = STATE_INIT_CONNECTION; | 335 next_state_ = STATE_RESTART_TUNNEL_AUTH; |
| 336 auth_controllers_[target] = NULL; | |
| 336 ResetStateForRestart(); | 337 ResetStateForRestart(); |
| 337 } else { | 338 } else { |
| 338 PrepareForAuthRestart(target); | 339 PrepareForAuthRestart(target); |
| 339 } | 340 } |
| 340 | 341 |
| 341 DCHECK(user_callback_ == NULL); | 342 DCHECK(user_callback_ == NULL); |
| 342 int rv = DoLoop(OK); | 343 int rv = DoLoop(OK); |
| 343 if (rv == ERR_IO_PENDING) | 344 if (rv == ERR_IO_PENDING) |
| 344 user_callback_ = callback; | 345 user_callback_ = callback; |
| 345 | 346 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 526 case STATE_RESOLVE_PROXY_COMPLETE: | 527 case STATE_RESOLVE_PROXY_COMPLETE: |
| 527 rv = DoResolveProxyComplete(rv); | 528 rv = DoResolveProxyComplete(rv); |
| 528 break; | 529 break; |
| 529 case STATE_INIT_CONNECTION: | 530 case STATE_INIT_CONNECTION: |
| 530 DCHECK_EQ(OK, rv); | 531 DCHECK_EQ(OK, rv); |
| 531 rv = DoInitConnection(); | 532 rv = DoInitConnection(); |
| 532 break; | 533 break; |
| 533 case STATE_INIT_CONNECTION_COMPLETE: | 534 case STATE_INIT_CONNECTION_COMPLETE: |
| 534 rv = DoInitConnectionComplete(rv); | 535 rv = DoInitConnectionComplete(rv); |
| 535 break; | 536 break; |
| 537 case STATE_RESTART_TUNNEL_AUTH: | |
| 538 DCHECK_EQ(OK, rv); | |
| 539 rv = DoRestartTunnelAuth(); | |
| 540 break; | |
| 541 case STATE_RESTART_TUNNEL_AUTH_COMPLETE: | |
| 542 rv = DoRestartTunnelAuthComplete(rv); | |
| 543 break; | |
| 536 case STATE_GENERATE_PROXY_AUTH_TOKEN: | 544 case STATE_GENERATE_PROXY_AUTH_TOKEN: |
| 537 DCHECK_EQ(OK, rv); | 545 DCHECK_EQ(OK, rv); |
| 538 rv = DoGenerateProxyAuthToken(); | 546 rv = DoGenerateProxyAuthToken(); |
| 539 break; | 547 break; |
| 540 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: | 548 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: |
| 541 rv = DoGenerateProxyAuthTokenComplete(rv); | 549 rv = DoGenerateProxyAuthTokenComplete(rv); |
| 542 break; | 550 break; |
| 543 case STATE_GENERATE_SERVER_AUTH_TOKEN: | 551 case STATE_GENERATE_SERVER_AUTH_TOKEN: |
| 544 DCHECK_EQ(OK, rv); | 552 DCHECK_EQ(OK, rv); |
| 545 rv = DoGenerateServerAuthToken(); | 553 rv = DoGenerateServerAuthToken(); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 | 717 |
| 710 next_state_ = STATE_INIT_CONNECTION; | 718 next_state_ = STATE_INIT_CONNECTION; |
| 711 return OK; | 719 return OK; |
| 712 } | 720 } |
| 713 | 721 |
| 714 int HttpNetworkTransaction::DoInitConnection() { | 722 int HttpNetworkTransaction::DoInitConnection() { |
| 715 DCHECK(!connection_->is_initialized()); | 723 DCHECK(!connection_->is_initialized()); |
| 716 DCHECK(proxy_info_.proxy_server().is_valid()); | 724 DCHECK(proxy_info_.proxy_server().is_valid()); |
| 717 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 725 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
| 718 | 726 |
| 719 // Now that the proxy server has been resolved, create the auth_controllers_. | |
| 720 for (int i = 0; i < HttpAuth::AUTH_NUM_TARGETS; i++) { | |
| 721 HttpAuth::Target target = static_cast<HttpAuth::Target>(i); | |
| 722 if (!auth_controllers_[target].get()) | |
| 723 auth_controllers_[target] = new HttpAuthController(target, | |
| 724 AuthURL(target), | |
| 725 session_); | |
| 726 } | |
| 727 | |
| 728 bool want_spdy_over_npn = alternate_protocol_mode_ == kUsingAlternateProtocol | 727 bool want_spdy_over_npn = alternate_protocol_mode_ == kUsingAlternateProtocol |
| 729 && alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_1; | 728 && alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_1; |
| 730 using_ssl_ = request_->url.SchemeIs("https") || | 729 using_ssl_ = request_->url.SchemeIs("https") || |
| 731 (want_spdy_without_npn_ && want_ssl_over_spdy_without_npn_) || | 730 (want_spdy_without_npn_ && want_ssl_over_spdy_without_npn_) || |
| 732 want_spdy_over_npn; | 731 want_spdy_over_npn; |
| 733 using_spdy_ = false; | 732 using_spdy_ = false; |
| 734 response_.was_fetched_via_proxy = !proxy_info_.is_direct(); | 733 response_.was_fetched_via_proxy = !proxy_info_.is_direct(); |
| 735 | 734 |
| 736 // Check first if we have a spdy session for this group. If so, then go | 735 // Check first if we have a spdy session for this group. If so, then go |
| 737 // straight to using that. | 736 // straight to using that. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 766 request_->referrer, | 765 request_->referrer, |
| 767 disable_resolver_cache); | 766 disable_resolver_cache); |
| 768 } else { | 767 } else { |
| 769 ProxyServer proxy_server = proxy_info_.proxy_server(); | 768 ProxyServer proxy_server = proxy_info_.proxy_server(); |
| 770 proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair())); | 769 proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair())); |
| 771 scoped_refptr<TCPSocketParams> proxy_tcp_params = | 770 scoped_refptr<TCPSocketParams> proxy_tcp_params = |
| 772 new TCPSocketParams(*proxy_host_port, request_->priority, | 771 new TCPSocketParams(*proxy_host_port, request_->priority, |
| 773 request_->referrer, disable_resolver_cache); | 772 request_->referrer, disable_resolver_cache); |
| 774 | 773 |
| 775 if (proxy_info_.is_http()) { | 774 if (proxy_info_.is_http()) { |
| 776 scoped_refptr<HttpAuthController> http_proxy_auth; | 775 establishing_tunnel_ = using_ssl_; |
| 777 if (using_ssl_) { | |
| 778 http_proxy_auth = auth_controllers_[HttpAuth::AUTH_PROXY]; | |
| 779 establishing_tunnel_ = true; | |
| 780 } | |
| 781 http_proxy_params = new HttpProxySocketParams(proxy_tcp_params, | 776 http_proxy_params = new HttpProxySocketParams(proxy_tcp_params, |
| 782 request_->url, endpoint_, | 777 request_->url, endpoint_, |
| 783 http_proxy_auth, | 778 session_, using_ssl_); |
| 784 using_ssl_); | |
| 785 } else { | 779 } else { |
| 786 DCHECK(proxy_info_.is_socks()); | 780 DCHECK(proxy_info_.is_socks()); |
| 787 char socks_version; | 781 char socks_version; |
| 788 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5) | 782 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5) |
| 789 socks_version = '5'; | 783 socks_version = '5'; |
| 790 else | 784 else |
| 791 socks_version = '4'; | 785 socks_version = '4'; |
| 792 connection_group = | 786 connection_group = |
| 793 StringPrintf("socks%c/%s", socks_version, connection_group.c_str()); | 787 StringPrintf("socks%c/%s", socks_version, connection_group.c_str()); |
| 794 | 788 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 882 if(want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_) | 876 if(want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_) |
| 883 using_spdy_ = true; | 877 using_spdy_ = true; |
| 884 } | 878 } |
| 885 | 879 |
| 886 // We may be using spdy without SSL | 880 // We may be using spdy without SSL |
| 887 if(!want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_) | 881 if(!want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_) |
| 888 using_spdy_ = true; | 882 using_spdy_ = true; |
| 889 | 883 |
| 890 if (result == ERR_PROXY_AUTH_REQUESTED) { | 884 if (result == ERR_PROXY_AUTH_REQUESTED) { |
| 891 DCHECK(!ssl_started); | 885 DCHECK(!ssl_started); |
| 892 const HttpResponseInfo& tunnel_auth_response = | 886 // Other state (i.e. |using_ssl_| suggests that |connection_| will have an |
|
eroman
2010/07/30 22:11:11
This seems like an unmatched parenthesis.
| |
| 893 connection_->ssl_error_response_info(); | 887 // SSL socket, but there was an error before that could happened. This |
| 894 | 888 // puts the in progress HttpProxy socket into |connection_| in order to |
| 895 response_.headers = tunnel_auth_response.headers; | 889 // complete the auth. The tunnel restart code is carefully to remove it |
| 896 response_.auth_challenge = tunnel_auth_response.auth_challenge; | 890 // before returning control to the rest of this class. |
| 897 headers_valid_ = true; | 891 connection_.reset(connection_->release_pending_http_proxy_connection()); |
| 898 pending_auth_target_ = HttpAuth::AUTH_PROXY; | 892 return HandleTunnelAuthFailure(result); |
| 899 return OK; | |
| 900 } | 893 } |
| 901 | 894 |
| 902 if ((!ssl_started && result < 0 && | 895 if ((!ssl_started && result < 0 && |
| 903 alternate_protocol_mode_ == kUsingAlternateProtocol) || | 896 alternate_protocol_mode_ == kUsingAlternateProtocol) || |
| 904 result == ERR_NPN_NEGOTIATION_FAILED) { | 897 result == ERR_NPN_NEGOTIATION_FAILED) { |
| 905 // Mark the alternate protocol as broken and fallback. | 898 // Mark the alternate protocol as broken and fallback. |
| 906 MarkBrokenAlternateProtocolAndFallback(); | 899 MarkBrokenAlternateProtocolAndFallback(); |
| 907 return OK; | 900 return OK; |
| 908 } | 901 } |
| 909 | 902 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 969 if (using_spdy_) { | 962 if (using_spdy_) { |
| 970 UpdateConnectionTypeHistograms(CONNECTION_SPDY); | 963 UpdateConnectionTypeHistograms(CONNECTION_SPDY); |
| 971 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 | 964 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 |
| 972 next_state_ = STATE_SPDY_GET_STREAM; | 965 next_state_ = STATE_SPDY_GET_STREAM; |
| 973 } else { | 966 } else { |
| 974 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | 967 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
| 975 } | 968 } |
| 976 return OK; | 969 return OK; |
| 977 } | 970 } |
| 978 | 971 |
| 972 int HttpNetworkTransaction::DoRestartTunnelAuth() { | |
| 973 next_state_ = STATE_RESTART_TUNNEL_AUTH_COMPLETE; | |
| 974 HttpProxyClientSocket* http_proxy_socket = | |
| 975 static_cast<HttpProxyClientSocket*>(connection_->socket()); | |
| 976 return http_proxy_socket->RestartWithAuth(&io_callback_); | |
| 977 } | |
| 978 | |
| 979 int HttpNetworkTransaction::DoRestartTunnelAuthComplete(int result) { | |
| 980 if (result == ERR_PROXY_AUTH_REQUESTED) | |
| 981 return HandleTunnelAuthFailure(result); | |
| 982 | |
| 983 if (result == OK) { | |
| 984 // Now that we've got the HttpProxyClientSocket connected. We have | |
| 985 // to release it as an idle socket into the pool and start the connection | |
| 986 // process from the beginning. Trying to pass it in with the | |
| 987 // SSLSocketParams might cause a deadlock since params are dispatched | |
| 988 // interchangeably. This request won't necessarily get this http proxy | |
| 989 // socket, but there will be forward progress. | |
| 990 connection_->Reset(); | |
| 991 establishing_tunnel_ = false; | |
| 992 next_state_ = STATE_INIT_CONNECTION; | |
| 993 return OK; | |
| 994 } | |
| 995 | |
| 996 return ReconsiderProxyAfterError(result); | |
| 997 } | |
| 998 | |
| 979 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { | 999 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { |
| 980 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; | 1000 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; |
| 981 if (!ShouldApplyProxyAuth()) | 1001 if (!ShouldApplyProxyAuth()) |
| 982 return OK; | 1002 return OK; |
| 983 return auth_controllers_[HttpAuth::AUTH_PROXY]->MaybeGenerateAuthToken( | 1003 HttpAuth::Target target = HttpAuth::AUTH_PROXY; |
| 984 request_, &io_callback_, net_log_); | 1004 if (!auth_controllers_[target].get()) |
| 1005 auth_controllers_[target] = new HttpAuthController(target, AuthURL(target), | |
| 1006 session_); | |
| 1007 return auth_controllers_[target]->MaybeGenerateAuthToken(request_, | |
| 1008 &io_callback_, | |
| 1009 net_log_); | |
| 985 } | 1010 } |
| 986 | 1011 |
| 987 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) { | 1012 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) { |
| 988 DCHECK_NE(ERR_IO_PENDING, rv); | 1013 DCHECK_NE(ERR_IO_PENDING, rv); |
| 989 if (rv == OK) | 1014 if (rv == OK) |
| 990 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN; | 1015 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN; |
| 991 return rv; | 1016 return rv; |
| 992 } | 1017 } |
| 993 | 1018 |
| 994 int HttpNetworkTransaction::DoGenerateServerAuthToken() { | 1019 int HttpNetworkTransaction::DoGenerateServerAuthToken() { |
| 995 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE; | 1020 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE; |
| 1021 HttpAuth::Target target = HttpAuth::AUTH_SERVER; | |
| 1022 if (!auth_controllers_[target].get()) | |
| 1023 auth_controllers_[target] = new HttpAuthController(target, AuthURL(target), | |
| 1024 session_); | |
| 996 if (!ShouldApplyServerAuth()) | 1025 if (!ShouldApplyServerAuth()) |
| 997 return OK; | 1026 return OK; |
| 998 return auth_controllers_[HttpAuth::AUTH_SERVER]->MaybeGenerateAuthToken( | 1027 return auth_controllers_[target]->MaybeGenerateAuthToken(request_, |
| 999 request_, &io_callback_, net_log_); | 1028 &io_callback_, |
| 1029 net_log_); | |
| 1000 } | 1030 } |
| 1001 | 1031 |
| 1002 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) { | 1032 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) { |
| 1003 DCHECK_NE(ERR_IO_PENDING, rv); | 1033 DCHECK_NE(ERR_IO_PENDING, rv); |
| 1004 if (rv == OK) | 1034 if (rv == OK) |
| 1005 next_state_ = STATE_SEND_REQUEST; | 1035 next_state_ = STATE_SEND_REQUEST; |
| 1006 return rv; | 1036 return rv; |
| 1007 } | 1037 } |
| 1008 | 1038 |
| 1009 int HttpNetworkTransaction::DoSendRequest() { | 1039 int HttpNetworkTransaction::DoSendRequest() { |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1509 base::TimeDelta::FromMilliseconds(1), | 1539 base::TimeDelta::FromMilliseconds(1), |
| 1510 base::TimeDelta::FromMinutes(10), 100); | 1540 base::TimeDelta::FromMinutes(10), 100); |
| 1511 if (!reused_socket_) { | 1541 if (!reused_socket_) { |
| 1512 UMA_HISTOGRAM_CLIPPED_TIMES( | 1542 UMA_HISTOGRAM_CLIPPED_TIMES( |
| 1513 "Net.Transaction_Latency_Total_New_Connection_Under_10", | 1543 "Net.Transaction_Latency_Total_New_Connection_Under_10", |
| 1514 total_duration, base::TimeDelta::FromMilliseconds(1), | 1544 total_duration, base::TimeDelta::FromMilliseconds(1), |
| 1515 base::TimeDelta::FromMinutes(10), 100); | 1545 base::TimeDelta::FromMinutes(10), 100); |
| 1516 } | 1546 } |
| 1517 } | 1547 } |
| 1518 | 1548 |
| 1549 int HttpNetworkTransaction::HandleTunnelAuthFailure(int error) { | |
| 1550 DCHECK(establishing_tunnel_); | |
| 1551 DCHECK_EQ(ERR_PROXY_AUTH_REQUESTED, error); | |
| 1552 HttpProxyClientSocket* http_proxy_socket = | |
| 1553 static_cast<HttpProxyClientSocket*>(connection_->socket()); | |
| 1554 | |
| 1555 const HttpResponseInfo* tunnel_auth_response = | |
| 1556 http_proxy_socket->GetResponseInfo(); | |
| 1557 response_.headers = tunnel_auth_response->headers; | |
| 1558 response_.auth_challenge = tunnel_auth_response->auth_challenge; | |
| 1559 headers_valid_ = true; | |
| 1560 | |
| 1561 auth_controllers_[HttpAuth::AUTH_PROXY] = | |
| 1562 http_proxy_socket->auth_controller(); | |
| 1563 pending_auth_target_ = HttpAuth::AUTH_PROXY; | |
| 1564 return OK; | |
| 1565 } | |
| 1566 | |
| 1519 int HttpNetworkTransaction::HandleCertificateError(int error) { | 1567 int HttpNetworkTransaction::HandleCertificateError(int error) { |
| 1520 DCHECK(using_ssl_); | 1568 DCHECK(using_ssl_); |
| 1521 DCHECK(IsCertificateError(error)); | 1569 DCHECK(IsCertificateError(error)); |
| 1522 | 1570 |
| 1523 SSLClientSocket* ssl_socket = | 1571 SSLClientSocket* ssl_socket = |
| 1524 static_cast<SSLClientSocket*>(connection_->socket()); | 1572 static_cast<SSLClientSocket*>(connection_->socket()); |
| 1525 ssl_socket->GetSSLInfo(&response_.ssl_info); | 1573 ssl_socket->GetSSLInfo(&response_.ssl_info); |
| 1526 | 1574 |
| 1527 // Add the bad certificate to the set of allowed certificates in the | 1575 // Add the bad certificate to the set of allowed certificates in the |
| 1528 // SSL info object. This data structure will be consulted after calling | 1576 // SSL info object. This data structure will be consulted after calling |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1823 default: | 1871 default: |
| 1824 description = StringPrintf("Unknown state 0x%08X (%u)", state, state); | 1872 description = StringPrintf("Unknown state 0x%08X (%u)", state, state); |
| 1825 break; | 1873 break; |
| 1826 } | 1874 } |
| 1827 return description; | 1875 return description; |
| 1828 } | 1876 } |
| 1829 | 1877 |
| 1830 #undef STATE_CASE | 1878 #undef STATE_CASE |
| 1831 | 1879 |
| 1832 } // namespace net | 1880 } // namespace net |
| OLD | NEW |