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