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