| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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.method = "CONNECT"; |
| 752 request_info.load_flags = 0; |
| 753 request_info.priority = MEDIUM; |
| 754 request_info.request_id = 0; |
| 755 return proxy_auth_controller_->MaybeGenerateAuthToken( |
| 756 &request_info, io_callback_, net_log_); |
| 757 } |
| 758 |
| 759 int SocketStream::DoGenerateProxyAuthTokenComplete(int result) { |
| 760 if (result != OK) { |
| 761 next_state_ = STATE_CLOSE; |
| 762 return result; |
| 763 } |
| 764 |
| 765 next_state_ = STATE_WRITE_TUNNEL_HEADERS; |
| 766 return result; |
| 767 } |
| 768 |
| 733 int SocketStream::DoWriteTunnelHeaders() { | 769 int SocketStream::DoWriteTunnelHeaders() { |
| 734 DCHECK_EQ(kTunnelProxy, proxy_mode_); | 770 DCHECK_EQ(kTunnelProxy, proxy_mode_); |
| 735 | 771 |
| 736 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE; | 772 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE; |
| 737 | 773 |
| 738 if (!tunnel_request_headers_.get()) { | 774 if (!tunnel_request_headers_.get()) { |
| 739 metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION); | 775 metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION); |
| 740 tunnel_request_headers_ = new RequestHeaders(); | 776 tunnel_request_headers_ = new RequestHeaders(); |
| 741 tunnel_request_headers_bytes_sent_ = 0; | 777 tunnel_request_headers_bytes_sent_ = 0; |
| 742 } | 778 } |
| 743 if (tunnel_request_headers_->headers_.empty()) { | 779 if (tunnel_request_headers_->headers_.empty()) { |
| 744 std::string authorization_headers; | 780 HttpRequestHeaders request_headers; |
| 745 | 781 request_headers.SetHeader("Host", GetHostAndOptionalPort(url_)); |
| 746 if (!auth_handler_.get()) { | 782 request_headers.SetHeader("Proxy-Connection", "keep-alive"); |
| 747 // Do preemptive authentication. | 783 if (proxy_auth_controller_.get() && proxy_auth_controller_->HaveAuth()) |
| 748 HttpAuthCache::Entry* entry = auth_cache_.LookupByPath( | 784 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( | 785 tunnel_request_headers_->headers_ = base::StringPrintf( |
| 788 "CONNECT %s HTTP/1.1\r\n" | 786 "CONNECT %s HTTP/1.1\r\n" |
| 789 "Host: %s\r\n" | 787 "%s", |
| 790 "Proxy-Connection: keep-alive\r\n", | |
| 791 GetHostAndPort(url_).c_str(), | 788 GetHostAndPort(url_).c_str(), |
| 792 GetHostAndOptionalPort(url_).c_str()); | 789 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 } | 790 } |
| 797 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_); | 791 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_); |
| 798 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() - | 792 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() - |
| 799 tunnel_request_headers_bytes_sent_); | 793 tunnel_request_headers_bytes_sent_); |
| 800 DCHECK_GT(buf_len, 0); | 794 DCHECK_GT(buf_len, 0); |
| 801 return socket_->Write(tunnel_request_headers_, buf_len, io_callback_); | 795 return socket_->Write(tunnel_request_headers_, buf_len, io_callback_); |
| 802 } | 796 } |
| 803 | 797 |
| 804 int SocketStream::DoWriteTunnelHeadersComplete(int result) { | 798 int SocketStream::DoWriteTunnelHeadersComplete(int result) { |
| 805 DCHECK_EQ(kTunnelProxy, proxy_mode_); | 799 DCHECK_EQ(kTunnelProxy, proxy_mode_); |
| 806 | 800 |
| 807 if (result < 0) { | 801 if (result < 0) { |
| 808 next_state_ = STATE_CLOSE; | 802 next_state_ = STATE_CLOSE; |
| 809 return result; | 803 return result; |
| 810 } | 804 } |
| 811 | 805 |
| 812 tunnel_request_headers_bytes_sent_ += result; | 806 tunnel_request_headers_bytes_sent_ += result; |
| 813 if (tunnel_request_headers_bytes_sent_ < | 807 if (tunnel_request_headers_bytes_sent_ < |
| 814 tunnel_request_headers_->headers_.size()) { | 808 tunnel_request_headers_->headers_.size()) { |
| 815 next_state_ = STATE_WRITE_TUNNEL_HEADERS; | 809 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
| 816 } else { | 810 } else { |
| 817 // Handling a cert error or a client cert request requires reconnection. | 811 // Handling a cert error or a client cert request requires reconnection. |
| 818 // DoWriteTunnelHeaders() will be called again. | 812 // DoWriteTunnelHeaders() will be called again. |
| 819 // Thus |tunnel_request_headers_bytes_sent_| should be reset to 0 for | 813 // Thus |tunnel_request_headers_bytes_sent_| should be reset to 0 for |
| 820 // sending |tunnel_request_headers_| correctly. | 814 // sending |tunnel_request_headers_| correctly. |
| 821 tunnel_request_headers_bytes_sent_ = 0; | 815 tunnel_request_headers_bytes_sent_ = 0; |
| 822 next_state_ = STATE_READ_TUNNEL_HEADERS; | 816 next_state_ = STATE_READ_TUNNEL_HEADERS; |
| 823 } | 817 } |
| 824 return OK; | 818 return OK; |
| 825 } | 819 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 892 next_state_ = STATE_CLOSE; | 886 next_state_ = STATE_CLOSE; |
| 893 return result; | 887 return result; |
| 894 } | 888 } |
| 895 if ((eoh < tunnel_response_headers_len_) && delegate_) | 889 if ((eoh < tunnel_response_headers_len_) && delegate_) |
| 896 delegate_->OnReceivedData( | 890 delegate_->OnReceivedData( |
| 897 this, tunnel_response_headers_->headers() + eoh, | 891 this, tunnel_response_headers_->headers() + eoh, |
| 898 tunnel_response_headers_len_ - eoh); | 892 tunnel_response_headers_len_ - eoh); |
| 899 } | 893 } |
| 900 return OK; | 894 return OK; |
| 901 case 407: // Proxy Authentication Required. | 895 case 407: // Proxy Authentication Required. |
| 902 result = HandleAuthChallenge(headers.get()); | 896 if (proxy_mode_ != kTunnelProxy) |
| 903 if (result == ERR_PROXY_AUTH_UNSUPPORTED && | 897 return ERR_UNEXPECTED_PROXY_AUTH; |
| 904 auth_handler_.get() && delegate_) { | 898 |
| 899 result = proxy_auth_controller_->HandleAuthChallenge( |
| 900 headers, false, true, net_log_); |
| 901 if (result == OK && delegate_) { |
| 905 DCHECK(!proxy_info_.is_empty()); | 902 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. | 903 // Wait until RestartWithAuth or Close is called. |
| 913 MessageLoop::current()->PostTask( | 904 MessageLoop::current()->PostTask( |
| 914 FROM_HERE, | 905 FROM_HERE, |
| 915 base::Bind(&SocketStream::DoAuthRequired, this)); | 906 base::Bind(&SocketStream::DoAuthRequired, this)); |
| 916 next_state_ = STATE_AUTH_REQUIRED; | 907 next_state_ = STATE_AUTH_REQUIRED; |
| 917 return ERR_IO_PENDING; | 908 return ERR_IO_PENDING; |
| 918 } | 909 } |
| 910 break; |
| 919 default: | 911 default: |
| 920 break; | 912 break; |
| 921 } | 913 } |
| 922 next_state_ = STATE_CLOSE; | 914 next_state_ = STATE_CLOSE; |
| 923 return ERR_TUNNEL_CONNECTION_FAILED; | 915 return ERR_TUNNEL_CONNECTION_FAILED; |
| 924 } | 916 } |
| 925 | 917 |
| 926 int SocketStream::DoSOCKSConnect() { | 918 int SocketStream::DoSOCKSConnect() { |
| 927 DCHECK_EQ(kSOCKSProxy, proxy_mode_); | 919 DCHECK_EQ(kSOCKSProxy, proxy_mode_); |
| 928 | 920 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 | 964 |
| 973 int SocketStream::DoSecureProxyConnectComplete(int result) { | 965 int SocketStream::DoSecureProxyConnectComplete(int result) { |
| 974 DCHECK_EQ(STATE_NONE, next_state_); | 966 DCHECK_EQ(STATE_NONE, next_state_); |
| 975 // Reconnect with client authentication. | 967 // Reconnect with client authentication. |
| 976 if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) | 968 if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) |
| 977 return HandleCertificateRequest(result, &proxy_ssl_config_); | 969 return HandleCertificateRequest(result, &proxy_ssl_config_); |
| 978 | 970 |
| 979 if (IsCertificateError(result)) | 971 if (IsCertificateError(result)) |
| 980 next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR; | 972 next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR; |
| 981 else if (result == OK) | 973 else if (result == OK) |
| 982 next_state_ = STATE_WRITE_TUNNEL_HEADERS; | 974 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
| 983 else | 975 else |
| 984 next_state_ = STATE_CLOSE; | 976 next_state_ = STATE_CLOSE; |
| 985 return result; | 977 return result; |
| 986 } | 978 } |
| 987 | 979 |
| 988 int SocketStream::DoSecureProxyHandleCertError(int result) { | 980 int SocketStream::DoSecureProxyHandleCertError(int result) { |
| 989 DCHECK_EQ(STATE_NONE, next_state_); | 981 DCHECK_EQ(STATE_NONE, next_state_); |
| 990 DCHECK(IsCertificateError(result)); | 982 DCHECK(IsCertificateError(result)); |
| 991 result = HandleCertificateError(result); | 983 result = HandleCertificateError(result); |
| 992 if (result == ERR_IO_PENDING) | 984 if (result == ERR_IO_PENDING) |
| 993 next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE; | 985 next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE; |
| 994 else | 986 else |
| 995 next_state_ = STATE_CLOSE; | 987 next_state_ = STATE_CLOSE; |
| 996 return result; | 988 return result; |
| 997 } | 989 } |
| 998 | 990 |
| 999 int SocketStream::DoSecureProxyHandleCertErrorComplete(int result) { | 991 int SocketStream::DoSecureProxyHandleCertErrorComplete(int result) { |
| 1000 DCHECK_EQ(STATE_NONE, next_state_); | 992 DCHECK_EQ(STATE_NONE, next_state_); |
| 1001 if (result == OK) { | 993 if (result == OK) { |
| 1002 if (!socket_->IsConnectedAndIdle()) | 994 if (!socket_->IsConnectedAndIdle()) |
| 1003 return AllowCertErrorForReconnection(&proxy_ssl_config_); | 995 return AllowCertErrorForReconnection(&proxy_ssl_config_); |
| 1004 next_state_ = STATE_WRITE_TUNNEL_HEADERS; | 996 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
| 1005 } else { | 997 } else { |
| 1006 next_state_ = STATE_CLOSE; | 998 next_state_ = STATE_CLOSE; |
| 1007 } | 999 } |
| 1008 return result; | 1000 return result; |
| 1009 } | 1001 } |
| 1010 | 1002 |
| 1011 int SocketStream::DoSSLConnect() { | 1003 int SocketStream::DoSSLConnect() { |
| 1012 DCHECK(factory_); | 1004 DCHECK(factory_); |
| 1013 SSLClientSocketContext ssl_context; | 1005 SSLClientSocketContext ssl_context; |
| 1014 ssl_context.cert_verifier = cert_verifier_; | 1006 ssl_context.cert_verifier = cert_verifier_; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1137 // We arrived here when both operation is pending. | 1129 // We arrived here when both operation is pending. |
| 1138 return ERR_IO_PENDING; | 1130 return ERR_IO_PENDING; |
| 1139 } | 1131 } |
| 1140 | 1132 |
| 1141 GURL SocketStream::ProxyAuthOrigin() const { | 1133 GURL SocketStream::ProxyAuthOrigin() const { |
| 1142 DCHECK(!proxy_info_.is_empty()); | 1134 DCHECK(!proxy_info_.is_empty()); |
| 1143 return GURL("http://" + | 1135 return GURL("http://" + |
| 1144 proxy_info_.proxy_server().host_port_pair().ToString()); | 1136 proxy_info_.proxy_server().host_port_pair().ToString()); |
| 1145 } | 1137 } |
| 1146 | 1138 |
| 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) { | 1139 int SocketStream::HandleCertificateRequest(int result, SSLConfig* ssl_config) { |
| 1195 if (ssl_config->send_client_cert) | 1140 if (ssl_config->send_client_cert) |
| 1196 // We already have performed SSL client authentication once and failed. | 1141 // We already have performed SSL client authentication once and failed. |
| 1197 return result; | 1142 return result; |
| 1198 | 1143 |
| 1199 DCHECK(socket_.get()); | 1144 DCHECK(socket_.get()); |
| 1200 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo; | 1145 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo; |
| 1201 SSLClientSocket* ssl_socket = | 1146 SSLClientSocket* ssl_socket = |
| 1202 static_cast<SSLClientSocket*>(socket_.get()); | 1147 static_cast<SSLClientSocket*>(socket_.get()); |
| 1203 ssl_socket->GetSSLCertRequestInfo(cert_request_info); | 1148 ssl_socket->GetSSLCertRequestInfo(cert_request_info); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1264 bad_cert.cert_status = ssl_info.cert_status; | 1209 bad_cert.cert_status = ssl_info.cert_status; |
| 1265 ssl_config->allowed_bad_certs.push_back(bad_cert); | 1210 ssl_config->allowed_bad_certs.push_back(bad_cert); |
| 1266 // Restart connection ignoring the bad certificate. | 1211 // Restart connection ignoring the bad certificate. |
| 1267 socket_->Disconnect(); | 1212 socket_->Disconnect(); |
| 1268 socket_.reset(); | 1213 socket_.reset(); |
| 1269 next_state_ = STATE_TCP_CONNECT; | 1214 next_state_ = STATE_TCP_CONNECT; |
| 1270 return OK; | 1215 return OK; |
| 1271 } | 1216 } |
| 1272 | 1217 |
| 1273 void SocketStream::DoAuthRequired() { | 1218 void SocketStream::DoAuthRequired() { |
| 1274 if (delegate_ && auth_info_.get()) | 1219 if (delegate_ && proxy_auth_controller_.get()) |
| 1275 delegate_->OnAuthRequired(this, auth_info_.get()); | 1220 delegate_->OnAuthRequired(this, proxy_auth_controller_->auth_info().get()); |
| 1276 else | 1221 else |
| 1277 DoLoop(ERR_UNEXPECTED); | 1222 DoLoop(ERR_UNEXPECTED); |
| 1278 } | 1223 } |
| 1279 | 1224 |
| 1280 void SocketStream::DoRestartWithAuth() { | 1225 void SocketStream::DoRestartWithAuth() { |
| 1281 DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED); | 1226 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; | 1227 tunnel_request_headers_ = NULL; |
| 1290 tunnel_request_headers_bytes_sent_ = 0; | 1228 tunnel_request_headers_bytes_sent_ = 0; |
| 1291 tunnel_response_headers_ = NULL; | 1229 tunnel_response_headers_ = NULL; |
| 1292 tunnel_response_headers_capacity_ = 0; | 1230 tunnel_response_headers_capacity_ = 0; |
| 1293 tunnel_response_headers_len_ = 0; | 1231 tunnel_response_headers_len_ = 0; |
| 1294 | 1232 |
| 1295 next_state_ = STATE_TCP_CONNECT; | 1233 next_state_ = STATE_TCP_CONNECT; |
| 1296 DoLoop(OK); | 1234 DoLoop(OK); |
| 1297 } | 1235 } |
| 1298 | 1236 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1326 | 1264 |
| 1327 SSLConfigService* SocketStream::ssl_config_service() const { | 1265 SSLConfigService* SocketStream::ssl_config_service() const { |
| 1328 return context_->ssl_config_service(); | 1266 return context_->ssl_config_service(); |
| 1329 } | 1267 } |
| 1330 | 1268 |
| 1331 ProxyService* SocketStream::proxy_service() const { | 1269 ProxyService* SocketStream::proxy_service() const { |
| 1332 return context_->proxy_service(); | 1270 return context_->proxy_service(); |
| 1333 } | 1271 } |
| 1334 | 1272 |
| 1335 } // namespace net | 1273 } // namespace net |
| OLD | NEW |