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

Side by Side Diff: net/socket_stream/socket_stream.cc

Issue 10854139: Use HttpAuthController in SocketStream (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Rebased and Skipped added browser test on chromeos Created 8 years, 3 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/socket_stream/socket_stream.h ('k') | net/socket_stream/socket_stream_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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // TODO(ukai): code is similar with http_network_transaction.cc. We should 5 // TODO(ukai): code is similar with http_network_transaction.cc. We should
6 // think about ways to share code, if possible. 6 // think about ways to share code, if possible.
7 7
8 #include "net/socket_stream/socket_stream.h" 8 #include "net/socket_stream/socket_stream.h"
9 9
10 #include <set> 10 #include <set>
11 #include <string> 11 #include <string>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/bind_helpers.h" 15 #include "base/bind_helpers.h"
16 #include "base/compiler_specific.h" 16 #include "base/compiler_specific.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/message_loop.h" 18 #include "base/message_loop.h"
19 #include "base/string_util.h" 19 #include "base/string_util.h"
20 #include "base/stringprintf.h" 20 #include "base/stringprintf.h"
21 #include "base/utf_string_conversions.h" 21 #include "base/utf_string_conversions.h"
22 #include "net/base/auth.h" 22 #include "net/base/auth.h"
23 #include "net/base/host_resolver.h" 23 #include "net/base/host_resolver.h"
24 #include "net/base/io_buffer.h" 24 #include "net/base/io_buffer.h"
25 #include "net/base/net_errors.h" 25 #include "net/base/net_errors.h"
26 #include "net/base/net_util.h" 26 #include "net/base/net_util.h"
27 #include "net/base/ssl_cert_request_info.h" 27 #include "net/base/ssl_cert_request_info.h"
28 #include "net/http/http_auth_handler_factory.h" 28 #include "net/http/http_auth_controller.h"
29 #include "net/http/http_network_session.h" 29 #include "net/http/http_network_session.h"
30 #include "net/http/http_request_headers.h"
30 #include "net/http/http_request_info.h" 31 #include "net/http/http_request_info.h"
31 #include "net/http/http_response_headers.h" 32 #include "net/http/http_response_headers.h"
32 #include "net/http/http_stream_factory.h" 33 #include "net/http/http_stream_factory.h"
33 #include "net/http/http_transaction_factory.h" 34 #include "net/http/http_transaction_factory.h"
34 #include "net/http/http_util.h" 35 #include "net/http/http_util.h"
35 #include "net/socket/client_socket_factory.h" 36 #include "net/socket/client_socket_factory.h"
36 #include "net/socket/socks5_client_socket.h" 37 #include "net/socket/socks5_client_socket.h"
37 #include "net/socket/socks_client_socket.h" 38 #include "net/socket/socks_client_socket.h"
38 #include "net/socket/ssl_client_socket.h" 39 #include "net/socket/ssl_client_socket.h"
39 #include "net/socket/tcp_client_socket.h" 40 #include "net/socket/tcp_client_socket.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 86
86 SocketStream::SocketStream(const GURL& url, Delegate* delegate) 87 SocketStream::SocketStream(const GURL& url, Delegate* delegate)
87 : delegate_(delegate), 88 : delegate_(delegate),
88 url_(url), 89 url_(url),
89 max_pending_send_allowed_(kMaxPendingSendAllowed), 90 max_pending_send_allowed_(kMaxPendingSendAllowed),
90 context_(NULL), 91 context_(NULL),
91 next_state_(STATE_NONE), 92 next_state_(STATE_NONE),
92 host_resolver_(NULL), 93 host_resolver_(NULL),
93 cert_verifier_(NULL), 94 cert_verifier_(NULL),
94 server_bound_cert_service_(NULL), 95 server_bound_cert_service_(NULL),
95 http_auth_handler_factory_(NULL),
96 factory_(ClientSocketFactory::GetDefaultFactory()), 96 factory_(ClientSocketFactory::GetDefaultFactory()),
97 proxy_mode_(kDirectConnection), 97 proxy_mode_(kDirectConnection),
98 proxy_url_(url), 98 proxy_url_(url),
99 pac_request_(NULL), 99 pac_request_(NULL),
100 // Unretained() is required; without it, Bind() creates a circular 100 // Unretained() is required; without it, Bind() creates a circular
101 // dependency and the SocketStream object will not be freed. 101 // dependency and the SocketStream object will not be freed.
102 ALLOW_THIS_IN_INITIALIZER_LIST( 102 ALLOW_THIS_IN_INITIALIZER_LIST(
103 io_callback_(base::Bind(&SocketStream::OnIOCompleted, 103 io_callback_(base::Bind(&SocketStream::OnIOCompleted,
104 base::Unretained(this)))), 104 base::Unretained(this)))),
105 read_buf_(NULL), 105 read_buf_(NULL),
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 NetLog::SOURCE_SOCKET_STREAM); 153 NetLog::SOURCE_SOCKET_STREAM);
154 154
155 net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE); 155 net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE);
156 } 156 }
157 } 157 }
158 158
159 if (context_) { 159 if (context_) {
160 host_resolver_ = context_->host_resolver(); 160 host_resolver_ = context_->host_resolver();
161 cert_verifier_ = context_->cert_verifier(); 161 cert_verifier_ = context_->cert_verifier();
162 server_bound_cert_service_ = context_->server_bound_cert_service(); 162 server_bound_cert_service_ = context_->server_bound_cert_service();
163 http_auth_handler_factory_ = context_->http_auth_handler_factory();
164 } 163 }
165 } 164 }
166 165
167 void SocketStream::Connect() { 166 void SocketStream::Connect() {
168 DCHECK(MessageLoop::current()) << 167 DCHECK(MessageLoop::current()) <<
169 "The current MessageLoop must exist"; 168 "The current MessageLoop must exist";
170 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << 169 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
171 "The current MessageLoop must be TYPE_IO"; 170 "The current MessageLoop must be TYPE_IO";
172 if (context_) { 171 if (context_) {
173 ssl_config_service()->GetSSLConfig(&server_ssl_config_); 172 ssl_config_service()->GetSSLConfig(&server_ssl_config_);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 MessageLoop::current()->PostTask( 236 MessageLoop::current()->PostTask(
238 FROM_HERE, 237 FROM_HERE,
239 base::Bind(&SocketStream::DoClose, this)); 238 base::Bind(&SocketStream::DoClose, this));
240 } 239 }
241 240
242 void SocketStream::RestartWithAuth(const AuthCredentials& credentials) { 241 void SocketStream::RestartWithAuth(const AuthCredentials& credentials) {
243 DCHECK(MessageLoop::current()) << 242 DCHECK(MessageLoop::current()) <<
244 "The current MessageLoop must exist"; 243 "The current MessageLoop must exist";
245 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << 244 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
246 "The current MessageLoop must be TYPE_IO"; 245 "The current MessageLoop must be TYPE_IO";
247 DCHECK(auth_handler_.get()); 246 DCHECK(proxy_auth_controller_.get());
248 if (!socket_.get()) { 247 if (!socket_.get()) {
249 LOG(ERROR) << "Socket is closed before restarting with auth."; 248 LOG(ERROR) << "Socket is closed before restarting with auth.";
250 return; 249 return;
251 } 250 }
252 251
253 if (auth_identity_.invalid) { 252 proxy_auth_controller_->ResetAuth(credentials);
254 // Update the credentials.
255 auth_identity_.source = HttpAuth::IDENT_SRC_EXTERNAL;
256 auth_identity_.invalid = false;
257 auth_identity_.credentials = credentials;
258 }
259 253
260 MessageLoop::current()->PostTask( 254 MessageLoop::current()->PostTask(
261 FROM_HERE, 255 FROM_HERE,
262 base::Bind(&SocketStream::DoRestartWithAuth, this)); 256 base::Bind(&SocketStream::DoRestartWithAuth, this));
263 } 257 }
264 258
265 void SocketStream::DetachDelegate() { 259 void SocketStream::DetachDelegate() {
266 if (!delegate_) 260 if (!delegate_)
267 return; 261 return;
268 delegate_ = NULL; 262 delegate_ = NULL;
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 break; 462 break;
469 case STATE_RESOLVE_PROTOCOL_COMPLETE: 463 case STATE_RESOLVE_PROTOCOL_COMPLETE:
470 result = DoResolveProtocolComplete(result); 464 result = DoResolveProtocolComplete(result);
471 break; 465 break;
472 case STATE_TCP_CONNECT: 466 case STATE_TCP_CONNECT:
473 result = DoTcpConnect(result); 467 result = DoTcpConnect(result);
474 break; 468 break;
475 case STATE_TCP_CONNECT_COMPLETE: 469 case STATE_TCP_CONNECT_COMPLETE:
476 result = DoTcpConnectComplete(result); 470 result = DoTcpConnectComplete(result);
477 break; 471 break;
472 case STATE_GENERATE_PROXY_AUTH_TOKEN:
473 result = DoGenerateProxyAuthToken();
474 break;
475 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE:
476 result = DoGenerateProxyAuthTokenComplete(result);
477 break;
478 case STATE_WRITE_TUNNEL_HEADERS: 478 case STATE_WRITE_TUNNEL_HEADERS:
479 DCHECK_EQ(OK, result); 479 DCHECK_EQ(OK, result);
480 result = DoWriteTunnelHeaders(); 480 result = DoWriteTunnelHeaders();
481 break; 481 break;
482 case STATE_WRITE_TUNNEL_HEADERS_COMPLETE: 482 case STATE_WRITE_TUNNEL_HEADERS_COMPLETE:
483 result = DoWriteTunnelHeadersComplete(result); 483 result = DoWriteTunnelHeadersComplete(result);
484 break; 484 break;
485 case STATE_READ_TUNNEL_HEADERS: 485 case STATE_READ_TUNNEL_HEADERS:
486 DCHECK_EQ(OK, result); 486 DCHECK_EQ(OK, result);
487 result = DoReadTunnelHeaders(); 487 result = DoReadTunnelHeaders();
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 // TODO(ukai): if error occured, reconsider proxy after error. 712 // TODO(ukai): if error occured, reconsider proxy after error.
713 if (result != OK) { 713 if (result != OK) {
714 next_state_ = STATE_CLOSE; 714 next_state_ = STATE_CLOSE;
715 return result; 715 return result;
716 } 716 }
717 717
718 if (proxy_mode_ == kTunnelProxy) { 718 if (proxy_mode_ == kTunnelProxy) {
719 if (proxy_info_.is_https()) 719 if (proxy_info_.is_https())
720 next_state_ = STATE_SECURE_PROXY_CONNECT; 720 next_state_ = STATE_SECURE_PROXY_CONNECT;
721 else 721 else
722 next_state_ = STATE_WRITE_TUNNEL_HEADERS; 722 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
723 } else if (proxy_mode_ == kSOCKSProxy) { 723 } else if (proxy_mode_ == kSOCKSProxy) {
724 next_state_ = STATE_SOCKS_CONNECT; 724 next_state_ = STATE_SOCKS_CONNECT;
725 } else if (is_secure()) { 725 } else if (is_secure()) {
726 next_state_ = STATE_SSL_CONNECT; 726 next_state_ = STATE_SSL_CONNECT;
727 } else { 727 } else {
728 result = DidEstablishConnection(); 728 result = DidEstablishConnection();
729 } 729 }
730 return result; 730 return result;
731 } 731 }
732 732
733 int SocketStream::DoGenerateProxyAuthToken() {
734 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
735 if (!proxy_auth_controller_.get()) {
736 DCHECK(context_);
737 DCHECK(context_->http_transaction_factory());
738 DCHECK(context_->http_transaction_factory()->GetSession());
739 HttpNetworkSession* session =
740 context_->http_transaction_factory()->GetSession();
741 const char* scheme = proxy_info_.is_https() ? "https://" : "http://";
742 GURL auth_url(scheme +
743 proxy_info_.proxy_server().host_port_pair().ToString());
744 proxy_auth_controller_ =
745 new HttpAuthController(HttpAuth::AUTH_PROXY,
746 auth_url,
747 session->http_auth_cache(),
748 session->http_auth_handler_factory());
749 }
750 HttpRequestInfo request_info;
751 request_info.url = url_;
752 request_info.method = "CONNECT";
753 return proxy_auth_controller_->MaybeGenerateAuthToken(
754 &request_info, io_callback_, net_log_);
755 }
756
757 int SocketStream::DoGenerateProxyAuthTokenComplete(int result) {
758 if (result != OK) {
759 next_state_ = STATE_CLOSE;
760 return result;
761 }
762
763 next_state_ = STATE_WRITE_TUNNEL_HEADERS;
764 return result;
765 }
766
733 int SocketStream::DoWriteTunnelHeaders() { 767 int SocketStream::DoWriteTunnelHeaders() {
734 DCHECK_EQ(kTunnelProxy, proxy_mode_); 768 DCHECK_EQ(kTunnelProxy, proxy_mode_);
735 769
736 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE; 770 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE;
737 771
738 if (!tunnel_request_headers_.get()) { 772 if (!tunnel_request_headers_.get()) {
739 metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION); 773 metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION);
740 tunnel_request_headers_ = new RequestHeaders(); 774 tunnel_request_headers_ = new RequestHeaders();
741 tunnel_request_headers_bytes_sent_ = 0; 775 tunnel_request_headers_bytes_sent_ = 0;
742 } 776 }
743 if (tunnel_request_headers_->headers_.empty()) { 777 if (tunnel_request_headers_->headers_.empty()) {
744 std::string authorization_headers; 778 HttpRequestHeaders request_headers;
745 779 request_headers.SetHeader("Host", GetHostAndOptionalPort(url_));
746 if (!auth_handler_.get()) { 780 request_headers.SetHeader("Proxy-Connection", "keep-alive");
747 // Do preemptive authentication. 781 if (proxy_auth_controller_.get() && proxy_auth_controller_->HaveAuth())
748 HttpAuthCache::Entry* entry = auth_cache_.LookupByPath( 782 proxy_auth_controller_->AddAuthorizationHeader(&request_headers);
749 ProxyAuthOrigin(), std::string());
750 if (entry) {
751 scoped_ptr<HttpAuthHandler> handler_preemptive;
752 int rv_create = http_auth_handler_factory_->
753 CreatePreemptiveAuthHandlerFromString(
754 entry->auth_challenge(), HttpAuth::AUTH_PROXY,
755 ProxyAuthOrigin(), entry->IncrementNonceCount(),
756 net_log_, &handler_preemptive);
757 if (rv_create == OK) {
758 auth_identity_.source = HttpAuth::IDENT_SRC_PATH_LOOKUP;
759 auth_identity_.invalid = false;
760 auth_identity_.credentials = AuthCredentials();
761 auth_handler_.swap(handler_preemptive);
762 }
763 }
764 }
765
766 // Support basic authentication scheme only, because we don't have
767 // HttpRequestInfo.
768 // TODO(ukai): Add support other authentication scheme.
769 if (auth_handler_.get() &&
770 auth_handler_->auth_scheme() == HttpAuth::AUTH_SCHEME_BASIC) {
771 HttpRequestInfo request_info;
772 std::string auth_token;
773 int rv = auth_handler_->GenerateAuthToken(
774 &auth_identity_.credentials,
775 &request_info,
776 CompletionCallback(),
777 &auth_token);
778 // TODO(cbentzel): Support async auth handlers.
779 DCHECK_NE(ERR_IO_PENDING, rv);
780 if (rv != OK)
781 return rv;
782 authorization_headers.append(
783 HttpAuth::GetAuthorizationHeaderName(HttpAuth::AUTH_PROXY) +
784 ": " + auth_token + "\r\n");
785 }
786
787 tunnel_request_headers_->headers_ = base::StringPrintf( 783 tunnel_request_headers_->headers_ = base::StringPrintf(
788 "CONNECT %s HTTP/1.1\r\n" 784 "CONNECT %s HTTP/1.1\r\n"
789 "Host: %s\r\n" 785 "%s",
790 "Proxy-Connection: keep-alive\r\n",
791 GetHostAndPort(url_).c_str(), 786 GetHostAndPort(url_).c_str(),
792 GetHostAndOptionalPort(url_).c_str()); 787 request_headers.ToString().c_str());
793 if (!authorization_headers.empty())
794 tunnel_request_headers_->headers_ += authorization_headers;
795 tunnel_request_headers_->headers_ += "\r\n";
796 } 788 }
797 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_); 789 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_);
798 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() - 790 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() -
799 tunnel_request_headers_bytes_sent_); 791 tunnel_request_headers_bytes_sent_);
800 DCHECK_GT(buf_len, 0); 792 DCHECK_GT(buf_len, 0);
801 return socket_->Write(tunnel_request_headers_, buf_len, io_callback_); 793 return socket_->Write(tunnel_request_headers_, buf_len, io_callback_);
802 } 794 }
803 795
804 int SocketStream::DoWriteTunnelHeadersComplete(int result) { 796 int SocketStream::DoWriteTunnelHeadersComplete(int result) {
805 DCHECK_EQ(kTunnelProxy, proxy_mode_); 797 DCHECK_EQ(kTunnelProxy, proxy_mode_);
806 798
807 if (result < 0) { 799 if (result < 0) {
808 next_state_ = STATE_CLOSE; 800 next_state_ = STATE_CLOSE;
809 return result; 801 return result;
810 } 802 }
811 803
812 tunnel_request_headers_bytes_sent_ += result; 804 tunnel_request_headers_bytes_sent_ += result;
813 if (tunnel_request_headers_bytes_sent_ < 805 if (tunnel_request_headers_bytes_sent_ <
814 tunnel_request_headers_->headers_.size()) { 806 tunnel_request_headers_->headers_.size()) {
815 next_state_ = STATE_WRITE_TUNNEL_HEADERS; 807 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
816 } else { 808 } else {
817 // Handling a cert error or a client cert request requires reconnection. 809 // Handling a cert error or a client cert request requires reconnection.
818 // DoWriteTunnelHeaders() will be called again. 810 // DoWriteTunnelHeaders() will be called again.
819 // Thus |tunnel_request_headers_bytes_sent_| should be reset to 0 for 811 // Thus |tunnel_request_headers_bytes_sent_| should be reset to 0 for
820 // sending |tunnel_request_headers_| correctly. 812 // sending |tunnel_request_headers_| correctly.
821 tunnel_request_headers_bytes_sent_ = 0; 813 tunnel_request_headers_bytes_sent_ = 0;
822 next_state_ = STATE_READ_TUNNEL_HEADERS; 814 next_state_ = STATE_READ_TUNNEL_HEADERS;
823 } 815 }
824 return OK; 816 return OK;
825 } 817 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 next_state_ = STATE_CLOSE; 884 next_state_ = STATE_CLOSE;
893 return result; 885 return result;
894 } 886 }
895 if ((eoh < tunnel_response_headers_len_) && delegate_) 887 if ((eoh < tunnel_response_headers_len_) && delegate_)
896 delegate_->OnReceivedData( 888 delegate_->OnReceivedData(
897 this, tunnel_response_headers_->headers() + eoh, 889 this, tunnel_response_headers_->headers() + eoh,
898 tunnel_response_headers_len_ - eoh); 890 tunnel_response_headers_len_ - eoh);
899 } 891 }
900 return OK; 892 return OK;
901 case 407: // Proxy Authentication Required. 893 case 407: // Proxy Authentication Required.
902 result = HandleAuthChallenge(headers.get()); 894 if (proxy_mode_ != kTunnelProxy)
903 if (result == ERR_PROXY_AUTH_UNSUPPORTED && 895 return ERR_UNEXPECTED_PROXY_AUTH;
904 auth_handler_.get() && delegate_) { 896
905 DCHECK(!proxy_info_.is_empty()); 897 result = proxy_auth_controller_->HandleAuthChallenge(
906 auth_info_ = new AuthChallengeInfo; 898 headers, false, true, net_log_);
907 auth_info_->is_proxy = true; 899 if (result != OK)
908 auth_info_->challenger = proxy_info_.proxy_server().host_port_pair(); 900 return result;
909 auth_info_->scheme = HttpAuth::SchemeToString( 901 DCHECK(!proxy_info_.is_empty());
910 auth_handler_->auth_scheme()); 902 next_state_ = STATE_AUTH_REQUIRED;
911 auth_info_->realm = auth_handler_->realm(); 903 if (proxy_auth_controller_->HaveAuth()) {
904 MessageLoop::current()->PostTask(
905 FROM_HERE,
906 base::Bind(&SocketStream::DoRestartWithAuth, this));
907 return ERR_IO_PENDING;
908 }
909 if (delegate_) {
912 // Wait until RestartWithAuth or Close is called. 910 // Wait until RestartWithAuth or Close is called.
913 MessageLoop::current()->PostTask( 911 MessageLoop::current()->PostTask(
914 FROM_HERE, 912 FROM_HERE,
915 base::Bind(&SocketStream::DoAuthRequired, this)); 913 base::Bind(&SocketStream::DoAuthRequired, this));
916 next_state_ = STATE_AUTH_REQUIRED;
917 return ERR_IO_PENDING; 914 return ERR_IO_PENDING;
918 } 915 }
916 break;
919 default: 917 default:
920 break; 918 break;
921 } 919 }
922 next_state_ = STATE_CLOSE; 920 next_state_ = STATE_CLOSE;
923 return ERR_TUNNEL_CONNECTION_FAILED; 921 return ERR_TUNNEL_CONNECTION_FAILED;
924 } 922 }
925 923
926 int SocketStream::DoSOCKSConnect() { 924 int SocketStream::DoSOCKSConnect() {
927 DCHECK_EQ(kSOCKSProxy, proxy_mode_); 925 DCHECK_EQ(kSOCKSProxy, proxy_mode_);
928 926
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 970
973 int SocketStream::DoSecureProxyConnectComplete(int result) { 971 int SocketStream::DoSecureProxyConnectComplete(int result) {
974 DCHECK_EQ(STATE_NONE, next_state_); 972 DCHECK_EQ(STATE_NONE, next_state_);
975 // Reconnect with client authentication. 973 // Reconnect with client authentication.
976 if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) 974 if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED)
977 return HandleCertificateRequest(result, &proxy_ssl_config_); 975 return HandleCertificateRequest(result, &proxy_ssl_config_);
978 976
979 if (IsCertificateError(result)) 977 if (IsCertificateError(result))
980 next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR; 978 next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR;
981 else if (result == OK) 979 else if (result == OK)
982 next_state_ = STATE_WRITE_TUNNEL_HEADERS; 980 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
983 else 981 else
984 next_state_ = STATE_CLOSE; 982 next_state_ = STATE_CLOSE;
985 return result; 983 return result;
986 } 984 }
987 985
988 int SocketStream::DoSecureProxyHandleCertError(int result) { 986 int SocketStream::DoSecureProxyHandleCertError(int result) {
989 DCHECK_EQ(STATE_NONE, next_state_); 987 DCHECK_EQ(STATE_NONE, next_state_);
990 DCHECK(IsCertificateError(result)); 988 DCHECK(IsCertificateError(result));
991 result = HandleCertificateError(result); 989 result = HandleCertificateError(result);
992 if (result == ERR_IO_PENDING) 990 if (result == ERR_IO_PENDING)
993 next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE; 991 next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE;
994 else 992 else
995 next_state_ = STATE_CLOSE; 993 next_state_ = STATE_CLOSE;
996 return result; 994 return result;
997 } 995 }
998 996
999 int SocketStream::DoSecureProxyHandleCertErrorComplete(int result) { 997 int SocketStream::DoSecureProxyHandleCertErrorComplete(int result) {
1000 DCHECK_EQ(STATE_NONE, next_state_); 998 DCHECK_EQ(STATE_NONE, next_state_);
1001 if (result == OK) { 999 if (result == OK) {
1002 if (!socket_->IsConnectedAndIdle()) 1000 if (!socket_->IsConnectedAndIdle())
1003 return AllowCertErrorForReconnection(&proxy_ssl_config_); 1001 return AllowCertErrorForReconnection(&proxy_ssl_config_);
1004 next_state_ = STATE_WRITE_TUNNEL_HEADERS; 1002 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
1005 } else { 1003 } else {
1006 next_state_ = STATE_CLOSE; 1004 next_state_ = STATE_CLOSE;
1007 } 1005 }
1008 return result; 1006 return result;
1009 } 1007 }
1010 1008
1011 int SocketStream::DoSSLConnect() { 1009 int SocketStream::DoSSLConnect() {
1012 DCHECK(factory_); 1010 DCHECK(factory_);
1013 SSLClientSocketContext ssl_context; 1011 SSLClientSocketContext ssl_context;
1014 ssl_context.cert_verifier = cert_verifier_; 1012 ssl_context.cert_verifier = cert_verifier_;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 // We arrived here when both operation is pending. 1135 // We arrived here when both operation is pending.
1138 return ERR_IO_PENDING; 1136 return ERR_IO_PENDING;
1139 } 1137 }
1140 1138
1141 GURL SocketStream::ProxyAuthOrigin() const { 1139 GURL SocketStream::ProxyAuthOrigin() const {
1142 DCHECK(!proxy_info_.is_empty()); 1140 DCHECK(!proxy_info_.is_empty());
1143 return GURL("http://" + 1141 return GURL("http://" +
1144 proxy_info_.proxy_server().host_port_pair().ToString()); 1142 proxy_info_.proxy_server().host_port_pair().ToString());
1145 } 1143 }
1146 1144
1147 int SocketStream::HandleAuthChallenge(const HttpResponseHeaders* headers) {
1148 GURL auth_origin(ProxyAuthOrigin());
1149
1150 VLOG(1) << "The proxy " << auth_origin << " requested auth";
1151
1152 // TODO(cbentzel): Since SocketStream only suppports basic authentication
1153 // right now, another challenge is always treated as a rejection.
1154 // Ultimately this should be converted to use HttpAuthController like the
1155 // HttpNetworkTransaction has.
1156 if (auth_handler_.get() && !auth_identity_.invalid) {
1157 if (auth_identity_.source != HttpAuth::IDENT_SRC_PATH_LOOKUP)
1158 auth_cache_.Remove(auth_origin,
1159 auth_handler_->realm(),
1160 auth_handler_->auth_scheme(),
1161 auth_identity_.credentials);
1162 auth_handler_.reset();
1163 auth_identity_ = HttpAuth::Identity();
1164 }
1165
1166 auth_identity_.invalid = true;
1167 std::set<HttpAuth::Scheme> disabled_schemes;
1168 HttpAuth::ChooseBestChallenge(http_auth_handler_factory_, headers,
1169 HttpAuth::AUTH_PROXY,
1170 auth_origin, disabled_schemes,
1171 net_log_, &auth_handler_);
1172 if (!auth_handler_.get()) {
1173 LOG(ERROR) << "Can't perform auth to the proxy " << auth_origin;
1174 return ERR_TUNNEL_CONNECTION_FAILED;
1175 }
1176 if (auth_handler_->NeedsIdentity()) {
1177 // We only support basic authentication scheme now.
1178 // TODO(ukai): Support other authentication scheme.
1179 HttpAuthCache::Entry* entry = auth_cache_.Lookup(
1180 auth_origin, auth_handler_->realm(), HttpAuth::AUTH_SCHEME_BASIC);
1181 if (entry) {
1182 auth_identity_.source = HttpAuth::IDENT_SRC_REALM_LOOKUP;
1183 auth_identity_.invalid = false;
1184 auth_identity_.credentials = AuthCredentials();
1185 // Restart with auth info.
1186 }
1187 return ERR_PROXY_AUTH_UNSUPPORTED;
1188 } else {
1189 auth_identity_.invalid = false;
1190 }
1191 return ERR_TUNNEL_CONNECTION_FAILED;
1192 }
1193
1194 int SocketStream::HandleCertificateRequest(int result, SSLConfig* ssl_config) { 1145 int SocketStream::HandleCertificateRequest(int result, SSLConfig* ssl_config) {
1195 if (ssl_config->send_client_cert) 1146 if (ssl_config->send_client_cert)
1196 // We already have performed SSL client authentication once and failed. 1147 // We already have performed SSL client authentication once and failed.
1197 return result; 1148 return result;
1198 1149
1199 DCHECK(socket_.get()); 1150 DCHECK(socket_.get());
1200 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo; 1151 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo;
1201 SSLClientSocket* ssl_socket = 1152 SSLClientSocket* ssl_socket =
1202 static_cast<SSLClientSocket*>(socket_.get()); 1153 static_cast<SSLClientSocket*>(socket_.get());
1203 ssl_socket->GetSSLCertRequestInfo(cert_request_info); 1154 ssl_socket->GetSSLCertRequestInfo(cert_request_info);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 bad_cert.cert_status = ssl_info.cert_status; 1215 bad_cert.cert_status = ssl_info.cert_status;
1265 ssl_config->allowed_bad_certs.push_back(bad_cert); 1216 ssl_config->allowed_bad_certs.push_back(bad_cert);
1266 // Restart connection ignoring the bad certificate. 1217 // Restart connection ignoring the bad certificate.
1267 socket_->Disconnect(); 1218 socket_->Disconnect();
1268 socket_.reset(); 1219 socket_.reset();
1269 next_state_ = STATE_TCP_CONNECT; 1220 next_state_ = STATE_TCP_CONNECT;
1270 return OK; 1221 return OK;
1271 } 1222 }
1272 1223
1273 void SocketStream::DoAuthRequired() { 1224 void SocketStream::DoAuthRequired() {
1274 if (delegate_ && auth_info_.get()) 1225 if (delegate_ && proxy_auth_controller_.get())
1275 delegate_->OnAuthRequired(this, auth_info_.get()); 1226 delegate_->OnAuthRequired(this, proxy_auth_controller_->auth_info().get());
1276 else 1227 else
1277 DoLoop(ERR_UNEXPECTED); 1228 DoLoop(ERR_UNEXPECTED);
1278 } 1229 }
1279 1230
1280 void SocketStream::DoRestartWithAuth() { 1231 void SocketStream::DoRestartWithAuth() {
1281 DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED); 1232 DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED);
1282 auth_cache_.Add(ProxyAuthOrigin(),
1283 auth_handler_->realm(),
1284 auth_handler_->auth_scheme(),
1285 auth_handler_->challenge(),
1286 auth_identity_.credentials,
1287 std::string());
1288
1289 tunnel_request_headers_ = NULL; 1233 tunnel_request_headers_ = NULL;
1290 tunnel_request_headers_bytes_sent_ = 0; 1234 tunnel_request_headers_bytes_sent_ = 0;
1291 tunnel_response_headers_ = NULL; 1235 tunnel_response_headers_ = NULL;
1292 tunnel_response_headers_capacity_ = 0; 1236 tunnel_response_headers_capacity_ = 0;
1293 tunnel_response_headers_len_ = 0; 1237 tunnel_response_headers_len_ = 0;
1294 1238
1295 next_state_ = STATE_TCP_CONNECT; 1239 next_state_ = STATE_TCP_CONNECT;
1296 DoLoop(OK); 1240 DoLoop(OK);
1297 } 1241 }
1298 1242
(...skipping 27 matching lines...) Expand all
1326 1270
1327 SSLConfigService* SocketStream::ssl_config_service() const { 1271 SSLConfigService* SocketStream::ssl_config_service() const {
1328 return context_->ssl_config_service(); 1272 return context_->ssl_config_service();
1329 } 1273 }
1330 1274
1331 ProxyService* SocketStream::proxy_service() const { 1275 ProxyService* SocketStream::proxy_service() const {
1332 return context_->proxy_service(); 1276 return context_->proxy_service();
1333 } 1277 }
1334 1278
1335 } // namespace net 1279 } // namespace net
OLDNEW
« no previous file with comments | « net/socket_stream/socket_stream.h ('k') | net/socket_stream/socket_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698