// 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/spdy/spdy_proxy_client_socket.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/utf_string_conversions.h"
#include "net/base/address_list.h"
#include "net/base/net_log.h"
#include "net/base/net_log_unittest.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/test_completion_callback.h"
#include "net/base/winsock_init.h"
#include "net/http/http_response_info.h"
#include "net/http/http_response_headers.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/tcp_client_socket.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/buffered_spdy_framer.h"
#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_protocol.h"
#include "net/spdy/spdy_session_pool.h"
#include "net/spdy/spdy_test_util_spdy3.h"
#include "testing/platform_test.h"
#include "testing/gtest/include/gtest/gtest.h"

using namespace net::test_spdy3;

//-----------------------------------------------------------------------------

namespace {

static const char kRequestUrl[] = "https://www.google.com/";
static const char kOriginHost[] = "www.google.com";
static const int kOriginPort = 443;
static const char kOriginHostPort[] = "www.google.com:443";
static const char kProxyUrl[] = "https://myproxy:6121/";
static const char kProxyHost[] = "myproxy";
static const int kProxyPort = 6121;
static const char kUserAgent[] = "Mozilla/1.0";

static const int kStreamId = 1;

static const char kMsg1[] = "\0hello!\xff";
static const int kLen1 = 8;
static const char kMsg2[] = "\00012345678\0";
static const int kLen2 = 10;
static const char kMsg3[] = "bye!";
static const int kLen3 = 4;
static const char kMsg33[] = "bye!bye!";
static const int kLen33 = kLen3 + kLen3;
static const char kMsg333[] = "bye!bye!bye!";
static const int kLen333 = kLen3 + kLen3 + kLen3;

static const char kRedirectUrl[] = "https://example.com/";

}  // anonymous namespace

namespace net {

class SpdyProxyClientSocketSpdy3Test : public PlatformTest {
 public:
  SpdyProxyClientSocketSpdy3Test();

  virtual void TearDown();

 protected:
  void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
                  size_t writes_count);
  SpdyFrame* ConstructConnectRequestFrame();
  SpdyFrame* ConstructConnectAuthRequestFrame();
  SpdyFrame* ConstructConnectReplyFrame();
  SpdyFrame* ConstructConnectAuthReplyFrame();
  SpdyFrame* ConstructConnectRedirectReplyFrame();
  SpdyFrame* ConstructConnectErrorReplyFrame();
  SpdyFrame* ConstructBodyFrame(const char* data, int length);
  scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
  void AssertConnectSucceeds();
  void AssertConnectFails(int result);
  void AssertConnectionEstablished();
  void AssertSyncReadEquals(const char* data, int len);
  void AssertAsyncReadEquals(const char* data, int len);
  void AssertReadStarts(const char* data, int len);
  void AssertReadReturns(const char* data, int len);
  void AssertAsyncWriteSucceeds(const char* data, int len);
  void AssertWriteReturns(const char* data, int len, int rv);
  void AssertWriteLength(int len);
  void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
                                        int num_reads);

  void AddAuthToCache() {
    const string16 kFoo(ASCIIToUTF16("foo"));
    const string16 kBar(ASCIIToUTF16("bar"));
    session_->http_auth_cache()->Add(GURL(kProxyUrl),
                                     "MyRealm1",
                                     HttpAuth::AUTH_SCHEME_BASIC,
                                     "Basic realm=MyRealm1",
                                     AuthCredentials(kFoo, kBar),
                                     "/");
  }

  void Run(int steps) {
    data_->StopAfter(steps);
    data_->Run();
  }

  scoped_ptr<SpdyProxyClientSocket> sock_;
  TestCompletionCallback read_callback_;
  TestCompletionCallback write_callback_;
  scoped_ptr<DeterministicSocketData> data_;

 private:
  scoped_refptr<HttpNetworkSession> session_;
  scoped_refptr<IOBuffer> read_buf_;
  SpdySessionDependencies session_deps_;
  MockConnect connect_data_;
  scoped_refptr<SpdySession> spdy_session_;
  scoped_refptr<SpdyStream> spdy_stream_;
  BufferedSpdyFramer framer_;

  std::string user_agent_;
  GURL url_;
  HostPortPair proxy_host_port_;
  HostPortPair endpoint_host_port_pair_;
  ProxyServer proxy_;
  HostPortProxyPair endpoint_host_port_proxy_pair_;
  scoped_refptr<TransportSocketParams> transport_params_;

  DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketSpdy3Test);
};

SpdyProxyClientSocketSpdy3Test::SpdyProxyClientSocketSpdy3Test()
    : sock_(NULL),
      data_(NULL),
      session_(NULL),
      read_buf_(NULL),
      session_deps_(),
      connect_data_(SYNCHRONOUS, OK),
      spdy_session_(NULL),
      spdy_stream_(NULL),
      framer_(3, false),
      user_agent_(kUserAgent),
      url_(kRequestUrl),
      proxy_host_port_(kProxyHost, kProxyPort),
      endpoint_host_port_pair_(kOriginHost, kOriginPort),
      proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
      endpoint_host_port_proxy_pair_(endpoint_host_port_pair_, proxy_),
      transport_params_(new TransportSocketParams(proxy_host_port_,
                                                  LOWEST,
                                                  false,
                                                  false,
                                                  OnHostResolutionCallback())) {
}

void SpdyProxyClientSocketSpdy3Test::TearDown() {
  sock_.reset(NULL);
  if (session_ != NULL)
    session_->spdy_session_pool()->CloseAllSessions();

  // Empty the current queue.
  MessageLoop::current()->RunUntilIdle();
  PlatformTest::TearDown();
}

void SpdyProxyClientSocketSpdy3Test::Initialize(MockRead* reads,
                                           size_t reads_count,
                                           MockWrite* writes,
                                           size_t writes_count) {
  data_.reset(new DeterministicSocketData(reads, reads_count,
                                          writes, writes_count));
  data_->set_connect_data(connect_data_);
  data_->SetStop(2);

  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
      data_.get());
  session_deps_.host_resolver->set_synchronous_mode(true);

  session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
      &session_deps_);

  // Creates a new spdy session
  spdy_session_ =
      session_->spdy_session_pool()->Get(endpoint_host_port_proxy_pair_,
                                         BoundNetLog());

  // Perform the TCP connect
  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
  EXPECT_EQ(OK,
            connection->Init(endpoint_host_port_pair_.ToString(),
                             transport_params_, LOWEST, CompletionCallback(),
                             session_->GetTransportSocketPool(
                                 HttpNetworkSession::NORMAL_SOCKET_POOL),
                             BoundNetLog()));
  spdy_session_->InitializeWithSocket(connection.release(), false, OK);

  // Create the SPDY Stream
  ASSERT_EQ(
      OK,
      spdy_session_->CreateStream(url_, LOWEST, &spdy_stream_, BoundNetLog(),
                                  CompletionCallback()));

  // Create the SpdyProxyClientSocket
  sock_.reset(
      new SpdyProxyClientSocket(spdy_stream_, user_agent_,
                                endpoint_host_port_pair_, url_,
                                proxy_host_port_, session_->http_auth_cache(),
                                session_->http_auth_handler_factory()));
}

scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketSpdy3Test::CreateBuffer(
    const char* data, int size) {
  scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
  memcpy(buf->data(), data, size);
  return buf;
}

void SpdyProxyClientSocketSpdy3Test::AssertConnectSucceeds() {
  ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
  data_->Run();
  ASSERT_EQ(OK, read_callback_.WaitForResult());
}

void SpdyProxyClientSocketSpdy3Test::AssertConnectFails(int result) {
  ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
  data_->Run();
  ASSERT_EQ(result, read_callback_.WaitForResult());
}

void SpdyProxyClientSocketSpdy3Test::AssertConnectionEstablished() {
  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
  ASSERT_TRUE(response != NULL);
  ASSERT_EQ(200, response->headers->response_code());
  ASSERT_EQ("Connection Established", response->headers->GetStatusText());
}

void SpdyProxyClientSocketSpdy3Test::AssertSyncReadEquals(const char* data,
                                                          int len) {
  scoped_refptr<IOBuffer> buf(new IOBuffer(len));
  ASSERT_EQ(len, sock_->Read(buf, len, CompletionCallback()));
  ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
  ASSERT_TRUE(sock_->IsConnected());
}

void SpdyProxyClientSocketSpdy3Test::AssertAsyncReadEquals(const char* data,
                                                           int len) {
  data_->StopAfter(1);
  // Issue the read, which will be completed asynchronously
  scoped_refptr<IOBuffer> buf(new IOBuffer(len));
  ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, len, read_callback_.callback()));
  EXPECT_TRUE(sock_->IsConnected());
  data_->Run();

  EXPECT_TRUE(sock_->IsConnected());

  // Now the read will return
  EXPECT_EQ(len, read_callback_.WaitForResult());
  ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
}

void SpdyProxyClientSocketSpdy3Test::AssertReadStarts(const char* data,
                                                      int len) {
  data_->StopAfter(1);
  // Issue the read, which will be completed asynchronously
  read_buf_ = new IOBuffer(len);
  ASSERT_EQ(ERR_IO_PENDING,
            sock_->Read(read_buf_, len, read_callback_.callback()));
  EXPECT_TRUE(sock_->IsConnected());
}

void SpdyProxyClientSocketSpdy3Test::AssertReadReturns(const char* data,
                                                       int len) {
  EXPECT_TRUE(sock_->IsConnected());

  // Now the read will return
  EXPECT_EQ(len, read_callback_.WaitForResult());
  ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
}

void SpdyProxyClientSocketSpdy3Test::AssertAsyncWriteSucceeds(const char* data,
                                                              int len) {
  AssertWriteReturns(data, len, ERR_IO_PENDING);
  data_->RunFor(1);
  AssertWriteLength(len);
}

void SpdyProxyClientSocketSpdy3Test::AssertWriteReturns(const char* data,
                                                        int len,
                                                        int rv) {
  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
  EXPECT_EQ(rv, sock_->Write(buf, buf->size(), write_callback_.callback()));
}

void SpdyProxyClientSocketSpdy3Test::AssertWriteLength(int len) {
  EXPECT_EQ(len, write_callback_.WaitForResult());
}

void SpdyProxyClientSocketSpdy3Test::AssertAsyncWriteWithReadsSucceeds(
    const char* data, int len, int num_reads) {
  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));

  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(),
                                         write_callback_.callback()));

  for (int i = 0; i < num_reads; i++) {
    Run(1);
    AssertSyncReadEquals(kMsg2, kLen2);
  }

  write_callback_.WaitForResult();
}

// Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
SpdyFrame*
SpdyProxyClientSocketSpdy3Test::ConstructConnectRequestFrame() {
  const SpdyHeaderInfo kSynStartHeader = {
    SYN_STREAM,
    kStreamId,
    0,
    net::ConvertRequestPriorityToSpdyPriority(LOWEST, 3),
    0,
    CONTROL_FLAG_NONE,
    false,
    INVALID,
    NULL,
    0,
    DATA_FLAG_NONE
  };
  const char* const kConnectHeaders[] = {
    ":method", "CONNECT",
    ":path", kOriginHostPort,
    ":host", kOriginHost,
    "user-agent", kUserAgent,
    ":version", "HTTP/1.1",
  };
  return ConstructSpdyPacket(
      kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
}

// Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
// Proxy-Authorization headers.
SpdyFrame*
SpdyProxyClientSocketSpdy3Test::ConstructConnectAuthRequestFrame() {
  const SpdyHeaderInfo kSynStartHeader = {
    SYN_STREAM,
    kStreamId,
    0,
    net::ConvertRequestPriorityToSpdyPriority(LOWEST, 3),
    0,
    CONTROL_FLAG_NONE,
    false,
    INVALID,
    NULL,
    0,
    DATA_FLAG_NONE
  };
  const char* const kConnectHeaders[] = {
    ":method", "CONNECT",
    ":path", kOriginHostPort,
    ":host", kOriginHost,
    "user-agent", kUserAgent,
    ":version", "HTTP/1.1",
    "proxy-authorization", "Basic Zm9vOmJhcg==",
  };
  return ConstructSpdyPacket(
      kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
}

// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
SpdyFrame* SpdyProxyClientSocketSpdy3Test::ConstructConnectReplyFrame() {
  const char* const kStandardReplyHeaders[] = {
      ":status", "200 Connection Established",
      ":version", "HTTP/1.1"
  };
  return ConstructSpdyControlFrame(NULL,
                                   0,
                                   false,
                                   kStreamId,
                                   LOWEST,
                                   SYN_REPLY,
                                   CONTROL_FLAG_NONE,
                                   kStandardReplyHeaders,
                                   arraysize(kStandardReplyHeaders));
}

// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
SpdyFrame*
SpdyProxyClientSocketSpdy3Test::ConstructConnectAuthReplyFrame() {
  const char* const kStandardReplyHeaders[] = {
      ":status", "407 Proxy Authentication Required",
      ":version", "HTTP/1.1",
      "proxy-authenticate", "Basic realm=\"MyRealm1\"",
  };

  return ConstructSpdyControlFrame(NULL,
                                   0,
                                   false,
                                   kStreamId,
                                   LOWEST,
                                   SYN_REPLY,
                                   CONTROL_FLAG_NONE,
                                   kStandardReplyHeaders,
                                   arraysize(kStandardReplyHeaders));
}

// Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
SpdyFrame*
SpdyProxyClientSocketSpdy3Test::ConstructConnectRedirectReplyFrame() {
  const char* const kStandardReplyHeaders[] = {
      ":status", "302 Found",
      ":version", "HTTP/1.1",
      "location", kRedirectUrl,
      "set-cookie", "foo=bar"
  };

  return ConstructSpdyControlFrame(NULL,
                                   0,
                                   false,
                                   kStreamId,
                                   LOWEST,
                                   SYN_REPLY,
                                   CONTROL_FLAG_NONE,
                                   kStandardReplyHeaders,
                                   arraysize(kStandardReplyHeaders));
}

// Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
SpdyFrame*
SpdyProxyClientSocketSpdy3Test::ConstructConnectErrorReplyFrame() {
  const char* const kStandardReplyHeaders[] = {
      ":status", "500 Internal Server Error",
      ":version", "HTTP/1.1",
  };

  return ConstructSpdyControlFrame(NULL,
                                   0,
                                   false,
                                   kStreamId,
                                   LOWEST,
                                   SYN_REPLY,
                                   CONTROL_FLAG_NONE,
                                   kStandardReplyHeaders,
                                   arraysize(kStandardReplyHeaders));
}

SpdyFrame* SpdyProxyClientSocketSpdy3Test::ConstructBodyFrame(
    const char* data,
    int length) {
  return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
}

// ----------- Connect

TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectSendsCorrectRequest) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 2),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  ASSERT_FALSE(sock_->IsConnected());

  AssertConnectSucceeds();

  AssertConnectionEstablished();
}

TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectWithAuthRequested) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 2),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);

  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
  ASSERT_TRUE(response != NULL);
  ASSERT_EQ(407, response->headers->response_code());
  ASSERT_EQ("Proxy Authentication Required",
            response->headers->GetStatusText());
}

TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectWithAuthCredentials) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 2),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));
  AddAuthToCache();

  AssertConnectSucceeds();

  AssertConnectionEstablished();
}

TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectRedirects) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 2),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);

  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
  ASSERT_TRUE(response != NULL);

  const HttpResponseHeaders* headers = response->headers;
  ASSERT_EQ(302, headers->response_code());
  ASSERT_FALSE(headers->HasHeader("set-cookie"));
  ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));

  std::string location;
  ASSERT_TRUE(headers->IsRedirect(&location));
  ASSERT_EQ(location, kRedirectUrl);
}

TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectFails) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    MockRead(ASYNC, 0, 1),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  ASSERT_FALSE(sock_->IsConnected());

  AssertConnectFails(ERR_CONNECTION_CLOSED);

  ASSERT_FALSE(sock_->IsConnected());
}

// ----------- WasEverUsed

TEST_F(SpdyProxyClientSocketSpdy3Test, WasEverUsedReturnsCorrectValues) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 2),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  EXPECT_FALSE(sock_->WasEverUsed());
  AssertConnectSucceeds();
  EXPECT_TRUE(sock_->WasEverUsed());
  sock_->Disconnect();
  EXPECT_TRUE(sock_->WasEverUsed());
}

// ----------- GetPeerAddress

TEST_F(SpdyProxyClientSocketSpdy3Test, GetPeerAddressReturnsCorrectValues) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 2),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  net::IPEndPoint addr;
  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));

  AssertConnectSucceeds();
  EXPECT_TRUE(sock_->IsConnected());
  EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));

  Run(1);

  EXPECT_FALSE(sock_->IsConnected());
  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));

  sock_->Disconnect();

  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
}

// ----------- Write

TEST_F(SpdyProxyClientSocketSpdy3Test, WriteSendsDataInDataFrame) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
    CreateMockWrite(*msg1, 2, SYNCHRONOUS),
    CreateMockWrite(*msg2, 3, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 4),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  AssertAsyncWriteSucceeds(kMsg1, kLen1);
  AssertAsyncWriteSucceeds(kMsg2, kLen2);
}

TEST_F(SpdyProxyClientSocketSpdy3Test, WriteSplitsLargeDataIntoMultipleFrames) {
  std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
                                                       chunk_data.length()));
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
    CreateMockWrite(*chunk, 2, SYNCHRONOUS),
    CreateMockWrite(*chunk, 3, SYNCHRONOUS),
    CreateMockWrite(*chunk, 4, SYNCHRONOUS)
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 5),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
                                                   big_data.length()));

  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(),
                                         write_callback_.callback()));
  data_->RunFor(3);

  EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
}

// ----------- Read

TEST_F(SpdyProxyClientSocketSpdy3Test, ReadReadsDataInDataFrame) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*msg1, 2, ASYNC),
    MockRead(ASYNC, 0, 3),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  Run(1);  // SpdySession consumes the next read and sends it to
           // sock_ to be buffered.
  AssertSyncReadEquals(kMsg1, kLen1);
}

TEST_F(SpdyProxyClientSocketSpdy3Test, ReadDataFromBufferedFrames) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*msg1, 2, ASYNC),
    CreateMockRead(*msg2, 3, ASYNC),
    MockRead(ASYNC, 0, 4),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  Run(1);  // SpdySession consumes the next read and sends it to
           // sock_ to be buffered.
  AssertSyncReadEquals(kMsg1, kLen1);
  Run(1);  // SpdySession consumes the next read and sends it to
           // sock_ to be buffered.
  AssertSyncReadEquals(kMsg2, kLen2);
}

TEST_F(SpdyProxyClientSocketSpdy3Test, ReadDataMultipleBufferedFrames) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*msg1, 2, ASYNC),
    CreateMockRead(*msg2, 3, ASYNC),
    MockRead(ASYNC, 0, 4),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  Run(2);  // SpdySession consumes the next two reads and sends then to
           // sock_ to be buffered.
  AssertSyncReadEquals(kMsg1, kLen1);
  AssertSyncReadEquals(kMsg2, kLen2);
}

TEST_F(SpdyProxyClientSocketSpdy3Test,
       LargeReadWillMergeDataFromDifferentFrames) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*msg3, 2, ASYNC),
    CreateMockRead(*msg3, 3, ASYNC),
    MockRead(ASYNC, 0, 4),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  Run(2);  // SpdySession consumes the next two reads and sends then to
           // sock_ to be buffered.
  // The payload from two data frames, each with kMsg3 will be combined
  // together into a single read().
  AssertSyncReadEquals(kMsg33, kLen33);
}

TEST_F(SpdyProxyClientSocketSpdy3Test, MultipleShortReadsThenMoreRead) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*msg1, 2, ASYNC),
    CreateMockRead(*msg3, 3, ASYNC),
    CreateMockRead(*msg3, 4, ASYNC),
    CreateMockRead(*msg2, 5, ASYNC),
    MockRead(ASYNC, 0, 6),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  Run(4);  // SpdySession consumes the next four reads and sends then to
           // sock_ to be buffered.
  AssertSyncReadEquals(kMsg1, kLen1);
  // The payload from two data frames, each with kMsg3 will be combined
  // together into a single read().
  AssertSyncReadEquals(kMsg33, kLen33);
  AssertSyncReadEquals(kMsg2, kLen2);
}

TEST_F(SpdyProxyClientSocketSpdy3Test, ReadWillSplitDataFromLargeFrame) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*msg1, 2, ASYNC),
    CreateMockRead(*msg33, 3, ASYNC),
    MockRead(ASYNC, 0, 4),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  Run(2);  // SpdySession consumes the next two reads and sends then to
           // sock_ to be buffered.
  AssertSyncReadEquals(kMsg1, kLen1);
  // The payload from the single large data frame will be read across
  // two different reads.
  AssertSyncReadEquals(kMsg3, kLen3);
  AssertSyncReadEquals(kMsg3, kLen3);
}

TEST_F(SpdyProxyClientSocketSpdy3Test, MultipleReadsFromSameLargeFrame) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*msg333, 2, ASYNC),
    MockRead(ASYNC, 0, 3),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  Run(1);  // SpdySession consumes the next read and sends it to
           // sock_ to be buffered.
  // The payload from the single large data frame will be read across
  // two different reads.
  AssertSyncReadEquals(kMsg33, kLen33);

  // Now attempt to do a read of more data than remains buffered
  scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
  ASSERT_EQ(kLen3, sock_->Read(buf, kLen33, read_callback_.callback()));
  ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
  ASSERT_TRUE(sock_->IsConnected());
}

TEST_F(SpdyProxyClientSocketSpdy3Test, ReadAuthResponseBody) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*msg1, 2, ASYNC),
    CreateMockRead(*msg2, 3, ASYNC),
    MockRead(ASYNC, 0, 4),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);

  Run(2);  // SpdySession consumes the next two reads and sends then to
           // sock_ to be buffered.
  AssertSyncReadEquals(kMsg1, kLen1);
  AssertSyncReadEquals(kMsg2, kLen2);
}

TEST_F(SpdyProxyClientSocketSpdy3Test, ReadErrorResponseBody) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*msg1, 2, ASYNC),
    CreateMockRead(*msg2, 3, ASYNC),
    MockRead(ASYNC, 0, 4),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
}

// ----------- Reads and Writes

TEST_F(SpdyProxyClientSocketSpdy3Test, AsyncReadAroundWrite) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
    CreateMockWrite(*msg2, 3, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*msg1, 2, ASYNC),  // sync read
    CreateMockRead(*msg3, 4, ASYNC),  // async read
    MockRead(ASYNC, 0, 5),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  Run(1);
  AssertSyncReadEquals(kMsg1, kLen1);

  AssertReadStarts(kMsg3, kLen3);
  // Read should block until after the write succeeds

  AssertAsyncWriteSucceeds(kMsg2, kLen2);  // Runs 1 step

  ASSERT_FALSE(read_callback_.have_result());
  Run(1);
  // Now the read will return
  AssertReadReturns(kMsg3, kLen3);
}

TEST_F(SpdyProxyClientSocketSpdy3Test, AsyncWriteAroundReads) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
    CreateMockWrite(*msg2, 4, ASYNC),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*msg1, 2, ASYNC),
    CreateMockRead(*msg3, 3, ASYNC),
    MockRead(ASYNC, 0, 5),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  Run(1);
  AssertSyncReadEquals(kMsg1, kLen1);
  // Write should block until the read completes
  AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);

  AssertAsyncReadEquals(kMsg3, kLen3);

  ASSERT_FALSE(write_callback_.have_result());

  // Now the write will complete
  Run(1);
  AssertWriteLength(kLen2);
}

// ----------- Reading/Writing on Closed socket

// Reading from an already closed socket should return 0
TEST_F(SpdyProxyClientSocketSpdy3Test, ReadOnClosedSocketReturnsZero) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 2),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  Run(1);

  ASSERT_FALSE(sock_->IsConnected());
  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
  ASSERT_FALSE(sock_->IsConnectedAndIdle());
}

// Read pending when socket is closed should return 0
TEST_F(SpdyProxyClientSocketSpdy3Test, PendingReadOnCloseReturnsZero) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 2),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  AssertReadStarts(kMsg1, kLen1);

  Run(1);

  ASSERT_EQ(0, read_callback_.WaitForResult());
}

// Reading from a disconnected socket is an error
TEST_F(SpdyProxyClientSocketSpdy3Test,
       ReadOnDisconnectSocketReturnsNotConnected) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 2),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  sock_->Disconnect();

  ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
            sock_->Read(NULL, 1, CompletionCallback()));
}

// Reading buffered data from an already closed socket should return
// buffered data, then 0.
TEST_F(SpdyProxyClientSocketSpdy3Test, ReadOnClosedSocketReturnsBufferedData) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*msg1, 2, ASYNC),
    MockRead(ASYNC, 0, 3),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  Run(2);

  ASSERT_FALSE(sock_->IsConnected());
  scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
  ASSERT_EQ(kLen1, sock_->Read(buf, kLen1, CompletionCallback()));
  ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));

  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
  sock_->Disconnect();
  ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
            sock_->Read(NULL, 1, CompletionCallback()));
}

// Calling Write() on a closed socket is an error
TEST_F(SpdyProxyClientSocketSpdy3Test, WriteOnClosedStream) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 2),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  Run(1);  // Read EOF which will close the stream
  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
            sock_->Write(buf, buf->size(), CompletionCallback()));
}

// Calling Write() on a disconnected socket is an error
TEST_F(SpdyProxyClientSocketSpdy3Test, WriteOnDisconnectedSocket) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 2),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  sock_->Disconnect();

  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
            sock_->Write(buf, buf->size(), CompletionCallback()));
}

// If the socket is closed with a pending Write(), the callback
// should be called with ERR_CONNECTION_CLOSED.
TEST_F(SpdyProxyClientSocketSpdy3Test, WritePendingOnClose) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
    MockWrite(ASYNC, ERR_IO_PENDING, 2),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 3),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  EXPECT_TRUE(sock_->IsConnected());

  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
  EXPECT_EQ(ERR_IO_PENDING,
            sock_->Write(buf, buf->size(), write_callback_.callback()));

  Run(1);

  EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
}

// If the socket is Disconnected with a pending Write(), the callback
// should not be called.
TEST_F(SpdyProxyClientSocketSpdy3Test, DisconnectWithWritePending) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
    MockWrite(SYNCHRONOUS, 0, 2),  // EOF
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 3),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  EXPECT_TRUE(sock_->IsConnected());

  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
  EXPECT_EQ(ERR_IO_PENDING,
            sock_->Write(buf, buf->size(), write_callback_.callback()));

  sock_->Disconnect();

  EXPECT_FALSE(sock_->IsConnected());
  EXPECT_FALSE(write_callback_.have_result());
}

// If the socket is Disconnected with a pending Read(), the callback
// should not be called.
TEST_F(SpdyProxyClientSocketSpdy3Test, DisconnectWithReadPending) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    MockRead(ASYNC, 0, 2),  // EOF
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  EXPECT_TRUE(sock_->IsConnected());

  scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
  ASSERT_EQ(ERR_IO_PENDING,
            sock_->Read(buf, kLen1, read_callback_.callback()));

  sock_->Disconnect();

  EXPECT_FALSE(sock_->IsConnected());
  EXPECT_FALSE(read_callback_.have_result());
}

// If the socket is Reset when both a read and write are pending,
// both should be called back.
TEST_F(SpdyProxyClientSocketSpdy3Test, RstWithReadAndWritePending) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
    MockWrite(ASYNC, ERR_IO_PENDING, 2),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, CANCEL));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*rst, 3, ASYNC),
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  EXPECT_TRUE(sock_->IsConnected());

  scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
  ASSERT_EQ(ERR_IO_PENDING,
            sock_->Read(read_buf, kLen1, read_callback_.callback()));

  scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
  EXPECT_EQ(ERR_IO_PENDING,
            sock_->Write(write_buf, write_buf->size(),
                         write_callback_.callback()));

  Run(2);

  EXPECT_TRUE(sock_.get());
  EXPECT_TRUE(read_callback_.have_result());
  EXPECT_TRUE(write_callback_.have_result());
}

// CompletionCallback that causes the SpdyProxyClientSocket to be
// deleted when Run is invoked.
class DeleteSockCallback : public TestCompletionCallbackBase {
 public:
  explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
    : sock_(sock),
      ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
          base::Bind(&DeleteSockCallback::OnComplete,
                     base::Unretained(this)))) {
  }

  virtual ~DeleteSockCallback() {
  }

  const CompletionCallback& callback() const { return callback_; }

 private:
  void OnComplete(int result) {
    sock_->reset(NULL);
    SetResult(result);
  }

  scoped_ptr<SpdyProxyClientSocket>* sock_;
  CompletionCallback callback_;

  DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
};

// If the socket is Reset when both a read and write are pending, and the
// read callback causes the socket to be deleted, the write callback should
// not be called.
TEST_F(SpdyProxyClientSocketSpdy3Test, RstWithReadAndWritePendingDelete) {
  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
  MockWrite writes[] = {
    CreateMockWrite(*conn, 0, SYNCHRONOUS),
    MockWrite(ASYNC, ERR_IO_PENDING, 2),
  };

  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
  scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, CANCEL));
  MockRead reads[] = {
    CreateMockRead(*resp, 1, ASYNC),
    CreateMockRead(*rst, 3, ASYNC),
  };

  Initialize(reads, arraysize(reads), writes, arraysize(writes));

  AssertConnectSucceeds();

  EXPECT_TRUE(sock_->IsConnected());

  DeleteSockCallback read_callback(&sock_);

  scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
  ASSERT_EQ(ERR_IO_PENDING,
            sock_->Read(read_buf, kLen1, read_callback.callback()));

  scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(write_buf, write_buf->size(),
                                         write_callback_.callback()));

  Run(2);

  EXPECT_FALSE(sock_.get());
  EXPECT_TRUE(read_callback.have_result());
  EXPECT_FALSE(write_callback_.have_result());
}

}  // namespace net
