Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: net/http/http_network_transaction.cc

Issue 3058013: Fix late binding induced mismatch of Socket and AuthController (Closed)
Patch Set: Address comments Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698