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