// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/socket_stream/socket_stream.h"

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/utf_string_conversions.h"
#include "net/base/auth.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/net_log.h"
#include "net/base/net_log_unittest.h"
#include "net/base/test_completion_callback.h"
#include "net/http/http_network_session.h"
#include "net/proxy/proxy_service.h"
#include "net/socket/socket_test_util.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

namespace net {

namespace {

struct SocketStreamEvent {
  enum EventType {
    EVENT_START_OPEN_CONNECTION, EVENT_CONNECTED, EVENT_SENT_DATA,
    EVENT_RECEIVED_DATA, EVENT_CLOSE, EVENT_AUTH_REQUIRED, EVENT_ERROR,
  };

  SocketStreamEvent(EventType type,
                    SocketStream* socket_stream,
                    int num,
                    const std::string& str,
                    AuthChallengeInfo* auth_challenge_info,
                    int error)
      : event_type(type), socket(socket_stream), number(num), data(str),
        auth_info(auth_challenge_info), error_code(error) {}

  EventType event_type;
  SocketStream* socket;
  int number;
  std::string data;
  scoped_refptr<AuthChallengeInfo> auth_info;
  int error_code;
};

class SocketStreamEventRecorder : public SocketStream::Delegate {
 public:
  explicit SocketStreamEventRecorder(const CompletionCallback& callback)
      : callback_(callback) {}
  virtual ~SocketStreamEventRecorder() {}

  void SetOnStartOpenConnection(
      const base::Callback<int(SocketStreamEvent*)>& callback) {
    on_start_open_connection_ = callback;
  }
  void SetOnConnected(
      const base::Callback<void(SocketStreamEvent*)>& callback) {
    on_connected_ = callback;
  }
  void SetOnSentData(
      const base::Callback<void(SocketStreamEvent*)>& callback) {
    on_sent_data_ = callback;
  }
  void SetOnReceivedData(
      const base::Callback<void(SocketStreamEvent*)>& callback) {
    on_received_data_ = callback;
  }
  void SetOnClose(const base::Callback<void(SocketStreamEvent*)>& callback) {
    on_close_ = callback;
  }
  void SetOnAuthRequired(
      const base::Callback<void(SocketStreamEvent*)>& callback) {
    on_auth_required_ = callback;
  }
  void SetOnError(const base::Callback<void(SocketStreamEvent*)>& callback) {
    on_error_ = callback;
  }

  virtual int OnStartOpenConnection(
      SocketStream* socket,
      const CompletionCallback& callback) OVERRIDE {
    connection_callback_ = callback;
    events_.push_back(
        SocketStreamEvent(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
                          socket, 0, std::string(), NULL, OK));
    if (!on_start_open_connection_.is_null())
      return on_start_open_connection_.Run(&events_.back());
    return OK;
  }
  virtual void OnConnected(SocketStream* socket,
                           int num_pending_send_allowed) OVERRIDE {
    events_.push_back(
        SocketStreamEvent(SocketStreamEvent::EVENT_CONNECTED,
                          socket, num_pending_send_allowed, std::string(),
                          NULL, OK));
    if (!on_connected_.is_null())
      on_connected_.Run(&events_.back());
  }
  virtual void OnSentData(SocketStream* socket,
                          int amount_sent) OVERRIDE {
    events_.push_back(
        SocketStreamEvent(SocketStreamEvent::EVENT_SENT_DATA, socket,
                          amount_sent, std::string(), NULL, OK));
    if (!on_sent_data_.is_null())
      on_sent_data_.Run(&events_.back());
  }
  virtual void OnReceivedData(SocketStream* socket,
                              const char* data, int len) OVERRIDE {
    events_.push_back(
        SocketStreamEvent(SocketStreamEvent::EVENT_RECEIVED_DATA, socket, len,
                          std::string(data, len), NULL, OK));
    if (!on_received_data_.is_null())
      on_received_data_.Run(&events_.back());
  }
  virtual void OnClose(SocketStream* socket) OVERRIDE {
    events_.push_back(
        SocketStreamEvent(SocketStreamEvent::EVENT_CLOSE, socket, 0,
                          std::string(), NULL, OK));
    if (!on_close_.is_null())
      on_close_.Run(&events_.back());
    if (!callback_.is_null())
      callback_.Run(OK);
  }
  virtual void OnAuthRequired(SocketStream* socket,
                              AuthChallengeInfo* auth_info) OVERRIDE {
    events_.push_back(
        SocketStreamEvent(SocketStreamEvent::EVENT_AUTH_REQUIRED, socket, 0,
                          std::string(), auth_info, OK));
    if (!on_auth_required_.is_null())
      on_auth_required_.Run(&events_.back());
  }
  virtual void OnError(const SocketStream* socket, int error) OVERRIDE {
    events_.push_back(
        SocketStreamEvent(SocketStreamEvent::EVENT_ERROR, NULL, 0,
                          std::string(), NULL, error));
    if (!on_error_.is_null())
      on_error_.Run(&events_.back());
    if (!callback_.is_null())
      callback_.Run(error);
  }

  void DoClose(SocketStreamEvent* event) {
    event->socket->Close();
  }
  void DoRestartWithAuth(SocketStreamEvent* event) {
    VLOG(1) << "RestartWithAuth username=" << credentials_.username()
            << " password=" << credentials_.password();
    event->socket->RestartWithAuth(credentials_);
  }
  void SetAuthInfo(const AuthCredentials& credentials) {
    credentials_ = credentials;
  }
  void CompleteConnection(int result) {
    connection_callback_.Run(result);
  }

  const std::vector<SocketStreamEvent>& GetSeenEvents() const {
    return events_;
  }

 private:
  std::vector<SocketStreamEvent> events_;
  base::Callback<int(SocketStreamEvent*)> on_start_open_connection_;
  base::Callback<void(SocketStreamEvent*)> on_connected_;
  base::Callback<void(SocketStreamEvent*)> on_sent_data_;
  base::Callback<void(SocketStreamEvent*)> on_received_data_;
  base::Callback<void(SocketStreamEvent*)> on_close_;
  base::Callback<void(SocketStreamEvent*)> on_auth_required_;
  base::Callback<void(SocketStreamEvent*)> on_error_;
  const CompletionCallback callback_;
  CompletionCallback connection_callback_;
  AuthCredentials credentials_;

  DISALLOW_COPY_AND_ASSIGN(SocketStreamEventRecorder);
};

class TestURLRequestContextWithProxy : public TestURLRequestContext {
 public:
  explicit TestURLRequestContextWithProxy(const std::string& proxy)
      : TestURLRequestContext(true) {
    context_storage_.set_proxy_service(ProxyService::CreateFixed(proxy));
    Init();
  }
  virtual ~TestURLRequestContextWithProxy() {}
};

class TestSocketStreamNetworkDelegate : public TestNetworkDelegate {
 public:
  TestSocketStreamNetworkDelegate()
      : before_connect_result_(OK) {}
  virtual ~TestSocketStreamNetworkDelegate() {}

  virtual int OnBeforeSocketStreamConnect(
      SocketStream* stream,
      const CompletionCallback& callback) OVERRIDE {
    return before_connect_result_;
  }

  void SetBeforeConnectResult(int result) {
    before_connect_result_ = result;
  }

 private:
  int before_connect_result_;
};

}  // namespace

class SocketStreamTest : public PlatformTest {
 public:
  virtual ~SocketStreamTest() {}
  virtual void SetUp() {
    mock_socket_factory_.reset();
    handshake_request_ = kWebSocketHandshakeRequest;
    handshake_response_ = kWebSocketHandshakeResponse;
  }
  virtual void TearDown() {
    mock_socket_factory_.reset();
  }

  virtual void SetWebSocketHandshakeMessage(
      const char* request, const char* response) {
    handshake_request_ = request;
    handshake_response_ = response;
  }
  virtual void AddWebSocketMessage(const std::string& message) {
    messages_.push_back(message);
  }

  virtual MockClientSocketFactory* GetMockClientSocketFactory() {
    mock_socket_factory_.reset(new MockClientSocketFactory);
    return mock_socket_factory_.get();
  }

  virtual void DoSendWebSocketHandshake(SocketStreamEvent* event) {
    event->socket->SendData(
        handshake_request_.data(), handshake_request_.size());
  }

  virtual void DoCloseFlushPendingWriteTest(SocketStreamEvent* event) {
    // handshake response received.
    for (size_t i = 0; i < messages_.size(); i++) {
      std::vector<char> frame;
      frame.push_back('\0');
      frame.insert(frame.end(), messages_[i].begin(), messages_[i].end());
      frame.push_back('\xff');
      EXPECT_TRUE(event->socket->SendData(&frame[0], frame.size()));
    }
    // Actual StreamSocket close must happen after all frames queued by
    // SendData above are sent out.
    event->socket->Close();
  }

  virtual int DoSwitchToSpdyTest(SocketStreamEvent* event) {
    return ERR_PROTOCOL_SWITCHED;
  }

  virtual int DoIOPending(SocketStreamEvent* event) {
    io_test_callback_.callback().Run(OK);
    return ERR_IO_PENDING;
  }

  static const char kWebSocketHandshakeRequest[];
  static const char kWebSocketHandshakeResponse[];

 protected:
  TestCompletionCallback io_test_callback_;

 private:
  std::string handshake_request_;
  std::string handshake_response_;
  std::vector<std::string> messages_;

  scoped_ptr<MockClientSocketFactory> mock_socket_factory_;
};

const char SocketStreamTest::kWebSocketHandshakeRequest[] =
    "GET /demo HTTP/1.1\r\n"
    "Host: example.com\r\n"
    "Connection: Upgrade\r\n"
    "Sec-WebSocket-Key2: 12998 5 Y3 1  .P00\r\n"
    "Sec-WebSocket-Protocol: sample\r\n"
    "Upgrade: WebSocket\r\n"
    "Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5\r\n"
    "Origin: http://example.com\r\n"
    "\r\n"
    "^n:ds[4U";

const char SocketStreamTest::kWebSocketHandshakeResponse[] =
    "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
    "Upgrade: WebSocket\r\n"
    "Connection: Upgrade\r\n"
    "Sec-WebSocket-Origin: http://example.com\r\n"
    "Sec-WebSocket-Location: ws://example.com/demo\r\n"
    "Sec-WebSocket-Protocol: sample\r\n"
    "\r\n"
    "8jKS'y:G*Co,Wxa-";

TEST_F(SocketStreamTest, CloseFlushPendingWrite) {
  TestCompletionCallback test_callback;

  scoped_ptr<SocketStreamEventRecorder> delegate(
      new SocketStreamEventRecorder(test_callback.callback()));
  delegate->SetOnConnected(base::Bind(
      &SocketStreamTest::DoSendWebSocketHandshake, base::Unretained(this)));
  delegate->SetOnReceivedData(base::Bind(
      &SocketStreamTest::DoCloseFlushPendingWriteTest,
      base::Unretained(this)));

  TestURLRequestContext context;

  scoped_refptr<SocketStream> socket_stream(
      new SocketStream(GURL("ws://example.com/demo"), delegate.get()));

  socket_stream->set_context(&context);

  MockWrite data_writes[] = {
    MockWrite(SocketStreamTest::kWebSocketHandshakeRequest),
    MockWrite(ASYNC, "\0message1\xff", 10),
    MockWrite(ASYNC, "\0message2\xff", 10)
  };
  MockRead data_reads[] = {
    MockRead(SocketStreamTest::kWebSocketHandshakeResponse),
    // Server doesn't close the connection after handshake.
    MockRead(ASYNC, ERR_IO_PENDING)
  };
  AddWebSocketMessage("message1");
  AddWebSocketMessage("message2");

  DelayedSocketData data_provider(
      1, data_reads, arraysize(data_reads),
      data_writes, arraysize(data_writes));

  MockClientSocketFactory* mock_socket_factory =
      GetMockClientSocketFactory();
  mock_socket_factory->AddSocketDataProvider(&data_provider);

  socket_stream->SetClientSocketFactory(mock_socket_factory);

  socket_stream->Connect();

  test_callback.WaitForResult();

  const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
  ASSERT_EQ(8U, events.size());

  EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
            events[0].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[2].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA, events[3].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[4].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[5].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[6].event_type);
  EXPECT_EQ(ERR_CONNECTION_CLOSED, events[6].error_code);
  EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[7].event_type);
}

TEST_F(SocketStreamTest, BasicAuthProxy) {
  MockClientSocketFactory mock_socket_factory;
  MockWrite data_writes1[] = {
    MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
              "Host: example.com\r\n"
              "Proxy-Connection: keep-alive\r\n\r\n"),
  };
  MockRead data_reads1[] = {
    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
    MockRead("\r\n"),
  };
  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
                                 data_writes1, arraysize(data_writes1));
  mock_socket_factory.AddSocketDataProvider(&data1);

  MockWrite data_writes2[] = {
    MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
              "Host: example.com\r\n"
              "Proxy-Connection: keep-alive\r\n"
              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
  };
  MockRead data_reads2[] = {
    MockRead("HTTP/1.1 200 Connection Established\r\n"),
    MockRead("Proxy-agent: Apache/2.2.8\r\n"),
    MockRead("\r\n"),
    // SocketStream::DoClose is run asynchronously.  Socket can be read after
    // "\r\n".  We have to give ERR_IO_PENDING to SocketStream then to indicate
    // server doesn't close the connection.
    MockRead(ASYNC, ERR_IO_PENDING)
  };
  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
                                 data_writes2, arraysize(data_writes2));
  mock_socket_factory.AddSocketDataProvider(&data2);

  TestCompletionCallback test_callback;

  scoped_ptr<SocketStreamEventRecorder> delegate(
      new SocketStreamEventRecorder(test_callback.callback()));
  delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
                                      base::Unretained(delegate.get())));
  delegate->SetAuthInfo(AuthCredentials(ASCIIToUTF16("foo"),
                                        ASCIIToUTF16("bar")));
  delegate->SetOnAuthRequired(base::Bind(
      &SocketStreamEventRecorder::DoRestartWithAuth,
      base::Unretained(delegate.get())));

  scoped_refptr<SocketStream> socket_stream(
      new SocketStream(GURL("ws://example.com/demo"), delegate.get()));

  TestURLRequestContextWithProxy context("myproxy:70");

  socket_stream->set_context(&context);
  socket_stream->SetClientSocketFactory(&mock_socket_factory);

  socket_stream->Connect();

  test_callback.WaitForResult();

  const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
  ASSERT_EQ(5U, events.size());

  EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
            events[0].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_AUTH_REQUIRED, events[1].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[2].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[3].event_type);
  EXPECT_EQ(ERR_ABORTED, events[3].error_code);
  EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[4].event_type);

  // TODO(eroman): Add back NetLogTest here...
}

TEST_F(SocketStreamTest, BasicAuthProxyWithAuthCache) {
  MockClientSocketFactory mock_socket_factory;
  MockWrite data_writes[] = {
    // WebSocket(SocketStream) always uses CONNECT when it is configured to use
    // proxy so the port may not be 443.
    MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
              "Host: example.com\r\n"
              "Proxy-Connection: keep-alive\r\n"
              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
  };
  MockRead data_reads[] = {
    MockRead("HTTP/1.1 200 Connection Established\r\n"),
    MockRead("Proxy-agent: Apache/2.2.8\r\n"),
    MockRead("\r\n"),
    MockRead(ASYNC, ERR_IO_PENDING)
  };
  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
                                 data_writes, arraysize(data_writes));
  mock_socket_factory.AddSocketDataProvider(&data);

  TestCompletionCallback test_callback;
  scoped_ptr<SocketStreamEventRecorder> delegate(
      new SocketStreamEventRecorder(test_callback.callback()));
  delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
                                      base::Unretained(delegate.get())));

  scoped_refptr<SocketStream> socket_stream(
      new SocketStream(GURL("ws://example.com/demo"), delegate.get()));

  TestURLRequestContextWithProxy context("myproxy:70");
  HttpAuthCache* auth_cache =
      context.http_transaction_factory()->GetSession()->http_auth_cache();
  auth_cache->Add(GURL("http://myproxy:70"),
                  "MyRealm1",
                  HttpAuth::AUTH_SCHEME_BASIC,
                  "Basic realm=MyRealm1",
                  AuthCredentials(ASCIIToUTF16("foo"),
                                  ASCIIToUTF16("bar")),
                  "/");

  socket_stream->set_context(&context);
  socket_stream->SetClientSocketFactory(&mock_socket_factory);

  socket_stream->Connect();

  test_callback.WaitForResult();

  const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
  ASSERT_EQ(4U, events.size());
  EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
            events[0].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type);
  EXPECT_EQ(ERR_ABORTED, events[2].error_code);
  EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type);
}

TEST_F(SocketStreamTest, WSSBasicAuthProxyWithAuthCache) {
  MockClientSocketFactory mock_socket_factory;
  MockWrite data_writes1[] = {
    MockWrite("CONNECT example.com:443 HTTP/1.1\r\n"
              "Host: example.com\r\n"
              "Proxy-Connection: keep-alive\r\n"
              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
  };
  MockRead data_reads1[] = {
    MockRead("HTTP/1.1 200 Connection Established\r\n"),
    MockRead("Proxy-agent: Apache/2.2.8\r\n"),
    MockRead("\r\n"),
    MockRead(ASYNC, ERR_IO_PENDING)
  };
  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
                                 data_writes1, arraysize(data_writes1));
  mock_socket_factory.AddSocketDataProvider(&data1);

  SSLSocketDataProvider data2(ASYNC, OK);
  mock_socket_factory.AddSSLSocketDataProvider(&data2);

  TestCompletionCallback test_callback;
  scoped_ptr<SocketStreamEventRecorder> delegate(
      new SocketStreamEventRecorder(test_callback.callback()));
  delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
                                      base::Unretained(delegate.get())));

  scoped_refptr<SocketStream> socket_stream(
      new SocketStream(GURL("wss://example.com/demo"), delegate.get()));

  TestURLRequestContextWithProxy context("myproxy:70");
  HttpAuthCache* auth_cache =
      context.http_transaction_factory()->GetSession()->http_auth_cache();
  auth_cache->Add(GURL("http://myproxy:70"),
                  "MyRealm1",
                  HttpAuth::AUTH_SCHEME_BASIC,
                  "Basic realm=MyRealm1",
                  AuthCredentials(ASCIIToUTF16("foo"),
                                  ASCIIToUTF16("bar")),
                  "/");

  socket_stream->set_context(&context);
  socket_stream->SetClientSocketFactory(&mock_socket_factory);

  socket_stream->Connect();

  test_callback.WaitForResult();

  const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
  ASSERT_EQ(4U, events.size());
  EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
            events[0].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type);
  EXPECT_EQ(ERR_ABORTED, events[2].error_code);
  EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type);
}

TEST_F(SocketStreamTest, IOPending) {
  TestCompletionCallback test_callback;

  scoped_ptr<SocketStreamEventRecorder> delegate(
      new SocketStreamEventRecorder(test_callback.callback()));
  delegate->SetOnConnected(base::Bind(
      &SocketStreamTest::DoSendWebSocketHandshake, base::Unretained(this)));
  delegate->SetOnReceivedData(base::Bind(
      &SocketStreamTest::DoCloseFlushPendingWriteTest,
      base::Unretained(this)));
  delegate->SetOnStartOpenConnection(base::Bind(
      &SocketStreamTest::DoIOPending, base::Unretained(this)));

  TestURLRequestContext context;

  scoped_refptr<SocketStream> socket_stream(
      new SocketStream(GURL("ws://example.com/demo"), delegate.get()));

  socket_stream->set_context(&context);

  MockWrite data_writes[] = {
    MockWrite(SocketStreamTest::kWebSocketHandshakeRequest),
    MockWrite(ASYNC, "\0message1\xff", 10),
    MockWrite(ASYNC, "\0message2\xff", 10)
  };
  MockRead data_reads[] = {
    MockRead(SocketStreamTest::kWebSocketHandshakeResponse),
    // Server doesn't close the connection after handshake.
    MockRead(ASYNC, ERR_IO_PENDING)
  };
  AddWebSocketMessage("message1");
  AddWebSocketMessage("message2");

  DelayedSocketData data_provider(
      1, data_reads, arraysize(data_reads),
      data_writes, arraysize(data_writes));

  MockClientSocketFactory* mock_socket_factory =
      GetMockClientSocketFactory();
  mock_socket_factory->AddSocketDataProvider(&data_provider);

  socket_stream->SetClientSocketFactory(mock_socket_factory);

  socket_stream->Connect();
  io_test_callback_.WaitForResult();
  EXPECT_EQ(SocketStream::STATE_RESOLVE_PROTOCOL_COMPLETE,
            socket_stream->next_state_);
  delegate->CompleteConnection(OK);

  EXPECT_EQ(OK, test_callback.WaitForResult());

  const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
  ASSERT_EQ(8U, events.size());

  EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
            events[0].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[2].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA, events[3].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[4].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[5].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[6].event_type);
  EXPECT_EQ(ERR_CONNECTION_CLOSED, events[6].error_code);
  EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[7].event_type);
}

TEST_F(SocketStreamTest, SwitchToSpdy) {
  TestCompletionCallback test_callback;

  scoped_ptr<SocketStreamEventRecorder> delegate(
      new SocketStreamEventRecorder(test_callback.callback()));
  delegate->SetOnStartOpenConnection(base::Bind(
      &SocketStreamTest::DoSwitchToSpdyTest, base::Unretained(this)));

  TestURLRequestContext context;

  scoped_refptr<SocketStream> socket_stream(
      new SocketStream(GURL("ws://example.com/demo"), delegate.get()));

  socket_stream->set_context(&context);

  socket_stream->Connect();

  EXPECT_EQ(ERR_PROTOCOL_SWITCHED, test_callback.WaitForResult());

  const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
  ASSERT_EQ(2U, events.size());

  EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
            events[0].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[1].event_type);
  EXPECT_EQ(ERR_PROTOCOL_SWITCHED, events[1].error_code);
}

TEST_F(SocketStreamTest, SwitchAfterPending) {
  TestCompletionCallback test_callback;

  scoped_ptr<SocketStreamEventRecorder> delegate(
      new SocketStreamEventRecorder(test_callback.callback()));
  delegate->SetOnStartOpenConnection(base::Bind(
      &SocketStreamTest::DoIOPending, base::Unretained(this)));

  TestURLRequestContext context;

  scoped_refptr<SocketStream> socket_stream(
      new SocketStream(GURL("ws://example.com/demo"), delegate.get()));

  socket_stream->set_context(&context);

  socket_stream->Connect();
  io_test_callback_.WaitForResult();
  EXPECT_EQ(SocketStream::STATE_RESOLVE_PROTOCOL_COMPLETE,
            socket_stream->next_state_);
  delegate->CompleteConnection(ERR_PROTOCOL_SWITCHED);

  EXPECT_EQ(ERR_PROTOCOL_SWITCHED, test_callback.WaitForResult());

  const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
  ASSERT_EQ(2U, events.size());

  EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
            events[0].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[1].event_type);
  EXPECT_EQ(ERR_PROTOCOL_SWITCHED, events[1].error_code);
}

// Test a connection though a secure proxy.
TEST_F(SocketStreamTest, SecureProxyConnectError) {
  MockClientSocketFactory mock_socket_factory;
  MockWrite data_writes[] = {
    MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
              "Host: example.com\r\n"
              "Proxy-Connection: keep-alive\r\n\r\n")
  };
  MockRead data_reads[] = {
    MockRead("HTTP/1.1 200 Connection Established\r\n"),
    MockRead("Proxy-agent: Apache/2.2.8\r\n"),
    MockRead("\r\n"),
    // SocketStream::DoClose is run asynchronously.  Socket can be read after
    // "\r\n".  We have to give ERR_IO_PENDING to SocketStream then to indicate
    // server doesn't close the connection.
    MockRead(ASYNC, ERR_IO_PENDING)
  };
  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
                                data_writes, arraysize(data_writes));
  mock_socket_factory.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
  mock_socket_factory.AddSSLSocketDataProvider(&ssl);

  TestCompletionCallback test_callback;
  TestURLRequestContextWithProxy context("https://myproxy:70");

  scoped_ptr<SocketStreamEventRecorder> delegate(
      new SocketStreamEventRecorder(test_callback.callback()));
  delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
                                      base::Unretained(delegate.get())));

  scoped_refptr<SocketStream> socket_stream(
      new SocketStream(GURL("ws://example.com/demo"), delegate.get()));

  socket_stream->set_context(&context);
  socket_stream->SetClientSocketFactory(&mock_socket_factory);

  socket_stream->Connect();

  test_callback.WaitForResult();

  const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
  ASSERT_EQ(3U, events.size());

  EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
            events[0].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[1].event_type);
  EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, events[1].error_code);
  EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[2].event_type);
}

// Test a connection though a secure proxy.
TEST_F(SocketStreamTest, SecureProxyConnect) {
  MockClientSocketFactory mock_socket_factory;
  MockWrite data_writes[] = {
    MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
              "Host: example.com\r\n"
              "Proxy-Connection: keep-alive\r\n\r\n")
  };
  MockRead data_reads[] = {
    MockRead("HTTP/1.1 200 Connection Established\r\n"),
    MockRead("Proxy-agent: Apache/2.2.8\r\n"),
    MockRead("\r\n"),
    // SocketStream::DoClose is run asynchronously.  Socket can be read after
    // "\r\n".  We have to give ERR_IO_PENDING to SocketStream then to indicate
    // server doesn't close the connection.
    MockRead(ASYNC, ERR_IO_PENDING)
  };
  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
                                data_writes, arraysize(data_writes));
  mock_socket_factory.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
  mock_socket_factory.AddSSLSocketDataProvider(&ssl);

  TestCompletionCallback test_callback;
  TestURLRequestContextWithProxy context("https://myproxy:70");

  scoped_ptr<SocketStreamEventRecorder> delegate(
      new SocketStreamEventRecorder(test_callback.callback()));
  delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
                                      base::Unretained(delegate.get())));

  scoped_refptr<SocketStream> socket_stream(
      new SocketStream(GURL("ws://example.com/demo"), delegate.get()));

  socket_stream->set_context(&context);
  socket_stream->SetClientSocketFactory(&mock_socket_factory);

  socket_stream->Connect();

  test_callback.WaitForResult();

  const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
  ASSERT_EQ(4U, events.size());

  EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
            events[0].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type);
  EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[2].event_type);
  EXPECT_EQ(ERR_ABORTED, events[2].error_code);
  EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type);
}

TEST_F(SocketStreamTest, BeforeConnectFailed) {
  TestCompletionCallback test_callback;

  scoped_ptr<SocketStreamEventRecorder> delegate(
      new SocketStreamEventRecorder(test_callback.callback()));

  TestURLRequestContext context;
  TestSocketStreamNetworkDelegate network_delegate;
  network_delegate.SetBeforeConnectResult(ERR_ACCESS_DENIED);
  context.set_network_delegate(&network_delegate);

  scoped_refptr<SocketStream> socket_stream(
      new SocketStream(GURL("ws://example.com/demo"), delegate.get()));

  socket_stream->set_context(&context);

  socket_stream->Connect();

  test_callback.WaitForResult();

  const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
  ASSERT_EQ(2U, events.size());

  EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[0].event_type);
  EXPECT_EQ(ERR_ACCESS_DENIED, events[0].error_code);
  EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[1].event_type);
}

}  // namespace net
