Home | History | Annotate | Download | only in spdy
      1 // Copyright (c) 2012 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 #include "net/spdy/spdy_proxy_client_socket.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/strings/utf_string_conversions.h"
     10 #include "net/base/address_list.h"
     11 #include "net/base/capturing_net_log.h"
     12 #include "net/base/net_log.h"
     13 #include "net/base/net_log_unittest.h"
     14 #include "net/base/test_completion_callback.h"
     15 #include "net/base/winsock_init.h"
     16 #include "net/dns/mock_host_resolver.h"
     17 #include "net/http/http_response_headers.h"
     18 #include "net/http/http_response_info.h"
     19 #include "net/socket/client_socket_factory.h"
     20 #include "net/socket/next_proto.h"
     21 #include "net/socket/socket_test_util.h"
     22 #include "net/socket/tcp_client_socket.h"
     23 #include "net/spdy/buffered_spdy_framer.h"
     24 #include "net/spdy/spdy_http_utils.h"
     25 #include "net/spdy/spdy_protocol.h"
     26 #include "net/spdy/spdy_session_pool.h"
     27 #include "net/spdy/spdy_test_util_common.h"
     28 #include "testing/gtest/include/gtest/gtest.h"
     29 #include "testing/platform_test.h"
     30 
     31 //-----------------------------------------------------------------------------
     32 
     33 namespace {
     34 
     35 static const char kRequestUrl[] = "https://www.google.com/";
     36 static const char kOriginHost[] = "www.google.com";
     37 static const int kOriginPort = 443;
     38 static const char kOriginHostPort[] = "www.google.com:443";
     39 static const char kProxyUrl[] = "https://myproxy:6121/";
     40 static const char kProxyHost[] = "myproxy";
     41 static const int kProxyPort = 6121;
     42 static const char kUserAgent[] = "Mozilla/1.0";
     43 
     44 static const int kStreamId = 1;
     45 
     46 static const char kMsg1[] = "\0hello!\xff";
     47 static const int kLen1 = 8;
     48 static const char kMsg2[] = "\0a2345678\0";
     49 static const int kLen2 = 10;
     50 static const char kMsg3[] = "bye!";
     51 static const int kLen3 = 4;
     52 static const char kMsg33[] = "bye!bye!";
     53 static const int kLen33 = kLen3 + kLen3;
     54 static const char kMsg333[] = "bye!bye!bye!";
     55 static const int kLen333 = kLen3 + kLen3 + kLen3;
     56 
     57 static const char kRedirectUrl[] = "https://example.com/";
     58 
     59 }  // anonymous namespace
     60 
     61 namespace net {
     62 
     63 class SpdyProxyClientSocketTest
     64     : public PlatformTest,
     65       public testing::WithParamInterface<NextProto> {
     66  public:
     67   SpdyProxyClientSocketTest();
     68 
     69   virtual void TearDown();
     70 
     71  protected:
     72   void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
     73                   size_t writes_count);
     74   void PopulateConnectRequestIR(SpdyHeaderBlock* syn_ir);
     75   void PopulateConnectReplyIR(SpdyHeaderBlock* block, const char* status);
     76   SpdyFrame* ConstructConnectRequestFrame();
     77   SpdyFrame* ConstructConnectAuthRequestFrame();
     78   SpdyFrame* ConstructConnectReplyFrame();
     79   SpdyFrame* ConstructConnectAuthReplyFrame();
     80   SpdyFrame* ConstructConnectRedirectReplyFrame();
     81   SpdyFrame* ConstructConnectErrorReplyFrame();
     82   SpdyFrame* ConstructBodyFrame(const char* data, int length);
     83   scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
     84   void AssertConnectSucceeds();
     85   void AssertConnectFails(int result);
     86   void AssertConnectionEstablished();
     87   void AssertSyncReadEquals(const char* data, int len);
     88   void AssertAsyncReadEquals(const char* data, int len);
     89   void AssertReadStarts(const char* data, int len);
     90   void AssertReadReturns(const char* data, int len);
     91   void AssertAsyncWriteSucceeds(const char* data, int len);
     92   void AssertWriteReturns(const char* data, int len, int rv);
     93   void AssertWriteLength(int len);
     94   void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
     95                                         int num_reads);
     96 
     97   void AddAuthToCache() {
     98     const base::string16 kFoo(base::ASCIIToUTF16("foo"));
     99     const base::string16 kBar(base::ASCIIToUTF16("bar"));
    100     session_->http_auth_cache()->Add(GURL(kProxyUrl),
    101                                      "MyRealm1",
    102                                      HttpAuth::AUTH_SCHEME_BASIC,
    103                                      "Basic realm=MyRealm1",
    104                                      AuthCredentials(kFoo, kBar),
    105                                      "/");
    106   }
    107 
    108   void Run(int steps) {
    109     data_->StopAfter(steps);
    110     data_->Run();
    111   }
    112 
    113   void CloseSpdySession(net::Error error, const std::string& description) {
    114     spdy_session_->CloseSessionOnError(error, description);
    115   }
    116 
    117   SpdyTestUtil spdy_util_;
    118   scoped_ptr<SpdyProxyClientSocket> sock_;
    119   TestCompletionCallback read_callback_;
    120   TestCompletionCallback write_callback_;
    121   scoped_ptr<DeterministicSocketData> data_;
    122   CapturingBoundNetLog net_log_;
    123 
    124  private:
    125   scoped_refptr<HttpNetworkSession> session_;
    126   scoped_refptr<IOBuffer> read_buf_;
    127   SpdySessionDependencies session_deps_;
    128   MockConnect connect_data_;
    129   base::WeakPtr<SpdySession> spdy_session_;
    130   BufferedSpdyFramer framer_;
    131 
    132   std::string user_agent_;
    133   GURL url_;
    134   HostPortPair proxy_host_port_;
    135   HostPortPair endpoint_host_port_pair_;
    136   ProxyServer proxy_;
    137   SpdySessionKey endpoint_spdy_session_key_;
    138 
    139   DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
    140 };
    141 
    142 INSTANTIATE_TEST_CASE_P(
    143     NextProto,
    144     SpdyProxyClientSocketTest,
    145     testing::Values(kProtoDeprecatedSPDY2,
    146                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
    147 
    148 SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
    149     : spdy_util_(GetParam()),
    150       session_(NULL),
    151       read_buf_(NULL),
    152       session_deps_(GetParam()),
    153       connect_data_(SYNCHRONOUS, OK),
    154       framer_(spdy_util_.spdy_version(), false),
    155       user_agent_(kUserAgent),
    156       url_(kRequestUrl),
    157       proxy_host_port_(kProxyHost, kProxyPort),
    158       endpoint_host_port_pair_(kOriginHost, kOriginPort),
    159       proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
    160       endpoint_spdy_session_key_(endpoint_host_port_pair_,
    161                                  proxy_,
    162                                  PRIVACY_MODE_DISABLED) {
    163   session_deps_.net_log = net_log_.bound().net_log();
    164 }
    165 
    166 void SpdyProxyClientSocketTest::TearDown() {
    167   if (session_.get() != NULL)
    168     session_->spdy_session_pool()->CloseAllSessions();
    169 
    170   // Empty the current queue.
    171   base::MessageLoop::current()->RunUntilIdle();
    172   PlatformTest::TearDown();
    173 }
    174 
    175 void SpdyProxyClientSocketTest::Initialize(MockRead* reads,
    176                                                 size_t reads_count,
    177                                                 MockWrite* writes,
    178                                                 size_t writes_count) {
    179   data_.reset(new DeterministicSocketData(reads, reads_count,
    180                                           writes, writes_count));
    181   data_->set_connect_data(connect_data_);
    182   data_->SetStop(2);
    183 
    184   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
    185       data_.get());
    186   session_deps_.host_resolver->set_synchronous_mode(true);
    187 
    188   session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
    189       &session_deps_);
    190 
    191   // Creates the SPDY session and stream.
    192   spdy_session_ =
    193       CreateInsecureSpdySession(
    194           session_, endpoint_spdy_session_key_, BoundNetLog());
    195   base::WeakPtr<SpdyStream> spdy_stream(
    196       CreateStreamSynchronously(
    197           SPDY_BIDIRECTIONAL_STREAM, spdy_session_, url_, LOWEST,
    198           net_log_.bound()));
    199   ASSERT_TRUE(spdy_stream.get() != NULL);
    200 
    201   // Create the SpdyProxyClientSocket.
    202   sock_.reset(
    203       new SpdyProxyClientSocket(spdy_stream, user_agent_,
    204                                 endpoint_host_port_pair_, url_,
    205                                 proxy_host_port_, net_log_.bound(),
    206                                 session_->http_auth_cache(),
    207                                 session_->http_auth_handler_factory()));
    208 }
    209 
    210 scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
    211     const char* data, int size) {
    212   scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
    213   memcpy(buf->data(), data, size);
    214   return buf;
    215 }
    216 
    217 void SpdyProxyClientSocketTest::AssertConnectSucceeds() {
    218   ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
    219   data_->Run();
    220   ASSERT_EQ(OK, read_callback_.WaitForResult());
    221 }
    222 
    223 void SpdyProxyClientSocketTest::AssertConnectFails(int result) {
    224   ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
    225   data_->Run();
    226   ASSERT_EQ(result, read_callback_.WaitForResult());
    227 }
    228 
    229 void SpdyProxyClientSocketTest::AssertConnectionEstablished() {
    230   const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
    231   ASSERT_TRUE(response != NULL);
    232   ASSERT_EQ(200, response->headers->response_code());
    233 }
    234 
    235 void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data,
    236                                                      int len) {
    237   scoped_refptr<IOBuffer> buf(new IOBuffer(len));
    238   ASSERT_EQ(len, sock_->Read(buf.get(), len, CompletionCallback()));
    239   ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
    240   ASSERT_TRUE(sock_->IsConnected());
    241 }
    242 
    243 void SpdyProxyClientSocketTest::AssertAsyncReadEquals(const char* data,
    244                                                            int len) {
    245   data_->StopAfter(1);
    246   // Issue the read, which will be completed asynchronously
    247   scoped_refptr<IOBuffer> buf(new IOBuffer(len));
    248   ASSERT_EQ(ERR_IO_PENDING,
    249             sock_->Read(buf.get(), len, read_callback_.callback()));
    250   EXPECT_TRUE(sock_->IsConnected());
    251   data_->Run();
    252 
    253   EXPECT_TRUE(sock_->IsConnected());
    254 
    255   // Now the read will return
    256   EXPECT_EQ(len, read_callback_.WaitForResult());
    257   ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
    258 }
    259 
    260 void SpdyProxyClientSocketTest::AssertReadStarts(const char* data,
    261                                                       int len) {
    262   data_->StopAfter(1);
    263   // Issue the read, which will be completed asynchronously
    264   read_buf_ = new IOBuffer(len);
    265   ASSERT_EQ(ERR_IO_PENDING,
    266             sock_->Read(read_buf_.get(), len, read_callback_.callback()));
    267   EXPECT_TRUE(sock_->IsConnected());
    268 }
    269 
    270 void SpdyProxyClientSocketTest::AssertReadReturns(const char* data,
    271                                                        int len) {
    272   EXPECT_TRUE(sock_->IsConnected());
    273 
    274   // Now the read will return
    275   EXPECT_EQ(len, read_callback_.WaitForResult());
    276   ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
    277 }
    278 
    279 void SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data,
    280                                                               int len) {
    281   AssertWriteReturns(data, len, ERR_IO_PENDING);
    282   data_->RunFor(1);
    283   AssertWriteLength(len);
    284 }
    285 
    286 void SpdyProxyClientSocketTest::AssertWriteReturns(const char* data,
    287                                                         int len,
    288                                                         int rv) {
    289   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
    290   EXPECT_EQ(rv,
    291             sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
    292 }
    293 
    294 void SpdyProxyClientSocketTest::AssertWriteLength(int len) {
    295   EXPECT_EQ(len, write_callback_.WaitForResult());
    296 }
    297 
    298 void SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds(
    299     const char* data, int len, int num_reads) {
    300   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
    301 
    302   EXPECT_EQ(ERR_IO_PENDING,
    303             sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
    304 
    305   for (int i = 0; i < num_reads; i++) {
    306     Run(1);
    307     AssertSyncReadEquals(kMsg2, kLen2);
    308   }
    309 
    310   write_callback_.WaitForResult();
    311 }
    312 
    313 void SpdyProxyClientSocketTest::PopulateConnectRequestIR(
    314     SpdyHeaderBlock* block) {
    315   (*block)[spdy_util_.GetMethodKey()] = "CONNECT";
    316   (*block)[spdy_util_.GetPathKey()] = kOriginHostPort;
    317   (*block)[spdy_util_.GetHostKey()] = kOriginHost;
    318   (*block)["user-agent"] = kUserAgent;
    319   spdy_util_.MaybeAddVersionHeader(block);
    320 }
    321 
    322 void SpdyProxyClientSocketTest::PopulateConnectReplyIR(SpdyHeaderBlock* block,
    323                                                        const char* status) {
    324   (*block)[spdy_util_.GetStatusKey()] = status;
    325   spdy_util_.MaybeAddVersionHeader(block);
    326 }
    327 
    328 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
    329 SpdyFrame*
    330 SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
    331   SpdyHeaderBlock block;
    332   PopulateConnectRequestIR(&block);
    333   return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
    334 }
    335 
    336 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
    337 // Proxy-Authorization headers.
    338 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
    339   SpdyHeaderBlock block;
    340   PopulateConnectRequestIR(&block);
    341   block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
    342   return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
    343 }
    344 
    345 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
    346 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
    347   SpdyHeaderBlock block;
    348   PopulateConnectReplyIR(&block, "200");
    349   SpdySynReplyIR reply_ir(kStreamId);
    350   return spdy_util_.ConstructSpdyReply(kStreamId, block);
    351 }
    352 
    353 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT,
    354 // including Proxy-Authenticate headers.
    355 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
    356   SpdyHeaderBlock block;
    357   PopulateConnectReplyIR(&block, "407");
    358   block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
    359   return spdy_util_.ConstructSpdyReply(kStreamId, block);
    360 }
    361 
    362 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
    363 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
    364   SpdyHeaderBlock block;
    365   PopulateConnectReplyIR(&block, "302");
    366   block["location"] = kRedirectUrl;
    367   block["set-cookie"] = "foo=bar";
    368   return spdy_util_.ConstructSpdyReply(kStreamId, block);
    369 }
    370 
    371 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
    372 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
    373   SpdyHeaderBlock block;
    374   PopulateConnectReplyIR(&block, "500");
    375   return spdy_util_.ConstructSpdyReply(kStreamId, block);
    376 }
    377 
    378 SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(
    379     const char* data,
    380     int length) {
    381   return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
    382 }
    383 
    384 // ----------- Connect
    385 
    386 TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
    387   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    388   MockWrite writes[] = {
    389     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    390   };
    391 
    392   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    393   MockRead reads[] = {
    394     CreateMockRead(*resp, 1, ASYNC),
    395     MockRead(ASYNC, 0, 2),  // EOF
    396   };
    397 
    398   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    399 
    400   ASSERT_FALSE(sock_->IsConnected());
    401 
    402   AssertConnectSucceeds();
    403 
    404   AssertConnectionEstablished();
    405 }
    406 
    407 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
    408   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    409   MockWrite writes[] = {
    410     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    411   };
    412 
    413   scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
    414   MockRead reads[] = {
    415     CreateMockRead(*resp, 1, ASYNC),
    416     MockRead(ASYNC, 0, 2),  // EOF
    417   };
    418 
    419   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    420 
    421   AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
    422 
    423   const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
    424   ASSERT_TRUE(response != NULL);
    425   ASSERT_EQ(407, response->headers->response_code());
    426 }
    427 
    428 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
    429   scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
    430   MockWrite writes[] = {
    431     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    432   };
    433 
    434   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    435   MockRead reads[] = {
    436     CreateMockRead(*resp, 1, ASYNC),
    437     MockRead(ASYNC, 0, 2),  // EOF
    438   };
    439 
    440   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    441   AddAuthToCache();
    442 
    443   AssertConnectSucceeds();
    444 
    445   AssertConnectionEstablished();
    446 }
    447 
    448 TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
    449   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    450   scoped_ptr<SpdyFrame> rst(
    451       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
    452   MockWrite writes[] = {
    453       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
    454   };
    455 
    456   scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
    457   MockRead reads[] = {
    458       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),  // EOF
    459   };
    460 
    461   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    462 
    463   AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
    464 
    465   const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
    466   ASSERT_TRUE(response != NULL);
    467 
    468   const HttpResponseHeaders* headers = response->headers.get();
    469   ASSERT_EQ(302, headers->response_code());
    470   ASSERT_FALSE(headers->HasHeader("set-cookie"));
    471   ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
    472 
    473   std::string location;
    474   ASSERT_TRUE(headers->IsRedirect(&location));
    475   ASSERT_EQ(location, kRedirectUrl);
    476 
    477   // Let the RST_STREAM write while |rst| is in-scope.
    478   base::MessageLoop::current()->RunUntilIdle();
    479 }
    480 
    481 TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
    482   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    483   MockWrite writes[] = {
    484     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    485   };
    486 
    487   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    488   MockRead reads[] = {
    489     MockRead(ASYNC, 0, 1),  // EOF
    490   };
    491 
    492   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    493 
    494   ASSERT_FALSE(sock_->IsConnected());
    495 
    496   AssertConnectFails(ERR_CONNECTION_CLOSED);
    497 
    498   ASSERT_FALSE(sock_->IsConnected());
    499 }
    500 
    501 // ----------- WasEverUsed
    502 
    503 TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
    504   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    505   scoped_ptr<SpdyFrame> rst(
    506       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
    507   MockWrite writes[] = {
    508       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
    509   };
    510 
    511   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    512   MockRead reads[] = {
    513       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),  // EOF
    514   };
    515 
    516   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    517 
    518   EXPECT_FALSE(sock_->WasEverUsed());
    519   AssertConnectSucceeds();
    520   EXPECT_TRUE(sock_->WasEverUsed());
    521   sock_->Disconnect();
    522   EXPECT_TRUE(sock_->WasEverUsed());
    523 
    524   // Let the RST_STREAM write while |rst| is in-scope.
    525   base::MessageLoop::current()->RunUntilIdle();
    526 }
    527 
    528 // ----------- GetPeerAddress
    529 
    530 TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
    531   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    532   MockWrite writes[] = {
    533     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    534   };
    535 
    536   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    537   MockRead reads[] = {
    538     CreateMockRead(*resp, 1, ASYNC),
    539     MockRead(ASYNC, 0, 2),  // EOF
    540   };
    541 
    542   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    543 
    544   net::IPEndPoint addr;
    545   EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
    546 
    547   AssertConnectSucceeds();
    548   EXPECT_TRUE(sock_->IsConnected());
    549   EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
    550 
    551   Run(1);
    552 
    553   EXPECT_FALSE(sock_->IsConnected());
    554   EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
    555 
    556   sock_->Disconnect();
    557 
    558   EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
    559 }
    560 
    561 // ----------- Write
    562 
    563 TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
    564   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    565   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
    566   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
    567   MockWrite writes[] = {
    568     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    569     CreateMockWrite(*msg1, 2, SYNCHRONOUS),
    570     CreateMockWrite(*msg2, 3, SYNCHRONOUS),
    571   };
    572 
    573   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    574   MockRead reads[] = {
    575     CreateMockRead(*resp, 1, ASYNC),
    576     MockRead(ASYNC, 0, 4),  // EOF
    577   };
    578 
    579   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    580 
    581   AssertConnectSucceeds();
    582 
    583   AssertAsyncWriteSucceeds(kMsg1, kLen1);
    584   AssertAsyncWriteSucceeds(kMsg2, kLen2);
    585 }
    586 
    587 TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
    588   std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
    589   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    590   scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
    591                                                        chunk_data.length()));
    592   MockWrite writes[] = {
    593     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    594     CreateMockWrite(*chunk, 2, SYNCHRONOUS),
    595     CreateMockWrite(*chunk, 3, SYNCHRONOUS),
    596     CreateMockWrite(*chunk, 4, SYNCHRONOUS)
    597   };
    598 
    599   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    600   MockRead reads[] = {
    601     CreateMockRead(*resp, 1, ASYNC),
    602     MockRead(ASYNC, 0, 5),  // EOF
    603   };
    604 
    605   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    606 
    607   AssertConnectSucceeds();
    608 
    609   std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
    610   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
    611                                                    big_data.length()));
    612 
    613   EXPECT_EQ(ERR_IO_PENDING,
    614             sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
    615   data_->RunFor(3);
    616 
    617   EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
    618 }
    619 
    620 // ----------- Read
    621 
    622 TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
    623   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    624   MockWrite writes[] = {
    625     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    626   };
    627 
    628   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    629   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
    630   MockRead reads[] = {
    631     CreateMockRead(*resp, 1, ASYNC),
    632     CreateMockRead(*msg1, 2, ASYNC),
    633     MockRead(ASYNC, 0, 3),  // EOF
    634   };
    635 
    636   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    637 
    638   AssertConnectSucceeds();
    639 
    640   Run(1);  // SpdySession consumes the next read and sends it to
    641            // sock_ to be buffered.
    642   AssertSyncReadEquals(kMsg1, kLen1);
    643 }
    644 
    645 TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
    646   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    647   MockWrite writes[] = {
    648     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    649   };
    650 
    651   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    652   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
    653   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
    654   MockRead reads[] = {
    655     CreateMockRead(*resp, 1, ASYNC),
    656     CreateMockRead(*msg1, 2, ASYNC),
    657     CreateMockRead(*msg2, 3, ASYNC),
    658     MockRead(ASYNC, 0, 4),  // EOF
    659   };
    660 
    661   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    662 
    663   AssertConnectSucceeds();
    664 
    665   Run(1);  // SpdySession consumes the next read and sends it to
    666            // sock_ to be buffered.
    667   AssertSyncReadEquals(kMsg1, kLen1);
    668   Run(1);  // SpdySession consumes the next read and sends it to
    669            // sock_ to be buffered.
    670   AssertSyncReadEquals(kMsg2, kLen2);
    671 }
    672 
    673 TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
    674   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    675   MockWrite writes[] = {
    676     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    677   };
    678 
    679   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    680   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
    681   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
    682   MockRead reads[] = {
    683     CreateMockRead(*resp, 1, ASYNC),
    684     CreateMockRead(*msg1, 2, ASYNC),
    685     CreateMockRead(*msg2, 3, ASYNC),
    686     MockRead(ASYNC, 0, 4),  // EOF
    687   };
    688 
    689   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    690 
    691   AssertConnectSucceeds();
    692 
    693   Run(2);  // SpdySession consumes the next two reads and sends then to
    694            // sock_ to be buffered.
    695   AssertSyncReadEquals(kMsg1, kLen1);
    696   AssertSyncReadEquals(kMsg2, kLen2);
    697 }
    698 
    699 TEST_P(SpdyProxyClientSocketTest,
    700        LargeReadWillMergeDataFromDifferentFrames) {
    701   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    702   MockWrite writes[] = {
    703     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    704   };
    705 
    706   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    707   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
    708   scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
    709   MockRead reads[] = {
    710     CreateMockRead(*resp, 1, ASYNC),
    711     CreateMockRead(*msg3, 2, ASYNC),
    712     CreateMockRead(*msg3, 3, ASYNC),
    713     MockRead(ASYNC, 0, 4),  // EOF
    714   };
    715 
    716   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    717 
    718   AssertConnectSucceeds();
    719 
    720   Run(2);  // SpdySession consumes the next two reads and sends then to
    721            // sock_ to be buffered.
    722   // The payload from two data frames, each with kMsg3 will be combined
    723   // together into a single read().
    724   AssertSyncReadEquals(kMsg33, kLen33);
    725 }
    726 
    727 TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
    728   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    729   MockWrite writes[] = {
    730     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    731   };
    732 
    733   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    734   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
    735   scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
    736   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
    737   MockRead reads[] = {
    738     CreateMockRead(*resp, 1, ASYNC),
    739     CreateMockRead(*msg1, 2, ASYNC),
    740     CreateMockRead(*msg3, 3, ASYNC),
    741     CreateMockRead(*msg3, 4, ASYNC),
    742     CreateMockRead(*msg2, 5, ASYNC),
    743     MockRead(ASYNC, 0, 6),  // EOF
    744   };
    745 
    746   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    747 
    748   AssertConnectSucceeds();
    749 
    750   Run(4);  // SpdySession consumes the next four reads and sends then to
    751            // sock_ to be buffered.
    752   AssertSyncReadEquals(kMsg1, kLen1);
    753   // The payload from two data frames, each with kMsg3 will be combined
    754   // together into a single read().
    755   AssertSyncReadEquals(kMsg33, kLen33);
    756   AssertSyncReadEquals(kMsg2, kLen2);
    757 }
    758 
    759 TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
    760   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    761   MockWrite writes[] = {
    762     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    763   };
    764 
    765   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    766   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
    767   scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
    768   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
    769   MockRead reads[] = {
    770     CreateMockRead(*resp, 1, ASYNC),
    771     CreateMockRead(*msg1, 2, ASYNC),
    772     CreateMockRead(*msg33, 3, ASYNC),
    773     MockRead(ASYNC, 0, 4),  // EOF
    774   };
    775 
    776   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    777 
    778   AssertConnectSucceeds();
    779 
    780   Run(2);  // SpdySession consumes the next two reads and sends then to
    781            // sock_ to be buffered.
    782   AssertSyncReadEquals(kMsg1, kLen1);
    783   // The payload from the single large data frame will be read across
    784   // two different reads.
    785   AssertSyncReadEquals(kMsg3, kLen3);
    786   AssertSyncReadEquals(kMsg3, kLen3);
    787 }
    788 
    789 TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
    790   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    791   MockWrite writes[] = {
    792     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    793   };
    794 
    795   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    796   scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
    797   MockRead reads[] = {
    798     CreateMockRead(*resp, 1, ASYNC),
    799     CreateMockRead(*msg333, 2, ASYNC),
    800     MockRead(ASYNC, 0, 3),  // EOF
    801   };
    802 
    803   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    804 
    805   AssertConnectSucceeds();
    806 
    807   Run(1);  // SpdySession consumes the next read and sends it to
    808            // sock_ to be buffered.
    809   // The payload from the single large data frame will be read across
    810   // two different reads.
    811   AssertSyncReadEquals(kMsg33, kLen33);
    812 
    813   // Now attempt to do a read of more data than remains buffered
    814   scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
    815   ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, read_callback_.callback()));
    816   ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
    817   ASSERT_TRUE(sock_->IsConnected());
    818 }
    819 
    820 TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
    821   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    822   MockWrite writes[] = {
    823     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    824   };
    825 
    826   scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
    827   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
    828   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
    829   MockRead reads[] = {
    830     CreateMockRead(*resp, 1, ASYNC),
    831     CreateMockRead(*msg1, 2, ASYNC),
    832     CreateMockRead(*msg2, 3, ASYNC),
    833     MockRead(ASYNC, 0, 4),  // EOF
    834   };
    835 
    836   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    837 
    838   AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
    839 
    840   Run(2);  // SpdySession consumes the next two reads and sends then to
    841            // sock_ to be buffered.
    842   AssertSyncReadEquals(kMsg1, kLen1);
    843   AssertSyncReadEquals(kMsg2, kLen2);
    844 }
    845 
    846 TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
    847   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    848   MockWrite writes[] = {
    849     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    850   };
    851 
    852   scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
    853   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
    854   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
    855   MockRead reads[] = {
    856     CreateMockRead(*resp, 1, ASYNC),
    857     CreateMockRead(*msg1, 2, ASYNC),
    858     CreateMockRead(*msg2, 3, ASYNC),
    859     MockRead(ASYNC, 0, 4),  // EOF
    860   };
    861 
    862   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    863 
    864   AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
    865 }
    866 
    867 // ----------- Reads and Writes
    868 
    869 TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
    870   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    871   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
    872   MockWrite writes[] = {
    873     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    874     CreateMockWrite(*msg2, 3, SYNCHRONOUS),
    875   };
    876 
    877   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    878   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
    879   scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
    880   MockRead reads[] = {
    881     CreateMockRead(*resp, 1, ASYNC),
    882     CreateMockRead(*msg1, 2, ASYNC),  // sync read
    883     CreateMockRead(*msg3, 4, ASYNC),  // async read
    884     MockRead(ASYNC, 0, 5),  // EOF
    885   };
    886 
    887   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    888 
    889   AssertConnectSucceeds();
    890 
    891   Run(1);
    892   AssertSyncReadEquals(kMsg1, kLen1);
    893 
    894   AssertReadStarts(kMsg3, kLen3);
    895   // Read should block until after the write succeeds
    896 
    897   AssertAsyncWriteSucceeds(kMsg2, kLen2);  // Runs 1 step
    898 
    899   ASSERT_FALSE(read_callback_.have_result());
    900   Run(1);
    901   // Now the read will return
    902   AssertReadReturns(kMsg3, kLen3);
    903 }
    904 
    905 TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
    906   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    907   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
    908   MockWrite writes[] = {
    909     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    910     CreateMockWrite(*msg2, 4, ASYNC),
    911   };
    912 
    913   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    914   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
    915   scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
    916   MockRead reads[] = {
    917     CreateMockRead(*resp, 1, ASYNC),
    918     CreateMockRead(*msg1, 2, ASYNC),
    919     CreateMockRead(*msg3, 3, ASYNC),
    920     MockRead(ASYNC, 0, 5),  // EOF
    921   };
    922 
    923   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    924 
    925   AssertConnectSucceeds();
    926 
    927   Run(1);
    928   AssertSyncReadEquals(kMsg1, kLen1);
    929   // Write should block until the read completes
    930   AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
    931 
    932   AssertAsyncReadEquals(kMsg3, kLen3);
    933 
    934   ASSERT_FALSE(write_callback_.have_result());
    935 
    936   // Now the write will complete
    937   Run(1);
    938   AssertWriteLength(kLen2);
    939 }
    940 
    941 // ----------- Reading/Writing on Closed socket
    942 
    943 // Reading from an already closed socket should return 0
    944 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
    945   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    946   MockWrite writes[] = {
    947     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    948   };
    949 
    950   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    951   MockRead reads[] = {
    952     CreateMockRead(*resp, 1, ASYNC),
    953     MockRead(ASYNC, 0, 2),  // EOF
    954   };
    955 
    956   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    957 
    958   AssertConnectSucceeds();
    959 
    960   Run(1);
    961 
    962   ASSERT_FALSE(sock_->IsConnected());
    963   ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
    964   ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
    965   ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
    966   ASSERT_FALSE(sock_->IsConnectedAndIdle());
    967 }
    968 
    969 // Read pending when socket is closed should return 0
    970 TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
    971   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    972   MockWrite writes[] = {
    973     CreateMockWrite(*conn, 0, SYNCHRONOUS),
    974   };
    975 
    976   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
    977   MockRead reads[] = {
    978     CreateMockRead(*resp, 1, ASYNC),
    979     MockRead(ASYNC, 0, 2),  // EOF
    980   };
    981 
    982   Initialize(reads, arraysize(reads), writes, arraysize(writes));
    983 
    984   AssertConnectSucceeds();
    985 
    986   AssertReadStarts(kMsg1, kLen1);
    987 
    988   Run(1);
    989 
    990   ASSERT_EQ(0, read_callback_.WaitForResult());
    991 }
    992 
    993 // Reading from a disconnected socket is an error
    994 TEST_P(SpdyProxyClientSocketTest,
    995        ReadOnDisconnectSocketReturnsNotConnected) {
    996   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
    997   scoped_ptr<SpdyFrame> rst(
    998       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
    999   MockWrite writes[] = {
   1000       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
   1001   };
   1002 
   1003   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
   1004   MockRead reads[] = {
   1005       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),  // EOF
   1006   };
   1007 
   1008   Initialize(reads, arraysize(reads), writes, arraysize(writes));
   1009 
   1010   AssertConnectSucceeds();
   1011 
   1012   sock_->Disconnect();
   1013 
   1014   ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
   1015             sock_->Read(NULL, 1, CompletionCallback()));
   1016 
   1017   // Let the RST_STREAM write while |rst| is in-scope.
   1018   base::MessageLoop::current()->RunUntilIdle();
   1019 }
   1020 
   1021 // Reading buffered data from an already closed socket should return
   1022 // buffered data, then 0.
   1023 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
   1024   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
   1025   MockWrite writes[] = {
   1026     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   1027   };
   1028 
   1029   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
   1030   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
   1031   MockRead reads[] = {
   1032     CreateMockRead(*resp, 1, ASYNC),
   1033     CreateMockRead(*msg1, 2, ASYNC),
   1034     MockRead(ASYNC, 0, 3),  // EOF
   1035   };
   1036 
   1037   Initialize(reads, arraysize(reads), writes, arraysize(writes));
   1038 
   1039   AssertConnectSucceeds();
   1040 
   1041   Run(2);
   1042 
   1043   ASSERT_FALSE(sock_->IsConnected());
   1044   scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
   1045   ASSERT_EQ(kLen1, sock_->Read(buf.get(), kLen1, CompletionCallback()));
   1046   ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
   1047 
   1048   ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
   1049   ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
   1050   sock_->Disconnect();
   1051   ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
   1052             sock_->Read(NULL, 1, CompletionCallback()));
   1053 }
   1054 
   1055 // Calling Write() on a closed socket is an error
   1056 TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) {
   1057   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
   1058   MockWrite writes[] = {
   1059     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   1060   };
   1061 
   1062   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
   1063   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
   1064   MockRead reads[] = {
   1065     CreateMockRead(*resp, 1, ASYNC),
   1066     MockRead(ASYNC, 0, 2),  // EOF
   1067   };
   1068 
   1069   Initialize(reads, arraysize(reads), writes, arraysize(writes));
   1070 
   1071   AssertConnectSucceeds();
   1072 
   1073   Run(1);  // Read EOF which will close the stream
   1074   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
   1075   EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
   1076             sock_->Write(buf.get(), buf->size(), CompletionCallback()));
   1077 }
   1078 
   1079 // Calling Write() on a disconnected socket is an error
   1080 TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
   1081   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
   1082   scoped_ptr<SpdyFrame> rst(
   1083       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   1084   MockWrite writes[] = {
   1085       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
   1086   };
   1087 
   1088   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
   1089   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
   1090   MockRead reads[] = {
   1091       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),  // EOF
   1092   };
   1093 
   1094   Initialize(reads, arraysize(reads), writes, arraysize(writes));
   1095 
   1096   AssertConnectSucceeds();
   1097 
   1098   sock_->Disconnect();
   1099 
   1100   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
   1101   EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
   1102             sock_->Write(buf.get(), buf->size(), CompletionCallback()));
   1103 
   1104   // Let the RST_STREAM write while |rst| is in-scope.
   1105   base::MessageLoop::current()->RunUntilIdle();
   1106 }
   1107 
   1108 // If the socket is closed with a pending Write(), the callback
   1109 // should be called with ERR_CONNECTION_CLOSED.
   1110 TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
   1111   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
   1112   MockWrite writes[] = {
   1113     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   1114     MockWrite(ASYNC, ERR_ABORTED, 2),
   1115   };
   1116 
   1117   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
   1118   MockRead reads[] = {
   1119     CreateMockRead(*resp, 1, ASYNC),
   1120     MockRead(ASYNC, 0, 3),  // EOF
   1121   };
   1122 
   1123   Initialize(reads, arraysize(reads), writes, arraysize(writes));
   1124 
   1125   AssertConnectSucceeds();
   1126 
   1127   EXPECT_TRUE(sock_->IsConnected());
   1128 
   1129   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
   1130   EXPECT_EQ(ERR_IO_PENDING,
   1131             sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
   1132 
   1133   CloseSpdySession(ERR_ABORTED, std::string());
   1134 
   1135   EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
   1136 }
   1137 
   1138 // If the socket is Disconnected with a pending Write(), the callback
   1139 // should not be called.
   1140 TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
   1141   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
   1142   scoped_ptr<SpdyFrame> rst(
   1143       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   1144   MockWrite writes[] = {
   1145       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
   1146       MockWrite(SYNCHRONOUS, 0, 3),  // EOF
   1147   };
   1148 
   1149   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
   1150   MockRead reads[] = {
   1151       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 4),  // EOF
   1152   };
   1153 
   1154   Initialize(reads, arraysize(reads), writes, arraysize(writes));
   1155 
   1156   AssertConnectSucceeds();
   1157 
   1158   EXPECT_TRUE(sock_->IsConnected());
   1159 
   1160   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
   1161   EXPECT_EQ(ERR_IO_PENDING,
   1162             sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
   1163 
   1164   sock_->Disconnect();
   1165 
   1166   EXPECT_FALSE(sock_->IsConnected());
   1167   EXPECT_FALSE(write_callback_.have_result());
   1168 
   1169   // Let the RST_STREAM write while |rst| is in-scope.
   1170   base::MessageLoop::current()->RunUntilIdle();
   1171 }
   1172 
   1173 // If the socket is Disconnected with a pending Read(), the callback
   1174 // should not be called.
   1175 TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
   1176   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
   1177   scoped_ptr<SpdyFrame> rst(
   1178       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   1179   MockWrite writes[] = {
   1180       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
   1181   };
   1182 
   1183   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
   1184   MockRead reads[] = {
   1185       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),  // EOF
   1186   };
   1187 
   1188   Initialize(reads, arraysize(reads), writes, arraysize(writes));
   1189 
   1190   AssertConnectSucceeds();
   1191 
   1192   EXPECT_TRUE(sock_->IsConnected());
   1193 
   1194   scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
   1195   ASSERT_EQ(ERR_IO_PENDING,
   1196             sock_->Read(buf.get(), kLen1, read_callback_.callback()));
   1197 
   1198   sock_->Disconnect();
   1199 
   1200   EXPECT_FALSE(sock_->IsConnected());
   1201   EXPECT_FALSE(read_callback_.have_result());
   1202 
   1203   // Let the RST_STREAM write while |rst| is in-scope.
   1204   base::MessageLoop::current()->RunUntilIdle();
   1205 }
   1206 
   1207 // If the socket is Reset when both a read and write are pending,
   1208 // both should be called back.
   1209 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
   1210   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
   1211   MockWrite writes[] = {
   1212     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   1213     MockWrite(ASYNC, ERR_ABORTED, 3),
   1214   };
   1215 
   1216   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
   1217   scoped_ptr<SpdyFrame> rst(
   1218       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   1219   MockRead reads[] = {
   1220     CreateMockRead(*resp, 1, ASYNC),
   1221     CreateMockRead(*rst, 2, ASYNC),
   1222     MockRead(ASYNC, 0, 4)  // EOF
   1223   };
   1224 
   1225   Initialize(reads, arraysize(reads), writes, arraysize(writes));
   1226 
   1227   AssertConnectSucceeds();
   1228 
   1229   EXPECT_TRUE(sock_->IsConnected());
   1230 
   1231   scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
   1232   ASSERT_EQ(ERR_IO_PENDING,
   1233             sock_->Read(read_buf.get(), kLen1, read_callback_.callback()));
   1234 
   1235   scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
   1236   EXPECT_EQ(
   1237       ERR_IO_PENDING,
   1238       sock_->Write(
   1239           write_buf.get(), write_buf->size(), write_callback_.callback()));
   1240 
   1241   Run(2);
   1242 
   1243   EXPECT_TRUE(sock_.get());
   1244   EXPECT_TRUE(read_callback_.have_result());
   1245   EXPECT_TRUE(write_callback_.have_result());
   1246 
   1247   // Let the RST_STREAM write while |rst| is in-scope.
   1248   base::MessageLoop::current()->RunUntilIdle();
   1249 }
   1250 
   1251 // Makes sure the proxy client socket's source gets the expected NetLog events
   1252 // and only the expected NetLog events (No SpdySession events).
   1253 TEST_P(SpdyProxyClientSocketTest, NetLog) {
   1254   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
   1255   scoped_ptr<SpdyFrame> rst(
   1256       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   1257   MockWrite writes[] = {
   1258       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
   1259   };
   1260 
   1261   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
   1262   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
   1263   MockRead reads[] = {
   1264       CreateMockRead(*resp, 1, ASYNC), CreateMockRead(*msg1, 2, ASYNC),
   1265       MockRead(ASYNC, 0, 4),  // EOF
   1266   };
   1267 
   1268   Initialize(reads, arraysize(reads), writes, arraysize(writes));
   1269 
   1270   AssertConnectSucceeds();
   1271 
   1272   Run(1);  // SpdySession consumes the next read and sends it to
   1273            // sock_ to be buffered.
   1274   AssertSyncReadEquals(kMsg1, kLen1);
   1275 
   1276   NetLog::Source sock_source = sock_->NetLog().source();
   1277   sock_.reset();
   1278 
   1279   CapturingNetLog::CapturedEntryList entry_list;
   1280   net_log_.GetEntriesForSource(sock_source, &entry_list);
   1281 
   1282   ASSERT_EQ(entry_list.size(), 10u);
   1283   EXPECT_TRUE(LogContainsBeginEvent(entry_list, 0, NetLog::TYPE_SOCKET_ALIVE));
   1284   EXPECT_TRUE(LogContainsEvent(entry_list, 1,
   1285                   NetLog::TYPE_SPDY_PROXY_CLIENT_SESSION,
   1286                   NetLog::PHASE_NONE));
   1287   EXPECT_TRUE(LogContainsBeginEvent(entry_list, 2,
   1288                   NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
   1289   EXPECT_TRUE(LogContainsEvent(entry_list, 3,
   1290                   NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   1291                   NetLog::PHASE_NONE));
   1292   EXPECT_TRUE(LogContainsEndEvent(entry_list, 4,
   1293                   NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
   1294   EXPECT_TRUE(LogContainsBeginEvent(entry_list, 5,
   1295                   NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
   1296   EXPECT_TRUE(LogContainsEvent(entry_list, 6,
   1297                   NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   1298                   NetLog::PHASE_NONE));
   1299   EXPECT_TRUE(LogContainsEndEvent(entry_list, 7,
   1300                   NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
   1301   EXPECT_TRUE(LogContainsEvent(entry_list, 8,
   1302                   NetLog::TYPE_SOCKET_BYTES_RECEIVED,
   1303                   NetLog::PHASE_NONE));
   1304   EXPECT_TRUE(LogContainsEndEvent(entry_list, 9, NetLog::TYPE_SOCKET_ALIVE));
   1305 
   1306   // Let the RST_STREAM write while |rst| is in-scope.
   1307   base::MessageLoop::current()->RunUntilIdle();
   1308 }
   1309 
   1310 // CompletionCallback that causes the SpdyProxyClientSocket to be
   1311 // deleted when Run is invoked.
   1312 class DeleteSockCallback : public TestCompletionCallbackBase {
   1313  public:
   1314   explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
   1315       : sock_(sock),
   1316         callback_(base::Bind(&DeleteSockCallback::OnComplete,
   1317                              base::Unretained(this))) {
   1318   }
   1319 
   1320   virtual ~DeleteSockCallback() {
   1321   }
   1322 
   1323   const CompletionCallback& callback() const { return callback_; }
   1324 
   1325  private:
   1326   void OnComplete(int result) {
   1327     sock_->reset(NULL);
   1328     SetResult(result);
   1329   }
   1330 
   1331   scoped_ptr<SpdyProxyClientSocket>* sock_;
   1332   CompletionCallback callback_;
   1333 
   1334   DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
   1335 };
   1336 
   1337 // If the socket is Reset when both a read and write are pending, and the
   1338 // read callback causes the socket to be deleted, the write callback should
   1339 // not be called.
   1340 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
   1341   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
   1342   MockWrite writes[] = {
   1343     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   1344     MockWrite(ASYNC, ERR_ABORTED, 3),
   1345   };
   1346 
   1347   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
   1348   scoped_ptr<SpdyFrame> rst(
   1349       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   1350   MockRead reads[] = {
   1351     CreateMockRead(*resp, 1, ASYNC),
   1352     CreateMockRead(*rst, 2, ASYNC),
   1353     MockRead(ASYNC, 0, 4),  // EOF
   1354   };
   1355 
   1356   Initialize(reads, arraysize(reads), writes, arraysize(writes));
   1357 
   1358   AssertConnectSucceeds();
   1359 
   1360   EXPECT_TRUE(sock_->IsConnected());
   1361 
   1362   DeleteSockCallback read_callback(&sock_);
   1363 
   1364   scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
   1365   ASSERT_EQ(ERR_IO_PENDING,
   1366             sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
   1367 
   1368   scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
   1369   EXPECT_EQ(
   1370       ERR_IO_PENDING,
   1371       sock_->Write(
   1372           write_buf.get(), write_buf->size(), write_callback_.callback()));
   1373 
   1374   Run(1);
   1375 
   1376   EXPECT_FALSE(sock_.get());
   1377   EXPECT_TRUE(read_callback.have_result());
   1378   EXPECT_FALSE(write_callback_.have_result());
   1379 
   1380   // Let the RST_STREAM write while |rst| is in-scope.
   1381   base::MessageLoop::current()->RunUntilIdle();
   1382 }
   1383 
   1384 }  // namespace net
   1385