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

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: 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));
wtc 2012/08/21 21:30:45 Do you know why we can't just call DoRestartWithAu
bashi 2012/08/22 08:36:44 Hmm, I have no idea. yutak@, toshoshim@, do you ha
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;
269 net_log_.AddEvent(NetLog::TYPE_CANCELLED); 263 net_log_.AddEvent(NetLog::TYPE_CANCELLED);
270 // We don't need to send pending data when client detach the delegate. 264 // We don't need to send pending data when client detach the delegate.
271 pending_write_bufs_.clear(); 265 pending_write_bufs_.clear();
272 Close(); 266 Close();
(...skipping 195 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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 } 701 }
702 next_state_ = STATE_TCP_CONNECT_COMPLETE; 702 next_state_ = STATE_TCP_CONNECT_COMPLETE;
703 DCHECK(factory_); 703 DCHECK(factory_);
704 socket_.reset(factory_->CreateTransportClientSocket(addresses_, 704 socket_.reset(factory_->CreateTransportClientSocket(addresses_,
705 net_log_.net_log(), 705 net_log_.net_log(),
706 net_log_.source())); 706 net_log_.source()));
707 metrics_->OnStartConnection(); 707 metrics_->OnStartConnection();
708 return socket_->Connect(io_callback_); 708 return socket_->Connect(io_callback_);
709 } 709 }
710 710
711 bool SocketStream::ShouldApplyProxyAuth() const {
712 return proxy_mode_ == kTunnelProxy &&
713 (proxy_info_.is_http() || proxy_info_.is_https());
wtc 2012/08/21 21:30:45 Based on my code inspection, it is enough to just
bashi 2012/08/22 08:36:44 Thank you for the suggestion. Removed ShouldApplyP
714 }
715
711 int SocketStream::DoTcpConnectComplete(int result) { 716 int SocketStream::DoTcpConnectComplete(int result) {
712 // TODO(ukai): if error occured, reconsider proxy after error. 717 // TODO(ukai): if error occured, reconsider proxy after error.
713 if (result != OK) { 718 if (result != OK) {
714 next_state_ = STATE_CLOSE; 719 next_state_ = STATE_CLOSE;
715 return result; 720 return result;
716 } 721 }
717 722
723 if (ShouldApplyProxyAuth())
724 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
725 else
726 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
727 return result;
728 }
729
730 int SocketStream::DoGenerateProxyAuthToken() {
731 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
732 if (!proxy_auth_controller_.get()) {
733 DCHECK(context_);
734 DCHECK(context_->http_transaction_factory());
735 DCHECK(context_->http_transaction_factory()->GetSession());
736 HttpNetworkSession* session =
737 context_->http_transaction_factory()->GetSession();
738 const char* scheme = proxy_info_.is_https() ? "https://" : "http://";
739 GURL auth_url(scheme +
740 proxy_info_.proxy_server().host_port_pair().ToString());
741 proxy_auth_controller_ =
742 new HttpAuthController(HttpAuth::AUTH_PROXY,
743 auth_url,
744 session->http_auth_cache(),
745 session->http_auth_handler_factory());
746 }
747 HttpRequestInfo request_info;
748 request_info.method = "GET";
wtc 2012/08/21 21:30:45 Since we are generating the auth token for proxy t
bashi 2012/08/22 08:36:44 Done.
749 request_info.load_flags = 0;
750 request_info.priority = MEDIUM;
751 request_info.request_id = 0;
752 return proxy_auth_controller_->MaybeGenerateAuthToken(
753 &request_info, io_callback_, net_log_);
754 }
755
756 int SocketStream::DoGenerateProxyAuthTokenComplete(int result) {
757 if (result != OK) {
758 next_state_ = STATE_CLOSE;
759 return result;
760 }
761
718 if (proxy_mode_ == kTunnelProxy) { 762 if (proxy_mode_ == kTunnelProxy) {
719 if (proxy_info_.is_https()) 763 if (proxy_info_.is_https())
720 next_state_ = STATE_SECURE_PROXY_CONNECT; 764 next_state_ = STATE_SECURE_PROXY_CONNECT;
721 else 765 else
722 next_state_ = STATE_WRITE_TUNNEL_HEADERS; 766 next_state_ = STATE_WRITE_TUNNEL_HEADERS;
723 } else if (proxy_mode_ == kSOCKSProxy) { 767 } else if (proxy_mode_ == kSOCKSProxy) {
724 next_state_ = STATE_SOCKS_CONNECT; 768 next_state_ = STATE_SOCKS_CONNECT;
725 } else if (is_secure()) { 769 } else if (is_secure()) {
726 next_state_ = STATE_SSL_CONNECT; 770 next_state_ = STATE_SSL_CONNECT;
727 } else { 771 } else {
728 result = DidEstablishConnection(); 772 result = DidEstablishConnection();
729 } 773 }
730 return result; 774 return result;
731 } 775 }
732 776
733 int SocketStream::DoWriteTunnelHeaders() { 777 int SocketStream::DoWriteTunnelHeaders() {
734 DCHECK_EQ(kTunnelProxy, proxy_mode_); 778 DCHECK_EQ(kTunnelProxy, proxy_mode_);
735 779
736 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE; 780 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE;
737 781
738 if (!tunnel_request_headers_.get()) { 782 if (!tunnel_request_headers_.get()) {
739 metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION); 783 metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION);
740 tunnel_request_headers_ = new RequestHeaders(); 784 tunnel_request_headers_ = new RequestHeaders();
741 tunnel_request_headers_bytes_sent_ = 0; 785 tunnel_request_headers_bytes_sent_ = 0;
742 } 786 }
743 if (tunnel_request_headers_->headers_.empty()) { 787 if (tunnel_request_headers_->headers_.empty()) {
744 std::string authorization_headers; 788 HttpRequestHeaders request_headers;
745 789 request_headers.SetHeader("Host", GetHostAndOptionalPort(url_));
746 if (!auth_handler_.get()) { 790 request_headers.SetHeader("Proxy-Connection", "keep-alive");
747 // Do preemptive authentication. 791 if (proxy_auth_controller_.get() && proxy_auth_controller_->HaveAuth())
748 HttpAuthCache::Entry* entry = auth_cache_.LookupByPath( 792 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( 793 tunnel_request_headers_->headers_ = base::StringPrintf(
788 "CONNECT %s HTTP/1.1\r\n" 794 "CONNECT %s HTTP/1.1\r\n"
789 "Host: %s\r\n" 795 "%s",
790 "Proxy-Connection: keep-alive\r\n",
791 GetHostAndPort(url_).c_str(), 796 GetHostAndPort(url_).c_str(),
792 GetHostAndOptionalPort(url_).c_str()); 797 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 } 798 }
797 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_); 799 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_);
798 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() - 800 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() -
799 tunnel_request_headers_bytes_sent_); 801 tunnel_request_headers_bytes_sent_);
800 DCHECK_GT(buf_len, 0); 802 DCHECK_GT(buf_len, 0);
801 return socket_->Write(tunnel_request_headers_, buf_len, io_callback_); 803 return socket_->Write(tunnel_request_headers_, buf_len, io_callback_);
802 } 804 }
803 805
804 int SocketStream::DoWriteTunnelHeadersComplete(int result) { 806 int SocketStream::DoWriteTunnelHeadersComplete(int result) {
805 DCHECK_EQ(kTunnelProxy, proxy_mode_); 807 DCHECK_EQ(kTunnelProxy, proxy_mode_);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 next_state_ = STATE_CLOSE; 894 next_state_ = STATE_CLOSE;
893 return result; 895 return result;
894 } 896 }
895 if ((eoh < tunnel_response_headers_len_) && delegate_) 897 if ((eoh < tunnel_response_headers_len_) && delegate_)
896 delegate_->OnReceivedData( 898 delegate_->OnReceivedData(
897 this, tunnel_response_headers_->headers() + eoh, 899 this, tunnel_response_headers_->headers() + eoh,
898 tunnel_response_headers_len_ - eoh); 900 tunnel_response_headers_len_ - eoh);
899 } 901 }
900 return OK; 902 return OK;
901 case 407: // Proxy Authentication Required. 903 case 407: // Proxy Authentication Required.
902 result = HandleAuthChallenge(headers.get()); 904 if (!proxy_auth_controller_.get() || proxy_mode_ != kTunnelProxy ||
wtc 2012/08/21 21:30:45 It seems that we just need to test proxy_mode_ !=
bashi 2012/08/22 08:36:44 Done. HttpNetworkTransaction has similar code and
903 if (result == ERR_PROXY_AUTH_UNSUPPORTED && 905 proxy_info_.is_direct()) {
904 auth_handler_.get() && delegate_) { 906 return ERR_UNEXPECTED_PROXY_AUTH;
907 }
908 result = proxy_auth_controller_->HandleAuthChallenge(
909 headers, false, true, net_log_);
910 if (result == OK && delegate_) {
905 DCHECK(!proxy_info_.is_empty()); 911 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. 912 // Wait until RestartWithAuth or Close is called.
913 MessageLoop::current()->PostTask( 913 MessageLoop::current()->PostTask(
914 FROM_HERE, 914 FROM_HERE,
915 base::Bind(&SocketStream::DoAuthRequired, this)); 915 base::Bind(&SocketStream::DoAuthRequired, this));
916 next_state_ = STATE_AUTH_REQUIRED; 916 next_state_ = STATE_AUTH_REQUIRED;
917 return ERR_IO_PENDING; 917 return ERR_IO_PENDING;
918 } 918 }
919 break;
919 default: 920 default:
920 break; 921 break;
921 } 922 }
922 next_state_ = STATE_CLOSE; 923 next_state_ = STATE_CLOSE;
923 return ERR_TUNNEL_CONNECTION_FAILED; 924 return ERR_TUNNEL_CONNECTION_FAILED;
924 } 925 }
925 926
926 int SocketStream::DoSOCKSConnect() { 927 int SocketStream::DoSOCKSConnect() {
927 DCHECK_EQ(kSOCKSProxy, proxy_mode_); 928 DCHECK_EQ(kSOCKSProxy, proxy_mode_);
928 929
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 // We arrived here when both operation is pending. 1138 // We arrived here when both operation is pending.
1138 return ERR_IO_PENDING; 1139 return ERR_IO_PENDING;
1139 } 1140 }
1140 1141
1141 GURL SocketStream::ProxyAuthOrigin() const { 1142 GURL SocketStream::ProxyAuthOrigin() const {
1142 DCHECK(!proxy_info_.is_empty()); 1143 DCHECK(!proxy_info_.is_empty());
1143 return GURL("http://" + 1144 return GURL("http://" +
1144 proxy_info_.proxy_server().host_port_pair().ToString()); 1145 proxy_info_.proxy_server().host_port_pair().ToString());
1145 } 1146 }
1146 1147
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) { 1148 int SocketStream::HandleCertificateRequest(int result, SSLConfig* ssl_config) {
1195 if (ssl_config->send_client_cert) 1149 if (ssl_config->send_client_cert)
1196 // We already have performed SSL client authentication once and failed. 1150 // We already have performed SSL client authentication once and failed.
1197 return result; 1151 return result;
1198 1152
1199 DCHECK(socket_.get()); 1153 DCHECK(socket_.get());
1200 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo; 1154 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo;
1201 SSLClientSocket* ssl_socket = 1155 SSLClientSocket* ssl_socket =
1202 static_cast<SSLClientSocket*>(socket_.get()); 1156 static_cast<SSLClientSocket*>(socket_.get());
1203 ssl_socket->GetSSLCertRequestInfo(cert_request_info); 1157 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; 1218 bad_cert.cert_status = ssl_info.cert_status;
1265 ssl_config->allowed_bad_certs.push_back(bad_cert); 1219 ssl_config->allowed_bad_certs.push_back(bad_cert);
1266 // Restart connection ignoring the bad certificate. 1220 // Restart connection ignoring the bad certificate.
1267 socket_->Disconnect(); 1221 socket_->Disconnect();
1268 socket_.reset(); 1222 socket_.reset();
1269 next_state_ = STATE_TCP_CONNECT; 1223 next_state_ = STATE_TCP_CONNECT;
1270 return OK; 1224 return OK;
1271 } 1225 }
1272 1226
1273 void SocketStream::DoAuthRequired() { 1227 void SocketStream::DoAuthRequired() {
1274 if (delegate_ && auth_info_.get()) 1228 if (delegate_ && proxy_auth_controller_.get())
1275 delegate_->OnAuthRequired(this, auth_info_.get()); 1229 delegate_->OnAuthRequired(this, proxy_auth_controller_->auth_info().get());
1276 else 1230 else
1277 DoLoop(ERR_UNEXPECTED); 1231 DoLoop(ERR_UNEXPECTED);
1278 } 1232 }
1279 1233
1280 void SocketStream::DoRestartWithAuth() { 1234 void SocketStream::DoRestartWithAuth() {
1281 DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED); 1235 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; 1236 tunnel_request_headers_ = NULL;
1290 tunnel_request_headers_bytes_sent_ = 0; 1237 tunnel_request_headers_bytes_sent_ = 0;
1291 tunnel_response_headers_ = NULL; 1238 tunnel_response_headers_ = NULL;
1292 tunnel_response_headers_capacity_ = 0; 1239 tunnel_response_headers_capacity_ = 0;
1293 tunnel_response_headers_len_ = 0; 1240 tunnel_response_headers_len_ = 0;
1294 1241
1295 next_state_ = STATE_TCP_CONNECT; 1242 next_state_ = STATE_TCP_CONNECT;
1296 DoLoop(OK); 1243 DoLoop(OK);
1297 } 1244 }
1298 1245
(...skipping 27 matching lines...) Expand all
1326 1273
1327 SSLConfigService* SocketStream::ssl_config_service() const { 1274 SSLConfigService* SocketStream::ssl_config_service() const {
1328 return context_->ssl_config_service(); 1275 return context_->ssl_config_service();
1329 } 1276 }
1330 1277
1331 ProxyService* SocketStream::proxy_service() const { 1278 ProxyService* SocketStream::proxy_service() const {
1332 return context_->proxy_service(); 1279 return context_->proxy_service();
1333 } 1280 }
1334 1281
1335 } // namespace net 1282 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698