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 |