Home | History | Annotate | Download | only in socket_stream
      1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 //
      5 // TODO(ukai): code is similar with http_network_transaction.cc.  We should
      6 //   think about ways to share code, if possible.
      7 
      8 #include "net/socket_stream/socket_stream.h"
      9 
     10 #include <string>
     11 
     12 #include "base/compiler_specific.h"
     13 #include "base/logging.h"
     14 #include "base/message_loop.h"
     15 #include "base/string_util.h"
     16 #include "net/base/auth.h"
     17 #include "net/base/host_resolver.h"
     18 #include "net/base/io_buffer.h"
     19 #include "net/base/net_errors.h"
     20 #include "net/base/net_util.h"
     21 #include "net/http/http_response_headers.h"
     22 #include "net/http/http_util.h"
     23 #include "net/socket/client_socket_factory.h"
     24 #include "net/socket/ssl_client_socket.h"
     25 #include "net/socket/socks5_client_socket.h"
     26 #include "net/socket/socks_client_socket.h"
     27 #include "net/socket/tcp_client_socket.h"
     28 #include "net/socket_stream/socket_stream_metrics.h"
     29 #include "net/socket_stream/socket_stream_throttle.h"
     30 #include "net/url_request/url_request.h"
     31 
     32 static const int kMaxPendingSendAllowed = 32768;  // 32 kilobytes.
     33 static const int kReadBufferSize = 4096;
     34 
     35 namespace net {
     36 
     37 void SocketStream::ResponseHeaders::Realloc(size_t new_size) {
     38   headers_.reset(static_cast<char*>(realloc(headers_.release(), new_size)));
     39 }
     40 
     41 SocketStream::SocketStream(const GURL& url, Delegate* delegate)
     42     : url_(url),
     43       delegate_(delegate),
     44       max_pending_send_allowed_(kMaxPendingSendAllowed),
     45       next_state_(STATE_NONE),
     46       factory_(ClientSocketFactory::GetDefaultFactory()),
     47       proxy_mode_(kDirectConnection),
     48       proxy_url_(url),
     49       pac_request_(NULL),
     50       ALLOW_THIS_IN_INITIALIZER_LIST(
     51           io_callback_(this, &SocketStream::OnIOCompleted)),
     52       ALLOW_THIS_IN_INITIALIZER_LIST(
     53           read_callback_(this, &SocketStream::OnReadCompleted)),
     54       ALLOW_THIS_IN_INITIALIZER_LIST(
     55           write_callback_(this, &SocketStream::OnWriteCompleted)),
     56       read_buf_(NULL),
     57       write_buf_(NULL),
     58       current_write_buf_(NULL),
     59       write_buf_offset_(0),
     60       write_buf_size_(0),
     61       throttle_(
     62           SocketStreamThrottle::GetSocketStreamThrottleForScheme(
     63               url.scheme())),
     64       metrics_(new SocketStreamMetrics(url)),
     65       ALLOW_THIS_IN_INITIALIZER_LIST(
     66           request_tracker_node_(this)) {
     67   DCHECK(MessageLoop::current()) <<
     68       "The current MessageLoop must exist";
     69   DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
     70       "The current MessageLoop must be TYPE_IO";
     71   DCHECK(delegate_);
     72   DCHECK(throttle_);
     73 }
     74 
     75 SocketStream::~SocketStream() {
     76   set_context(NULL);
     77   DCHECK(!delegate_);
     78 }
     79 
     80 SocketStream::UserData* SocketStream::GetUserData(
     81     const void* key) const {
     82   UserDataMap::const_iterator found = user_data_.find(key);
     83   if (found != user_data_.end())
     84     return found->second.get();
     85   return NULL;
     86 }
     87 
     88 void SocketStream::SetUserData(const void* key, UserData* data) {
     89   user_data_[key] = linked_ptr<UserData>(data);
     90 }
     91 
     92 void SocketStream::set_context(URLRequestContext* context) {
     93   scoped_refptr<URLRequestContext> prev_context = context_;
     94 
     95   context_ = context;
     96 
     97   if (prev_context != context) {
     98     if (prev_context)
     99       prev_context->socket_stream_tracker()->Remove(this);
    100     if (context) {
    101       if (!load_log_) {
    102         // Create the LoadLog -- we waited until now to create it so we know
    103         // what constraints the URLRequestContext is enforcing on log levels.
    104         load_log_ = context->socket_stream_tracker()->CreateLoadLog();
    105       }
    106       context->socket_stream_tracker()->Add(this);
    107     }
    108   }
    109 
    110   if (context_)
    111     host_resolver_ = context_->host_resolver();
    112 
    113 }
    114 
    115 void SocketStream::Connect() {
    116   DCHECK(MessageLoop::current()) <<
    117       "The current MessageLoop must exist";
    118   DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
    119       "The current MessageLoop must be TYPE_IO";
    120   if (context_)
    121     ssl_config_service()->GetSSLConfig(&ssl_config_);
    122   DCHECK_EQ(next_state_, STATE_NONE);
    123 
    124   AddRef();  // Released in Finish()
    125   // Open a connection asynchronously, so that delegate won't be called
    126   // back before returning Connect().
    127   next_state_ = STATE_RESOLVE_PROXY;
    128   LoadLog::BeginEvent(load_log_, LoadLog::TYPE_SOCKET_STREAM_CONNECT);
    129   MessageLoop::current()->PostTask(
    130       FROM_HERE,
    131       NewRunnableMethod(this, &SocketStream::DoLoop, OK));
    132 }
    133 
    134 bool SocketStream::SendData(const char* data, int len) {
    135   DCHECK(MessageLoop::current()) <<
    136       "The current MessageLoop must exist";
    137   DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
    138       "The current MessageLoop must be TYPE_IO";
    139   if (!socket_.get() || !socket_->IsConnected() || next_state_ == STATE_NONE)
    140     return false;
    141   if (write_buf_) {
    142     int current_amount_send = write_buf_size_ - write_buf_offset_;
    143     for (PendingDataQueue::const_iterator iter = pending_write_bufs_.begin();
    144          iter != pending_write_bufs_.end();
    145          ++iter)
    146       current_amount_send += (*iter)->size();
    147 
    148     current_amount_send += len;
    149     if (current_amount_send > max_pending_send_allowed_)
    150       return false;
    151 
    152     pending_write_bufs_.push_back(new IOBufferWithSize(len));
    153     memcpy(pending_write_bufs_.back()->data(), data, len);
    154     return true;
    155   }
    156   DCHECK(!current_write_buf_);
    157   write_buf_ = new IOBuffer(len);
    158   memcpy(write_buf_->data(), data, len);
    159   write_buf_size_ = len;
    160   write_buf_offset_ = 0;
    161   // Send pending data asynchronously, so that delegate won't be called
    162   // back before returning SendData().
    163   MessageLoop::current()->PostTask(
    164       FROM_HERE,
    165       NewRunnableMethod(this, &SocketStream::DoLoop, OK));
    166   return true;
    167 }
    168 
    169 void SocketStream::Close() {
    170   DCHECK(MessageLoop::current()) <<
    171       "The current MessageLoop must exist";
    172   DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
    173       "The current MessageLoop must be TYPE_IO";
    174   if (!socket_.get() || !socket_->IsConnected() || next_state_ == STATE_NONE)
    175     return;
    176   socket_->Disconnect();
    177   next_state_ = STATE_CLOSE;
    178   // Close asynchronously, so that delegate won't be called
    179   // back before returning Close().
    180   MessageLoop::current()->PostTask(
    181       FROM_HERE,
    182       NewRunnableMethod(this, &SocketStream::DoLoop, OK));
    183 }
    184 
    185 void SocketStream::RestartWithAuth(
    186     const std::wstring& username, const std::wstring& password) {
    187   DCHECK(MessageLoop::current()) <<
    188       "The current MessageLoop must exist";
    189   DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
    190       "The current MessageLoop must be TYPE_IO";
    191   DCHECK(auth_handler_);
    192   if (!socket_.get()) {
    193     LOG(ERROR) << "Socket is closed before restarting with auth.";
    194     return;
    195   }
    196 
    197   if (auth_identity_.invalid) {
    198     // Update the username/password.
    199     auth_identity_.source = HttpAuth::IDENT_SRC_EXTERNAL;
    200     auth_identity_.invalid = false;
    201     auth_identity_.username = username;
    202     auth_identity_.password = password;
    203   }
    204 
    205   MessageLoop::current()->PostTask(
    206       FROM_HERE,
    207       NewRunnableMethod(this, &SocketStream::DoRestartWithAuth));
    208 }
    209 
    210 void SocketStream::DetachDelegate() {
    211   if (!delegate_)
    212     return;
    213   delegate_ = NULL;
    214   LoadLog::AddEvent(load_log_, LoadLog::TYPE_CANCELLED);
    215   Close();
    216 }
    217 
    218 void SocketStream::Finish(int result) {
    219   DCHECK(MessageLoop::current()) <<
    220       "The current MessageLoop must exist";
    221   DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
    222       "The current MessageLoop must be TYPE_IO";
    223   DCHECK_LE(result, OK);
    224   if (result == OK)
    225     result = ERR_CONNECTION_CLOSED;
    226   DCHECK_EQ(next_state_, STATE_NONE);
    227   DLOG(INFO) << "Finish result=" << net::ErrorToString(result);
    228   if (delegate_)
    229     delegate_->OnError(this, result);
    230 
    231   metrics_->OnClose();
    232   Delegate* delegate = delegate_;
    233   delegate_ = NULL;
    234   if (delegate) {
    235     delegate->OnClose(this);
    236   }
    237   throttle_->OnClose(this);
    238   Release();
    239 }
    240 
    241 void SocketStream::SetHostResolver(HostResolver* host_resolver) {
    242   DCHECK(host_resolver);
    243   host_resolver_ = host_resolver;
    244 }
    245 
    246 void SocketStream::SetClientSocketFactory(
    247     ClientSocketFactory* factory) {
    248   DCHECK(factory);
    249   factory_ = factory;
    250 }
    251 
    252 void SocketStream::CopyAddrInfo(struct addrinfo* head) {
    253   addresses_.Copy(head);
    254 }
    255 
    256 int SocketStream::DidEstablishConnection() {
    257   if (!socket_.get() || !socket_->IsConnected()) {
    258     next_state_ = STATE_CLOSE;
    259     return ERR_CONNECTION_FAILED;
    260   }
    261   next_state_ = STATE_READ_WRITE;
    262   metrics_->OnConnected();
    263 
    264   LoadLog::EndEvent(load_log_, LoadLog::TYPE_SOCKET_STREAM_CONNECT);
    265   if (delegate_)
    266     delegate_->OnConnected(this, max_pending_send_allowed_);
    267 
    268   return OK;
    269 }
    270 
    271 int SocketStream::DidReceiveData(int result) {
    272   DCHECK(read_buf_);
    273   DCHECK_GT(result, 0);
    274   LoadLog::AddEvent(load_log_, LoadLog::TYPE_SOCKET_STREAM_RECEIVED);
    275   int len = result;
    276   metrics_->OnRead(len);
    277   result = throttle_->OnRead(this, read_buf_->data(), len, &io_callback_);
    278   if (delegate_) {
    279     // Notify recevied data to delegate.
    280     delegate_->OnReceivedData(this, read_buf_->data(), len);
    281   }
    282   read_buf_ = NULL;
    283   return result;
    284 }
    285 
    286 int SocketStream::DidSendData(int result) {
    287   DCHECK_GT(result, 0);
    288   LoadLog::AddEvent(load_log_, LoadLog::TYPE_SOCKET_STREAM_SENT);
    289   int len = result;
    290   metrics_->OnWrite(len);
    291   result = throttle_->OnWrite(this, current_write_buf_->data(), len,
    292                               &io_callback_);
    293   current_write_buf_ = NULL;
    294   if (delegate_)
    295     delegate_->OnSentData(this, len);
    296 
    297   int remaining_size = write_buf_size_ - write_buf_offset_ - len;
    298   if (remaining_size == 0) {
    299     if (!pending_write_bufs_.empty()) {
    300       write_buf_size_ = pending_write_bufs_.front()->size();
    301       write_buf_ = pending_write_bufs_.front();
    302       pending_write_bufs_.pop_front();
    303     } else {
    304       write_buf_size_ = 0;
    305       write_buf_ = NULL;
    306     }
    307     write_buf_offset_ = 0;
    308   } else {
    309     write_buf_offset_ += len;
    310   }
    311   return result;
    312 }
    313 
    314 void SocketStream::OnIOCompleted(int result) {
    315   DoLoop(result);
    316 }
    317 
    318 void SocketStream::OnReadCompleted(int result) {
    319   if (result == 0) {
    320     // 0 indicates end-of-file, so socket was closed.
    321     next_state_ = STATE_CLOSE;
    322   } else if (result > 0 && read_buf_) {
    323     result = DidReceiveData(result);
    324   }
    325   DoLoop(result);
    326 }
    327 
    328 void SocketStream::OnWriteCompleted(int result) {
    329   if (result >= 0 && write_buf_) {
    330     result = DidSendData(result);
    331   }
    332   DoLoop(result);
    333 }
    334 
    335 void SocketStream::DoLoop(int result) {
    336   // If context was not set, close immediately.
    337   if (!context_)
    338     next_state_ = STATE_CLOSE;
    339 
    340   if (next_state_ == STATE_NONE)
    341     return;
    342 
    343   do {
    344     State state = next_state_;
    345     next_state_ = STATE_NONE;
    346     switch (state) {
    347       case STATE_RESOLVE_PROXY:
    348         DCHECK_EQ(OK, result);
    349         result = DoResolveProxy();
    350         break;
    351       case STATE_RESOLVE_PROXY_COMPLETE:
    352         result = DoResolveProxyComplete(result);
    353         break;
    354       case STATE_RESOLVE_HOST:
    355         DCHECK_EQ(OK, result);
    356         result = DoResolveHost();
    357         break;
    358       case STATE_RESOLVE_HOST_COMPLETE:
    359         result = DoResolveHostComplete(result);
    360         break;
    361       case STATE_TCP_CONNECT:
    362         DCHECK_EQ(OK, result);
    363         result = DoTcpConnect();
    364         break;
    365       case STATE_TCP_CONNECT_COMPLETE:
    366         result = DoTcpConnectComplete(result);
    367         break;
    368       case STATE_WRITE_TUNNEL_HEADERS:
    369         DCHECK_EQ(OK, result);
    370         result = DoWriteTunnelHeaders();
    371         break;
    372       case STATE_WRITE_TUNNEL_HEADERS_COMPLETE:
    373         result = DoWriteTunnelHeadersComplete(result);
    374         break;
    375       case STATE_READ_TUNNEL_HEADERS:
    376         DCHECK_EQ(OK, result);
    377         result = DoReadTunnelHeaders();
    378         break;
    379       case STATE_READ_TUNNEL_HEADERS_COMPLETE:
    380         result = DoReadTunnelHeadersComplete(result);
    381         break;
    382       case STATE_SOCKS_CONNECT:
    383         DCHECK_EQ(OK, result);
    384         result = DoSOCKSConnect();
    385         break;
    386       case STATE_SOCKS_CONNECT_COMPLETE:
    387         result = DoSOCKSConnectComplete(result);
    388         break;
    389       case STATE_SSL_CONNECT:
    390         DCHECK_EQ(OK, result);
    391         result = DoSSLConnect();
    392         break;
    393       case STATE_SSL_CONNECT_COMPLETE:
    394         result = DoSSLConnectComplete(result);
    395         break;
    396       case STATE_READ_WRITE:
    397         result = DoReadWrite(result);
    398         break;
    399       case STATE_CLOSE:
    400         DCHECK_LE(result, OK);
    401         Finish(result);
    402         return;
    403       default:
    404         NOTREACHED() << "bad state";
    405         Finish(result);
    406         return;
    407     }
    408     // If the connection is not established yet and had actual errors,
    409     // close the connection.
    410     if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) {
    411       DCHECK_EQ(next_state_, STATE_CLOSE);
    412       LoadLog::EndEvent(load_log_, LoadLog::TYPE_SOCKET_STREAM_CONNECT);
    413     }
    414   } while (result != ERR_IO_PENDING);
    415 }
    416 
    417 int SocketStream::DoResolveProxy() {
    418   DCHECK(!pac_request_);
    419   next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
    420 
    421   if (!proxy_url_.is_valid()) {
    422     next_state_ = STATE_CLOSE;
    423     return ERR_INVALID_ARGUMENT;
    424   }
    425 
    426   return proxy_service()->ResolveProxy(
    427       proxy_url_, &proxy_info_, &io_callback_, &pac_request_, load_log_);
    428 }
    429 
    430 int SocketStream::DoResolveProxyComplete(int result) {
    431   next_state_ = STATE_RESOLVE_HOST;
    432 
    433   pac_request_ = NULL;
    434   if (result != OK) {
    435     LOG(ERROR) << "Failed to resolve proxy: " << result;
    436     if (delegate_)
    437       delegate_->OnError(this, result);
    438     proxy_info_.UseDirect();
    439   }
    440   if (proxy_info_.is_direct()) {
    441     // If proxy was not found for original URL (i.e. websocket URL),
    442     // try again with https URL, like Safari implementation.
    443     // Note that we don't want to use http proxy, because we'll use tunnel
    444     // proxy using CONNECT method, which is used by https proxy.
    445     if (!proxy_url_.SchemeIs("https")) {
    446       const std::string scheme = "https";
    447       GURL::Replacements repl;
    448       repl.SetSchemeStr(scheme);
    449       proxy_url_ = url_.ReplaceComponents(repl);
    450       DLOG(INFO) << "Try https proxy: " << proxy_url_;
    451       next_state_ = STATE_RESOLVE_PROXY;
    452       return OK;
    453     }
    454   }
    455 
    456   return OK;
    457 }
    458 
    459 int SocketStream::DoResolveHost() {
    460   next_state_ = STATE_RESOLVE_HOST_COMPLETE;
    461 
    462   if (proxy_info_.is_direct())
    463     proxy_mode_ = kDirectConnection;
    464   else if (proxy_info_.proxy_server().is_socks())
    465     proxy_mode_ = kSOCKSProxy;
    466   else
    467     proxy_mode_ = kTunnelProxy;
    468 
    469   // Determine the host and port to connect to.
    470   std::string host;
    471   int port;
    472   if (proxy_mode_ != kDirectConnection) {
    473     ProxyServer proxy_server = proxy_info_.proxy_server();
    474     host = proxy_server.HostNoBrackets();
    475     port = proxy_server.port();
    476   } else {
    477     host = url_.HostNoBrackets();
    478     port = url_.EffectiveIntPort();
    479   }
    480 
    481   HostResolver::RequestInfo resolve_info(host, port);
    482 
    483   DCHECK(host_resolver_.get());
    484   resolver_.reset(new SingleRequestHostResolver(host_resolver_.get()));
    485   return resolver_->Resolve(resolve_info, &addresses_, &io_callback_,
    486                             load_log_);
    487 }
    488 
    489 int SocketStream::DoResolveHostComplete(int result) {
    490   if (result == OK) {
    491     next_state_ = STATE_TCP_CONNECT;
    492     result = throttle_->OnStartOpenConnection(this, &io_callback_);
    493     if (result == net::ERR_IO_PENDING)
    494       metrics_->OnWaitConnection();
    495   } else {
    496     next_state_ = STATE_CLOSE;
    497   }
    498   // TODO(ukai): if error occured, reconsider proxy after error.
    499   return result;
    500 }
    501 
    502 int SocketStream::DoTcpConnect() {
    503   next_state_ = STATE_TCP_CONNECT_COMPLETE;
    504   DCHECK(factory_);
    505   socket_.reset(factory_->CreateTCPClientSocket(addresses_));
    506   metrics_->OnStartConnection();
    507   return socket_->Connect(&io_callback_, load_log_);
    508 }
    509 
    510 int SocketStream::DoTcpConnectComplete(int result) {
    511   // TODO(ukai): if error occured, reconsider proxy after error.
    512   if (result != OK) {
    513     next_state_ = STATE_CLOSE;
    514     return result;
    515   }
    516 
    517   if (proxy_mode_ == kTunnelProxy)
    518     next_state_ = STATE_WRITE_TUNNEL_HEADERS;
    519   else if (proxy_mode_ == kSOCKSProxy)
    520     next_state_ = STATE_SOCKS_CONNECT;
    521   else if (is_secure()) {
    522     next_state_ = STATE_SSL_CONNECT;
    523   } else {
    524     result = DidEstablishConnection();
    525   }
    526   return result;
    527 }
    528 
    529 int SocketStream::DoWriteTunnelHeaders() {
    530   DCHECK_EQ(kTunnelProxy, proxy_mode_);
    531 
    532   next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE;
    533 
    534   if (!tunnel_request_headers_.get()) {
    535     metrics_->OnTunnelProxy();
    536     tunnel_request_headers_ = new RequestHeaders();
    537     tunnel_request_headers_bytes_sent_ = 0;
    538   }
    539   if (tunnel_request_headers_->headers_.empty()) {
    540     std::string authorization_headers;
    541 
    542     if (!auth_handler_.get()) {
    543       // First attempt.  Find auth from the proxy address.
    544       HttpAuthCache::Entry* entry = auth_cache_.LookupByPath(
    545           ProxyAuthOrigin(), std::string());
    546       if (entry && !entry->handler()->is_connection_based()) {
    547         auth_identity_.source = HttpAuth::IDENT_SRC_PATH_LOOKUP;
    548         auth_identity_.invalid = false;
    549         auth_identity_.username = entry->username();
    550         auth_identity_.password = entry->password();
    551         auth_handler_ = entry->handler();
    552       }
    553     }
    554 
    555     // Support basic authentication scheme only, because we don't have
    556     // HttpRequestInfo.
    557     // TODO(ukai): Add support other authentication scheme.
    558     if (auth_handler_.get() && auth_handler_->scheme() == "basic") {
    559       std::string credentials = auth_handler_->GenerateCredentials(
    560           auth_identity_.username,
    561           auth_identity_.password,
    562           NULL,
    563           &proxy_info_);
    564       authorization_headers.append(
    565           HttpAuth::GetAuthorizationHeaderName(HttpAuth::AUTH_PROXY) +
    566           ": " + credentials + "\r\n");
    567     }
    568 
    569     tunnel_request_headers_->headers_ = StringPrintf(
    570         "CONNECT %s HTTP/1.1\r\n"
    571         "Host: %s\r\n"
    572         "Proxy-Connection: keep-alive\r\n",
    573         GetHostAndPort(url_).c_str(),
    574         GetHostAndOptionalPort(url_).c_str());
    575     if (!authorization_headers.empty())
    576       tunnel_request_headers_->headers_ += authorization_headers;
    577     tunnel_request_headers_->headers_ += "\r\n";
    578   }
    579   tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_);
    580   int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() -
    581                                  tunnel_request_headers_bytes_sent_);
    582   DCHECK_GT(buf_len, 0);
    583   return socket_->Write(tunnel_request_headers_, buf_len, &io_callback_);
    584 }
    585 
    586 int SocketStream::DoWriteTunnelHeadersComplete(int result) {
    587   DCHECK_EQ(kTunnelProxy, proxy_mode_);
    588 
    589   if (result < 0) {
    590     next_state_ = STATE_CLOSE;
    591     return result;
    592   }
    593 
    594   tunnel_request_headers_bytes_sent_ += result;
    595   if (tunnel_request_headers_bytes_sent_ <
    596       tunnel_request_headers_->headers_.size())
    597     next_state_ = STATE_WRITE_TUNNEL_HEADERS;
    598   else
    599     next_state_ = STATE_READ_TUNNEL_HEADERS;
    600   return OK;
    601 }
    602 
    603 int SocketStream::DoReadTunnelHeaders() {
    604   DCHECK_EQ(kTunnelProxy, proxy_mode_);
    605 
    606   next_state_ = STATE_READ_TUNNEL_HEADERS_COMPLETE;
    607 
    608   if (!tunnel_response_headers_.get()) {
    609     tunnel_response_headers_ = new ResponseHeaders();
    610     tunnel_response_headers_capacity_ = kMaxTunnelResponseHeadersSize;
    611     tunnel_response_headers_->Realloc(tunnel_response_headers_capacity_);
    612     tunnel_response_headers_len_ = 0;
    613   }
    614 
    615   int buf_len = tunnel_response_headers_capacity_ -
    616       tunnel_response_headers_len_;
    617   tunnel_response_headers_->SetDataOffset(tunnel_response_headers_len_);
    618   CHECK(tunnel_response_headers_->data());
    619 
    620   return socket_->Read(tunnel_response_headers_, buf_len, &io_callback_);
    621 }
    622 
    623 int SocketStream::DoReadTunnelHeadersComplete(int result) {
    624   DCHECK_EQ(kTunnelProxy, proxy_mode_);
    625 
    626   if (result < 0) {
    627     next_state_ = STATE_CLOSE;
    628     return result;
    629   }
    630 
    631   if (result == 0) {
    632     // 0 indicates end-of-file, so socket was closed.
    633     next_state_ = STATE_CLOSE;
    634     return ERR_CONNECTION_CLOSED;
    635   }
    636 
    637   tunnel_response_headers_len_ += result;
    638   DCHECK(tunnel_response_headers_len_ <= tunnel_response_headers_capacity_);
    639 
    640   int eoh = HttpUtil::LocateEndOfHeaders(
    641       tunnel_response_headers_->headers(), tunnel_response_headers_len_, 0);
    642   if (eoh == -1) {
    643     if (tunnel_response_headers_len_ >= kMaxTunnelResponseHeadersSize) {
    644       next_state_ = STATE_CLOSE;
    645       return ERR_RESPONSE_HEADERS_TOO_BIG;
    646     }
    647 
    648     next_state_ = STATE_READ_TUNNEL_HEADERS;
    649     return OK;
    650   }
    651   // DidReadResponseHeaders
    652   scoped_refptr<HttpResponseHeaders> headers;
    653   headers = new HttpResponseHeaders(
    654       HttpUtil::AssembleRawHeaders(tunnel_response_headers_->headers(), eoh));
    655   if (headers->GetParsedHttpVersion() < HttpVersion(1, 0)) {
    656     // Require the "HTTP/1.x" status line.
    657     next_state_ = STATE_CLOSE;
    658     return ERR_TUNNEL_CONNECTION_FAILED;
    659   }
    660   switch (headers->response_code()) {
    661     case 200:  // OK
    662       if (is_secure()) {
    663         DCHECK_EQ(eoh, tunnel_response_headers_len_);
    664         next_state_ = STATE_SSL_CONNECT;
    665       } else {
    666         result = DidEstablishConnection();
    667         if (result < 0) {
    668           next_state_ = STATE_CLOSE;
    669           return result;
    670         }
    671         if ((eoh < tunnel_response_headers_len_) && delegate_)
    672           delegate_->OnReceivedData(
    673               this, tunnel_response_headers_->headers() + eoh,
    674               tunnel_response_headers_len_ - eoh);
    675       }
    676       return OK;
    677     case 407:  // Proxy Authentication Required.
    678       result = HandleAuthChallenge(headers.get());
    679       if (result == ERR_PROXY_AUTH_REQUESTED &&
    680           auth_handler_.get() && delegate_) {
    681         auth_info_ = new AuthChallengeInfo;
    682         auth_info_->is_proxy = true;
    683         auth_info_->host_and_port =
    684             ASCIIToWide(proxy_info_.proxy_server().host_and_port());
    685         auth_info_->scheme = ASCIIToWide(auth_handler_->scheme());
    686         auth_info_->realm = ASCIIToWide(auth_handler_->realm());
    687         // Wait until RestartWithAuth or Close is called.
    688         MessageLoop::current()->PostTask(
    689             FROM_HERE,
    690             NewRunnableMethod(this, &SocketStream::DoAuthRequired));
    691         next_state_ = STATE_AUTH_REQUIRED;
    692         return ERR_IO_PENDING;
    693       }
    694     default:
    695       break;
    696   }
    697   next_state_ = STATE_CLOSE;
    698   return ERR_TUNNEL_CONNECTION_FAILED;
    699 }
    700 
    701 int SocketStream::DoSOCKSConnect() {
    702   DCHECK_EQ(kSOCKSProxy, proxy_mode_);
    703 
    704   next_state_ = STATE_SOCKS_CONNECT_COMPLETE;
    705 
    706   ClientSocket* s = socket_.release();
    707   HostResolver::RequestInfo req_info(url_.HostNoBrackets(),
    708                                      url_.EffectiveIntPort());
    709 
    710   if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5)
    711     s = new SOCKS5ClientSocket(s, req_info);
    712   else
    713     s = new SOCKSClientSocket(s, req_info, host_resolver_.get());
    714   socket_.reset(s);
    715   metrics_->OnSOCKSProxy();
    716   return socket_->Connect(&io_callback_, load_log_);
    717 }
    718 
    719 int SocketStream::DoSOCKSConnectComplete(int result) {
    720   DCHECK_EQ(kSOCKSProxy, proxy_mode_);
    721 
    722   if (result == OK) {
    723     if (is_secure())
    724       next_state_ = STATE_SSL_CONNECT;
    725     else
    726       result = DidEstablishConnection();
    727   } else {
    728     next_state_ = STATE_CLOSE;
    729   }
    730   return result;
    731 }
    732 
    733 int SocketStream::DoSSLConnect() {
    734   DCHECK(factory_);
    735   socket_.reset(factory_->CreateSSLClientSocket(
    736       socket_.release(), url_.HostNoBrackets(), ssl_config_));
    737   next_state_ = STATE_SSL_CONNECT_COMPLETE;
    738   metrics_->OnSSLConnection();
    739   return socket_->Connect(&io_callback_, load_log_);
    740 }
    741 
    742 int SocketStream::DoSSLConnectComplete(int result) {
    743   if (IsCertificateError(result)) {
    744     if (socket_->IsConnectedAndIdle()) {
    745       result = HandleCertificateError(result);
    746     } else {
    747       // SSLClientSocket for Mac will report socket is not connected,
    748       // if it returns cert verification error.  It didn't perform
    749       // SSLHandshake yet.
    750       // So, we should restart establishing connection with the
    751       // certificate in allowed bad certificates in |ssl_config_|.
    752       // See also net/http/http_network_transaction.cc
    753       //  HandleCertificateError() and RestartIgnoringLastError().
    754       SSLClientSocket* ssl_socket =
    755         reinterpret_cast<SSLClientSocket*>(socket_.get());
    756       SSLInfo ssl_info;
    757       ssl_socket->GetSSLInfo(&ssl_info);
    758       SSLConfig::CertAndStatus bad_cert;
    759       bad_cert.cert = ssl_info.cert;
    760       bad_cert.cert_status = ssl_info.cert_status;
    761       if (ssl_config_.IsAllowedBadCert(ssl_info.cert)) {
    762         // If we already have the certificate in the set of allowed bad
    763         // certificates, we did try it and failed again, so we should not
    764         // retry again: the connection should fail at last.
    765         next_state_ = STATE_CLOSE;
    766         return result;
    767       }
    768       // Add the bad certificate to the set of allowed certificates in the
    769       // SSL info object.
    770       ssl_config_.allowed_bad_certs.push_back(bad_cert);
    771       // Restart connection ignoring the bad certificate.
    772       socket_->Disconnect();
    773       socket_.reset();
    774       next_state_ = STATE_TCP_CONNECT;
    775       return OK;
    776     }
    777   }
    778 
    779   if (result == OK)
    780     result = DidEstablishConnection();
    781   else
    782     next_state_ = STATE_CLOSE;
    783   return result;
    784 }
    785 
    786 int SocketStream::DoReadWrite(int result) {
    787   if (result < OK) {
    788     next_state_ = STATE_CLOSE;
    789     return result;
    790   }
    791   if (!socket_.get() || !socket_->IsConnected()) {
    792     next_state_ = STATE_CLOSE;
    793     return ERR_CONNECTION_CLOSED;
    794   }
    795 
    796   next_state_ = STATE_READ_WRITE;
    797 
    798   if (!read_buf_) {
    799     // No read pending.
    800     read_buf_ = new IOBuffer(kReadBufferSize);
    801     result = socket_->Read(read_buf_, kReadBufferSize, &read_callback_);
    802     if (result > 0) {
    803       return DidReceiveData(result);
    804     } else if (result == 0) {
    805       // 0 indicates end-of-file, so socket was closed.
    806       next_state_ = STATE_CLOSE;
    807       return ERR_CONNECTION_CLOSED;
    808     }
    809     // If read is pending, try write as well.
    810     // Otherwise, return the result and do next loop (to close the connection).
    811     if (result != ERR_IO_PENDING) {
    812       next_state_ = STATE_CLOSE;
    813       return result;
    814     }
    815   }
    816   // Read is pending.
    817   DCHECK(read_buf_);
    818 
    819   if (write_buf_ && !current_write_buf_) {
    820     // No write pending.
    821     current_write_buf_ = new DrainableIOBuffer(write_buf_, write_buf_size_);
    822     current_write_buf_->SetOffset(write_buf_offset_);
    823     result = socket_->Write(current_write_buf_,
    824                             current_write_buf_->BytesRemaining(),
    825                             &write_callback_);
    826     if (result > 0) {
    827       return DidSendData(result);
    828     }
    829     // If write is not pending, return the result and do next loop (to close
    830     // the connection).
    831     if (result != 0 && result != ERR_IO_PENDING) {
    832       next_state_ = STATE_CLOSE;
    833       return result;
    834     }
    835     return result;
    836   }
    837 
    838   // We arrived here when both operation is pending.
    839   return ERR_IO_PENDING;
    840 }
    841 
    842 GURL SocketStream::ProxyAuthOrigin() const {
    843   return GURL("http://" + proxy_info_.proxy_server().host_and_port());
    844 }
    845 
    846 int SocketStream::HandleAuthChallenge(const HttpResponseHeaders* headers) {
    847   GURL auth_origin(ProxyAuthOrigin());
    848 
    849   LOG(INFO) << "The proxy " << auth_origin << " requested auth";
    850 
    851   // The auth we tried just failed, hence it can't be valid.
    852   // Remove it from the cache so it won't be used again.
    853   if (auth_handler_.get() && !auth_identity_.invalid &&
    854       auth_handler_->IsFinalRound()) {
    855     if (auth_identity_.source != HttpAuth::IDENT_SRC_PATH_LOOKUP)
    856       auth_cache_.Remove(auth_origin,
    857                          auth_handler_->realm(),
    858                          auth_identity_.username,
    859                          auth_identity_.password);
    860     auth_handler_ = NULL;
    861     auth_identity_ = HttpAuth::Identity();
    862   }
    863 
    864   auth_identity_.invalid = true;
    865   HttpAuth::ChooseBestChallenge(headers, HttpAuth::AUTH_PROXY, auth_origin,
    866                                 &auth_handler_);
    867   if (!auth_handler_) {
    868     LOG(ERROR) << "Can't perform auth to the proxy " << auth_origin;
    869     return ERR_TUNNEL_CONNECTION_FAILED;
    870   }
    871   if (auth_handler_->NeedsIdentity()) {
    872     HttpAuthCache::Entry* entry = auth_cache_.LookupByRealm(
    873         auth_origin, auth_handler_->realm());
    874     if (entry) {
    875       if (entry->handler()->scheme() != "basic") {
    876         // We only support basic authentication scheme now.
    877         // TODO(ukai): Support other authentication scheme.
    878         return ERR_TUNNEL_CONNECTION_FAILED;
    879       }
    880       auth_identity_.source = HttpAuth::IDENT_SRC_REALM_LOOKUP;
    881       auth_identity_.invalid = false;
    882       auth_identity_.username = entry->username();
    883       auth_identity_.password = entry->password();
    884       // Restart with auth info.
    885     }
    886     return ERR_PROXY_AUTH_REQUESTED;
    887   } else {
    888     auth_identity_.invalid = false;
    889   }
    890   return ERR_TUNNEL_CONNECTION_FAILED;
    891 }
    892 
    893 void SocketStream::DoAuthRequired() {
    894   if (delegate_ && auth_info_.get())
    895     delegate_->OnAuthRequired(this, auth_info_.get());
    896   else
    897     DoLoop(net::ERR_UNEXPECTED);
    898 }
    899 
    900 void SocketStream::DoRestartWithAuth() {
    901   DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED);
    902   auth_cache_.Add(ProxyAuthOrigin(), auth_handler_,
    903                   auth_identity_.username, auth_identity_.password,
    904                   std::string());
    905 
    906   tunnel_request_headers_ = NULL;
    907   tunnel_request_headers_bytes_sent_ = 0;
    908   tunnel_response_headers_ = NULL;
    909   tunnel_response_headers_capacity_ = 0;
    910   tunnel_response_headers_len_ = 0;
    911 
    912   next_state_ = STATE_TCP_CONNECT;
    913   DoLoop(OK);
    914 }
    915 
    916 int SocketStream::HandleCertificateError(int result) {
    917   // TODO(ukai): handle cert error properly.
    918   switch (result) {
    919     case ERR_CERT_COMMON_NAME_INVALID:
    920     case ERR_CERT_DATE_INVALID:
    921     case ERR_CERT_AUTHORITY_INVALID:
    922       result = OK;
    923       break;
    924     default:
    925       break;
    926   }
    927   return result;
    928 }
    929 
    930 bool SocketStream::is_secure() const {
    931   return url_.SchemeIs("wss");
    932 }
    933 
    934 SSLConfigService* SocketStream::ssl_config_service() const {
    935   return context_->ssl_config_service();
    936 }
    937 
    938 ProxyService* SocketStream::proxy_service() const {
    939   return context_->proxy_service();
    940 }
    941 
    942 void SocketStream::GetInfoForTracker(
    943     RequestTracker<SocketStream>::RecentRequestInfo* info) const {
    944   info->original_url = url_;
    945   info->load_log = load_log_;
    946 }
    947 
    948 }  // namespace net
    949