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

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

Issue 3029052: Recommit 54405 - Fix late binding induced mismatch of Socket and AuthController (Closed)
Patch Set: 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
« no previous file with comments | « net/http/http_network_transaction.h ('k') | net/http/http_network_transaction_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 if (target == HttpAuth::AUTH_NONE) { 341 if (target == HttpAuth::AUTH_NONE) {
342 NOTREACHED(); 342 NOTREACHED();
343 return ERR_UNEXPECTED; 343 return ERR_UNEXPECTED;
344 } 344 }
345 pending_auth_target_ = HttpAuth::AUTH_NONE; 345 pending_auth_target_ = HttpAuth::AUTH_NONE;
346 346
347 auth_controllers_[target]->ResetAuth(username, password); 347 auth_controllers_[target]->ResetAuth(username, password);
348 348
349 if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) { 349 if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) {
350 DCHECK(establishing_tunnel_); 350 DCHECK(establishing_tunnel_);
351 next_state_ = STATE_INIT_CONNECTION; 351 next_state_ = STATE_RESTART_TUNNEL_AUTH;
352 auth_controllers_[target] = NULL;
352 ResetStateForRestart(); 353 ResetStateForRestart();
353 } else { 354 } else {
354 PrepareForAuthRestart(target); 355 PrepareForAuthRestart(target);
355 } 356 }
356 357
357 DCHECK(user_callback_ == NULL); 358 DCHECK(user_callback_ == NULL);
358 int rv = DoLoop(OK); 359 int rv = DoLoop(OK);
359 if (rv == ERR_IO_PENDING) 360 if (rv == ERR_IO_PENDING)
360 user_callback_ = callback; 361 user_callback_ = callback;
361 362
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 case STATE_RESOLVE_PROXY_COMPLETE: 543 case STATE_RESOLVE_PROXY_COMPLETE:
543 rv = DoResolveProxyComplete(rv); 544 rv = DoResolveProxyComplete(rv);
544 break; 545 break;
545 case STATE_INIT_CONNECTION: 546 case STATE_INIT_CONNECTION:
546 DCHECK_EQ(OK, rv); 547 DCHECK_EQ(OK, rv);
547 rv = DoInitConnection(); 548 rv = DoInitConnection();
548 break; 549 break;
549 case STATE_INIT_CONNECTION_COMPLETE: 550 case STATE_INIT_CONNECTION_COMPLETE:
550 rv = DoInitConnectionComplete(rv); 551 rv = DoInitConnectionComplete(rv);
551 break; 552 break;
553 case STATE_RESTART_TUNNEL_AUTH:
554 DCHECK_EQ(OK, rv);
555 rv = DoRestartTunnelAuth();
556 break;
557 case STATE_RESTART_TUNNEL_AUTH_COMPLETE:
558 rv = DoRestartTunnelAuthComplete(rv);
559 break;
552 case STATE_GENERATE_PROXY_AUTH_TOKEN: 560 case STATE_GENERATE_PROXY_AUTH_TOKEN:
553 DCHECK_EQ(OK, rv); 561 DCHECK_EQ(OK, rv);
554 rv = DoGenerateProxyAuthToken(); 562 rv = DoGenerateProxyAuthToken();
555 break; 563 break;
556 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: 564 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE:
557 rv = DoGenerateProxyAuthTokenComplete(rv); 565 rv = DoGenerateProxyAuthTokenComplete(rv);
558 break; 566 break;
559 case STATE_GENERATE_SERVER_AUTH_TOKEN: 567 case STATE_GENERATE_SERVER_AUTH_TOKEN:
560 DCHECK_EQ(OK, rv); 568 DCHECK_EQ(OK, rv);
561 rv = DoGenerateServerAuthToken(); 569 rv = DoGenerateServerAuthToken();
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 727
720 next_state_ = STATE_INIT_CONNECTION; 728 next_state_ = STATE_INIT_CONNECTION;
721 return OK; 729 return OK;
722 } 730 }
723 731
724 int HttpNetworkTransaction::DoInitConnection() { 732 int HttpNetworkTransaction::DoInitConnection() {
725 DCHECK(!connection_->is_initialized()); 733 DCHECK(!connection_->is_initialized());
726 DCHECK(proxy_info_.proxy_server().is_valid()); 734 DCHECK(proxy_info_.proxy_server().is_valid());
727 next_state_ = STATE_INIT_CONNECTION_COMPLETE; 735 next_state_ = STATE_INIT_CONNECTION_COMPLETE;
728 736
729 // Now that the proxy server has been resolved, create the auth_controllers_.
730 for (int i = 0; i < HttpAuth::AUTH_NUM_TARGETS; i++) {
731 HttpAuth::Target target = static_cast<HttpAuth::Target>(i);
732 if (!auth_controllers_[target].get())
733 auth_controllers_[target] = new HttpAuthController(target,
734 AuthURL(target),
735 session_);
736 }
737
738 bool want_spdy_over_npn = alternate_protocol_mode_ == kUsingAlternateProtocol 737 bool want_spdy_over_npn = alternate_protocol_mode_ == kUsingAlternateProtocol
739 && alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_2; 738 && alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_2;
740 using_ssl_ = request_->url.SchemeIs("https") || 739 using_ssl_ = request_->url.SchemeIs("https") ||
741 (want_spdy_without_npn_ && want_ssl_over_spdy_without_npn_) || 740 (want_spdy_without_npn_ && want_ssl_over_spdy_without_npn_) ||
742 want_spdy_over_npn; 741 want_spdy_over_npn;
743 using_spdy_ = false; 742 using_spdy_ = false;
744 response_.was_fetched_via_proxy = !proxy_info_.is_direct(); 743 response_.was_fetched_via_proxy = !proxy_info_.is_direct();
745 744
746 // Check first if we have a spdy session for this group. If so, then go 745 // Check first if we have a spdy session for this group. If so, then go
747 // straight to using that. 746 // straight to using that.
(...skipping 29 matching lines...) Expand all
777 request_->referrer, 776 request_->referrer,
778 disable_resolver_cache); 777 disable_resolver_cache);
779 } else { 778 } else {
780 ProxyServer proxy_server = proxy_info_.proxy_server(); 779 ProxyServer proxy_server = proxy_info_.proxy_server();
781 proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair())); 780 proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair()));
782 scoped_refptr<TCPSocketParams> proxy_tcp_params = 781 scoped_refptr<TCPSocketParams> proxy_tcp_params =
783 new TCPSocketParams(*proxy_host_port, request_->priority, 782 new TCPSocketParams(*proxy_host_port, request_->priority,
784 request_->referrer, disable_resolver_cache); 783 request_->referrer, disable_resolver_cache);
785 784
786 if (proxy_info_.is_http()) { 785 if (proxy_info_.is_http()) {
787 scoped_refptr<HttpAuthController> http_proxy_auth;
788 GURL authentication_url = request_->url; 786 GURL authentication_url = request_->url;
789 if (using_ssl_) { 787 if (using_ssl_ && !authentication_url.SchemeIs("https")) {
790 if (!authentication_url.SchemeIs("https")) { 788 // If a proxy tunnel connection needs to be established due to
791 // If a proxy tunnel connection needs to be established due to 789 // an Alternate-Protocol, the URL needs to be changed to indicate
792 // an Alternate-Protocol, the URL needs to be changed to indicate 790 // https or digest authentication attempts will fail.
793 // https or digest authentication attempts will fail. 791 // For example, suppose the initial request was for
794 // For example, suppose the initial request was for 792 // "http://www.example.com/index.html". If this is an SSL
795 // "http://www.example.com/index.html". If this is an SSL 793 // upgrade due to alternate protocol, the digest authorization
796 // upgrade due to alternate protocol, the digest authorization 794 // should have a uri="www.example.com:443" field rather than a
797 // should have a uri="www.example.com:443" field rather than a 795 // "/index.html" entry, even though the original request URL has not
798 // "/index.html" entry, even though the original request URL has not 796 // changed.
799 // changed. 797 authentication_url = UpgradeUrlToHttps(authentication_url);
800 authentication_url = UpgradeUrlToHttps(authentication_url);
801 }
802 http_proxy_auth = auth_controllers_[HttpAuth::AUTH_PROXY];
803 establishing_tunnel_ = true;
804 } 798 }
799 establishing_tunnel_ = using_ssl_;
805 http_proxy_params = new HttpProxySocketParams(proxy_tcp_params, 800 http_proxy_params = new HttpProxySocketParams(proxy_tcp_params,
806 authentication_url, 801 authentication_url,
807 endpoint_, 802 endpoint_,
808 http_proxy_auth, 803 session_, using_ssl_);
809 using_ssl_);
810 } else { 804 } else {
811 DCHECK(proxy_info_.is_socks()); 805 DCHECK(proxy_info_.is_socks());
812 char socks_version; 806 char socks_version;
813 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5) 807 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5)
814 socks_version = '5'; 808 socks_version = '5';
815 else 809 else
816 socks_version = '4'; 810 socks_version = '4';
817 connection_group = 811 connection_group =
818 StringPrintf("socks%c/%s", socks_version, connection_group.c_str()); 812 StringPrintf("socks%c/%s", socks_version, connection_group.c_str());
819 813
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 if(want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_) 901 if(want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_)
908 using_spdy_ = true; 902 using_spdy_ = true;
909 } 903 }
910 904
911 // We may be using spdy without SSL 905 // We may be using spdy without SSL
912 if(!want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_) 906 if(!want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_)
913 using_spdy_ = true; 907 using_spdy_ = true;
914 908
915 if (result == ERR_PROXY_AUTH_REQUESTED) { 909 if (result == ERR_PROXY_AUTH_REQUESTED) {
916 DCHECK(!ssl_started); 910 DCHECK(!ssl_started);
917 const HttpResponseInfo& tunnel_auth_response = 911 // Other state (i.e. |using_ssl_|) suggests that |connection_| will have an
918 connection_->ssl_error_response_info(); 912 // SSL socket, but there was an error before that could happened. This
919 913 // puts the in progress HttpProxy socket into |connection_| in order to
920 response_.headers = tunnel_auth_response.headers; 914 // complete the auth. The tunnel restart code is carefully to remove it
921 response_.auth_challenge = tunnel_auth_response.auth_challenge; 915 // before returning control to the rest of this class.
922 headers_valid_ = true; 916 connection_.reset(connection_->release_pending_http_proxy_connection());
923 pending_auth_target_ = HttpAuth::AUTH_PROXY; 917 return HandleTunnelAuthFailure(result);
924 return OK;
925 } 918 }
926 919
927 if ((!ssl_started && result < 0 && 920 if ((!ssl_started && result < 0 &&
928 alternate_protocol_mode_ == kUsingAlternateProtocol) || 921 alternate_protocol_mode_ == kUsingAlternateProtocol) ||
929 result == ERR_NPN_NEGOTIATION_FAILED) { 922 result == ERR_NPN_NEGOTIATION_FAILED) {
930 // Mark the alternate protocol as broken and fallback. 923 // Mark the alternate protocol as broken and fallback.
931 MarkBrokenAlternateProtocolAndFallback(); 924 MarkBrokenAlternateProtocolAndFallback();
932 return OK; 925 return OK;
933 } 926 }
934 927
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 if (using_spdy_) { 987 if (using_spdy_) {
995 UpdateConnectionTypeHistograms(CONNECTION_SPDY); 988 UpdateConnectionTypeHistograms(CONNECTION_SPDY);
996 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 989 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620
997 next_state_ = STATE_SPDY_GET_STREAM; 990 next_state_ = STATE_SPDY_GET_STREAM;
998 } else { 991 } else {
999 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; 992 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
1000 } 993 }
1001 return OK; 994 return OK;
1002 } 995 }
1003 996
997 int HttpNetworkTransaction::DoRestartTunnelAuth() {
998 next_state_ = STATE_RESTART_TUNNEL_AUTH_COMPLETE;
999 HttpProxyClientSocket* http_proxy_socket =
1000 static_cast<HttpProxyClientSocket*>(connection_->socket());
1001 return http_proxy_socket->RestartWithAuth(&io_callback_);
1002 }
1003
1004 int HttpNetworkTransaction::DoRestartTunnelAuthComplete(int result) {
1005 if (result == ERR_PROXY_AUTH_REQUESTED)
1006 return HandleTunnelAuthFailure(result);
1007
1008 if (result == OK) {
1009 // Now that we've got the HttpProxyClientSocket connected. We have
1010 // to release it as an idle socket into the pool and start the connection
1011 // process from the beginning. Trying to pass it in with the
1012 // SSLSocketParams might cause a deadlock since params are dispatched
1013 // interchangeably. This request won't necessarily get this http proxy
1014 // socket, but there will be forward progress.
1015 connection_->Reset();
1016 establishing_tunnel_ = false;
1017 next_state_ = STATE_INIT_CONNECTION;
1018 return OK;
1019 }
1020
1021 return ReconsiderProxyAfterError(result);
1022 }
1023
1004 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { 1024 int HttpNetworkTransaction::DoGenerateProxyAuthToken() {
1005 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; 1025 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
1006 if (!ShouldApplyProxyAuth()) 1026 if (!ShouldApplyProxyAuth())
1007 return OK; 1027 return OK;
1008 return auth_controllers_[HttpAuth::AUTH_PROXY]->MaybeGenerateAuthToken( 1028 HttpAuth::Target target = HttpAuth::AUTH_PROXY;
1009 request_, &io_callback_, net_log_); 1029 if (!auth_controllers_[target].get())
1030 auth_controllers_[target] = new HttpAuthController(target, AuthURL(target),
1031 session_);
1032 return auth_controllers_[target]->MaybeGenerateAuthToken(request_,
1033 &io_callback_,
1034 net_log_);
1010 } 1035 }
1011 1036
1012 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) { 1037 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) {
1013 DCHECK_NE(ERR_IO_PENDING, rv); 1038 DCHECK_NE(ERR_IO_PENDING, rv);
1014 if (rv == OK) 1039 if (rv == OK)
1015 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN; 1040 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN;
1016 return rv; 1041 return rv;
1017 } 1042 }
1018 1043
1019 int HttpNetworkTransaction::DoGenerateServerAuthToken() { 1044 int HttpNetworkTransaction::DoGenerateServerAuthToken() {
1020 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE; 1045 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE;
1046 HttpAuth::Target target = HttpAuth::AUTH_SERVER;
1047 if (!auth_controllers_[target].get())
1048 auth_controllers_[target] = new HttpAuthController(target, AuthURL(target),
1049 session_);
1021 if (!ShouldApplyServerAuth()) 1050 if (!ShouldApplyServerAuth())
1022 return OK; 1051 return OK;
1023 return auth_controllers_[HttpAuth::AUTH_SERVER]->MaybeGenerateAuthToken( 1052 return auth_controllers_[target]->MaybeGenerateAuthToken(request_,
1024 request_, &io_callback_, net_log_); 1053 &io_callback_,
1054 net_log_);
1025 } 1055 }
1026 1056
1027 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) { 1057 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) {
1028 DCHECK_NE(ERR_IO_PENDING, rv); 1058 DCHECK_NE(ERR_IO_PENDING, rv);
1029 if (rv == OK) 1059 if (rv == OK)
1030 next_state_ = STATE_SEND_REQUEST; 1060 next_state_ = STATE_SEND_REQUEST;
1031 return rv; 1061 return rv;
1032 } 1062 }
1033 1063
1034 int HttpNetworkTransaction::DoSendRequest() { 1064 int HttpNetworkTransaction::DoSendRequest() {
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
1537 base::TimeDelta::FromMilliseconds(1), 1567 base::TimeDelta::FromMilliseconds(1),
1538 base::TimeDelta::FromMinutes(10), 100); 1568 base::TimeDelta::FromMinutes(10), 100);
1539 if (!reused_socket_) { 1569 if (!reused_socket_) {
1540 UMA_HISTOGRAM_CLIPPED_TIMES( 1570 UMA_HISTOGRAM_CLIPPED_TIMES(
1541 "Net.Transaction_Latency_Total_New_Connection_Under_10", 1571 "Net.Transaction_Latency_Total_New_Connection_Under_10",
1542 total_duration, base::TimeDelta::FromMilliseconds(1), 1572 total_duration, base::TimeDelta::FromMilliseconds(1),
1543 base::TimeDelta::FromMinutes(10), 100); 1573 base::TimeDelta::FromMinutes(10), 100);
1544 } 1574 }
1545 } 1575 }
1546 1576
1577 int HttpNetworkTransaction::HandleTunnelAuthFailure(int error) {
1578 DCHECK(establishing_tunnel_);
1579 DCHECK_EQ(ERR_PROXY_AUTH_REQUESTED, error);
1580 HttpProxyClientSocket* http_proxy_socket =
1581 static_cast<HttpProxyClientSocket*>(connection_->socket());
1582
1583 const HttpResponseInfo* tunnel_auth_response =
1584 http_proxy_socket->GetResponseInfo();
1585 response_.headers = tunnel_auth_response->headers;
1586 response_.auth_challenge = tunnel_auth_response->auth_challenge;
1587 headers_valid_ = true;
1588
1589 auth_controllers_[HttpAuth::AUTH_PROXY] =
1590 http_proxy_socket->auth_controller();
1591 pending_auth_target_ = HttpAuth::AUTH_PROXY;
1592 return OK;
1593 }
1594
1547 int HttpNetworkTransaction::HandleCertificateError(int error) { 1595 int HttpNetworkTransaction::HandleCertificateError(int error) {
1548 DCHECK(using_ssl_); 1596 DCHECK(using_ssl_);
1549 DCHECK(IsCertificateError(error)); 1597 DCHECK(IsCertificateError(error));
1550 1598
1551 SSLClientSocket* ssl_socket = 1599 SSLClientSocket* ssl_socket =
1552 static_cast<SSLClientSocket*>(connection_->socket()); 1600 static_cast<SSLClientSocket*>(connection_->socket());
1553 ssl_socket->GetSSLInfo(&response_.ssl_info); 1601 ssl_socket->GetSSLInfo(&response_.ssl_info);
1554 1602
1555 // Add the bad certificate to the set of allowed certificates in the 1603 // Add the bad certificate to the set of allowed certificates in the
1556 // SSL info object. This data structure will be consulted after calling 1604 // SSL info object. This data structure will be consulted after calling
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
1880 default: 1928 default:
1881 return priority; 1929 return priority;
1882 } 1930 }
1883 } 1931 }
1884 1932
1885 1933
1886 1934
1887 #undef STATE_CASE 1935 #undef STATE_CASE
1888 1936
1889 } // namespace net 1937 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_network_transaction.h ('k') | net/http/http_network_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698