| 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.url = url_; | 
|  | 752   request_info.method = "CONNECT"; | 
|  | 753   return proxy_auth_controller_->MaybeGenerateAuthToken( | 
|  | 754       &request_info, io_callback_, net_log_); | 
|  | 755 } | 
|  | 756 | 
|  | 757 int SocketStream::DoGenerateProxyAuthTokenComplete(int result) { | 
|  | 758   if (result != OK) { | 
|  | 759     next_state_ = STATE_CLOSE; | 
|  | 760     return result; | 
|  | 761   } | 
|  | 762 | 
|  | 763   next_state_ = STATE_WRITE_TUNNEL_HEADERS; | 
|  | 764   return result; | 
|  | 765 } | 
|  | 766 | 
| 733 int SocketStream::DoWriteTunnelHeaders() { | 767 int SocketStream::DoWriteTunnelHeaders() { | 
| 734   DCHECK_EQ(kTunnelProxy, proxy_mode_); | 768   DCHECK_EQ(kTunnelProxy, proxy_mode_); | 
| 735 | 769 | 
| 736   next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE; | 770   next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE; | 
| 737 | 771 | 
| 738   if (!tunnel_request_headers_.get()) { | 772   if (!tunnel_request_headers_.get()) { | 
| 739     metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION); | 773     metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION); | 
| 740     tunnel_request_headers_ = new RequestHeaders(); | 774     tunnel_request_headers_ = new RequestHeaders(); | 
| 741     tunnel_request_headers_bytes_sent_ = 0; | 775     tunnel_request_headers_bytes_sent_ = 0; | 
| 742   } | 776   } | 
| 743   if (tunnel_request_headers_->headers_.empty()) { | 777   if (tunnel_request_headers_->headers_.empty()) { | 
| 744     std::string authorization_headers; | 778     HttpRequestHeaders request_headers; | 
| 745 | 779     request_headers.SetHeader("Host", GetHostAndOptionalPort(url_)); | 
| 746     if (!auth_handler_.get()) { | 780     request_headers.SetHeader("Proxy-Connection", "keep-alive"); | 
| 747       // Do preemptive authentication. | 781     if (proxy_auth_controller_.get() && proxy_auth_controller_->HaveAuth()) | 
| 748       HttpAuthCache::Entry* entry = auth_cache_.LookupByPath( | 782       proxy_auth_controller_->AddAuthorizationHeader(&request_headers); | 
| 749           ProxyAuthOrigin(), std::string()); |  | 
| 750       if (entry) { |  | 
| 751         scoped_ptr<HttpAuthHandler> handler_preemptive; |  | 
| 752         int rv_create = http_auth_handler_factory_-> |  | 
| 753             CreatePreemptiveAuthHandlerFromString( |  | 
| 754                 entry->auth_challenge(), HttpAuth::AUTH_PROXY, |  | 
| 755                 ProxyAuthOrigin(), entry->IncrementNonceCount(), |  | 
| 756                 net_log_, &handler_preemptive); |  | 
| 757         if (rv_create == OK) { |  | 
| 758           auth_identity_.source = HttpAuth::IDENT_SRC_PATH_LOOKUP; |  | 
| 759           auth_identity_.invalid = false; |  | 
| 760           auth_identity_.credentials = AuthCredentials(); |  | 
| 761           auth_handler_.swap(handler_preemptive); |  | 
| 762         } |  | 
| 763       } |  | 
| 764     } |  | 
| 765 |  | 
| 766     // Support basic authentication scheme only, because we don't have |  | 
| 767     // HttpRequestInfo. |  | 
| 768     // TODO(ukai): Add support other authentication scheme. |  | 
| 769     if (auth_handler_.get() && |  | 
| 770         auth_handler_->auth_scheme() == HttpAuth::AUTH_SCHEME_BASIC) { |  | 
| 771       HttpRequestInfo request_info; |  | 
| 772       std::string auth_token; |  | 
| 773       int rv = auth_handler_->GenerateAuthToken( |  | 
| 774           &auth_identity_.credentials, |  | 
| 775           &request_info, |  | 
| 776           CompletionCallback(), |  | 
| 777           &auth_token); |  | 
| 778       // TODO(cbentzel): Support async auth handlers. |  | 
| 779       DCHECK_NE(ERR_IO_PENDING, rv); |  | 
| 780       if (rv != OK) |  | 
| 781         return rv; |  | 
| 782       authorization_headers.append( |  | 
| 783           HttpAuth::GetAuthorizationHeaderName(HttpAuth::AUTH_PROXY) + |  | 
| 784           ": " + auth_token + "\r\n"); |  | 
| 785     } |  | 
| 786 |  | 
| 787     tunnel_request_headers_->headers_ = base::StringPrintf( | 783     tunnel_request_headers_->headers_ = base::StringPrintf( | 
| 788         "CONNECT %s HTTP/1.1\r\n" | 784         "CONNECT %s HTTP/1.1\r\n" | 
| 789         "Host: %s\r\n" | 785         "%s", | 
| 790         "Proxy-Connection: keep-alive\r\n", |  | 
| 791         GetHostAndPort(url_).c_str(), | 786         GetHostAndPort(url_).c_str(), | 
| 792         GetHostAndOptionalPort(url_).c_str()); | 787         request_headers.ToString().c_str()); | 
| 793     if (!authorization_headers.empty()) |  | 
| 794       tunnel_request_headers_->headers_ += authorization_headers; |  | 
| 795     tunnel_request_headers_->headers_ += "\r\n"; |  | 
| 796   } | 788   } | 
| 797   tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_); | 789   tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_); | 
| 798   int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() - | 790   int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() - | 
| 799                                  tunnel_request_headers_bytes_sent_); | 791                                  tunnel_request_headers_bytes_sent_); | 
| 800   DCHECK_GT(buf_len, 0); | 792   DCHECK_GT(buf_len, 0); | 
| 801   return socket_->Write(tunnel_request_headers_, buf_len, io_callback_); | 793   return socket_->Write(tunnel_request_headers_, buf_len, io_callback_); | 
| 802 } | 794 } | 
| 803 | 795 | 
| 804 int SocketStream::DoWriteTunnelHeadersComplete(int result) { | 796 int SocketStream::DoWriteTunnelHeadersComplete(int result) { | 
| 805   DCHECK_EQ(kTunnelProxy, proxy_mode_); | 797   DCHECK_EQ(kTunnelProxy, proxy_mode_); | 
| 806 | 798 | 
| 807   if (result < 0) { | 799   if (result < 0) { | 
| 808     next_state_ = STATE_CLOSE; | 800     next_state_ = STATE_CLOSE; | 
| 809     return result; | 801     return result; | 
| 810   } | 802   } | 
| 811 | 803 | 
| 812   tunnel_request_headers_bytes_sent_ += result; | 804   tunnel_request_headers_bytes_sent_ += result; | 
| 813   if (tunnel_request_headers_bytes_sent_ < | 805   if (tunnel_request_headers_bytes_sent_ < | 
| 814       tunnel_request_headers_->headers_.size()) { | 806       tunnel_request_headers_->headers_.size()) { | 
| 815     next_state_ = STATE_WRITE_TUNNEL_HEADERS; | 807     next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | 
| 816   } else { | 808   } else { | 
| 817     // Handling a cert error or a client cert request requires reconnection. | 809     // Handling a cert error or a client cert request requires reconnection. | 
| 818     // DoWriteTunnelHeaders() will be called again. | 810     // DoWriteTunnelHeaders() will be called again. | 
| 819     // Thus |tunnel_request_headers_bytes_sent_| should be reset to 0 for | 811     // Thus |tunnel_request_headers_bytes_sent_| should be reset to 0 for | 
| 820     // sending |tunnel_request_headers_| correctly. | 812     // sending |tunnel_request_headers_| correctly. | 
| 821     tunnel_request_headers_bytes_sent_ = 0; | 813     tunnel_request_headers_bytes_sent_ = 0; | 
| 822     next_state_ = STATE_READ_TUNNEL_HEADERS; | 814     next_state_ = STATE_READ_TUNNEL_HEADERS; | 
| 823   } | 815   } | 
| 824   return OK; | 816   return OK; | 
| 825 } | 817 } | 
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 892           next_state_ = STATE_CLOSE; | 884           next_state_ = STATE_CLOSE; | 
| 893           return result; | 885           return result; | 
| 894         } | 886         } | 
| 895         if ((eoh < tunnel_response_headers_len_) && delegate_) | 887         if ((eoh < tunnel_response_headers_len_) && delegate_) | 
| 896           delegate_->OnReceivedData( | 888           delegate_->OnReceivedData( | 
| 897               this, tunnel_response_headers_->headers() + eoh, | 889               this, tunnel_response_headers_->headers() + eoh, | 
| 898               tunnel_response_headers_len_ - eoh); | 890               tunnel_response_headers_len_ - eoh); | 
| 899       } | 891       } | 
| 900       return OK; | 892       return OK; | 
| 901     case 407:  // Proxy Authentication Required. | 893     case 407:  // Proxy Authentication Required. | 
| 902       result = HandleAuthChallenge(headers.get()); | 894       if (proxy_mode_ != kTunnelProxy) | 
| 903       if (result == ERR_PROXY_AUTH_UNSUPPORTED && | 895         return ERR_UNEXPECTED_PROXY_AUTH; | 
| 904           auth_handler_.get() && delegate_) { | 896 | 
| 905         DCHECK(!proxy_info_.is_empty()); | 897       result = proxy_auth_controller_->HandleAuthChallenge( | 
| 906         auth_info_ = new AuthChallengeInfo; | 898           headers, false, true, net_log_); | 
| 907         auth_info_->is_proxy = true; | 899       if (result != OK) | 
| 908         auth_info_->challenger = proxy_info_.proxy_server().host_port_pair(); | 900         return result; | 
| 909         auth_info_->scheme = HttpAuth::SchemeToString( | 901       DCHECK(!proxy_info_.is_empty()); | 
| 910             auth_handler_->auth_scheme()); | 902       next_state_ = STATE_AUTH_REQUIRED; | 
| 911         auth_info_->realm = auth_handler_->realm(); | 903       if (proxy_auth_controller_->HaveAuth()) { | 
|  | 904         MessageLoop::current()->PostTask( | 
|  | 905             FROM_HERE, | 
|  | 906             base::Bind(&SocketStream::DoRestartWithAuth, this)); | 
|  | 907         return ERR_IO_PENDING; | 
|  | 908       } | 
|  | 909       if (delegate_) { | 
| 912         // Wait until RestartWithAuth or Close is called. | 910         // Wait until RestartWithAuth or Close is called. | 
| 913         MessageLoop::current()->PostTask( | 911         MessageLoop::current()->PostTask( | 
| 914             FROM_HERE, | 912             FROM_HERE, | 
| 915             base::Bind(&SocketStream::DoAuthRequired, this)); | 913             base::Bind(&SocketStream::DoAuthRequired, this)); | 
| 916         next_state_ = STATE_AUTH_REQUIRED; |  | 
| 917         return ERR_IO_PENDING; | 914         return ERR_IO_PENDING; | 
| 918       } | 915       } | 
|  | 916       break; | 
| 919     default: | 917     default: | 
| 920       break; | 918       break; | 
| 921   } | 919   } | 
| 922   next_state_ = STATE_CLOSE; | 920   next_state_ = STATE_CLOSE; | 
| 923   return ERR_TUNNEL_CONNECTION_FAILED; | 921   return ERR_TUNNEL_CONNECTION_FAILED; | 
| 924 } | 922 } | 
| 925 | 923 | 
| 926 int SocketStream::DoSOCKSConnect() { | 924 int SocketStream::DoSOCKSConnect() { | 
| 927   DCHECK_EQ(kSOCKSProxy, proxy_mode_); | 925   DCHECK_EQ(kSOCKSProxy, proxy_mode_); | 
| 928 | 926 | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 972 | 970 | 
| 973 int SocketStream::DoSecureProxyConnectComplete(int result) { | 971 int SocketStream::DoSecureProxyConnectComplete(int result) { | 
| 974   DCHECK_EQ(STATE_NONE, next_state_); | 972   DCHECK_EQ(STATE_NONE, next_state_); | 
| 975   // Reconnect with client authentication. | 973   // Reconnect with client authentication. | 
| 976   if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) | 974   if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) | 
| 977     return HandleCertificateRequest(result, &proxy_ssl_config_); | 975     return HandleCertificateRequest(result, &proxy_ssl_config_); | 
| 978 | 976 | 
| 979   if (IsCertificateError(result)) | 977   if (IsCertificateError(result)) | 
| 980     next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR; | 978     next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR; | 
| 981   else if (result == OK) | 979   else if (result == OK) | 
| 982     next_state_ = STATE_WRITE_TUNNEL_HEADERS; | 980     next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | 
| 983   else | 981   else | 
| 984     next_state_ = STATE_CLOSE; | 982     next_state_ = STATE_CLOSE; | 
| 985   return result; | 983   return result; | 
| 986 } | 984 } | 
| 987 | 985 | 
| 988 int SocketStream::DoSecureProxyHandleCertError(int result) { | 986 int SocketStream::DoSecureProxyHandleCertError(int result) { | 
| 989   DCHECK_EQ(STATE_NONE, next_state_); | 987   DCHECK_EQ(STATE_NONE, next_state_); | 
| 990   DCHECK(IsCertificateError(result)); | 988   DCHECK(IsCertificateError(result)); | 
| 991   result = HandleCertificateError(result); | 989   result = HandleCertificateError(result); | 
| 992   if (result == ERR_IO_PENDING) | 990   if (result == ERR_IO_PENDING) | 
| 993     next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE; | 991     next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE; | 
| 994   else | 992   else | 
| 995     next_state_ = STATE_CLOSE; | 993     next_state_ = STATE_CLOSE; | 
| 996   return result; | 994   return result; | 
| 997 } | 995 } | 
| 998 | 996 | 
| 999 int SocketStream::DoSecureProxyHandleCertErrorComplete(int result) { | 997 int SocketStream::DoSecureProxyHandleCertErrorComplete(int result) { | 
| 1000   DCHECK_EQ(STATE_NONE, next_state_); | 998   DCHECK_EQ(STATE_NONE, next_state_); | 
| 1001   if (result == OK) { | 999   if (result == OK) { | 
| 1002     if (!socket_->IsConnectedAndIdle()) | 1000     if (!socket_->IsConnectedAndIdle()) | 
| 1003       return AllowCertErrorForReconnection(&proxy_ssl_config_); | 1001       return AllowCertErrorForReconnection(&proxy_ssl_config_); | 
| 1004     next_state_ = STATE_WRITE_TUNNEL_HEADERS; | 1002     next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | 
| 1005   } else { | 1003   } else { | 
| 1006     next_state_ = STATE_CLOSE; | 1004     next_state_ = STATE_CLOSE; | 
| 1007   } | 1005   } | 
| 1008   return result; | 1006   return result; | 
| 1009 } | 1007 } | 
| 1010 | 1008 | 
| 1011 int SocketStream::DoSSLConnect() { | 1009 int SocketStream::DoSSLConnect() { | 
| 1012   DCHECK(factory_); | 1010   DCHECK(factory_); | 
| 1013   SSLClientSocketContext ssl_context; | 1011   SSLClientSocketContext ssl_context; | 
| 1014   ssl_context.cert_verifier = cert_verifier_; | 1012   ssl_context.cert_verifier = cert_verifier_; | 
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1137   // We arrived here when both operation is pending. | 1135   // We arrived here when both operation is pending. | 
| 1138   return ERR_IO_PENDING; | 1136   return ERR_IO_PENDING; | 
| 1139 } | 1137 } | 
| 1140 | 1138 | 
| 1141 GURL SocketStream::ProxyAuthOrigin() const { | 1139 GURL SocketStream::ProxyAuthOrigin() const { | 
| 1142   DCHECK(!proxy_info_.is_empty()); | 1140   DCHECK(!proxy_info_.is_empty()); | 
| 1143   return GURL("http://" + | 1141   return GURL("http://" + | 
| 1144               proxy_info_.proxy_server().host_port_pair().ToString()); | 1142               proxy_info_.proxy_server().host_port_pair().ToString()); | 
| 1145 } | 1143 } | 
| 1146 | 1144 | 
| 1147 int SocketStream::HandleAuthChallenge(const HttpResponseHeaders* headers) { |  | 
| 1148   GURL auth_origin(ProxyAuthOrigin()); |  | 
| 1149 |  | 
| 1150   VLOG(1) << "The proxy " << auth_origin << " requested auth"; |  | 
| 1151 |  | 
| 1152   // TODO(cbentzel): Since SocketStream only suppports basic authentication |  | 
| 1153   // right now, another challenge is always treated as a rejection. |  | 
| 1154   // Ultimately this should be converted to use HttpAuthController like the |  | 
| 1155   // HttpNetworkTransaction has. |  | 
| 1156   if (auth_handler_.get() && !auth_identity_.invalid) { |  | 
| 1157     if (auth_identity_.source != HttpAuth::IDENT_SRC_PATH_LOOKUP) |  | 
| 1158       auth_cache_.Remove(auth_origin, |  | 
| 1159                          auth_handler_->realm(), |  | 
| 1160                          auth_handler_->auth_scheme(), |  | 
| 1161                          auth_identity_.credentials); |  | 
| 1162     auth_handler_.reset(); |  | 
| 1163     auth_identity_ = HttpAuth::Identity(); |  | 
| 1164   } |  | 
| 1165 |  | 
| 1166   auth_identity_.invalid = true; |  | 
| 1167   std::set<HttpAuth::Scheme> disabled_schemes; |  | 
| 1168   HttpAuth::ChooseBestChallenge(http_auth_handler_factory_, headers, |  | 
| 1169                                 HttpAuth::AUTH_PROXY, |  | 
| 1170                                 auth_origin, disabled_schemes, |  | 
| 1171                                 net_log_, &auth_handler_); |  | 
| 1172   if (!auth_handler_.get()) { |  | 
| 1173     LOG(ERROR) << "Can't perform auth to the proxy " << auth_origin; |  | 
| 1174     return ERR_TUNNEL_CONNECTION_FAILED; |  | 
| 1175   } |  | 
| 1176   if (auth_handler_->NeedsIdentity()) { |  | 
| 1177     // We only support basic authentication scheme now. |  | 
| 1178     // TODO(ukai): Support other authentication scheme. |  | 
| 1179     HttpAuthCache::Entry* entry = auth_cache_.Lookup( |  | 
| 1180         auth_origin, auth_handler_->realm(), HttpAuth::AUTH_SCHEME_BASIC); |  | 
| 1181     if (entry) { |  | 
| 1182       auth_identity_.source = HttpAuth::IDENT_SRC_REALM_LOOKUP; |  | 
| 1183       auth_identity_.invalid = false; |  | 
| 1184       auth_identity_.credentials = AuthCredentials(); |  | 
| 1185       // Restart with auth info. |  | 
| 1186     } |  | 
| 1187     return ERR_PROXY_AUTH_UNSUPPORTED; |  | 
| 1188   } else { |  | 
| 1189     auth_identity_.invalid = false; |  | 
| 1190   } |  | 
| 1191   return ERR_TUNNEL_CONNECTION_FAILED; |  | 
| 1192 } |  | 
| 1193 |  | 
| 1194 int SocketStream::HandleCertificateRequest(int result, SSLConfig* ssl_config) { | 1145 int SocketStream::HandleCertificateRequest(int result, SSLConfig* ssl_config) { | 
| 1195   if (ssl_config->send_client_cert) | 1146   if (ssl_config->send_client_cert) | 
| 1196     // We already have performed SSL client authentication once and failed. | 1147     // We already have performed SSL client authentication once and failed. | 
| 1197     return result; | 1148     return result; | 
| 1198 | 1149 | 
| 1199   DCHECK(socket_.get()); | 1150   DCHECK(socket_.get()); | 
| 1200   scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo; | 1151   scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo; | 
| 1201   SSLClientSocket* ssl_socket = | 1152   SSLClientSocket* ssl_socket = | 
| 1202       static_cast<SSLClientSocket*>(socket_.get()); | 1153       static_cast<SSLClientSocket*>(socket_.get()); | 
| 1203   ssl_socket->GetSSLCertRequestInfo(cert_request_info); | 1154   ssl_socket->GetSSLCertRequestInfo(cert_request_info); | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1264   bad_cert.cert_status = ssl_info.cert_status; | 1215   bad_cert.cert_status = ssl_info.cert_status; | 
| 1265   ssl_config->allowed_bad_certs.push_back(bad_cert); | 1216   ssl_config->allowed_bad_certs.push_back(bad_cert); | 
| 1266   // Restart connection ignoring the bad certificate. | 1217   // Restart connection ignoring the bad certificate. | 
| 1267   socket_->Disconnect(); | 1218   socket_->Disconnect(); | 
| 1268   socket_.reset(); | 1219   socket_.reset(); | 
| 1269   next_state_ = STATE_TCP_CONNECT; | 1220   next_state_ = STATE_TCP_CONNECT; | 
| 1270   return OK; | 1221   return OK; | 
| 1271 } | 1222 } | 
| 1272 | 1223 | 
| 1273 void SocketStream::DoAuthRequired() { | 1224 void SocketStream::DoAuthRequired() { | 
| 1274   if (delegate_ && auth_info_.get()) | 1225   if (delegate_ && proxy_auth_controller_.get()) | 
| 1275     delegate_->OnAuthRequired(this, auth_info_.get()); | 1226     delegate_->OnAuthRequired(this, proxy_auth_controller_->auth_info().get()); | 
| 1276   else | 1227   else | 
| 1277     DoLoop(ERR_UNEXPECTED); | 1228     DoLoop(ERR_UNEXPECTED); | 
| 1278 } | 1229 } | 
| 1279 | 1230 | 
| 1280 void SocketStream::DoRestartWithAuth() { | 1231 void SocketStream::DoRestartWithAuth() { | 
| 1281   DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED); | 1232   DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED); | 
| 1282   auth_cache_.Add(ProxyAuthOrigin(), |  | 
| 1283                   auth_handler_->realm(), |  | 
| 1284                   auth_handler_->auth_scheme(), |  | 
| 1285                   auth_handler_->challenge(), |  | 
| 1286                   auth_identity_.credentials, |  | 
| 1287                   std::string()); |  | 
| 1288 |  | 
| 1289   tunnel_request_headers_ = NULL; | 1233   tunnel_request_headers_ = NULL; | 
| 1290   tunnel_request_headers_bytes_sent_ = 0; | 1234   tunnel_request_headers_bytes_sent_ = 0; | 
| 1291   tunnel_response_headers_ = NULL; | 1235   tunnel_response_headers_ = NULL; | 
| 1292   tunnel_response_headers_capacity_ = 0; | 1236   tunnel_response_headers_capacity_ = 0; | 
| 1293   tunnel_response_headers_len_ = 0; | 1237   tunnel_response_headers_len_ = 0; | 
| 1294 | 1238 | 
| 1295   next_state_ = STATE_TCP_CONNECT; | 1239   next_state_ = STATE_TCP_CONNECT; | 
| 1296   DoLoop(OK); | 1240   DoLoop(OK); | 
| 1297 } | 1241 } | 
| 1298 | 1242 | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 1326 | 1270 | 
| 1327 SSLConfigService* SocketStream::ssl_config_service() const { | 1271 SSLConfigService* SocketStream::ssl_config_service() const { | 
| 1328   return context_->ssl_config_service(); | 1272   return context_->ssl_config_service(); | 
| 1329 } | 1273 } | 
| 1330 | 1274 | 
| 1331 ProxyService* SocketStream::proxy_service() const { | 1275 ProxyService* SocketStream::proxy_service() const { | 
| 1332   return context_->proxy_service(); | 1276   return context_->proxy_service(); | 
| 1333 } | 1277 } | 
| 1334 | 1278 | 
| 1335 }  // namespace net | 1279 }  // namespace net | 
| OLD | NEW | 
|---|