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

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: Add browser test. Created 8 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) 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 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 return socket_->Connect(io_callback_); 708 return socket_->Connect(io_callback_);
709 } 709 }
710 710
711 int SocketStream::DoTcpConnectComplete(int result) { 711 int SocketStream::DoTcpConnectComplete(int result) {
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)
719 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
720 else
721 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
722 return result;
723 }
724
725 int SocketStream::DoGenerateProxyAuthToken() {
726 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
727 if (!proxy_auth_controller_.get()) {
728 DCHECK(context_);
729 DCHECK(context_->http_transaction_factory());
730 DCHECK(context_->http_transaction_factory()->GetSession());
731 HttpNetworkSession* session =
732 context_->http_transaction_factory()->GetSession();
733 const char* scheme = proxy_info_.is_https() ? "https://" : "http://";
734 GURL auth_url(scheme +
735 proxy_info_.proxy_server().host_port_pair().ToString());
736 proxy_auth_controller_ =
737 new HttpAuthController(HttpAuth::AUTH_PROXY,
738 auth_url,
739 session->http_auth_cache(),
740 session->http_auth_handler_factory());
741 }
742 HttpRequestInfo request_info;
743 request_info.method = "CONNECT";
cbentzel 2012/08/22 20:19:43 BUG: This isn't sufficient for a digest-authentica
bashi 2012/08/23 09:54:15 Thanks. I didn't realized the issue. Changed to se
744 request_info.load_flags = 0;
745 request_info.priority = MEDIUM;
746 request_info.request_id = 0;
747 return proxy_auth_controller_->MaybeGenerateAuthToken(
748 &request_info, io_callback_, net_log_);
749 }
750
751 int SocketStream::DoGenerateProxyAuthTokenComplete(int result) {
752 if (result != OK) {
753 next_state_ = STATE_CLOSE;
754 return result;
755 }
756
718 if (proxy_mode_ == kTunnelProxy) { 757 if (proxy_mode_ == kTunnelProxy) {
719 if (proxy_info_.is_https()) 758 if (proxy_info_.is_https())
720 next_state_ = STATE_SECURE_PROXY_CONNECT; 759 next_state_ = STATE_SECURE_PROXY_CONNECT;
721 else 760 else
722 next_state_ = STATE_WRITE_TUNNEL_HEADERS; 761 next_state_ = STATE_WRITE_TUNNEL_HEADERS;
wtc 2012/08/22 19:42:27 I think we can simplify state transition by keepin
bashi 2012/08/23 09:54:15 Thank you so much for detailed suggestion. I follo
723 } else if (proxy_mode_ == kSOCKSProxy) { 762 } else if (proxy_mode_ == kSOCKSProxy) {
724 next_state_ = STATE_SOCKS_CONNECT; 763 next_state_ = STATE_SOCKS_CONNECT;
725 } else if (is_secure()) { 764 } else if (is_secure()) {
726 next_state_ = STATE_SSL_CONNECT; 765 next_state_ = STATE_SSL_CONNECT;
727 } else { 766 } else {
728 result = DidEstablishConnection(); 767 result = DidEstablishConnection();
729 } 768 }
730 return result; 769 return result;
731 } 770 }
732 771
733 int SocketStream::DoWriteTunnelHeaders() { 772 int SocketStream::DoWriteTunnelHeaders() {
734 DCHECK_EQ(kTunnelProxy, proxy_mode_); 773 DCHECK_EQ(kTunnelProxy, proxy_mode_);
735 774
736 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE; 775 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE;
737 776
738 if (!tunnel_request_headers_.get()) { 777 if (!tunnel_request_headers_.get()) {
739 metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION); 778 metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION);
740 tunnel_request_headers_ = new RequestHeaders(); 779 tunnel_request_headers_ = new RequestHeaders();
741 tunnel_request_headers_bytes_sent_ = 0; 780 tunnel_request_headers_bytes_sent_ = 0;
742 } 781 }
743 if (tunnel_request_headers_->headers_.empty()) { 782 if (tunnel_request_headers_->headers_.empty()) {
744 std::string authorization_headers; 783 HttpRequestHeaders request_headers;
745 784 request_headers.SetHeader("Host", GetHostAndOptionalPort(url_));
746 if (!auth_handler_.get()) { 785 request_headers.SetHeader("Proxy-Connection", "keep-alive");
747 // Do preemptive authentication. 786 if (proxy_auth_controller_.get() && proxy_auth_controller_->HaveAuth())
748 HttpAuthCache::Entry* entry = auth_cache_.LookupByPath( 787 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( 788 tunnel_request_headers_->headers_ = base::StringPrintf(
788 "CONNECT %s HTTP/1.1\r\n" 789 "CONNECT %s HTTP/1.1\r\n"
789 "Host: %s\r\n" 790 "%s",
790 "Proxy-Connection: keep-alive\r\n",
791 GetHostAndPort(url_).c_str(), 791 GetHostAndPort(url_).c_str(),
792 GetHostAndOptionalPort(url_).c_str()); 792 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 } 793 }
797 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_); 794 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_);
798 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() - 795 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() -
799 tunnel_request_headers_bytes_sent_); 796 tunnel_request_headers_bytes_sent_);
800 DCHECK_GT(buf_len, 0); 797 DCHECK_GT(buf_len, 0);
801 return socket_->Write(tunnel_request_headers_, buf_len, io_callback_); 798 return socket_->Write(tunnel_request_headers_, buf_len, io_callback_);
802 } 799 }
803 800
804 int SocketStream::DoWriteTunnelHeadersComplete(int result) { 801 int SocketStream::DoWriteTunnelHeadersComplete(int result) {
805 DCHECK_EQ(kTunnelProxy, proxy_mode_); 802 DCHECK_EQ(kTunnelProxy, proxy_mode_);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 next_state_ = STATE_CLOSE; 889 next_state_ = STATE_CLOSE;
893 return result; 890 return result;
894 } 891 }
895 if ((eoh < tunnel_response_headers_len_) && delegate_) 892 if ((eoh < tunnel_response_headers_len_) && delegate_)
896 delegate_->OnReceivedData( 893 delegate_->OnReceivedData(
897 this, tunnel_response_headers_->headers() + eoh, 894 this, tunnel_response_headers_->headers() + eoh,
898 tunnel_response_headers_len_ - eoh); 895 tunnel_response_headers_len_ - eoh);
899 } 896 }
900 return OK; 897 return OK;
901 case 407: // Proxy Authentication Required. 898 case 407: // Proxy Authentication Required.
902 result = HandleAuthChallenge(headers.get()); 899 if (proxy_mode_ != kTunnelProxy)
903 if (result == ERR_PROXY_AUTH_UNSUPPORTED && 900 return ERR_UNEXPECTED_PROXY_AUTH;
904 auth_handler_.get() && delegate_) { 901
902 result = proxy_auth_controller_->HandleAuthChallenge(
903 headers, false, true, net_log_);
904 if (result == OK && delegate_) {
905 DCHECK(!proxy_info_.is_empty()); 905 DCHECK(!proxy_info_.is_empty());
906 auth_info_ = new AuthChallengeInfo;
907 auth_info_->is_proxy = true;
908 auth_info_->challenger = proxy_info_.proxy_server().host_port_pair();
909 auth_info_->scheme = HttpAuth::SchemeToString(
910 auth_handler_->auth_scheme());
911 auth_info_->realm = auth_handler_->realm();
912 // Wait until RestartWithAuth or Close is called. 906 // Wait until RestartWithAuth or Close is called.
913 MessageLoop::current()->PostTask( 907 MessageLoop::current()->PostTask(
914 FROM_HERE, 908 FROM_HERE,
915 base::Bind(&SocketStream::DoAuthRequired, this)); 909 base::Bind(&SocketStream::DoAuthRequired, this));
916 next_state_ = STATE_AUTH_REQUIRED; 910 next_state_ = STATE_AUTH_REQUIRED;
917 return ERR_IO_PENDING; 911 return ERR_IO_PENDING;
918 } 912 }
913 break;
919 default: 914 default:
920 break; 915 break;
921 } 916 }
922 next_state_ = STATE_CLOSE; 917 next_state_ = STATE_CLOSE;
923 return ERR_TUNNEL_CONNECTION_FAILED; 918 return ERR_TUNNEL_CONNECTION_FAILED;
924 } 919 }
925 920
926 int SocketStream::DoSOCKSConnect() { 921 int SocketStream::DoSOCKSConnect() {
927 DCHECK_EQ(kSOCKSProxy, proxy_mode_); 922 DCHECK_EQ(kSOCKSProxy, proxy_mode_);
928 923
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 // We arrived here when both operation is pending. 1132 // We arrived here when both operation is pending.
1138 return ERR_IO_PENDING; 1133 return ERR_IO_PENDING;
1139 } 1134 }
1140 1135
1141 GURL SocketStream::ProxyAuthOrigin() const { 1136 GURL SocketStream::ProxyAuthOrigin() const {
1142 DCHECK(!proxy_info_.is_empty()); 1137 DCHECK(!proxy_info_.is_empty());
1143 return GURL("http://" + 1138 return GURL("http://" +
1144 proxy_info_.proxy_server().host_port_pair().ToString()); 1139 proxy_info_.proxy_server().host_port_pair().ToString());
1145 } 1140 }
1146 1141
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) { 1142 int SocketStream::HandleCertificateRequest(int result, SSLConfig* ssl_config) {
1195 if (ssl_config->send_client_cert) 1143 if (ssl_config->send_client_cert)
1196 // We already have performed SSL client authentication once and failed. 1144 // We already have performed SSL client authentication once and failed.
1197 return result; 1145 return result;
1198 1146
1199 DCHECK(socket_.get()); 1147 DCHECK(socket_.get());
1200 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo; 1148 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo;
1201 SSLClientSocket* ssl_socket = 1149 SSLClientSocket* ssl_socket =
1202 static_cast<SSLClientSocket*>(socket_.get()); 1150 static_cast<SSLClientSocket*>(socket_.get());
1203 ssl_socket->GetSSLCertRequestInfo(cert_request_info); 1151 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; 1212 bad_cert.cert_status = ssl_info.cert_status;
1265 ssl_config->allowed_bad_certs.push_back(bad_cert); 1213 ssl_config->allowed_bad_certs.push_back(bad_cert);
1266 // Restart connection ignoring the bad certificate. 1214 // Restart connection ignoring the bad certificate.
1267 socket_->Disconnect(); 1215 socket_->Disconnect();
1268 socket_.reset(); 1216 socket_.reset();
1269 next_state_ = STATE_TCP_CONNECT; 1217 next_state_ = STATE_TCP_CONNECT;
1270 return OK; 1218 return OK;
1271 } 1219 }
1272 1220
1273 void SocketStream::DoAuthRequired() { 1221 void SocketStream::DoAuthRequired() {
1274 if (delegate_ && auth_info_.get()) 1222 if (delegate_ && proxy_auth_controller_.get())
1275 delegate_->OnAuthRequired(this, auth_info_.get()); 1223 delegate_->OnAuthRequired(this, proxy_auth_controller_->auth_info().get());
1276 else 1224 else
1277 DoLoop(ERR_UNEXPECTED); 1225 DoLoop(ERR_UNEXPECTED);
1278 } 1226 }
1279 1227
1280 void SocketStream::DoRestartWithAuth() { 1228 void SocketStream::DoRestartWithAuth() {
1281 DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED); 1229 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; 1230 tunnel_request_headers_ = NULL;
1290 tunnel_request_headers_bytes_sent_ = 0; 1231 tunnel_request_headers_bytes_sent_ = 0;
1291 tunnel_response_headers_ = NULL; 1232 tunnel_response_headers_ = NULL;
1292 tunnel_response_headers_capacity_ = 0; 1233 tunnel_response_headers_capacity_ = 0;
1293 tunnel_response_headers_len_ = 0; 1234 tunnel_response_headers_len_ = 0;
1294 1235
1295 next_state_ = STATE_TCP_CONNECT; 1236 next_state_ = STATE_TCP_CONNECT;
1296 DoLoop(OK); 1237 DoLoop(OK);
1297 } 1238 }
1298 1239
(...skipping 27 matching lines...) Expand all
1326 1267
1327 SSLConfigService* SocketStream::ssl_config_service() const { 1268 SSLConfigService* SocketStream::ssl_config_service() const {
1328 return context_->ssl_config_service(); 1269 return context_->ssl_config_service();
1329 } 1270 }
1330 1271
1331 ProxyService* SocketStream::proxy_service() const { 1272 ProxyService* SocketStream::proxy_service() const {
1332 return context_->proxy_service(); 1273 return context_->proxy_service();
1333 } 1274 }
1334 1275
1335 } // namespace net 1276 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698