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

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

Issue 3066031: Merge 54714 - Recommit 54405 - Fix late binding induced mismatch of Socket an... (Closed) Base URL: svn://svn.chromium.org/chrome/branches/472/src/
Patch Set: Fix merge problems 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 | Annotate | Revision Log
« 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 "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/field_trial.h" 8 #include "base/field_trial.h"
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/histogram.h" 10 #include "base/histogram.h"
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 if (target == HttpAuth::AUTH_NONE) { 324 if (target == HttpAuth::AUTH_NONE) {
325 NOTREACHED(); 325 NOTREACHED();
326 return ERR_UNEXPECTED; 326 return ERR_UNEXPECTED;
327 } 327 }
328 pending_auth_target_ = HttpAuth::AUTH_NONE; 328 pending_auth_target_ = HttpAuth::AUTH_NONE;
329 329
330 auth_controllers_[target]->ResetAuth(username, password); 330 auth_controllers_[target]->ResetAuth(username, password);
331 331
332 if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) { 332 if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) {
333 DCHECK(establishing_tunnel_); 333 DCHECK(establishing_tunnel_);
334 next_state_ = STATE_INIT_CONNECTION; 334 next_state_ = STATE_RESTART_TUNNEL_AUTH;
335 auth_controllers_[target] = NULL;
335 ResetStateForRestart(); 336 ResetStateForRestart();
336 } else { 337 } else {
337 PrepareForAuthRestart(target); 338 PrepareForAuthRestart(target);
338 } 339 }
339 340
340 DCHECK(user_callback_ == NULL); 341 DCHECK(user_callback_ == NULL);
341 int rv = DoLoop(OK); 342 int rv = DoLoop(OK);
342 if (rv == ERR_IO_PENDING) 343 if (rv == ERR_IO_PENDING)
343 user_callback_ = callback; 344 user_callback_ = callback;
344 345
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 case STATE_RESOLVE_PROXY_COMPLETE: 526 case STATE_RESOLVE_PROXY_COMPLETE:
526 rv = DoResolveProxyComplete(rv); 527 rv = DoResolveProxyComplete(rv);
527 break; 528 break;
528 case STATE_INIT_CONNECTION: 529 case STATE_INIT_CONNECTION:
529 DCHECK_EQ(OK, rv); 530 DCHECK_EQ(OK, rv);
530 rv = DoInitConnection(); 531 rv = DoInitConnection();
531 break; 532 break;
532 case STATE_INIT_CONNECTION_COMPLETE: 533 case STATE_INIT_CONNECTION_COMPLETE:
533 rv = DoInitConnectionComplete(rv); 534 rv = DoInitConnectionComplete(rv);
534 break; 535 break;
536 case STATE_RESTART_TUNNEL_AUTH:
537 DCHECK_EQ(OK, rv);
538 rv = DoRestartTunnelAuth();
539 break;
540 case STATE_RESTART_TUNNEL_AUTH_COMPLETE:
541 rv = DoRestartTunnelAuthComplete(rv);
542 break;
535 case STATE_GENERATE_PROXY_AUTH_TOKEN: 543 case STATE_GENERATE_PROXY_AUTH_TOKEN:
536 DCHECK_EQ(OK, rv); 544 DCHECK_EQ(OK, rv);
537 rv = DoGenerateProxyAuthToken(); 545 rv = DoGenerateProxyAuthToken();
538 break; 546 break;
539 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: 547 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE:
540 rv = DoGenerateProxyAuthTokenComplete(rv); 548 rv = DoGenerateProxyAuthTokenComplete(rv);
541 break; 549 break;
542 case STATE_GENERATE_SERVER_AUTH_TOKEN: 550 case STATE_GENERATE_SERVER_AUTH_TOKEN:
543 DCHECK_EQ(OK, rv); 551 DCHECK_EQ(OK, rv);
544 rv = DoGenerateServerAuthToken(); 552 rv = DoGenerateServerAuthToken();
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 710
703 next_state_ = STATE_INIT_CONNECTION; 711 next_state_ = STATE_INIT_CONNECTION;
704 return OK; 712 return OK;
705 } 713 }
706 714
707 int HttpNetworkTransaction::DoInitConnection() { 715 int HttpNetworkTransaction::DoInitConnection() {
708 DCHECK(!connection_->is_initialized()); 716 DCHECK(!connection_->is_initialized());
709 DCHECK(proxy_info_.proxy_server().is_valid()); 717 DCHECK(proxy_info_.proxy_server().is_valid());
710 next_state_ = STATE_INIT_CONNECTION_COMPLETE; 718 next_state_ = STATE_INIT_CONNECTION_COMPLETE;
711 719
712 // Now that the proxy server has been resolved, create the auth_controllers_.
713 for (int i = 0; i < HttpAuth::AUTH_NUM_TARGETS; i++) {
714 HttpAuth::Target target = static_cast<HttpAuth::Target>(i);
715 if (!auth_controllers_[target].get())
716 auth_controllers_[target] = new HttpAuthController(target,
717 AuthURL(target),
718 session_);
719 }
720
721 bool want_spdy = alternate_protocol_mode_ == kUsingAlternateProtocol 720 bool want_spdy = alternate_protocol_mode_ == kUsingAlternateProtocol
722 && alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_2; 721 && alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_2;
723 using_ssl_ = request_->url.SchemeIs("https") || want_spdy; 722 using_ssl_ = request_->url.SchemeIs("https") || want_spdy;
724 using_spdy_ = false; 723 using_spdy_ = false;
725 response_.was_fetched_via_proxy = !proxy_info_.is_direct(); 724 response_.was_fetched_via_proxy = !proxy_info_.is_direct();
726 725
727 // Use the fixed testing ports if they've been provided. 726 // Use the fixed testing ports if they've been provided.
728 if (using_ssl_) { 727 if (using_ssl_) {
729 if (session_->fixed_https_port() != 0) 728 if (session_->fixed_https_port() != 0)
730 endpoint_.port = session_->fixed_https_port(); 729 endpoint_.port = session_->fixed_https_port();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 disable_resolver_cache); 765 disable_resolver_cache);
767 } else { 766 } else {
768 ProxyServer proxy_server = proxy_info_.proxy_server(); 767 ProxyServer proxy_server = proxy_info_.proxy_server();
769 proxy_host_port.reset(new HostPortPair(proxy_server.HostNoBrackets(), 768 proxy_host_port.reset(new HostPortPair(proxy_server.HostNoBrackets(),
770 proxy_server.port())); 769 proxy_server.port()));
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;
777 GURL authentication_url = request_->url; 775 GURL authentication_url = request_->url;
778 if (using_ssl_) { 776 if (using_ssl_ && !authentication_url.SchemeIs("https")) {
779 if (!authentication_url.SchemeIs("https")) { 777 // If a proxy tunnel connection needs to be established due to
780 // If a proxy tunnel connection needs to be established due to 778 // an Alternate-Protocol, the URL needs to be changed to indicate
781 // an Alternate-Protocol, the URL needs to be changed to indicate 779 // https or digest authentication attempts will fail.
782 // https or digest authentication attempts will fail. 780 // For example, suppose the initial request was for
783 // For example, suppose the initial request was for 781 // "http://www.example.com/index.html". If this is an SSL
784 // "http://www.example.com/index.html". If this is an SSL 782 // upgrade due to alternate protocol, the digest authorization
785 // upgrade due to alternate protocol, the digest authorization 783 // should have a uri="www.example.com:443" field rather than a
786 // should have a uri="www.example.com:443" field rather than a 784 // "/index.html" entry, even though the original request URL has not
787 // "/index.html" entry, even though the original request URL has not 785 // changed.
788 // changed. 786 authentication_url = UpgradeUrlToHttps(authentication_url);
789 authentication_url = UpgradeUrlToHttps(authentication_url);
790 }
791 http_proxy_auth = auth_controllers_[HttpAuth::AUTH_PROXY];
792 establishing_tunnel_ = true;
793 } 787 }
788 establishing_tunnel_ = using_ssl_;
794 http_proxy_params = new HttpProxySocketParams(proxy_tcp_params, 789 http_proxy_params = new HttpProxySocketParams(proxy_tcp_params,
795 authentication_url, 790 authentication_url,
796 endpoint_, 791 endpoint_,
797 http_proxy_auth, 792 session_, using_ssl_);
798 using_ssl_);
799 } else { 793 } else {
800 DCHECK(proxy_info_.is_socks()); 794 DCHECK(proxy_info_.is_socks());
801 char socks_version; 795 char socks_version;
802 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5) 796 if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5)
803 socks_version = '5'; 797 socks_version = '5';
804 else 798 else
805 socks_version = '4'; 799 socks_version = '4';
806 connection_group = 800 connection_group =
807 StringPrintf("socks%c/%s", socks_version, connection_group.c_str()); 801 StringPrintf("socks%c/%s", socks_version, connection_group.c_str());
808 802
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 std::string proto; 881 std::string proto;
888 ssl_socket->GetNextProto(&proto); 882 ssl_socket->GetNextProto(&proto);
889 if (SSLClientSocket::NextProtoFromString(proto) == 883 if (SSLClientSocket::NextProtoFromString(proto) ==
890 SSLClientSocket::kProtoSPDY2) 884 SSLClientSocket::kProtoSPDY2)
891 using_spdy_ = true; 885 using_spdy_ = true;
892 } 886 }
893 } 887 }
894 888
895 if (result == ERR_PROXY_AUTH_REQUESTED) { 889 if (result == ERR_PROXY_AUTH_REQUESTED) {
896 DCHECK(!ssl_started); 890 DCHECK(!ssl_started);
897 const HttpResponseInfo& tunnel_auth_response = 891 // Other state (i.e. |using_ssl_|) suggests that |connection_| will have an
898 connection_->ssl_error_response_info(); 892 // SSL socket, but there was an error before that could happened. This
899 893 // puts the in progress HttpProxy socket into |connection_| in order to
900 response_.headers = tunnel_auth_response.headers; 894 // complete the auth. The tunnel restart code is carefully to remove it
901 response_.auth_challenge = tunnel_auth_response.auth_challenge; 895 // before returning control to the rest of this class.
902 headers_valid_ = true; 896 connection_.reset(connection_->release_pending_http_proxy_connection());
903 pending_auth_target_ = HttpAuth::AUTH_PROXY; 897 return HandleTunnelAuthFailure(result);
904 return OK;
905 } 898 }
906 899
907 if ((!ssl_started && result < 0 && 900 if ((!ssl_started && result < 0 &&
908 alternate_protocol_mode_ == kUsingAlternateProtocol) || 901 alternate_protocol_mode_ == kUsingAlternateProtocol) ||
909 result == ERR_NPN_NEGOTIATION_FAILED) { 902 result == ERR_NPN_NEGOTIATION_FAILED) {
910 // Mark the alternate protocol as broken and fallback. 903 // Mark the alternate protocol as broken and fallback.
911 MarkBrokenAlternateProtocolAndFallback(); 904 MarkBrokenAlternateProtocolAndFallback();
912 return OK; 905 return OK;
913 } 906 }
914 907
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 if (using_spdy_) { 957 if (using_spdy_) {
965 UpdateConnectionTypeHistograms(CONNECTION_SPDY); 958 UpdateConnectionTypeHistograms(CONNECTION_SPDY);
966 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 959 // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620
967 next_state_ = STATE_SPDY_GET_STREAM; 960 next_state_ = STATE_SPDY_GET_STREAM;
968 } else { 961 } else {
969 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; 962 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
970 } 963 }
971 return OK; 964 return OK;
972 } 965 }
973 966
967 int HttpNetworkTransaction::DoRestartTunnelAuth() {
968 next_state_ = STATE_RESTART_TUNNEL_AUTH_COMPLETE;
969 HttpProxyClientSocket* http_proxy_socket =
970 static_cast<HttpProxyClientSocket*>(connection_->socket());
971 return http_proxy_socket->RestartWithAuth(&io_callback_);
972 }
973
974 int HttpNetworkTransaction::DoRestartTunnelAuthComplete(int result) {
975 if (result == ERR_PROXY_AUTH_REQUESTED)
976 return HandleTunnelAuthFailure(result);
977
978 if (result == OK) {
979 // Now that we've got the HttpProxyClientSocket connected. We have
980 // to release it as an idle socket into the pool and start the connection
981 // process from the beginning. Trying to pass it in with the
982 // SSLSocketParams might cause a deadlock since params are dispatched
983 // interchangeably. This request won't necessarily get this http proxy
984 // socket, but there will be forward progress.
985 connection_->Reset();
986 establishing_tunnel_ = false;
987 next_state_ = STATE_INIT_CONNECTION;
988 return OK;
989 }
990
991 return ReconsiderProxyAfterError(result);
992 }
993
974 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { 994 int HttpNetworkTransaction::DoGenerateProxyAuthToken() {
975 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; 995 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
976 if (!ShouldApplyProxyAuth()) 996 if (!ShouldApplyProxyAuth())
977 return OK; 997 return OK;
978 return auth_controllers_[HttpAuth::AUTH_PROXY]->MaybeGenerateAuthToken( 998 HttpAuth::Target target = HttpAuth::AUTH_PROXY;
979 request_, &io_callback_, net_log_); 999 if (!auth_controllers_[target].get())
1000 auth_controllers_[target] = new HttpAuthController(target, AuthURL(target),
1001 session_);
1002 return auth_controllers_[target]->MaybeGenerateAuthToken(request_,
1003 &io_callback_,
1004 net_log_);
980 } 1005 }
981 1006
982 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) { 1007 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) {
983 DCHECK_NE(ERR_IO_PENDING, rv); 1008 DCHECK_NE(ERR_IO_PENDING, rv);
984 if (rv == OK) 1009 if (rv == OK)
985 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN; 1010 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN;
986 return rv; 1011 return rv;
987 } 1012 }
988 1013
989 int HttpNetworkTransaction::DoGenerateServerAuthToken() { 1014 int HttpNetworkTransaction::DoGenerateServerAuthToken() {
990 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE; 1015 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE;
1016 HttpAuth::Target target = HttpAuth::AUTH_SERVER;
1017 if (!auth_controllers_[target].get())
1018 auth_controllers_[target] = new HttpAuthController(target, AuthURL(target),
1019 session_);
991 if (!ShouldApplyServerAuth()) 1020 if (!ShouldApplyServerAuth())
992 return OK; 1021 return OK;
993 return auth_controllers_[HttpAuth::AUTH_SERVER]->MaybeGenerateAuthToken( 1022 return auth_controllers_[target]->MaybeGenerateAuthToken(request_,
994 request_, &io_callback_, net_log_); 1023 &io_callback_,
1024 net_log_);
995 } 1025 }
996 1026
997 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) { 1027 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) {
998 DCHECK_NE(ERR_IO_PENDING, rv); 1028 DCHECK_NE(ERR_IO_PENDING, rv);
999 if (rv == OK) 1029 if (rv == OK)
1000 next_state_ = STATE_SEND_REQUEST; 1030 next_state_ = STATE_SEND_REQUEST;
1001 return rv; 1031 return rv;
1002 } 1032 }
1003 1033
1004 int HttpNetworkTransaction::DoSendRequest() { 1034 int HttpNetworkTransaction::DoSendRequest() {
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
1498 base::TimeDelta::FromMilliseconds(1), 1528 base::TimeDelta::FromMilliseconds(1),
1499 base::TimeDelta::FromMinutes(10), 100); 1529 base::TimeDelta::FromMinutes(10), 100);
1500 if (!reused_socket_) { 1530 if (!reused_socket_) {
1501 UMA_HISTOGRAM_CLIPPED_TIMES( 1531 UMA_HISTOGRAM_CLIPPED_TIMES(
1502 "Net.Transaction_Latency_Total_New_Connection_Under_10", 1532 "Net.Transaction_Latency_Total_New_Connection_Under_10",
1503 total_duration, base::TimeDelta::FromMilliseconds(1), 1533 total_duration, base::TimeDelta::FromMilliseconds(1),
1504 base::TimeDelta::FromMinutes(10), 100); 1534 base::TimeDelta::FromMinutes(10), 100);
1505 } 1535 }
1506 } 1536 }
1507 1537
1538 int HttpNetworkTransaction::HandleTunnelAuthFailure(int error) {
1539 DCHECK(establishing_tunnel_);
1540 DCHECK_EQ(ERR_PROXY_AUTH_REQUESTED, error);
1541 HttpProxyClientSocket* http_proxy_socket =
1542 static_cast<HttpProxyClientSocket*>(connection_->socket());
1543
1544 const HttpResponseInfo* tunnel_auth_response =
1545 http_proxy_socket->GetResponseInfo();
1546 response_.headers = tunnel_auth_response->headers;
1547 response_.auth_challenge = tunnel_auth_response->auth_challenge;
1548 headers_valid_ = true;
1549
1550 auth_controllers_[HttpAuth::AUTH_PROXY] =
1551 http_proxy_socket->auth_controller();
1552 pending_auth_target_ = HttpAuth::AUTH_PROXY;
1553 return OK;
1554 }
1555
1508 int HttpNetworkTransaction::HandleCertificateError(int error) { 1556 int HttpNetworkTransaction::HandleCertificateError(int error) {
1509 DCHECK(using_ssl_); 1557 DCHECK(using_ssl_);
1510 DCHECK(IsCertificateError(error)); 1558 DCHECK(IsCertificateError(error));
1511 1559
1512 SSLClientSocket* ssl_socket = 1560 SSLClientSocket* ssl_socket =
1513 static_cast<SSLClientSocket*>(connection_->socket()); 1561 static_cast<SSLClientSocket*>(connection_->socket());
1514 ssl_socket->GetSSLInfo(&response_.ssl_info); 1562 ssl_socket->GetSSLInfo(&response_.ssl_info);
1515 1563
1516 // Add the bad certificate to the set of allowed certificates in the 1564 // Add the bad certificate to the set of allowed certificates in the
1517 // SSL info object. This data structure will be consulted after calling 1565 // SSL info object. This data structure will be consulted after calling
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
1824 default: 1872 default:
1825 description = StringPrintf("Unknown state 0x%08X (%u)", state, state); 1873 description = StringPrintf("Unknown state 0x%08X (%u)", state, state);
1826 break; 1874 break;
1827 } 1875 }
1828 return description; 1876 return description;
1829 } 1877 }
1830 1878
1831 #undef STATE_CASE 1879 #undef STATE_CASE
1832 1880
1833 } // namespace net 1881 } // 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