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

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_controller.h"
28 #include "net/http/http_auth_handler_factory.h" 29 #include "net/http/http_auth_handler_factory.h"
29 #include "net/http/http_network_session.h" 30 #include "net/http/http_network_session.h"
31 #include "net/http/http_request_headers.h"
30 #include "net/http/http_request_info.h" 32 #include "net/http/http_request_info.h"
31 #include "net/http/http_response_headers.h" 33 #include "net/http/http_response_headers.h"
32 #include "net/http/http_stream_factory.h" 34 #include "net/http/http_stream_factory.h"
33 #include "net/http/http_transaction_factory.h" 35 #include "net/http/http_transaction_factory.h"
34 #include "net/http/http_util.h" 36 #include "net/http/http_util.h"
35 #include "net/socket/client_socket_factory.h" 37 #include "net/socket/client_socket_factory.h"
36 #include "net/socket/socks5_client_socket.h" 38 #include "net/socket/socks5_client_socket.h"
37 #include "net/socket/socks_client_socket.h" 39 #include "net/socket/socks_client_socket.h"
38 #include "net/socket/ssl_client_socket.h" 40 #include "net/socket/ssl_client_socket.h"
39 #include "net/socket/tcp_client_socket.h" 41 #include "net/socket/tcp_client_socket.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 87
86 SocketStream::SocketStream(const GURL& url, Delegate* delegate) 88 SocketStream::SocketStream(const GURL& url, Delegate* delegate)
87 : delegate_(delegate), 89 : delegate_(delegate),
88 url_(url), 90 url_(url),
89 max_pending_send_allowed_(kMaxPendingSendAllowed), 91 max_pending_send_allowed_(kMaxPendingSendAllowed),
90 context_(NULL), 92 context_(NULL),
91 next_state_(STATE_NONE), 93 next_state_(STATE_NONE),
92 host_resolver_(NULL), 94 host_resolver_(NULL),
93 cert_verifier_(NULL), 95 cert_verifier_(NULL),
94 server_bound_cert_service_(NULL), 96 server_bound_cert_service_(NULL),
95 http_auth_handler_factory_(NULL),
96 factory_(ClientSocketFactory::GetDefaultFactory()), 97 factory_(ClientSocketFactory::GetDefaultFactory()),
97 proxy_mode_(kDirectConnection), 98 proxy_mode_(kDirectConnection),
98 proxy_url_(url), 99 proxy_url_(url),
99 pac_request_(NULL), 100 pac_request_(NULL),
100 // Unretained() is required; without it, Bind() creates a circular 101 // Unretained() is required; without it, Bind() creates a circular
101 // dependency and the SocketStream object will not be freed. 102 // dependency and the SocketStream object will not be freed.
102 ALLOW_THIS_IN_INITIALIZER_LIST( 103 ALLOW_THIS_IN_INITIALIZER_LIST(
103 io_callback_(base::Bind(&SocketStream::OnIOCompleted, 104 io_callback_(base::Bind(&SocketStream::OnIOCompleted,
104 base::Unretained(this)))), 105 base::Unretained(this)))),
105 read_buf_(NULL), 106 read_buf_(NULL),
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 NetLog::SOURCE_SOCKET_STREAM); 154 NetLog::SOURCE_SOCKET_STREAM);
154 155
155 net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE); 156 net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE);
156 } 157 }
157 } 158 }
158 159
159 if (context_) { 160 if (context_) {
160 host_resolver_ = context_->host_resolver(); 161 host_resolver_ = context_->host_resolver();
161 cert_verifier_ = context_->cert_verifier(); 162 cert_verifier_ = context_->cert_verifier();
162 server_bound_cert_service_ = context_->server_bound_cert_service(); 163 server_bound_cert_service_ = context_->server_bound_cert_service();
163 http_auth_handler_factory_ = context_->http_auth_handler_factory();
164 } 164 }
165 } 165 }
166 166
167 void SocketStream::Connect() { 167 void SocketStream::Connect() {
168 DCHECK(MessageLoop::current()) << 168 DCHECK(MessageLoop::current()) <<
169 "The current MessageLoop must exist"; 169 "The current MessageLoop must exist";
170 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << 170 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
171 "The current MessageLoop must be TYPE_IO"; 171 "The current MessageLoop must be TYPE_IO";
172 if (context_) { 172 if (context_) {
173 ssl_config_service()->GetSSLConfig(&server_ssl_config_); 173 ssl_config_service()->GetSSLConfig(&server_ssl_config_);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 MessageLoop::current()->PostTask( 237 MessageLoop::current()->PostTask(
238 FROM_HERE, 238 FROM_HERE,
239 base::Bind(&SocketStream::DoClose, this)); 239 base::Bind(&SocketStream::DoClose, this));
240 } 240 }
241 241
242 void SocketStream::RestartWithAuth(const AuthCredentials& credentials) { 242 void SocketStream::RestartWithAuth(const AuthCredentials& credentials) {
243 DCHECK(MessageLoop::current()) << 243 DCHECK(MessageLoop::current()) <<
244 "The current MessageLoop must exist"; 244 "The current MessageLoop must exist";
245 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << 245 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
246 "The current MessageLoop must be TYPE_IO"; 246 "The current MessageLoop must be TYPE_IO";
247 DCHECK(auth_handler_.get()); 247 DCHECK(proxy_auth_controller_.get());
248 if (!socket_.get()) { 248 if (!socket_.get()) {
249 LOG(ERROR) << "Socket is closed before restarting with auth."; 249 LOG(ERROR) << "Socket is closed before restarting with auth.";
250 return; 250 return;
251 } 251 }
252 252
253 if (auth_identity_.invalid) { 253 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 254
260 MessageLoop::current()->PostTask( 255 MessageLoop::current()->PostTask(
261 FROM_HERE, 256 FROM_HERE,
262 base::Bind(&SocketStream::DoRestartWithAuth, this)); 257 base::Bind(&SocketStream::DoRestartWithAuth, this));
263 } 258 }
264 259
265 void SocketStream::DetachDelegate() { 260 void SocketStream::DetachDelegate() {
266 if (!delegate_) 261 if (!delegate_)
267 return; 262 return;
268 delegate_ = NULL; 263 delegate_ = NULL;
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 break; 463 break;
469 case STATE_RESOLVE_PROTOCOL_COMPLETE: 464 case STATE_RESOLVE_PROTOCOL_COMPLETE:
470 result = DoResolveProtocolComplete(result); 465 result = DoResolveProtocolComplete(result);
471 break; 466 break;
472 case STATE_TCP_CONNECT: 467 case STATE_TCP_CONNECT:
473 result = DoTcpConnect(result); 468 result = DoTcpConnect(result);
474 break; 469 break;
475 case STATE_TCP_CONNECT_COMPLETE: 470 case STATE_TCP_CONNECT_COMPLETE:
476 result = DoTcpConnectComplete(result); 471 result = DoTcpConnectComplete(result);
477 break; 472 break;
473 case STATE_GENERATE_PROXY_AUTH_TOKEN:
474 result = DoGenerateProxyAuthToken();
475 break;
476 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE:
477 result = DoGenerateProxyAuthTokenComplete(result);
478 break;
478 case STATE_WRITE_TUNNEL_HEADERS: 479 case STATE_WRITE_TUNNEL_HEADERS:
479 DCHECK_EQ(OK, result); 480 DCHECK_EQ(OK, result);
480 result = DoWriteTunnelHeaders(); 481 result = DoWriteTunnelHeaders();
481 break; 482 break;
482 case STATE_WRITE_TUNNEL_HEADERS_COMPLETE: 483 case STATE_WRITE_TUNNEL_HEADERS_COMPLETE:
483 result = DoWriteTunnelHeadersComplete(result); 484 result = DoWriteTunnelHeadersComplete(result);
484 break; 485 break;
485 case STATE_READ_TUNNEL_HEADERS: 486 case STATE_READ_TUNNEL_HEADERS:
486 DCHECK_EQ(OK, result); 487 DCHECK_EQ(OK, result);
487 result = DoReadTunnelHeaders(); 488 result = DoReadTunnelHeaders();
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 } 702 }
702 next_state_ = STATE_TCP_CONNECT_COMPLETE; 703 next_state_ = STATE_TCP_CONNECT_COMPLETE;
703 DCHECK(factory_); 704 DCHECK(factory_);
704 socket_.reset(factory_->CreateTransportClientSocket(addresses_, 705 socket_.reset(factory_->CreateTransportClientSocket(addresses_,
705 net_log_.net_log(), 706 net_log_.net_log(),
706 net_log_.source())); 707 net_log_.source()));
707 metrics_->OnStartConnection(); 708 metrics_->OnStartConnection();
708 return socket_->Connect(io_callback_); 709 return socket_->Connect(io_callback_);
709 } 710 }
710 711
712 bool SocketStream::ShouldApplyProxyAuth() const {
713 return !is_secure() && (proxy_info_.is_http() || proxy_info_.is_https());
wtc 2012/08/14 18:34:37 IMPORTANT: can you explain why you test !is_secure
bashi 2012/08/14 21:45:45 Done. The logic is the same as HttpNetworkTransact
wtc 2012/08/14 23:20:35 Thank you for the explanation. I think this test
bashi 2012/08/20 01:35:10 You are right. Removed !is_secure() and added the
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.url = url();
wtc 2012/08/14 18:34:37 Nit: this request_info.url assignment should be un
bashi 2012/08/14 21:45:45 Removed.
749 request_info.method = "GET";
750 request_info.load_flags = 0;
751 request_info.priority = MEDIUM;
752 request_info.request_id = 0;
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
718 if (proxy_mode_ == kTunnelProxy) { 763 if (proxy_mode_ == kTunnelProxy) {
719 if (proxy_info_.is_https()) 764 if (proxy_info_.is_https())
720 next_state_ = STATE_SECURE_PROXY_CONNECT; 765 next_state_ = STATE_SECURE_PROXY_CONNECT;
721 else 766 else
722 next_state_ = STATE_WRITE_TUNNEL_HEADERS; 767 next_state_ = STATE_WRITE_TUNNEL_HEADERS;
723 } else if (proxy_mode_ == kSOCKSProxy) { 768 } else if (proxy_mode_ == kSOCKSProxy) {
724 next_state_ = STATE_SOCKS_CONNECT; 769 next_state_ = STATE_SOCKS_CONNECT;
725 } else if (is_secure()) { 770 } else if (is_secure()) {
726 next_state_ = STATE_SSL_CONNECT; 771 next_state_ = STATE_SSL_CONNECT;
727 } else { 772 } else {
728 result = DidEstablishConnection(); 773 result = DidEstablishConnection();
729 } 774 }
730 return result; 775 return result;
731 } 776 }
732 777
733 int SocketStream::DoWriteTunnelHeaders() { 778 int SocketStream::DoWriteTunnelHeaders() {
734 DCHECK_EQ(kTunnelProxy, proxy_mode_); 779 DCHECK_EQ(kTunnelProxy, proxy_mode_);
735 780
736 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE; 781 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE;
737 782
738 if (!tunnel_request_headers_.get()) { 783 if (!tunnel_request_headers_.get()) {
739 metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION); 784 metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION);
740 tunnel_request_headers_ = new RequestHeaders(); 785 tunnel_request_headers_ = new RequestHeaders();
741 tunnel_request_headers_bytes_sent_ = 0; 786 tunnel_request_headers_bytes_sent_ = 0;
742 } 787 }
743 if (tunnel_request_headers_->headers_.empty()) { 788 if (tunnel_request_headers_->headers_.empty()) {
744 std::string authorization_headers; 789 HttpRequestHeaders authorization_headers;
745 790 if (proxy_auth_controller_.get() && proxy_auth_controller_->HaveAuth())
746 if (!auth_handler_.get()) { 791 proxy_auth_controller_->AddAuthorizationHeader(&authorization_headers);
747 // Do preemptive authentication.
748 HttpAuthCache::Entry* entry = auth_cache_.LookupByPath(
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( 792 tunnel_request_headers_->headers_ = base::StringPrintf(
788 "CONNECT %s HTTP/1.1\r\n" 793 "CONNECT %s HTTP/1.1\r\n"
789 "Host: %s\r\n" 794 "Host: %s\r\n"
790 "Proxy-Connection: keep-alive\r\n", 795 "Proxy-Connection: keep-alive\r\n",
791 GetHostAndPort(url_).c_str(), 796 GetHostAndPort(url_).c_str(),
792 GetHostAndOptionalPort(url_).c_str()); 797 GetHostAndOptionalPort(url_).c_str());
793 if (!authorization_headers.empty()) 798 if (authorization_headers.IsEmpty())
794 tunnel_request_headers_->headers_ += authorization_headers; 799 tunnel_request_headers_->headers_ += "\r\n";
795 tunnel_request_headers_->headers_ += "\r\n"; 800 else
801 tunnel_request_headers_->headers_ += authorization_headers.ToString();
wtc 2012/08/14 18:34:37 IMPORTANT: this seems wrong. This implies that au
bashi 2012/08/14 21:45:45 I agree. Done.
wtc 2012/08/14 23:20:35 Great! This change exceeds my expectations :-)
796 } 802 }
797 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_); 803 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_);
798 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() - 804 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() -
799 tunnel_request_headers_bytes_sent_); 805 tunnel_request_headers_bytes_sent_);
800 DCHECK_GT(buf_len, 0); 806 DCHECK_GT(buf_len, 0);
801 return socket_->Write(tunnel_request_headers_, buf_len, io_callback_); 807 return socket_->Write(tunnel_request_headers_, buf_len, io_callback_);
802 } 808 }
803 809
804 int SocketStream::DoWriteTunnelHeadersComplete(int result) { 810 int SocketStream::DoWriteTunnelHeadersComplete(int result) {
805 DCHECK_EQ(kTunnelProxy, proxy_mode_); 811 DCHECK_EQ(kTunnelProxy, proxy_mode_);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 next_state_ = STATE_CLOSE; 898 next_state_ = STATE_CLOSE;
893 return result; 899 return result;
894 } 900 }
895 if ((eoh < tunnel_response_headers_len_) && delegate_) 901 if ((eoh < tunnel_response_headers_len_) && delegate_)
896 delegate_->OnReceivedData( 902 delegate_->OnReceivedData(
897 this, tunnel_response_headers_->headers() + eoh, 903 this, tunnel_response_headers_->headers() + eoh,
898 tunnel_response_headers_len_ - eoh); 904 tunnel_response_headers_len_ - eoh);
899 } 905 }
900 return OK; 906 return OK;
901 case 407: // Proxy Authentication Required. 907 case 407: // Proxy Authentication Required.
902 result = HandleAuthChallenge(headers.get()); 908 if (!proxy_auth_controller_.get() || proxy_mode_ != kTunnelProxy ||
903 if (result == ERR_PROXY_AUTH_UNSUPPORTED && 909 proxy_info_.is_direct())
904 auth_handler_.get() && delegate_) { 910 return ERR_UNEXPECTED_PROXY_AUTH;
wtc 2012/08/14 18:34:37 Nit: add curly braces because the conditional expr
bashi 2012/08/14 21:45:45 Done.
911 result = proxy_auth_controller_->HandleAuthChallenge(
912 headers, false, true, net_log_);
913 if (result == OK && delegate_) {
905 DCHECK(!proxy_info_.is_empty()); 914 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. 915 // Wait until RestartWithAuth or Close is called.
913 MessageLoop::current()->PostTask( 916 MessageLoop::current()->PostTask(
914 FROM_HERE, 917 FROM_HERE,
915 base::Bind(&SocketStream::DoAuthRequired, this)); 918 base::Bind(&SocketStream::DoAuthRequired, this));
916 next_state_ = STATE_AUTH_REQUIRED; 919 next_state_ = STATE_AUTH_REQUIRED;
917 return ERR_IO_PENDING; 920 return ERR_IO_PENDING;
918 } 921 }
wtc 2012/08/14 18:34:37 IMPORTANT: you are falling through the the default
bashi 2012/08/14 21:45:45 Thank you for the catch. Added break.
919 default: 922 default:
920 break; 923 break;
921 } 924 }
922 next_state_ = STATE_CLOSE; 925 next_state_ = STATE_CLOSE;
923 return ERR_TUNNEL_CONNECTION_FAILED; 926 return ERR_TUNNEL_CONNECTION_FAILED;
924 } 927 }
925 928
926 int SocketStream::DoSOCKSConnect() { 929 int SocketStream::DoSOCKSConnect() {
927 DCHECK_EQ(kSOCKSProxy, proxy_mode_); 930 DCHECK_EQ(kSOCKSProxy, proxy_mode_);
928 931
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 // We arrived here when both operation is pending. 1140 // We arrived here when both operation is pending.
1138 return ERR_IO_PENDING; 1141 return ERR_IO_PENDING;
1139 } 1142 }
1140 1143
1141 GURL SocketStream::ProxyAuthOrigin() const { 1144 GURL SocketStream::ProxyAuthOrigin() const {
1142 DCHECK(!proxy_info_.is_empty()); 1145 DCHECK(!proxy_info_.is_empty());
1143 return GURL("http://" + 1146 return GURL("http://" +
1144 proxy_info_.proxy_server().host_port_pair().ToString()); 1147 proxy_info_.proxy_server().host_port_pair().ToString());
1145 } 1148 }
1146 1149
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) { 1150 int SocketStream::HandleCertificateRequest(int result, SSLConfig* ssl_config) {
1195 if (ssl_config->send_client_cert) 1151 if (ssl_config->send_client_cert)
1196 // We already have performed SSL client authentication once and failed. 1152 // We already have performed SSL client authentication once and failed.
1197 return result; 1153 return result;
1198 1154
1199 DCHECK(socket_.get()); 1155 DCHECK(socket_.get());
1200 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo; 1156 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo;
1201 SSLClientSocket* ssl_socket = 1157 SSLClientSocket* ssl_socket =
1202 static_cast<SSLClientSocket*>(socket_.get()); 1158 static_cast<SSLClientSocket*>(socket_.get());
1203 ssl_socket->GetSSLCertRequestInfo(cert_request_info); 1159 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; 1220 bad_cert.cert_status = ssl_info.cert_status;
1265 ssl_config->allowed_bad_certs.push_back(bad_cert); 1221 ssl_config->allowed_bad_certs.push_back(bad_cert);
1266 // Restart connection ignoring the bad certificate. 1222 // Restart connection ignoring the bad certificate.
1267 socket_->Disconnect(); 1223 socket_->Disconnect();
1268 socket_.reset(); 1224 socket_.reset();
1269 next_state_ = STATE_TCP_CONNECT; 1225 next_state_ = STATE_TCP_CONNECT;
1270 return OK; 1226 return OK;
1271 } 1227 }
1272 1228
1273 void SocketStream::DoAuthRequired() { 1229 void SocketStream::DoAuthRequired() {
1274 if (delegate_ && auth_info_.get()) 1230 if (delegate_ && proxy_auth_controller_.get())
1275 delegate_->OnAuthRequired(this, auth_info_.get()); 1231 delegate_->OnAuthRequired(this, proxy_auth_controller_->auth_info().get());
1276 else 1232 else
1277 DoLoop(ERR_UNEXPECTED); 1233 DoLoop(ERR_UNEXPECTED);
1278 } 1234 }
1279 1235
1280 void SocketStream::DoRestartWithAuth() { 1236 void SocketStream::DoRestartWithAuth() {
1281 DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED); 1237 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; 1238 tunnel_request_headers_ = NULL;
1290 tunnel_request_headers_bytes_sent_ = 0; 1239 tunnel_request_headers_bytes_sent_ = 0;
1291 tunnel_response_headers_ = NULL; 1240 tunnel_response_headers_ = NULL;
1292 tunnel_response_headers_capacity_ = 0; 1241 tunnel_response_headers_capacity_ = 0;
1293 tunnel_response_headers_len_ = 0; 1242 tunnel_response_headers_len_ = 0;
1294 1243
1295 next_state_ = STATE_TCP_CONNECT; 1244 next_state_ = STATE_TCP_CONNECT;
1296 DoLoop(OK); 1245 DoLoop(OK);
1297 } 1246 }
1298 1247
(...skipping 27 matching lines...) Expand all
1326 1275
1327 SSLConfigService* SocketStream::ssl_config_service() const { 1276 SSLConfigService* SocketStream::ssl_config_service() const {
1328 return context_->ssl_config_service(); 1277 return context_->ssl_config_service();
1329 } 1278 }
1330 1279
1331 ProxyService* SocketStream::proxy_service() const { 1280 ProxyService* SocketStream::proxy_service() const {
1332 return context_->proxy_service(); 1281 return context_->proxy_service();
1333 } 1282 }
1334 1283
1335 } // namespace net 1284 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698