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