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_session.h"
      6 
      7 #include "base/base64.h"
      8 #include "base/bind.h"
      9 #include "base/callback.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "base/run_loop.h"
     12 #include "base/test/histogram_tester.h"
     13 #include "net/base/io_buffer.h"
     14 #include "net/base/ip_endpoint.h"
     15 #include "net/base/net_log_unittest.h"
     16 #include "net/base/request_priority.h"
     17 #include "net/base/test_data_directory.h"
     18 #include "net/base/test_data_stream.h"
     19 #include "net/socket/client_socket_pool_manager.h"
     20 #include "net/socket/next_proto.h"
     21 #include "net/socket/socket_test_util.h"
     22 #include "net/spdy/spdy_http_utils.h"
     23 #include "net/spdy/spdy_session_pool.h"
     24 #include "net/spdy/spdy_session_test_util.h"
     25 #include "net/spdy/spdy_stream.h"
     26 #include "net/spdy/spdy_stream_test_util.h"
     27 #include "net/spdy/spdy_test_util_common.h"
     28 #include "net/spdy/spdy_test_utils.h"
     29 #include "net/test/cert_test_util.h"
     30 #include "testing/platform_test.h"
     31 
     32 namespace net {
     33 
     34 namespace {
     35 
     36 static const char kTestUrl[] = "http://www.example.org/";
     37 static const char kTestHost[] = "www.example.org";
     38 static const int kTestPort = 80;
     39 
     40 const char kBodyData[] = "Body data";
     41 const size_t kBodyDataSize = arraysize(kBodyData);
     42 const base::StringPiece kBodyDataStringPiece(kBodyData, kBodyDataSize);
     43 
     44 static base::TimeDelta g_time_delta;
     45 base::TimeTicks TheNearFuture() {
     46   return base::TimeTicks::Now() + g_time_delta;
     47 }
     48 
     49 }  // namespace
     50 
     51 class SpdySessionTest : public PlatformTest,
     52                         public ::testing::WithParamInterface<NextProto> {
     53  public:
     54   // Functions used with RunResumeAfterUnstallTest().
     55 
     56   void StallSessionOnly(SpdySession* session, SpdyStream* stream) {
     57     StallSessionSend(session);
     58   }
     59 
     60   void StallStreamOnly(SpdySession* session, SpdyStream* stream) {
     61     StallStreamSend(stream);
     62   }
     63 
     64   void StallSessionStream(SpdySession* session, SpdyStream* stream) {
     65     StallSessionSend(session);
     66     StallStreamSend(stream);
     67   }
     68 
     69   void StallStreamSession(SpdySession* session, SpdyStream* stream) {
     70     StallStreamSend(stream);
     71     StallSessionSend(session);
     72   }
     73 
     74   void UnstallSessionOnly(SpdySession* session,
     75                           SpdyStream* stream,
     76                           int32 delta_window_size) {
     77     UnstallSessionSend(session, delta_window_size);
     78   }
     79 
     80   void UnstallStreamOnly(SpdySession* session,
     81                          SpdyStream* stream,
     82                          int32 delta_window_size) {
     83     UnstallStreamSend(stream, delta_window_size);
     84   }
     85 
     86   void UnstallSessionStream(SpdySession* session,
     87                             SpdyStream* stream,
     88                             int32 delta_window_size) {
     89     UnstallSessionSend(session, delta_window_size);
     90     UnstallStreamSend(stream, delta_window_size);
     91   }
     92 
     93   void UnstallStreamSession(SpdySession* session,
     94                             SpdyStream* stream,
     95                             int32 delta_window_size) {
     96     UnstallStreamSend(stream, delta_window_size);
     97     UnstallSessionSend(session, delta_window_size);
     98   }
     99 
    100  protected:
    101   SpdySessionTest()
    102       : old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
    103             HttpNetworkSession::NORMAL_SOCKET_POOL)),
    104         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
    105             HttpNetworkSession::NORMAL_SOCKET_POOL)),
    106         spdy_util_(GetParam()),
    107         session_deps_(GetParam()),
    108         spdy_session_pool_(NULL),
    109         test_url_(kTestUrl),
    110         test_host_port_pair_(kTestHost, kTestPort),
    111         key_(test_host_port_pair_, ProxyServer::Direct(),
    112              PRIVACY_MODE_DISABLED) {
    113   }
    114 
    115   virtual ~SpdySessionTest() {
    116     // Important to restore the per-pool limit first, since the pool limit must
    117     // always be greater than group limit, and the tests reduce both limits.
    118     ClientSocketPoolManager::set_max_sockets_per_pool(
    119         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
    120     ClientSocketPoolManager::set_max_sockets_per_group(
    121         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
    122   }
    123 
    124   virtual void SetUp() OVERRIDE {
    125     g_time_delta = base::TimeDelta();
    126   }
    127 
    128   void CreateDeterministicNetworkSession() {
    129     http_session_ =
    130         SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
    131     spdy_session_pool_ = http_session_->spdy_session_pool();
    132   }
    133 
    134   void CreateNetworkSession() {
    135     http_session_ =
    136         SpdySessionDependencies::SpdyCreateSession(&session_deps_);
    137     spdy_session_pool_ = http_session_->spdy_session_pool();
    138   }
    139 
    140   void StallSessionSend(SpdySession* session) {
    141     // Reduce the send window size to 0 to stall.
    142     while (session->session_send_window_size_ > 0) {
    143       session->DecreaseSendWindowSize(
    144           std::min(kMaxSpdyFrameChunkSize, session->session_send_window_size_));
    145     }
    146   }
    147 
    148   void UnstallSessionSend(SpdySession* session, int32 delta_window_size) {
    149     session->IncreaseSendWindowSize(delta_window_size);
    150   }
    151 
    152   void StallStreamSend(SpdyStream* stream) {
    153     // Reduce the send window size to 0 to stall.
    154     while (stream->send_window_size() > 0) {
    155       stream->DecreaseSendWindowSize(
    156           std::min(kMaxSpdyFrameChunkSize, stream->send_window_size()));
    157     }
    158   }
    159 
    160   void UnstallStreamSend(SpdyStream* stream, int32 delta_window_size) {
    161     stream->IncreaseSendWindowSize(delta_window_size);
    162   }
    163 
    164   void RunResumeAfterUnstallTest(
    165       const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function,
    166       const base::Callback<void(SpdySession*, SpdyStream*, int32)>&
    167           unstall_function);
    168 
    169   // Original socket limits.  Some tests set these.  Safest to always restore
    170   // them once each test has been run.
    171   int old_max_group_sockets_;
    172   int old_max_pool_sockets_;
    173 
    174   SpdyTestUtil spdy_util_;
    175   SpdySessionDependencies session_deps_;
    176   scoped_refptr<HttpNetworkSession> http_session_;
    177   SpdySessionPool* spdy_session_pool_;
    178   GURL test_url_;
    179   HostPortPair test_host_port_pair_;
    180   SpdySessionKey key_;
    181 };
    182 
    183 INSTANTIATE_TEST_CASE_P(
    184     NextProto,
    185     SpdySessionTest,
    186     testing::Values(kProtoDeprecatedSPDY2,
    187                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
    188 
    189 // Try to create a SPDY session that will fail during
    190 // initialization. Nothing should blow up.
    191 TEST_P(SpdySessionTest, InitialReadError) {
    192   CreateDeterministicNetworkSession();
    193 
    194   base::WeakPtr<SpdySession> session = TryCreateFakeSpdySessionExpectingFailure(
    195       spdy_session_pool_, key_, ERR_CONNECTION_CLOSED);
    196   EXPECT_TRUE(session);
    197   // Flush the read.
    198   base::RunLoop().RunUntilIdle();
    199   EXPECT_FALSE(session);
    200 }
    201 
    202 namespace {
    203 
    204 // A helper class that vends a callback that, when fired, destroys a
    205 // given SpdyStreamRequest.
    206 class StreamRequestDestroyingCallback : public TestCompletionCallbackBase {
    207  public:
    208   StreamRequestDestroyingCallback() {}
    209 
    210   virtual ~StreamRequestDestroyingCallback() {}
    211 
    212   void SetRequestToDestroy(scoped_ptr<SpdyStreamRequest> request) {
    213     request_ = request.Pass();
    214   }
    215 
    216   CompletionCallback MakeCallback() {
    217     return base::Bind(&StreamRequestDestroyingCallback::OnComplete,
    218                       base::Unretained(this));
    219   }
    220 
    221  private:
    222   void OnComplete(int result) {
    223     request_.reset();
    224     SetResult(result);
    225   }
    226 
    227   scoped_ptr<SpdyStreamRequest> request_;
    228 };
    229 
    230 }  // namespace
    231 
    232 // Request kInitialMaxConcurrentStreams streams.  Request two more
    233 // streams, but have the callback for one destroy the second stream
    234 // request. Close the session. Nothing should blow up. This is a
    235 // regression test for http://crbug.com/250841 .
    236 TEST_P(SpdySessionTest, PendingStreamCancellingAnother) {
    237   session_deps_.host_resolver->set_synchronous_mode(true);
    238 
    239   MockRead reads[] = {MockRead(ASYNC, 0, 0), };
    240 
    241   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
    242   MockConnect connect_data(SYNCHRONOUS, OK);
    243   data.set_connect_data(connect_data);
    244   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    245 
    246   CreateDeterministicNetworkSession();
    247 
    248   base::WeakPtr<SpdySession> session =
    249       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    250 
    251   // Create the maximum number of concurrent streams.
    252   for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) {
    253     base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
    254         SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, BoundNetLog());
    255     ASSERT_TRUE(spdy_stream != NULL);
    256   }
    257 
    258   SpdyStreamRequest request1;
    259   scoped_ptr<SpdyStreamRequest> request2(new SpdyStreamRequest);
    260 
    261   StreamRequestDestroyingCallback callback1;
    262   ASSERT_EQ(ERR_IO_PENDING,
    263             request1.StartRequest(SPDY_BIDIRECTIONAL_STREAM,
    264                                   session,
    265                                   test_url_,
    266                                   MEDIUM,
    267                                   BoundNetLog(),
    268                                   callback1.MakeCallback()));
    269 
    270   // |callback2| is never called.
    271   TestCompletionCallback callback2;
    272   ASSERT_EQ(ERR_IO_PENDING,
    273             request2->StartRequest(SPDY_BIDIRECTIONAL_STREAM,
    274                                    session,
    275                                    test_url_,
    276                                    MEDIUM,
    277                                    BoundNetLog(),
    278                                    callback2.callback()));
    279 
    280   callback1.SetRequestToDestroy(request2.Pass());
    281 
    282   session->CloseSessionOnError(ERR_ABORTED, "Aborting session");
    283 
    284   EXPECT_EQ(ERR_ABORTED, callback1.WaitForResult());
    285 }
    286 
    287 // A session receiving a GOAWAY frame with no active streams should close.
    288 TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) {
    289   session_deps_.host_resolver->set_synchronous_mode(true);
    290 
    291   MockConnect connect_data(SYNCHRONOUS, OK);
    292   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    293   MockRead reads[] = {
    294     CreateMockRead(*goaway, 0),
    295   };
    296   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
    297   data.set_connect_data(connect_data);
    298   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    299 
    300   CreateDeterministicNetworkSession();
    301 
    302   base::WeakPtr<SpdySession> session =
    303       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    304 
    305   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    306 
    307   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    308 
    309   // Read and process the GOAWAY frame.
    310   data.RunFor(1);
    311   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    312   base::RunLoop().RunUntilIdle();
    313   EXPECT_TRUE(session == NULL);
    314 }
    315 
    316 // A session receiving a GOAWAY frame immediately with no active
    317 // streams should then close.
    318 TEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) {
    319   session_deps_.host_resolver->set_synchronous_mode(true);
    320 
    321   MockConnect connect_data(SYNCHRONOUS, OK);
    322   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    323   MockRead reads[] = {
    324     CreateMockRead(*goaway, 0, SYNCHRONOUS),
    325   };
    326   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
    327   data.set_connect_data(connect_data);
    328   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    329 
    330   CreateDeterministicNetworkSession();
    331 
    332   data.StopAfter(1);
    333 
    334   base::WeakPtr<SpdySession> session =
    335       TryCreateInsecureSpdySessionExpectingFailure(
    336           http_session_, key_, ERR_CONNECTION_CLOSED, BoundNetLog());
    337   base::RunLoop().RunUntilIdle();
    338 
    339   EXPECT_FALSE(session);
    340   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    341 }
    342 
    343 // A session receiving a GOAWAY frame with active streams should close
    344 // when the last active stream is closed.
    345 TEST_P(SpdySessionTest, GoAwayWithActiveStreams) {
    346   session_deps_.host_resolver->set_synchronous_mode(true);
    347 
    348   MockConnect connect_data(SYNCHRONOUS, OK);
    349   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    350   MockRead reads[] = {
    351     CreateMockRead(*goaway, 2),
    352     MockRead(ASYNC, 0, 3)  // EOF
    353   };
    354   scoped_ptr<SpdyFrame> req1(
    355       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
    356   scoped_ptr<SpdyFrame> req2(
    357       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
    358   MockWrite writes[] = {
    359     CreateMockWrite(*req1, 0),
    360     CreateMockWrite(*req2, 1),
    361   };
    362   DeterministicSocketData data(reads, arraysize(reads),
    363                                writes, arraysize(writes));
    364   data.set_connect_data(connect_data);
    365   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    366 
    367   CreateDeterministicNetworkSession();
    368 
    369   base::WeakPtr<SpdySession> session =
    370       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    371 
    372   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    373 
    374   GURL url(kDefaultURL);
    375   base::WeakPtr<SpdyStream> spdy_stream1 =
    376       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    377                                 session, url, MEDIUM, BoundNetLog());
    378   test::StreamDelegateDoNothing delegate1(spdy_stream1);
    379   spdy_stream1->SetDelegate(&delegate1);
    380 
    381   base::WeakPtr<SpdyStream> spdy_stream2 =
    382       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    383                                 session, url, MEDIUM, BoundNetLog());
    384   test::StreamDelegateDoNothing delegate2(spdy_stream2);
    385   spdy_stream2->SetDelegate(&delegate2);
    386 
    387   scoped_ptr<SpdyHeaderBlock> headers(
    388       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    389   scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers));
    390 
    391   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    392   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
    393   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
    394   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
    395 
    396   data.RunFor(2);
    397 
    398   EXPECT_EQ(1u, spdy_stream1->stream_id());
    399   EXPECT_EQ(3u, spdy_stream2->stream_id());
    400 
    401   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    402 
    403   // Read and process the GOAWAY frame.
    404   data.RunFor(1);
    405 
    406   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    407 
    408   EXPECT_FALSE(session->IsStreamActive(3));
    409   EXPECT_EQ(NULL, spdy_stream2.get());
    410   EXPECT_TRUE(session->IsStreamActive(1));
    411 
    412   EXPECT_TRUE(session->IsGoingAway());
    413 
    414   // Should close the session.
    415   spdy_stream1->Close();
    416   EXPECT_EQ(NULL, spdy_stream1.get());
    417 
    418   base::MessageLoop::current()->RunUntilIdle();
    419   EXPECT_TRUE(session == NULL);
    420 }
    421 
    422 // Have a session receive two GOAWAY frames, with the last one causing
    423 // the last active stream to be closed. The session should then be
    424 // closed after the second GOAWAY frame.
    425 TEST_P(SpdySessionTest, GoAwayTwice) {
    426   session_deps_.host_resolver->set_synchronous_mode(true);
    427 
    428   MockConnect connect_data(SYNCHRONOUS, OK);
    429   scoped_ptr<SpdyFrame> goaway1(spdy_util_.ConstructSpdyGoAway(1));
    430   scoped_ptr<SpdyFrame> goaway2(spdy_util_.ConstructSpdyGoAway(0));
    431   MockRead reads[] = {
    432     CreateMockRead(*goaway1, 2),
    433     CreateMockRead(*goaway2, 3),
    434     MockRead(ASYNC, 0, 4)  // EOF
    435   };
    436   scoped_ptr<SpdyFrame> req1(
    437       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
    438   scoped_ptr<SpdyFrame> req2(
    439       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
    440   MockWrite writes[] = {
    441     CreateMockWrite(*req1, 0),
    442     CreateMockWrite(*req2, 1),
    443   };
    444   DeterministicSocketData data(reads, arraysize(reads),
    445                                writes, arraysize(writes));
    446   data.set_connect_data(connect_data);
    447   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    448 
    449   CreateDeterministicNetworkSession();
    450 
    451   base::WeakPtr<SpdySession> session =
    452       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    453 
    454   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    455 
    456   GURL url(kDefaultURL);
    457   base::WeakPtr<SpdyStream> spdy_stream1 =
    458       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    459                                 session, url, MEDIUM, BoundNetLog());
    460   test::StreamDelegateDoNothing delegate1(spdy_stream1);
    461   spdy_stream1->SetDelegate(&delegate1);
    462 
    463   base::WeakPtr<SpdyStream> spdy_stream2 =
    464       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    465                                 session, url, MEDIUM, BoundNetLog());
    466   test::StreamDelegateDoNothing delegate2(spdy_stream2);
    467   spdy_stream2->SetDelegate(&delegate2);
    468 
    469   scoped_ptr<SpdyHeaderBlock> headers(
    470       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    471   scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers));
    472 
    473   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    474   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
    475   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
    476   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
    477 
    478   data.RunFor(2);
    479 
    480   EXPECT_EQ(1u, spdy_stream1->stream_id());
    481   EXPECT_EQ(3u, spdy_stream2->stream_id());
    482 
    483   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    484 
    485   // Read and process the first GOAWAY frame.
    486   data.RunFor(1);
    487 
    488   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    489 
    490   EXPECT_FALSE(session->IsStreamActive(3));
    491   EXPECT_EQ(NULL, spdy_stream2.get());
    492   EXPECT_TRUE(session->IsStreamActive(1));
    493   EXPECT_TRUE(session->IsGoingAway());
    494 
    495   // Read and process the second GOAWAY frame, which should close the
    496   // session.
    497   data.RunFor(1);
    498   base::MessageLoop::current()->RunUntilIdle();
    499   EXPECT_TRUE(session == NULL);
    500 }
    501 
    502 // Have a session with active streams receive a GOAWAY frame and then
    503 // close it. It should handle the close properly (i.e., not try to
    504 // make itself unavailable in its pool twice).
    505 TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
    506   session_deps_.host_resolver->set_synchronous_mode(true);
    507 
    508   MockConnect connect_data(SYNCHRONOUS, OK);
    509   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    510   MockRead reads[] = {
    511     CreateMockRead(*goaway, 2),
    512     MockRead(ASYNC, 0, 3)  // EOF
    513   };
    514   scoped_ptr<SpdyFrame> req1(
    515       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
    516   scoped_ptr<SpdyFrame> req2(
    517       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
    518   MockWrite writes[] = {
    519     CreateMockWrite(*req1, 0),
    520     CreateMockWrite(*req2, 1),
    521   };
    522   DeterministicSocketData data(reads, arraysize(reads),
    523                                writes, arraysize(writes));
    524   data.set_connect_data(connect_data);
    525   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    526 
    527   CreateDeterministicNetworkSession();
    528 
    529   base::WeakPtr<SpdySession> session =
    530       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    531 
    532   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    533 
    534   GURL url(kDefaultURL);
    535   base::WeakPtr<SpdyStream> spdy_stream1 =
    536       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    537                                 session, url, MEDIUM, BoundNetLog());
    538   test::StreamDelegateDoNothing delegate1(spdy_stream1);
    539   spdy_stream1->SetDelegate(&delegate1);
    540 
    541   base::WeakPtr<SpdyStream> spdy_stream2 =
    542       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    543                                 session, url, MEDIUM, BoundNetLog());
    544   test::StreamDelegateDoNothing delegate2(spdy_stream2);
    545   spdy_stream2->SetDelegate(&delegate2);
    546 
    547   scoped_ptr<SpdyHeaderBlock> headers(
    548       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    549   scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers));
    550 
    551   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    552   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
    553   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
    554   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
    555 
    556   data.RunFor(2);
    557 
    558   EXPECT_EQ(1u, spdy_stream1->stream_id());
    559   EXPECT_EQ(3u, spdy_stream2->stream_id());
    560 
    561   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    562 
    563   // Read and process the GOAWAY frame.
    564   data.RunFor(1);
    565 
    566   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    567 
    568   EXPECT_FALSE(session->IsStreamActive(3));
    569   EXPECT_EQ(NULL, spdy_stream2.get());
    570   EXPECT_TRUE(session->IsStreamActive(1));
    571   EXPECT_TRUE(session->IsGoingAway());
    572 
    573   session->CloseSessionOnError(ERR_ABORTED, "Aborting session");
    574   EXPECT_EQ(NULL, spdy_stream1.get());
    575 
    576   base::MessageLoop::current()->RunUntilIdle();
    577   EXPECT_TRUE(session == NULL);
    578 }
    579 
    580 // Process a joint read buffer which causes the session to begin draining, and
    581 // then processes a GOAWAY. The session should gracefully drain. Regression test
    582 // for crbug.com/379469
    583 TEST_P(SpdySessionTest, GoAwayWhileDraining) {
    584   session_deps_.host_resolver->set_synchronous_mode(true);
    585 
    586   scoped_ptr<SpdyFrame> req(
    587       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
    588   MockWrite writes[] = {
    589       CreateMockWrite(*req, 0),
    590   };
    591 
    592   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
    593   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    594   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
    595   size_t joint_size = goaway->size() * 2 + body->size();
    596 
    597   // Compose interleaved |goaway| and |body| frames into a single read.
    598   scoped_ptr<char[]> buffer(new char[joint_size]);
    599   {
    600     size_t out = 0;
    601     memcpy(&buffer[out], goaway->data(), goaway->size());
    602     out += goaway->size();
    603     memcpy(&buffer[out], body->data(), body->size());
    604     out += body->size();
    605     memcpy(&buffer[out], goaway->data(), goaway->size());
    606     out += goaway->size();
    607     ASSERT_EQ(out, joint_size);
    608   }
    609   SpdyFrame joint_frames(buffer.get(), joint_size, false);
    610 
    611   MockRead reads[] = {
    612       CreateMockRead(*resp, 1), CreateMockRead(joint_frames, 2),
    613       MockRead(ASYNC, 0, 3)  // EOF
    614   };
    615 
    616   MockConnect connect_data(SYNCHRONOUS, OK);
    617   DeterministicSocketData data(
    618       reads, arraysize(reads), writes, arraysize(writes));
    619   data.set_connect_data(connect_data);
    620   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    621 
    622   CreateDeterministicNetworkSession();
    623   base::WeakPtr<SpdySession> session =
    624       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    625 
    626   GURL url(kDefaultURL);
    627   base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
    628       SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
    629   test::StreamDelegateDoNothing delegate(spdy_stream);
    630   spdy_stream->SetDelegate(&delegate);
    631 
    632   scoped_ptr<SpdyHeaderBlock> headers(
    633       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    634   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    635   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
    636 
    637   data.RunFor(3);
    638   base::MessageLoop::current()->RunUntilIdle();
    639 
    640   // Stream and session closed gracefully.
    641   EXPECT_TRUE(delegate.StreamIsClosed());
    642   EXPECT_EQ(OK, delegate.WaitForClose());
    643   EXPECT_EQ(kUploadData, delegate.TakeReceivedData());
    644   EXPECT_TRUE(session == NULL);
    645 }
    646 
    647 // Try to create a stream after receiving a GOAWAY frame. It should
    648 // fail.
    649 TEST_P(SpdySessionTest, CreateStreamAfterGoAway) {
    650   session_deps_.host_resolver->set_synchronous_mode(true);
    651 
    652   MockConnect connect_data(SYNCHRONOUS, OK);
    653   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    654   MockRead reads[] = {
    655     CreateMockRead(*goaway, 1),
    656     MockRead(ASYNC, 0, 2)  // EOF
    657   };
    658   scoped_ptr<SpdyFrame> req(
    659       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
    660   MockWrite writes[] = {
    661     CreateMockWrite(*req, 0),
    662   };
    663   DeterministicSocketData data(reads, arraysize(reads),
    664                                writes, arraysize(writes));
    665   data.set_connect_data(connect_data);
    666   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    667 
    668   CreateDeterministicNetworkSession();
    669 
    670   base::WeakPtr<SpdySession> session =
    671       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    672 
    673   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    674 
    675   GURL url(kDefaultURL);
    676   base::WeakPtr<SpdyStream> spdy_stream =
    677       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    678                                 session, url, MEDIUM, BoundNetLog());
    679   test::StreamDelegateDoNothing delegate(spdy_stream);
    680   spdy_stream->SetDelegate(&delegate);
    681 
    682   scoped_ptr<SpdyHeaderBlock> headers(
    683       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    684   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    685   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
    686 
    687   data.RunFor(1);
    688 
    689   EXPECT_EQ(1u, spdy_stream->stream_id());
    690 
    691   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    692 
    693   // Read and process the GOAWAY frame.
    694   data.RunFor(1);
    695 
    696   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    697   EXPECT_TRUE(session->IsStreamActive(1));
    698 
    699   SpdyStreamRequest stream_request;
    700   int rv = stream_request.StartRequest(
    701       SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog(),
    702       CompletionCallback());
    703   EXPECT_EQ(ERR_FAILED, rv);
    704 
    705   // Read and process EOF.
    706   data.RunFor(1);
    707 
    708   EXPECT_TRUE(session == NULL);
    709 }
    710 
    711 // Receiving a SYN_STREAM frame after a GOAWAY frame should result in
    712 // the stream being refused.
    713 TEST_P(SpdySessionTest, SynStreamAfterGoAway) {
    714   session_deps_.host_resolver->set_synchronous_mode(true);
    715 
    716   MockConnect connect_data(SYNCHRONOUS, OK);
    717   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
    718   scoped_ptr<SpdyFrame>
    719       push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kDefaultURL));
    720   MockRead reads[] = {
    721     CreateMockRead(*goaway, 1),
    722     CreateMockRead(*push, 2),
    723     MockRead(ASYNC, 0, 4)  // EOF
    724   };
    725   scoped_ptr<SpdyFrame> req(
    726       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
    727   scoped_ptr<SpdyFrame> rst(
    728       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
    729   MockWrite writes[] = {
    730     CreateMockWrite(*req, 0),
    731     CreateMockWrite(*rst, 3)
    732   };
    733   DeterministicSocketData data(reads, arraysize(reads),
    734                                writes, arraysize(writes));
    735   data.set_connect_data(connect_data);
    736   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    737 
    738   CreateDeterministicNetworkSession();
    739 
    740   base::WeakPtr<SpdySession> session =
    741       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    742 
    743   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    744 
    745   GURL url(kDefaultURL);
    746   base::WeakPtr<SpdyStream> spdy_stream =
    747       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    748                                 session, url, MEDIUM, BoundNetLog());
    749   test::StreamDelegateDoNothing delegate(spdy_stream);
    750   spdy_stream->SetDelegate(&delegate);
    751 
    752   scoped_ptr<SpdyHeaderBlock> headers(
    753       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    754   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    755   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
    756 
    757   data.RunFor(1);
    758 
    759   EXPECT_EQ(1u, spdy_stream->stream_id());
    760 
    761   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    762 
    763   // Read and process the GOAWAY frame.
    764   data.RunFor(1);
    765 
    766   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    767   EXPECT_TRUE(session->IsStreamActive(1));
    768 
    769   // Read and process the SYN_STREAM frame, the subsequent RST_STREAM,
    770   // and EOF.
    771   data.RunFor(3);
    772   base::MessageLoop::current()->RunUntilIdle();
    773   EXPECT_TRUE(session == NULL);
    774 }
    775 
    776 // A session observing a network change with active streams should close
    777 // when the last active stream is closed.
    778 TEST_P(SpdySessionTest, NetworkChangeWithActiveStreams) {
    779   session_deps_.host_resolver->set_synchronous_mode(true);
    780 
    781   MockConnect connect_data(SYNCHRONOUS, OK);
    782   MockRead reads[] = {
    783     MockRead(ASYNC, 0, 1)  // EOF
    784   };
    785   scoped_ptr<SpdyFrame> req1(
    786       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
    787   MockWrite writes[] = {
    788     CreateMockWrite(*req1, 0),
    789   };
    790   DeterministicSocketData data(reads, arraysize(reads),
    791                                writes, arraysize(writes));
    792   data.set_connect_data(connect_data);
    793   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    794 
    795   CreateDeterministicNetworkSession();
    796 
    797   base::WeakPtr<SpdySession> session =
    798       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    799 
    800   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
    801 
    802   base::WeakPtr<SpdyStream> spdy_stream =
    803       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session,
    804                                 GURL(kDefaultURL), MEDIUM, BoundNetLog());
    805   test::StreamDelegateDoNothing delegate(spdy_stream);
    806   spdy_stream->SetDelegate(&delegate);
    807 
    808   scoped_ptr<SpdyHeaderBlock> headers(
    809       spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
    810 
    811   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    812   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
    813 
    814   data.RunFor(1);
    815 
    816   EXPECT_EQ(1u, spdy_stream->stream_id());
    817 
    818   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
    819 
    820   spdy_session_pool_->OnIPAddressChanged();
    821 
    822   // The SpdySessionPool behavior differs based on how the OSs reacts to
    823   // network changes; see comment in SpdySessionPool::OnIPAddressChanged().
    824 #if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS)
    825   // For OSs where the TCP connections will close upon relevant network
    826   // changes, SpdySessionPool doesn't need to force them to close, so in these
    827   // cases verify the session has become unavailable but remains open and the
    828   // pre-existing stream is still active.
    829   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    830 
    831   EXPECT_TRUE(session->IsGoingAway());
    832 
    833   EXPECT_TRUE(session->IsStreamActive(1));
    834 
    835   // Should close the session.
    836   spdy_stream->Close();
    837 #endif
    838   EXPECT_EQ(NULL, spdy_stream.get());
    839 
    840   base::MessageLoop::current()->RunUntilIdle();
    841   EXPECT_TRUE(session == NULL);
    842 }
    843 
    844 TEST_P(SpdySessionTest, ClientPing) {
    845   session_deps_.enable_ping = true;
    846   session_deps_.host_resolver->set_synchronous_mode(true);
    847 
    848   MockConnect connect_data(SYNCHRONOUS, OK);
    849   scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1, true));
    850   MockRead reads[] = {
    851     CreateMockRead(*read_ping, 1),
    852     MockRead(ASYNC, 0, 0, 2)  // EOF
    853   };
    854   scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
    855   MockWrite writes[] = {
    856     CreateMockWrite(*write_ping, 0),
    857   };
    858   DeterministicSocketData data(
    859       reads, arraysize(reads), writes, arraysize(writes));
    860   data.set_connect_data(connect_data);
    861   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    862 
    863   CreateDeterministicNetworkSession();
    864 
    865   base::WeakPtr<SpdySession> session =
    866       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    867 
    868   base::WeakPtr<SpdyStream> spdy_stream1 =
    869       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
    870                                 session, test_url_, MEDIUM, BoundNetLog());
    871   ASSERT_TRUE(spdy_stream1.get() != NULL);
    872   test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL);
    873   spdy_stream1->SetDelegate(&delegate);
    874 
    875   base::TimeTicks before_ping_time = base::TimeTicks::Now();
    876 
    877   session->set_connection_at_risk_of_loss_time(
    878       base::TimeDelta::FromSeconds(-1));
    879   session->set_hung_interval(base::TimeDelta::FromMilliseconds(50));
    880 
    881   session->SendPrefacePingIfNoneInFlight();
    882 
    883   data.RunFor(2);
    884 
    885   session->CheckPingStatus(before_ping_time);
    886 
    887   EXPECT_EQ(0, session->pings_in_flight());
    888   EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
    889   EXPECT_FALSE(session->check_ping_status_pending());
    890   EXPECT_GE(session->last_activity_time(), before_ping_time);
    891 
    892   data.RunFor(1);
    893 
    894   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
    895 
    896   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    897   EXPECT_TRUE(session == NULL);
    898 }
    899 
    900 TEST_P(SpdySessionTest, ServerPing) {
    901   session_deps_.host_resolver->set_synchronous_mode(true);
    902 
    903   MockConnect connect_data(SYNCHRONOUS, OK);
    904   scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(2, false));
    905   MockRead reads[] = {
    906     CreateMockRead(*read_ping),
    907     MockRead(SYNCHRONOUS, 0, 0)  // EOF
    908   };
    909   scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(2, true));
    910   MockWrite writes[] = {
    911     CreateMockWrite(*write_ping),
    912   };
    913   StaticSocketDataProvider data(
    914       reads, arraysize(reads), writes, arraysize(writes));
    915   data.set_connect_data(connect_data);
    916   session_deps_.socket_factory->AddSocketDataProvider(&data);
    917 
    918   CreateNetworkSession();
    919 
    920   base::WeakPtr<SpdySession> session =
    921       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    922 
    923   base::WeakPtr<SpdyStream> spdy_stream1 =
    924       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
    925                                 session, test_url_, MEDIUM, BoundNetLog());
    926   ASSERT_TRUE(spdy_stream1.get() != NULL);
    927   test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL);
    928   spdy_stream1->SetDelegate(&delegate);
    929 
    930   // Flush the read completion task.
    931   base::MessageLoop::current()->RunUntilIdle();
    932 
    933   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
    934 
    935   EXPECT_TRUE(session == NULL);
    936   EXPECT_EQ(NULL, spdy_stream1.get());
    937 }
    938 
    939 // Cause a ping to be sent out while producing a write. The write loop
    940 // should handle this properly, i.e. another DoWriteLoop task should
    941 // not be posted. This is a regression test for
    942 // http://crbug.com/261043 .
    943 TEST_P(SpdySessionTest, PingAndWriteLoop) {
    944   session_deps_.enable_ping = true;
    945   session_deps_.time_func = TheNearFuture;
    946 
    947   MockConnect connect_data(SYNCHRONOUS, OK);
    948   scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
    949   scoped_ptr<SpdyFrame> req(
    950       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
    951   MockWrite writes[] = {
    952     CreateMockWrite(*req, 0),
    953     CreateMockWrite(*write_ping, 1),
    954   };
    955 
    956   MockRead reads[] = {
    957     MockRead(ASYNC, 0, 2)  // EOF
    958   };
    959 
    960   session_deps_.host_resolver->set_synchronous_mode(true);
    961 
    962   DeterministicSocketData data(reads, arraysize(reads),
    963                                writes, arraysize(writes));
    964   data.set_connect_data(connect_data);
    965   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
    966 
    967   CreateDeterministicNetworkSession();
    968 
    969   base::WeakPtr<SpdySession> session =
    970       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
    971 
    972   GURL url(kDefaultURL);
    973   base::WeakPtr<SpdyStream> spdy_stream =
    974       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
    975                                 session, url, LOWEST, BoundNetLog());
    976   test::StreamDelegateDoNothing delegate(spdy_stream);
    977   spdy_stream->SetDelegate(&delegate);
    978 
    979   scoped_ptr<SpdyHeaderBlock> headers(
    980       spdy_util_.ConstructGetHeaderBlock(url.spec()));
    981   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
    982 
    983   // Shift time so that a ping will be sent out.
    984   g_time_delta = base::TimeDelta::FromSeconds(11);
    985 
    986   data.RunFor(2);
    987 
    988   session->CloseSessionOnError(ERR_ABORTED, "Aborting");
    989 }
    990 
    991 TEST_P(SpdySessionTest, StreamIdSpaceExhausted) {
    992   const SpdyStreamId kLastStreamId = 0x7fffffff;
    993   session_deps_.host_resolver->set_synchronous_mode(true);
    994 
    995   // Test setup: |stream_hi_water_mark_| and |max_concurrent_streams_| are
    996   // fixed to allow for two stream ID assignments, and three concurrent
    997   // streams. Four streams are started, and two are activated. Verify the
    998   // session goes away, and that the created (but not activated) and
    999   // stalled streams are aborted. Also verify the activated streams complete,
   1000   // at which point the session closes.
   1001 
   1002   scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyGet(
   1003       NULL, 0, false, kLastStreamId - 2, MEDIUM, true));
   1004   scoped_ptr<SpdyFrame> req2(
   1005       spdy_util_.ConstructSpdyGet(NULL, 0, false, kLastStreamId, MEDIUM, true));
   1006 
   1007   MockWrite writes[] = {
   1008       CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
   1009   };
   1010 
   1011   scoped_ptr<SpdyFrame> resp1(
   1012       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, kLastStreamId - 2));
   1013   scoped_ptr<SpdyFrame> resp2(
   1014       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, kLastStreamId));
   1015 
   1016   scoped_ptr<SpdyFrame> body1(
   1017       spdy_util_.ConstructSpdyBodyFrame(kLastStreamId - 2, true));
   1018   scoped_ptr<SpdyFrame> body2(
   1019       spdy_util_.ConstructSpdyBodyFrame(kLastStreamId, true));
   1020 
   1021   MockRead reads[] = {
   1022       CreateMockRead(*resp1, 2), CreateMockRead(*resp2, 3),
   1023       CreateMockRead(*body1, 4), CreateMockRead(*body2, 5),
   1024       MockRead(ASYNC, 0, 6)  // EOF
   1025   };
   1026 
   1027   DeterministicSocketData data(
   1028       reads, arraysize(reads), writes, arraysize(writes));
   1029 
   1030   MockConnect connect_data(SYNCHRONOUS, OK);
   1031   data.set_connect_data(connect_data);
   1032   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1033 
   1034   CreateDeterministicNetworkSession();
   1035   base::WeakPtr<SpdySession> session =
   1036       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1037 
   1038   // Fix stream_hi_water_mark_ to allow for two stream activations.
   1039   session->stream_hi_water_mark_ = kLastStreamId - 2;
   1040   // Fix max_concurrent_streams to allow for three stream creations.
   1041   session->max_concurrent_streams_ = 3;
   1042 
   1043   // Create three streams synchronously, and begin a fourth (which is stalled).
   1044   GURL url(kDefaultURL);
   1045   base::WeakPtr<SpdyStream> stream1 = CreateStreamSynchronously(
   1046       SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
   1047   test::StreamDelegateDoNothing delegate1(stream1);
   1048   stream1->SetDelegate(&delegate1);
   1049 
   1050   base::WeakPtr<SpdyStream> stream2 = CreateStreamSynchronously(
   1051       SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
   1052   test::StreamDelegateDoNothing delegate2(stream2);
   1053   stream2->SetDelegate(&delegate2);
   1054 
   1055   base::WeakPtr<SpdyStream> stream3 = CreateStreamSynchronously(
   1056       SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
   1057   test::StreamDelegateDoNothing delegate3(stream3);
   1058   stream3->SetDelegate(&delegate3);
   1059 
   1060   SpdyStreamRequest request4;
   1061   TestCompletionCallback callback4;
   1062   EXPECT_EQ(ERR_IO_PENDING,
   1063             request4.StartRequest(SPDY_REQUEST_RESPONSE_STREAM,
   1064                                   session,
   1065                                   url,
   1066                                   MEDIUM,
   1067                                   BoundNetLog(),
   1068                                   callback4.callback()));
   1069 
   1070   // Streams 1-3 were created. 4th is stalled. No streams are active yet.
   1071   EXPECT_EQ(0u, session->num_active_streams());
   1072   EXPECT_EQ(3u, session->num_created_streams());
   1073   EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM));
   1074 
   1075   // Activate stream 1. One ID remains available.
   1076   stream1->SendRequestHeaders(
   1077       scoped_ptr<SpdyHeaderBlock>(
   1078           spdy_util_.ConstructGetHeaderBlock(url.spec())),
   1079       NO_MORE_DATA_TO_SEND);
   1080   data.RunFor(1);
   1081 
   1082   EXPECT_EQ(kLastStreamId - 2u, stream1->stream_id());
   1083   EXPECT_EQ(1u, session->num_active_streams());
   1084   EXPECT_EQ(2u, session->num_created_streams());
   1085   EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM));
   1086 
   1087   // Activate stream 2. ID space is exhausted.
   1088   stream2->SendRequestHeaders(
   1089       scoped_ptr<SpdyHeaderBlock>(
   1090           spdy_util_.ConstructGetHeaderBlock(url.spec())),
   1091       NO_MORE_DATA_TO_SEND);
   1092   data.RunFor(1);
   1093 
   1094   // Active streams remain active.
   1095   EXPECT_EQ(kLastStreamId, stream2->stream_id());
   1096   EXPECT_EQ(2u, session->num_active_streams());
   1097 
   1098   // Session is going away. Created and stalled streams were aborted.
   1099   EXPECT_EQ(SpdySession::STATE_GOING_AWAY, session->availability_state_);
   1100   EXPECT_EQ(ERR_ABORTED, delegate3.WaitForClose());
   1101   EXPECT_EQ(ERR_ABORTED, callback4.WaitForResult());
   1102   EXPECT_EQ(0u, session->num_created_streams());
   1103   EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM));
   1104 
   1105   // Read responses on remaining active streams.
   1106   data.RunFor(4);
   1107   EXPECT_EQ(OK, delegate1.WaitForClose());
   1108   EXPECT_EQ(kUploadData, delegate1.TakeReceivedData());
   1109   EXPECT_EQ(OK, delegate2.WaitForClose());
   1110   EXPECT_EQ(kUploadData, delegate2.TakeReceivedData());
   1111 
   1112   // Session was destroyed.
   1113   base::MessageLoop::current()->RunUntilIdle();
   1114   EXPECT_FALSE(session.get());
   1115 }
   1116 
   1117 // Verifies that an unstalled pending stream creation racing with a new stream
   1118 // creation doesn't violate the maximum stream concurrency. Regression test for
   1119 // crbug.com/373858.
   1120 TEST_P(SpdySessionTest, UnstallRacesWithStreamCreation) {
   1121   session_deps_.host_resolver->set_synchronous_mode(true);
   1122 
   1123   MockRead reads[] = {
   1124       MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   1125   };
   1126 
   1127   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   1128 
   1129   MockConnect connect_data(SYNCHRONOUS, OK);
   1130   data.set_connect_data(connect_data);
   1131   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1132 
   1133   CreateNetworkSession();
   1134   base::WeakPtr<SpdySession> session =
   1135       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1136 
   1137   // Fix max_concurrent_streams to allow for one open stream.
   1138   session->max_concurrent_streams_ = 1;
   1139 
   1140   // Create two streams: one synchronously, and one which stalls.
   1141   GURL url(kDefaultURL);
   1142   base::WeakPtr<SpdyStream> stream1 = CreateStreamSynchronously(
   1143       SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
   1144 
   1145   SpdyStreamRequest request2;
   1146   TestCompletionCallback callback2;
   1147   EXPECT_EQ(ERR_IO_PENDING,
   1148             request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM,
   1149                                   session,
   1150                                   url,
   1151                                   MEDIUM,
   1152                                   BoundNetLog(),
   1153                                   callback2.callback()));
   1154 
   1155   EXPECT_EQ(1u, session->num_created_streams());
   1156   EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM));
   1157 
   1158   // Cancel the first stream. A callback to unstall the second stream was
   1159   // posted. Don't run it yet.
   1160   stream1->Cancel();
   1161 
   1162   EXPECT_EQ(0u, session->num_created_streams());
   1163   EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM));
   1164 
   1165   // Create a third stream prior to the second stream's callback.
   1166   base::WeakPtr<SpdyStream> stream3 = CreateStreamSynchronously(
   1167       SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
   1168 
   1169   EXPECT_EQ(1u, session->num_created_streams());
   1170   EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM));
   1171 
   1172   // NOW run the message loop. The unstalled stream will re-stall itself.
   1173   base::MessageLoop::current()->RunUntilIdle();
   1174   EXPECT_EQ(1u, session->num_created_streams());
   1175   EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM));
   1176 
   1177   // Cancel the third stream and run the message loop. Verify that the second
   1178   // stream creation now completes.
   1179   stream3->Cancel();
   1180   base::MessageLoop::current()->RunUntilIdle();
   1181 
   1182   EXPECT_EQ(1u, session->num_created_streams());
   1183   EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM));
   1184   EXPECT_EQ(OK, callback2.WaitForResult());
   1185 }
   1186 
   1187 TEST_P(SpdySessionTest, DeleteExpiredPushStreams) {
   1188   session_deps_.host_resolver->set_synchronous_mode(true);
   1189   session_deps_.time_func = TheNearFuture;
   1190 
   1191   scoped_ptr<SpdyFrame> req(
   1192       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   1193   scoped_ptr<SpdyFrame> rst(
   1194       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
   1195 
   1196   scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
   1197       NULL, 0, 2, 1, "http://www.google.com/a.dat"));
   1198   scoped_ptr<SpdyFrame> push_a_body(
   1199       spdy_util_.ConstructSpdyBodyFrame(2, false));
   1200   scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush(
   1201       NULL, 0, 4, 1, "http://www.google.com/b.dat"));
   1202   MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4)};
   1203   MockRead reads[] = {
   1204       CreateMockRead(*push_a, 1), CreateMockRead(*push_a_body, 2),
   1205       CreateMockRead(*push_b, 3), MockRead(ASYNC, 0, 5),  // EOF
   1206   };
   1207   DeterministicSocketData data(
   1208       reads, arraysize(reads), writes, arraysize(writes));
   1209 
   1210   MockConnect connect_data(SYNCHRONOUS, OK);
   1211   data.set_connect_data(connect_data);
   1212   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1213 
   1214   CreateDeterministicNetworkSession();
   1215   base::WeakPtr<SpdySession> session =
   1216       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1217 
   1218   // Process the principal request, and the first push stream request & body.
   1219   GURL url(kDefaultURL);
   1220   base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
   1221       SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog());
   1222   test::StreamDelegateDoNothing delegate(spdy_stream);
   1223   spdy_stream->SetDelegate(&delegate);
   1224 
   1225   scoped_ptr<SpdyHeaderBlock> headers(
   1226       spdy_util_.ConstructGetHeaderBlock(url.spec()));
   1227   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   1228 
   1229   data.RunFor(3);
   1230 
   1231   // Verify that there is one unclaimed push stream.
   1232   EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
   1233   SpdySession::PushedStreamMap::iterator iter =
   1234       session->unclaimed_pushed_streams_.find(
   1235           GURL("http://www.google.com/a.dat"));
   1236   EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
   1237 
   1238   if (session->flow_control_state_ ==
   1239       SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) {
   1240     // Unclaimed push body consumed bytes from the session window.
   1241     EXPECT_EQ(kSpdySessionInitialWindowSize - kUploadDataSize,
   1242               session->session_recv_window_size_);
   1243     EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   1244   }
   1245 
   1246   // Shift time to expire the push stream. Read the second SYN_STREAM,
   1247   // and verify a RST_STREAM was written.
   1248   g_time_delta = base::TimeDelta::FromSeconds(301);
   1249   data.RunFor(2);
   1250 
   1251   // Verify that the second pushed stream evicted the first pushed stream.
   1252   EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
   1253   iter = session->unclaimed_pushed_streams_.find(
   1254       GURL("http://www.google.com/b.dat"));
   1255   EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
   1256 
   1257   if (session->flow_control_state_ ==
   1258       SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) {
   1259     // Verify that the session window reclaimed the evicted stream body.
   1260     EXPECT_EQ(kSpdySessionInitialWindowSize,
   1261               session->session_recv_window_size_);
   1262     EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_);
   1263   }
   1264 
   1265   // Read and process EOF.
   1266   data.RunFor(1);
   1267   base::MessageLoop::current()->RunUntilIdle();
   1268   EXPECT_TRUE(session == NULL);
   1269 }
   1270 
   1271 TEST_P(SpdySessionTest, FailedPing) {
   1272   session_deps_.host_resolver->set_synchronous_mode(true);
   1273 
   1274   MockConnect connect_data(SYNCHRONOUS, OK);
   1275   MockRead reads[] = {
   1276       MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   1277   };
   1278   scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
   1279   scoped_ptr<SpdyFrame> goaway(
   1280       spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Failed ping."));
   1281   MockWrite writes[] = {CreateMockWrite(*write_ping), CreateMockWrite(*goaway)};
   1282   StaticSocketDataProvider data(
   1283       reads, arraysize(reads), writes, arraysize(writes));
   1284   data.set_connect_data(connect_data);
   1285   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1286 
   1287   CreateNetworkSession();
   1288 
   1289   base::WeakPtr<SpdySession> session =
   1290       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1291 
   1292   base::WeakPtr<SpdyStream> spdy_stream1 =
   1293       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   1294                                 session, test_url_, MEDIUM, BoundNetLog());
   1295   ASSERT_TRUE(spdy_stream1.get() != NULL);
   1296   test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL);
   1297   spdy_stream1->SetDelegate(&delegate);
   1298 
   1299   session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
   1300   session->set_hung_interval(base::TimeDelta::FromSeconds(0));
   1301 
   1302   // Send a PING frame.
   1303   session->WritePingFrame(1, false);
   1304   EXPECT_LT(0, session->pings_in_flight());
   1305   EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
   1306   EXPECT_TRUE(session->check_ping_status_pending());
   1307 
   1308   // Assert session is not closed.
   1309   EXPECT_TRUE(session->IsAvailable());
   1310   EXPECT_LT(0u, session->num_active_streams() + session->num_created_streams());
   1311   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
   1312 
   1313   // We set last time we have received any data in 1 sec less than now.
   1314   // CheckPingStatus will trigger timeout because hung interval is zero.
   1315   base::TimeTicks now = base::TimeTicks::Now();
   1316   session->last_activity_time_ = now - base::TimeDelta::FromSeconds(1);
   1317   session->CheckPingStatus(now);
   1318   base::MessageLoop::current()->RunUntilIdle();
   1319 
   1320   EXPECT_TRUE(session == NULL);
   1321   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
   1322   EXPECT_EQ(NULL, spdy_stream1.get());
   1323 }
   1324 
   1325 // Request kInitialMaxConcurrentStreams + 1 streams.  Receive a
   1326 // settings frame increasing the max concurrent streams by 1.  Make
   1327 // sure nothing blows up. This is a regression test for
   1328 // http://crbug.com/57331 .
   1329 TEST_P(SpdySessionTest, OnSettings) {
   1330   session_deps_.host_resolver->set_synchronous_mode(true);
   1331 
   1332   const SpdySettingsIds kSpdySettingsIds = SETTINGS_MAX_CONCURRENT_STREAMS;
   1333 
   1334   SettingsMap new_settings;
   1335   const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
   1336   new_settings[kSpdySettingsIds] =
   1337       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
   1338   scoped_ptr<SpdyFrame> settings_frame(
   1339       spdy_util_.ConstructSpdySettings(new_settings));
   1340   MockRead reads[] = {
   1341     CreateMockRead(*settings_frame, 0),
   1342     MockRead(ASYNC, 0, 1),
   1343   };
   1344 
   1345   scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
   1346   MockWrite writes[] = {
   1347     CreateMockWrite(*settings_ack, 2),
   1348   };
   1349 
   1350   DeterministicSocketData data(reads, arraysize(reads),
   1351                                writes, arraysize(writes));
   1352   MockConnect connect_data(SYNCHRONOUS, OK);
   1353   data.set_connect_data(connect_data);
   1354   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1355 
   1356   CreateDeterministicNetworkSession();
   1357 
   1358   base::WeakPtr<SpdySession> session =
   1359       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1360 
   1361   // Create the maximum number of concurrent streams.
   1362   for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) {
   1363     base::WeakPtr<SpdyStream> spdy_stream =
   1364         CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   1365                                   session, test_url_, MEDIUM, BoundNetLog());
   1366     ASSERT_TRUE(spdy_stream != NULL);
   1367   }
   1368 
   1369   StreamReleaserCallback stream_releaser;
   1370   SpdyStreamRequest request;
   1371   ASSERT_EQ(ERR_IO_PENDING,
   1372             request.StartRequest(
   1373                 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM,
   1374                 BoundNetLog(),
   1375                 stream_releaser.MakeCallback(&request)));
   1376 
   1377   data.RunFor(1);
   1378 
   1379   EXPECT_EQ(OK, stream_releaser.WaitForResult());
   1380 
   1381   data.RunFor(1);
   1382   if (spdy_util_.spdy_version() >= SPDY4) {
   1383     // Allow the SETTINGS+ACK to write, so the session finishes draining.
   1384     data.RunFor(1);
   1385   }
   1386   base::MessageLoop::current()->RunUntilIdle();
   1387   EXPECT_TRUE(session == NULL);
   1388 }
   1389 
   1390 // Start with a persisted value for max concurrent streams. Receive a
   1391 // settings frame increasing the max concurrent streams by 1 and which
   1392 // also clears the persisted data. Verify that persisted data is
   1393 // correct.
   1394 TEST_P(SpdySessionTest, ClearSettings) {
   1395   if (spdy_util_.spdy_version() >= SPDY4) {
   1396     // SPDY4 doesn't include settings persistence, or a CLEAR_SETTINGS flag.
   1397     // Flag 0x1, CLEAR_SETTINGS in SPDY3, is instead settings ACK in SPDY4.
   1398     return;
   1399   }
   1400   session_deps_.host_resolver->set_synchronous_mode(true);
   1401 
   1402   SettingsMap new_settings;
   1403   const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
   1404   new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
   1405       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
   1406   scoped_ptr<SpdyFrame> settings_frame(
   1407       spdy_util_.ConstructSpdySettings(new_settings));
   1408   uint8 flags = SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
   1409   test::SetFrameFlags(settings_frame.get(), flags, spdy_util_.spdy_version());
   1410   MockRead reads[] = {
   1411     CreateMockRead(*settings_frame, 0),
   1412     MockRead(ASYNC, 0, 1),
   1413   };
   1414 
   1415   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
   1416   MockConnect connect_data(SYNCHRONOUS, OK);
   1417   data.set_connect_data(connect_data);
   1418   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1419 
   1420   CreateDeterministicNetworkSession();
   1421 
   1422   // Initialize the SpdySetting with the default.
   1423   spdy_session_pool_->http_server_properties()->SetSpdySetting(
   1424       test_host_port_pair_,
   1425       SETTINGS_MAX_CONCURRENT_STREAMS,
   1426       SETTINGS_FLAG_PLEASE_PERSIST,
   1427       kInitialMaxConcurrentStreams);
   1428 
   1429   EXPECT_FALSE(
   1430       spdy_session_pool_->http_server_properties()->GetSpdySettings(
   1431           test_host_port_pair_).empty());
   1432 
   1433   base::WeakPtr<SpdySession> session =
   1434       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1435 
   1436   // Create the maximum number of concurrent streams.
   1437   for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) {
   1438     base::WeakPtr<SpdyStream> spdy_stream =
   1439         CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   1440                                   session, test_url_, MEDIUM, BoundNetLog());
   1441     ASSERT_TRUE(spdy_stream != NULL);
   1442   }
   1443 
   1444   StreamReleaserCallback stream_releaser;
   1445 
   1446   SpdyStreamRequest request;
   1447   ASSERT_EQ(ERR_IO_PENDING,
   1448             request.StartRequest(
   1449                 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM,
   1450                 BoundNetLog(),
   1451                 stream_releaser.MakeCallback(&request)));
   1452 
   1453   data.RunFor(1);
   1454 
   1455   EXPECT_EQ(OK, stream_releaser.WaitForResult());
   1456 
   1457   // Make sure that persisted data is cleared.
   1458   EXPECT_TRUE(
   1459       spdy_session_pool_->http_server_properties()->GetSpdySettings(
   1460           test_host_port_pair_).empty());
   1461 
   1462   // Make sure session's max_concurrent_streams is correct.
   1463   EXPECT_EQ(kInitialMaxConcurrentStreams + 1,
   1464             session->max_concurrent_streams());
   1465 
   1466   data.RunFor(1);
   1467   EXPECT_TRUE(session == NULL);
   1468 }
   1469 
   1470 // Start with max concurrent streams set to 1.  Request two streams.
   1471 // When the first completes, have the callback close its stream, which
   1472 // should trigger the second stream creation.  Then cancel that one
   1473 // immediately.  Don't crash.  This is a regression test for
   1474 // http://crbug.com/63532 .
   1475 TEST_P(SpdySessionTest, CancelPendingCreateStream) {
   1476   session_deps_.host_resolver->set_synchronous_mode(true);
   1477 
   1478   MockRead reads[] = {
   1479     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   1480   };
   1481 
   1482   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   1483   MockConnect connect_data(SYNCHRONOUS, OK);
   1484 
   1485   data.set_connect_data(connect_data);
   1486   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1487 
   1488   CreateNetworkSession();
   1489 
   1490   // Initialize the SpdySetting with 1 max concurrent streams.
   1491   spdy_session_pool_->http_server_properties()->SetSpdySetting(
   1492       test_host_port_pair_,
   1493       SETTINGS_MAX_CONCURRENT_STREAMS,
   1494       SETTINGS_FLAG_PLEASE_PERSIST,
   1495       1);
   1496 
   1497   base::WeakPtr<SpdySession> session =
   1498       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1499 
   1500   // Leave room for only one more stream to be created.
   1501   for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) {
   1502     base::WeakPtr<SpdyStream> spdy_stream =
   1503         CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   1504                                   session, test_url_, MEDIUM, BoundNetLog());
   1505     ASSERT_TRUE(spdy_stream != NULL);
   1506   }
   1507 
   1508   // Create 2 more streams.  First will succeed.  Second will be pending.
   1509   base::WeakPtr<SpdyStream> spdy_stream1 =
   1510       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   1511                                 session, test_url_, MEDIUM, BoundNetLog());
   1512   ASSERT_TRUE(spdy_stream1.get() != NULL);
   1513 
   1514   // Use scoped_ptr to let us invalidate the memory when we want to, to trigger
   1515   // a valgrind error if the callback is invoked when it's not supposed to be.
   1516   scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback);
   1517 
   1518   SpdyStreamRequest request;
   1519   ASSERT_EQ(ERR_IO_PENDING,
   1520             request.StartRequest(
   1521                 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM,
   1522                 BoundNetLog(),
   1523                 callback->callback()));
   1524 
   1525   // Release the first one, this will allow the second to be created.
   1526   spdy_stream1->Cancel();
   1527   EXPECT_EQ(NULL, spdy_stream1.get());
   1528 
   1529   request.CancelRequest();
   1530   callback.reset();
   1531 
   1532   // Should not crash when running the pending callback.
   1533   base::MessageLoop::current()->RunUntilIdle();
   1534 }
   1535 
   1536 TEST_P(SpdySessionTest, SendInitialDataOnNewSession) {
   1537   session_deps_.host_resolver->set_synchronous_mode(true);
   1538 
   1539   MockRead reads[] = {
   1540     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   1541   };
   1542 
   1543   SettingsMap settings;
   1544   const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
   1545   const SpdySettingsIds kSpdySettingsIds2 = SETTINGS_INITIAL_WINDOW_SIZE;
   1546   const uint32 kInitialRecvWindowSize = 10 * 1024 * 1024;
   1547   settings[kSpdySettingsIds1] =
   1548       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
   1549   if (spdy_util_.spdy_version() >= SPDY3) {
   1550     settings[kSpdySettingsIds2] =
   1551         SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kInitialRecvWindowSize);
   1552   }
   1553   MockConnect connect_data(SYNCHRONOUS, OK);
   1554   scoped_ptr<SpdyFrame> settings_frame(
   1555       spdy_util_.ConstructSpdySettings(settings));
   1556   scoped_ptr<SpdyFrame> initial_window_update(
   1557       spdy_util_.ConstructSpdyWindowUpdate(
   1558           kSessionFlowControlStreamId,
   1559           kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize));
   1560   std::vector<MockWrite> writes;
   1561   if (GetParam() == kProtoSPDY4) {
   1562     writes.push_back(
   1563         MockWrite(ASYNC,
   1564                   kHttp2ConnectionHeaderPrefix,
   1565                   kHttp2ConnectionHeaderPrefixSize));
   1566   }
   1567   writes.push_back(CreateMockWrite(*settings_frame));
   1568   if (GetParam() >= kProtoSPDY31) {
   1569     writes.push_back(CreateMockWrite(*initial_window_update));
   1570   };
   1571 
   1572   SettingsMap server_settings;
   1573   const uint32 initial_max_concurrent_streams = 1;
   1574   server_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
   1575       SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED,
   1576                             initial_max_concurrent_streams);
   1577   scoped_ptr<SpdyFrame> server_settings_frame(
   1578       spdy_util_.ConstructSpdySettings(server_settings));
   1579   if (GetParam() <= kProtoSPDY31) {
   1580     writes.push_back(CreateMockWrite(*server_settings_frame));
   1581   }
   1582 
   1583   session_deps_.stream_initial_recv_window_size = kInitialRecvWindowSize;
   1584 
   1585   StaticSocketDataProvider data(reads, arraysize(reads),
   1586                                 vector_as_array(&writes), writes.size());
   1587   data.set_connect_data(connect_data);
   1588   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1589 
   1590   CreateNetworkSession();
   1591 
   1592   spdy_session_pool_->http_server_properties()->SetSpdySetting(
   1593       test_host_port_pair_,
   1594       SETTINGS_MAX_CONCURRENT_STREAMS,
   1595       SETTINGS_FLAG_PLEASE_PERSIST,
   1596       initial_max_concurrent_streams);
   1597 
   1598   SpdySessionPoolPeer pool_peer(spdy_session_pool_);
   1599   pool_peer.SetEnableSendingInitialData(true);
   1600 
   1601   base::WeakPtr<SpdySession> session =
   1602       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1603 
   1604   base::MessageLoop::current()->RunUntilIdle();
   1605   EXPECT_TRUE(data.at_write_eof());
   1606 }
   1607 
   1608 TEST_P(SpdySessionTest, ClearSettingsStorageOnIPAddressChanged) {
   1609   CreateNetworkSession();
   1610 
   1611   base::WeakPtr<HttpServerProperties> test_http_server_properties =
   1612       spdy_session_pool_->http_server_properties();
   1613   SettingsFlagsAndValue flags_and_value1(SETTINGS_FLAG_PLEASE_PERSIST, 2);
   1614   test_http_server_properties->SetSpdySetting(
   1615       test_host_port_pair_,
   1616       SETTINGS_MAX_CONCURRENT_STREAMS,
   1617       SETTINGS_FLAG_PLEASE_PERSIST,
   1618       2);
   1619   EXPECT_NE(0u, test_http_server_properties->GetSpdySettings(
   1620       test_host_port_pair_).size());
   1621   spdy_session_pool_->OnIPAddressChanged();
   1622   EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings(
   1623       test_host_port_pair_).size());
   1624 }
   1625 
   1626 TEST_P(SpdySessionTest, Initialize) {
   1627   CapturingBoundNetLog log;
   1628   session_deps_.net_log = log.bound().net_log();
   1629   session_deps_.host_resolver->set_synchronous_mode(true);
   1630 
   1631   MockConnect connect_data(SYNCHRONOUS, OK);
   1632   MockRead reads[] = {
   1633     MockRead(ASYNC, 0, 0)  // EOF
   1634   };
   1635 
   1636   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   1637   data.set_connect_data(connect_data);
   1638   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1639 
   1640   CreateNetworkSession();
   1641 
   1642   base::WeakPtr<SpdySession> session =
   1643       CreateInsecureSpdySession(http_session_, key_, log.bound());
   1644   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
   1645 
   1646   // Flush the read completion task.
   1647   base::MessageLoop::current()->RunUntilIdle();
   1648 
   1649   net::CapturingNetLog::CapturedEntryList entries;
   1650   log.GetEntries(&entries);
   1651   EXPECT_LT(0u, entries.size());
   1652 
   1653   // Check that we logged TYPE_SPDY_SESSION_INITIALIZED correctly.
   1654   int pos = net::ExpectLogContainsSomewhere(
   1655       entries, 0,
   1656       net::NetLog::TYPE_SPDY_SESSION_INITIALIZED,
   1657       net::NetLog::PHASE_NONE);
   1658   EXPECT_LT(0, pos);
   1659 
   1660   CapturingNetLog::CapturedEntry entry = entries[pos];
   1661   NetLog::Source socket_source;
   1662   EXPECT_TRUE(NetLog::Source::FromEventParameters(entry.params.get(),
   1663                                                   &socket_source));
   1664   EXPECT_TRUE(socket_source.IsValid());
   1665   EXPECT_NE(log.bound().source().id, socket_source.id);
   1666 }
   1667 
   1668 TEST_P(SpdySessionTest, NetLogOnSessionGoaway) {
   1669   session_deps_.host_resolver->set_synchronous_mode(true);
   1670 
   1671   MockConnect connect_data(SYNCHRONOUS, OK);
   1672   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway());
   1673   MockRead reads[] = {
   1674     CreateMockRead(*goaway),
   1675     MockRead(SYNCHRONOUS, 0, 0)  // EOF
   1676   };
   1677 
   1678   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   1679   data.set_connect_data(connect_data);
   1680   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1681 
   1682   CreateNetworkSession();
   1683 
   1684   CapturingBoundNetLog log;
   1685   base::WeakPtr<SpdySession> session =
   1686       CreateInsecureSpdySession(http_session_, key_, log.bound());
   1687   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
   1688 
   1689   // Flush the read completion task.
   1690   base::MessageLoop::current()->RunUntilIdle();
   1691 
   1692   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
   1693   EXPECT_TRUE(session == NULL);
   1694 
   1695   // Check that the NetLog was filled reasonably.
   1696   net::CapturingNetLog::CapturedEntryList entries;
   1697   log.GetEntries(&entries);
   1698   EXPECT_LT(0u, entries.size());
   1699 
   1700   // Check that we logged SPDY_SESSION_CLOSE correctly.
   1701   int pos = net::ExpectLogContainsSomewhere(
   1702       entries, 0,
   1703       net::NetLog::TYPE_SPDY_SESSION_CLOSE,
   1704       net::NetLog::PHASE_NONE);
   1705 
   1706   if (pos < static_cast<int>(entries.size())) {
   1707     CapturingNetLog::CapturedEntry entry = entries[pos];
   1708     int error_code = 0;
   1709     ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
   1710     EXPECT_EQ(OK, error_code);
   1711   } else {
   1712     ADD_FAILURE();
   1713   }
   1714 }
   1715 
   1716 TEST_P(SpdySessionTest, NetLogOnSessionEOF) {
   1717   session_deps_.host_resolver->set_synchronous_mode(true);
   1718 
   1719   MockConnect connect_data(SYNCHRONOUS, OK);
   1720   MockRead reads[] = {
   1721       MockRead(SYNCHRONOUS, 0, 0)  // EOF
   1722   };
   1723 
   1724   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   1725   data.set_connect_data(connect_data);
   1726   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1727 
   1728   CreateNetworkSession();
   1729 
   1730   CapturingBoundNetLog log;
   1731   base::WeakPtr<SpdySession> session =
   1732       CreateInsecureSpdySession(http_session_, key_, log.bound());
   1733   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
   1734 
   1735   // Flush the read completion task.
   1736   base::MessageLoop::current()->RunUntilIdle();
   1737 
   1738   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
   1739   EXPECT_TRUE(session == NULL);
   1740 
   1741   // Check that the NetLog was filled reasonably.
   1742   net::CapturingNetLog::CapturedEntryList entries;
   1743   log.GetEntries(&entries);
   1744   EXPECT_LT(0u, entries.size());
   1745 
   1746   // Check that we logged SPDY_SESSION_CLOSE correctly.
   1747   int pos =
   1748       net::ExpectLogContainsSomewhere(entries,
   1749                                       0,
   1750                                       net::NetLog::TYPE_SPDY_SESSION_CLOSE,
   1751                                       net::NetLog::PHASE_NONE);
   1752 
   1753   if (pos < static_cast<int>(entries.size())) {
   1754     CapturingNetLog::CapturedEntry entry = entries[pos];
   1755     int error_code = 0;
   1756     ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
   1757     EXPECT_EQ(ERR_CONNECTION_CLOSED, error_code);
   1758   } else {
   1759     ADD_FAILURE();
   1760   }
   1761 }
   1762 
   1763 TEST_P(SpdySessionTest, SynCompressionHistograms) {
   1764   session_deps_.enable_compression = true;
   1765 
   1766   scoped_ptr<SpdyFrame> req(
   1767       spdy_util_.ConstructSpdyGet(NULL, 0, true, 1, MEDIUM, true));
   1768   MockWrite writes[] = {
   1769     CreateMockWrite(*req, 0),
   1770   };
   1771   MockRead reads[] = {
   1772     MockRead(ASYNC, 0, 1)  // EOF
   1773   };
   1774   DeterministicSocketData data(reads, arraysize(reads),
   1775                                writes, arraysize(writes));
   1776   MockConnect connect_data(SYNCHRONOUS, OK);
   1777   data.set_connect_data(connect_data);
   1778   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1779 
   1780   CreateDeterministicNetworkSession();
   1781   base::WeakPtr<SpdySession> session =
   1782       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1783 
   1784   GURL url(kDefaultURL);
   1785   base::WeakPtr<SpdyStream> spdy_stream =
   1786       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1787                                 session, url, MEDIUM, BoundNetLog());
   1788   test::StreamDelegateDoNothing delegate(spdy_stream);
   1789   spdy_stream->SetDelegate(&delegate);
   1790 
   1791   scoped_ptr<SpdyHeaderBlock> headers(
   1792       spdy_util_.ConstructGetHeaderBlock(url.spec()));
   1793   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   1794   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
   1795 
   1796   // Write request headers & capture resulting histogram update.
   1797   base::HistogramTester histogram_tester;
   1798 
   1799   data.RunFor(1);
   1800   // Regression test of compression performance under the request fixture.
   1801   switch (spdy_util_.spdy_version()) {
   1802     case SPDY2:
   1803       histogram_tester.ExpectBucketCount(
   1804           "Net.SpdySynStreamCompressionPercentage", 0, 1);
   1805       break;
   1806     case SPDY3:
   1807       histogram_tester.ExpectBucketCount(
   1808           "Net.SpdySynStreamCompressionPercentage", 30, 1);
   1809       break;
   1810     case SPDY4:
   1811       histogram_tester.ExpectBucketCount(
   1812           "Net.SpdySynStreamCompressionPercentage", 82, 1);
   1813       break;
   1814     case SPDY5:
   1815       histogram_tester.ExpectBucketCount(
   1816           "Net.SpdySynStreamCompressionPercentage", 82, 1);
   1817       break;
   1818     default:
   1819       NOTREACHED();
   1820   }
   1821 
   1822   // Read and process EOF.
   1823   data.RunFor(1);
   1824   base::MessageLoop::current()->RunUntilIdle();
   1825   EXPECT_TRUE(session == NULL);
   1826 }
   1827 
   1828 // Queue up a low-priority SYN_STREAM followed by a high-priority
   1829 // one. The high priority one should still send first and receive
   1830 // first.
   1831 TEST_P(SpdySessionTest, OutOfOrderSynStreams) {
   1832   // Construct the request.
   1833   MockConnect connect_data(SYNCHRONOUS, OK);
   1834   scoped_ptr<SpdyFrame> req_highest(
   1835       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, HIGHEST, true));
   1836   scoped_ptr<SpdyFrame> req_lowest(
   1837       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
   1838   MockWrite writes[] = {
   1839     CreateMockWrite(*req_highest, 0),
   1840     CreateMockWrite(*req_lowest, 1),
   1841   };
   1842 
   1843   scoped_ptr<SpdyFrame> resp_highest(
   1844       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   1845   scoped_ptr<SpdyFrame> body_highest(
   1846       spdy_util_.ConstructSpdyBodyFrame(1, true));
   1847   scoped_ptr<SpdyFrame> resp_lowest(
   1848       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   1849   scoped_ptr<SpdyFrame> body_lowest(
   1850       spdy_util_.ConstructSpdyBodyFrame(3, true));
   1851   MockRead reads[] = {
   1852     CreateMockRead(*resp_highest, 2),
   1853     CreateMockRead(*body_highest, 3),
   1854     CreateMockRead(*resp_lowest, 4),
   1855     CreateMockRead(*body_lowest, 5),
   1856     MockRead(ASYNC, 0, 6)  // EOF
   1857   };
   1858 
   1859   session_deps_.host_resolver->set_synchronous_mode(true);
   1860 
   1861   DeterministicSocketData data(reads, arraysize(reads),
   1862                                writes, arraysize(writes));
   1863   data.set_connect_data(connect_data);
   1864   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1865 
   1866   CreateDeterministicNetworkSession();
   1867 
   1868   base::WeakPtr<SpdySession> session =
   1869       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1870 
   1871   GURL url(kDefaultURL);
   1872 
   1873   base::WeakPtr<SpdyStream> spdy_stream_lowest =
   1874       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1875                                 session, url, LOWEST, BoundNetLog());
   1876   ASSERT_TRUE(spdy_stream_lowest);
   1877   EXPECT_EQ(0u, spdy_stream_lowest->stream_id());
   1878   test::StreamDelegateDoNothing delegate_lowest(spdy_stream_lowest);
   1879   spdy_stream_lowest->SetDelegate(&delegate_lowest);
   1880 
   1881   base::WeakPtr<SpdyStream> spdy_stream_highest =
   1882       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1883                                 session, url, HIGHEST, BoundNetLog());
   1884   ASSERT_TRUE(spdy_stream_highest);
   1885   EXPECT_EQ(0u, spdy_stream_highest->stream_id());
   1886   test::StreamDelegateDoNothing delegate_highest(spdy_stream_highest);
   1887   spdy_stream_highest->SetDelegate(&delegate_highest);
   1888 
   1889   // Queue the lower priority one first.
   1890 
   1891   scoped_ptr<SpdyHeaderBlock> headers_lowest(
   1892       spdy_util_.ConstructGetHeaderBlock(url.spec()));
   1893   spdy_stream_lowest->SendRequestHeaders(
   1894       headers_lowest.Pass(), NO_MORE_DATA_TO_SEND);
   1895   EXPECT_TRUE(spdy_stream_lowest->HasUrlFromHeaders());
   1896 
   1897   scoped_ptr<SpdyHeaderBlock> headers_highest(
   1898       spdy_util_.ConstructGetHeaderBlock(url.spec()));
   1899   spdy_stream_highest->SendRequestHeaders(
   1900       headers_highest.Pass(), NO_MORE_DATA_TO_SEND);
   1901   EXPECT_TRUE(spdy_stream_highest->HasUrlFromHeaders());
   1902 
   1903   data.RunFor(7);
   1904 
   1905   EXPECT_FALSE(spdy_stream_lowest);
   1906   EXPECT_FALSE(spdy_stream_highest);
   1907   EXPECT_EQ(3u, delegate_lowest.stream_id());
   1908   EXPECT_EQ(1u, delegate_highest.stream_id());
   1909 }
   1910 
   1911 TEST_P(SpdySessionTest, CancelStream) {
   1912   MockConnect connect_data(SYNCHRONOUS, OK);
   1913   // Request 1, at HIGHEST priority, will be cancelled before it writes data.
   1914   // Request 2, at LOWEST priority, will be a full request and will be id 1.
   1915   scoped_ptr<SpdyFrame> req2(
   1916       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   1917   MockWrite writes[] = {
   1918     CreateMockWrite(*req2, 0),
   1919   };
   1920 
   1921   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   1922   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
   1923   MockRead reads[] = {
   1924     CreateMockRead(*resp2, 1),
   1925     CreateMockRead(*body2, 2),
   1926     MockRead(ASYNC, 0, 3)  // EOF
   1927   };
   1928 
   1929   session_deps_.host_resolver->set_synchronous_mode(true);
   1930 
   1931   DeterministicSocketData data(reads, arraysize(reads),
   1932                                writes, arraysize(writes));
   1933   data.set_connect_data(connect_data);
   1934   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   1935 
   1936   CreateDeterministicNetworkSession();
   1937 
   1938   base::WeakPtr<SpdySession> session =
   1939       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   1940 
   1941   GURL url1(kDefaultURL);
   1942   base::WeakPtr<SpdyStream> spdy_stream1 =
   1943       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1944                                 session, url1, HIGHEST, BoundNetLog());
   1945   ASSERT_TRUE(spdy_stream1.get() != NULL);
   1946   EXPECT_EQ(0u, spdy_stream1->stream_id());
   1947   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   1948   spdy_stream1->SetDelegate(&delegate1);
   1949 
   1950   GURL url2(kDefaultURL);
   1951   base::WeakPtr<SpdyStream> spdy_stream2 =
   1952       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   1953                                 session, url2, LOWEST, BoundNetLog());
   1954   ASSERT_TRUE(spdy_stream2.get() != NULL);
   1955   EXPECT_EQ(0u, spdy_stream2->stream_id());
   1956   test::StreamDelegateDoNothing delegate2(spdy_stream2);
   1957   spdy_stream2->SetDelegate(&delegate2);
   1958 
   1959   scoped_ptr<SpdyHeaderBlock> headers(
   1960       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   1961   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   1962   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   1963 
   1964   scoped_ptr<SpdyHeaderBlock> headers2(
   1965       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
   1966   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
   1967   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
   1968 
   1969   EXPECT_EQ(0u, spdy_stream1->stream_id());
   1970 
   1971   spdy_stream1->Cancel();
   1972   EXPECT_EQ(NULL, spdy_stream1.get());
   1973 
   1974   EXPECT_EQ(0u, delegate1.stream_id());
   1975 
   1976   data.RunFor(1);
   1977 
   1978   EXPECT_EQ(0u, delegate1.stream_id());
   1979   EXPECT_EQ(1u, delegate2.stream_id());
   1980 
   1981   spdy_stream2->Cancel();
   1982   EXPECT_EQ(NULL, spdy_stream2.get());
   1983 }
   1984 
   1985 // Create two streams that are set to re-close themselves on close,
   1986 // and then close the session. Nothing should blow up. Also a
   1987 // regression test for http://crbug.com/139518 .
   1988 TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) {
   1989   session_deps_.host_resolver->set_synchronous_mode(true);
   1990 
   1991   MockConnect connect_data(SYNCHRONOUS, OK);
   1992 
   1993   // No actual data will be sent.
   1994   MockWrite writes[] = {
   1995     MockWrite(ASYNC, 0, 1)  // EOF
   1996   };
   1997 
   1998   MockRead reads[] = {
   1999     MockRead(ASYNC, 0, 0)  // EOF
   2000   };
   2001   DeterministicSocketData data(reads, arraysize(reads),
   2002                                writes, arraysize(writes));
   2003   data.set_connect_data(connect_data);
   2004   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2005 
   2006   CreateDeterministicNetworkSession();
   2007 
   2008   base::WeakPtr<SpdySession> session =
   2009       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2010 
   2011   GURL url1(kDefaultURL);
   2012   base::WeakPtr<SpdyStream> spdy_stream1 =
   2013       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   2014                                 session, url1, HIGHEST, BoundNetLog());
   2015   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2016   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2017 
   2018   GURL url2(kDefaultURL);
   2019   base::WeakPtr<SpdyStream> spdy_stream2 =
   2020       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   2021                                 session, url2, LOWEST, BoundNetLog());
   2022   ASSERT_TRUE(spdy_stream2.get() != NULL);
   2023   EXPECT_EQ(0u, spdy_stream2->stream_id());
   2024 
   2025   test::ClosingDelegate delegate1(spdy_stream1);
   2026   spdy_stream1->SetDelegate(&delegate1);
   2027 
   2028   test::ClosingDelegate delegate2(spdy_stream2);
   2029   spdy_stream2->SetDelegate(&delegate2);
   2030 
   2031   scoped_ptr<SpdyHeaderBlock> headers(
   2032       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2033   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   2034   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2035 
   2036   scoped_ptr<SpdyHeaderBlock> headers2(
   2037       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
   2038   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
   2039   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
   2040 
   2041   // Ensure that the streams have not yet been activated and assigned an id.
   2042   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2043   EXPECT_EQ(0u, spdy_stream2->stream_id());
   2044 
   2045   // Ensure we don't crash while closing the session.
   2046   session->CloseSessionOnError(ERR_ABORTED, std::string());
   2047 
   2048   EXPECT_EQ(NULL, spdy_stream1.get());
   2049   EXPECT_EQ(NULL, spdy_stream2.get());
   2050 
   2051   EXPECT_TRUE(delegate1.StreamIsClosed());
   2052   EXPECT_TRUE(delegate2.StreamIsClosed());
   2053 
   2054   base::MessageLoop::current()->RunUntilIdle();
   2055   EXPECT_TRUE(session == NULL);
   2056 }
   2057 
   2058 // Create two streams that are set to close each other on close, and
   2059 // then close the session. Nothing should blow up.
   2060 TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) {
   2061   session_deps_.host_resolver->set_synchronous_mode(true);
   2062 
   2063   MockConnect connect_data(SYNCHRONOUS, OK);
   2064 
   2065   // No actual data will be sent.
   2066   MockWrite writes[] = {
   2067     MockWrite(ASYNC, 0, 1)  // EOF
   2068   };
   2069 
   2070   MockRead reads[] = {
   2071     MockRead(ASYNC, 0, 0)  // EOF
   2072   };
   2073   DeterministicSocketData data(reads, arraysize(reads),
   2074                                writes, arraysize(writes));
   2075   data.set_connect_data(connect_data);
   2076   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2077 
   2078   CreateDeterministicNetworkSession();
   2079 
   2080   base::WeakPtr<SpdySession> session =
   2081       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2082 
   2083   GURL url1(kDefaultURL);
   2084   base::WeakPtr<SpdyStream> spdy_stream1 =
   2085       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   2086                                 session, url1, HIGHEST, BoundNetLog());
   2087   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2088   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2089 
   2090   GURL url2(kDefaultURL);
   2091   base::WeakPtr<SpdyStream> spdy_stream2 =
   2092       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   2093                                 session, url2, LOWEST, BoundNetLog());
   2094   ASSERT_TRUE(spdy_stream2.get() != NULL);
   2095   EXPECT_EQ(0u, spdy_stream2->stream_id());
   2096 
   2097   // Make |spdy_stream1| close |spdy_stream2|.
   2098   test::ClosingDelegate delegate1(spdy_stream2);
   2099   spdy_stream1->SetDelegate(&delegate1);
   2100 
   2101   // Make |spdy_stream2| close |spdy_stream1|.
   2102   test::ClosingDelegate delegate2(spdy_stream1);
   2103   spdy_stream2->SetDelegate(&delegate2);
   2104 
   2105   scoped_ptr<SpdyHeaderBlock> headers(
   2106       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2107   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   2108   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2109 
   2110   scoped_ptr<SpdyHeaderBlock> headers2(
   2111       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
   2112   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
   2113   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
   2114 
   2115   // Ensure that the streams have not yet been activated and assigned an id.
   2116   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2117   EXPECT_EQ(0u, spdy_stream2->stream_id());
   2118 
   2119   // Ensure we don't crash while closing the session.
   2120   session->CloseSessionOnError(ERR_ABORTED, std::string());
   2121 
   2122   EXPECT_EQ(NULL, spdy_stream1.get());
   2123   EXPECT_EQ(NULL, spdy_stream2.get());
   2124 
   2125   EXPECT_TRUE(delegate1.StreamIsClosed());
   2126   EXPECT_TRUE(delegate2.StreamIsClosed());
   2127 
   2128   base::MessageLoop::current()->RunUntilIdle();
   2129   EXPECT_TRUE(session == NULL);
   2130 }
   2131 
   2132 // Create two streams that are set to re-close themselves on close,
   2133 // activate them, and then close the session. Nothing should blow up.
   2134 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) {
   2135   session_deps_.host_resolver->set_synchronous_mode(true);
   2136 
   2137   MockConnect connect_data(SYNCHRONOUS, OK);
   2138 
   2139   scoped_ptr<SpdyFrame> req1(
   2140       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   2141   scoped_ptr<SpdyFrame> req2(
   2142       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
   2143   MockWrite writes[] = {
   2144     CreateMockWrite(*req1, 0),
   2145     CreateMockWrite(*req2, 1),
   2146   };
   2147 
   2148   MockRead reads[] = {
   2149     MockRead(ASYNC, 0, 2)  // EOF
   2150   };
   2151 
   2152   DeterministicSocketData data(reads, arraysize(reads),
   2153                                writes, arraysize(writes));
   2154   data.set_connect_data(connect_data);
   2155   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2156 
   2157   CreateDeterministicNetworkSession();
   2158 
   2159   base::WeakPtr<SpdySession> session =
   2160       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2161 
   2162   GURL url1(kDefaultURL);
   2163   base::WeakPtr<SpdyStream> spdy_stream1 =
   2164       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2165                                 session, url1, MEDIUM, BoundNetLog());
   2166   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2167   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2168 
   2169   GURL url2(kDefaultURL);
   2170   base::WeakPtr<SpdyStream> spdy_stream2 =
   2171       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2172                                 session, url2, MEDIUM, BoundNetLog());
   2173   ASSERT_TRUE(spdy_stream2.get() != NULL);
   2174   EXPECT_EQ(0u, spdy_stream2->stream_id());
   2175 
   2176   test::ClosingDelegate delegate1(spdy_stream1);
   2177   spdy_stream1->SetDelegate(&delegate1);
   2178 
   2179   test::ClosingDelegate delegate2(spdy_stream2);
   2180   spdy_stream2->SetDelegate(&delegate2);
   2181 
   2182   scoped_ptr<SpdyHeaderBlock> headers(
   2183       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2184   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   2185   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2186 
   2187   scoped_ptr<SpdyHeaderBlock> headers2(
   2188       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
   2189   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
   2190   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
   2191 
   2192   // Ensure that the streams have not yet been activated and assigned an id.
   2193   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2194   EXPECT_EQ(0u, spdy_stream2->stream_id());
   2195 
   2196   data.RunFor(2);
   2197 
   2198   EXPECT_EQ(1u, spdy_stream1->stream_id());
   2199   EXPECT_EQ(3u, spdy_stream2->stream_id());
   2200 
   2201   // Ensure we don't crash while closing the session.
   2202   session->CloseSessionOnError(ERR_ABORTED, std::string());
   2203 
   2204   EXPECT_EQ(NULL, spdy_stream1.get());
   2205   EXPECT_EQ(NULL, spdy_stream2.get());
   2206 
   2207   EXPECT_TRUE(delegate1.StreamIsClosed());
   2208   EXPECT_TRUE(delegate2.StreamIsClosed());
   2209 
   2210   base::MessageLoop::current()->RunUntilIdle();
   2211   EXPECT_TRUE(session == NULL);
   2212 }
   2213 
   2214 // Create two streams that are set to close each other on close,
   2215 // activate them, and then close the session. Nothing should blow up.
   2216 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) {
   2217   session_deps_.host_resolver->set_synchronous_mode(true);
   2218 
   2219   MockConnect connect_data(SYNCHRONOUS, OK);
   2220 
   2221   scoped_ptr<SpdyFrame> req1(
   2222       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   2223   scoped_ptr<SpdyFrame> req2(
   2224       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
   2225   MockWrite writes[] = {
   2226     CreateMockWrite(*req1, 0),
   2227     CreateMockWrite(*req2, 1),
   2228   };
   2229 
   2230   MockRead reads[] = {
   2231     MockRead(ASYNC, 0, 2)  // EOF
   2232   };
   2233 
   2234   DeterministicSocketData data(reads, arraysize(reads),
   2235                                writes, arraysize(writes));
   2236   data.set_connect_data(connect_data);
   2237   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2238 
   2239   CreateDeterministicNetworkSession();
   2240 
   2241   base::WeakPtr<SpdySession> session =
   2242       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2243 
   2244   GURL url1(kDefaultURL);
   2245   base::WeakPtr<SpdyStream> spdy_stream1 =
   2246       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2247                                 session, url1, MEDIUM, BoundNetLog());
   2248   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2249   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2250 
   2251   GURL url2(kDefaultURL);
   2252   base::WeakPtr<SpdyStream> spdy_stream2 =
   2253       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2254                                 session, url2, MEDIUM, BoundNetLog());
   2255   ASSERT_TRUE(spdy_stream2.get() != NULL);
   2256   EXPECT_EQ(0u, spdy_stream2->stream_id());
   2257 
   2258   // Make |spdy_stream1| close |spdy_stream2|.
   2259   test::ClosingDelegate delegate1(spdy_stream2);
   2260   spdy_stream1->SetDelegate(&delegate1);
   2261 
   2262   // Make |spdy_stream2| close |spdy_stream1|.
   2263   test::ClosingDelegate delegate2(spdy_stream1);
   2264   spdy_stream2->SetDelegate(&delegate2);
   2265 
   2266   scoped_ptr<SpdyHeaderBlock> headers(
   2267       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2268   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   2269   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2270 
   2271   scoped_ptr<SpdyHeaderBlock> headers2(
   2272       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
   2273   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
   2274   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
   2275 
   2276   // Ensure that the streams have not yet been activated and assigned an id.
   2277   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2278   EXPECT_EQ(0u, spdy_stream2->stream_id());
   2279 
   2280   data.RunFor(2);
   2281 
   2282   EXPECT_EQ(1u, spdy_stream1->stream_id());
   2283   EXPECT_EQ(3u, spdy_stream2->stream_id());
   2284 
   2285   // Ensure we don't crash while closing the session.
   2286   session->CloseSessionOnError(ERR_ABORTED, std::string());
   2287 
   2288   EXPECT_EQ(NULL, spdy_stream1.get());
   2289   EXPECT_EQ(NULL, spdy_stream2.get());
   2290 
   2291   EXPECT_TRUE(delegate1.StreamIsClosed());
   2292   EXPECT_TRUE(delegate2.StreamIsClosed());
   2293 
   2294   base::MessageLoop::current()->RunUntilIdle();
   2295   EXPECT_TRUE(session == NULL);
   2296 }
   2297 
   2298 // Delegate that closes a given session when the stream is closed.
   2299 class SessionClosingDelegate : public test::StreamDelegateDoNothing {
   2300  public:
   2301   SessionClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
   2302                          const base::WeakPtr<SpdySession>& session_to_close)
   2303       : StreamDelegateDoNothing(stream),
   2304         session_to_close_(session_to_close) {}
   2305 
   2306   virtual ~SessionClosingDelegate() {}
   2307 
   2308   virtual void OnClose(int status) OVERRIDE {
   2309     session_to_close_->CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Error");
   2310   }
   2311 
   2312  private:
   2313   base::WeakPtr<SpdySession> session_to_close_;
   2314 };
   2315 
   2316 // Close an activated stream that closes its session. Nothing should
   2317 // blow up. This is a regression test for http://crbug.com/263691 .
   2318 TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) {
   2319   session_deps_.host_resolver->set_synchronous_mode(true);
   2320 
   2321   MockConnect connect_data(SYNCHRONOUS, OK);
   2322 
   2323   scoped_ptr<SpdyFrame> req(
   2324       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   2325   scoped_ptr<SpdyFrame> rst(
   2326       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   2327   scoped_ptr<SpdyFrame> goaway(
   2328       spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Error"));
   2329   // The GOAWAY has higher-priority than the RST_STREAM, and is written first
   2330   // despite being queued second.
   2331   MockWrite writes[] = {
   2332       CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 1),
   2333       CreateMockWrite(*rst, 2),
   2334   };
   2335 
   2336   MockRead reads[] = {
   2337       MockRead(ASYNC, 0, 3)  // EOF
   2338   };
   2339   DeterministicSocketData data(reads, arraysize(reads),
   2340                                writes, arraysize(writes));
   2341   data.set_connect_data(connect_data);
   2342   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2343 
   2344   CreateDeterministicNetworkSession();
   2345 
   2346   base::WeakPtr<SpdySession> session =
   2347       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2348 
   2349   GURL url(kDefaultURL);
   2350   base::WeakPtr<SpdyStream> spdy_stream =
   2351       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2352                                 session, url, MEDIUM, BoundNetLog());
   2353   ASSERT_TRUE(spdy_stream.get() != NULL);
   2354   EXPECT_EQ(0u, spdy_stream->stream_id());
   2355 
   2356   SessionClosingDelegate delegate(spdy_stream, session);
   2357   spdy_stream->SetDelegate(&delegate);
   2358 
   2359   scoped_ptr<SpdyHeaderBlock> headers(
   2360       spdy_util_.ConstructGetHeaderBlock(url.spec()));
   2361   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   2362   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
   2363 
   2364   EXPECT_EQ(0u, spdy_stream->stream_id());
   2365 
   2366   data.RunFor(1);
   2367 
   2368   EXPECT_EQ(1u, spdy_stream->stream_id());
   2369 
   2370   // Ensure we don't crash while closing the stream (which closes the
   2371   // session).
   2372   spdy_stream->Cancel();
   2373 
   2374   EXPECT_EQ(NULL, spdy_stream.get());
   2375   EXPECT_TRUE(delegate.StreamIsClosed());
   2376 
   2377   data.RunFor(2);  // Write the RST_STREAM & GOAWAY.
   2378   base::MessageLoop::current()->RunUntilIdle();
   2379   EXPECT_TRUE(session == NULL);
   2380 }
   2381 
   2382 TEST_P(SpdySessionTest, VerifyDomainAuthentication) {
   2383   session_deps_.host_resolver->set_synchronous_mode(true);
   2384 
   2385   MockConnect connect_data(SYNCHRONOUS, OK);
   2386 
   2387   // No actual data will be sent.
   2388   MockWrite writes[] = {
   2389     MockWrite(ASYNC, 0, 1)  // EOF
   2390   };
   2391 
   2392   MockRead reads[] = {
   2393     MockRead(ASYNC, 0, 0)  // EOF
   2394   };
   2395   DeterministicSocketData data(reads, arraysize(reads),
   2396                                writes, arraysize(writes));
   2397   data.set_connect_data(connect_data);
   2398   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2399 
   2400   // Load a cert that is valid for:
   2401   //   www.example.org
   2402   //   mail.example.org
   2403   //   www.example.com
   2404   base::FilePath certs_dir = GetTestCertsDirectory();
   2405   scoped_refptr<X509Certificate> test_cert(
   2406       ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
   2407   ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
   2408 
   2409   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   2410   ssl.cert = test_cert;
   2411   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   2412 
   2413   CreateDeterministicNetworkSession();
   2414 
   2415   base::WeakPtr<SpdySession> session =
   2416       CreateSecureSpdySession(http_session_, key_, BoundNetLog());
   2417 
   2418   EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org"));
   2419   EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org"));
   2420   EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.com"));
   2421   EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com"));
   2422 }
   2423 
   2424 TEST_P(SpdySessionTest, ConnectionPooledWithTlsChannelId) {
   2425   session_deps_.host_resolver->set_synchronous_mode(true);
   2426 
   2427   MockConnect connect_data(SYNCHRONOUS, OK);
   2428 
   2429   // No actual data will be sent.
   2430   MockWrite writes[] = {
   2431     MockWrite(ASYNC, 0, 1)  // EOF
   2432   };
   2433 
   2434   MockRead reads[] = {
   2435     MockRead(ASYNC, 0, 0)  // EOF
   2436   };
   2437   DeterministicSocketData data(reads, arraysize(reads),
   2438                                writes, arraysize(writes));
   2439   data.set_connect_data(connect_data);
   2440   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2441 
   2442   // Load a cert that is valid for:
   2443   //   www.example.org
   2444   //   mail.example.org
   2445   //   www.example.com
   2446   base::FilePath certs_dir = GetTestCertsDirectory();
   2447   scoped_refptr<X509Certificate> test_cert(
   2448       ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
   2449   ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
   2450 
   2451   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   2452   ssl.channel_id_sent = true;
   2453   ssl.cert = test_cert;
   2454   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   2455 
   2456   CreateDeterministicNetworkSession();
   2457 
   2458   base::WeakPtr<SpdySession> session =
   2459       CreateSecureSpdySession(http_session_, key_, BoundNetLog());
   2460 
   2461   EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org"));
   2462   EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org"));
   2463   EXPECT_FALSE(session->VerifyDomainAuthentication("mail.example.com"));
   2464   EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com"));
   2465 }
   2466 
   2467 TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
   2468   // TODO(rtenneti): Define a helper class/methods and move the common code in
   2469   // this file.
   2470   MockConnect connect_data(SYNCHRONOUS, OK);
   2471 
   2472   SettingsMap new_settings;
   2473   const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
   2474   const uint32 max_concurrent_streams = 1;
   2475   new_settings[kSpdySettingsIds1] =
   2476       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
   2477 
   2478   scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
   2479   scoped_ptr<SpdyFrame> req1(
   2480       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   2481   scoped_ptr<SpdyFrame> req2(
   2482       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
   2483   scoped_ptr<SpdyFrame> req3(
   2484       spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true));
   2485   MockWrite writes[] = {
   2486     CreateMockWrite(*settings_ack, 1),
   2487     CreateMockWrite(*req1, 2),
   2488     CreateMockWrite(*req2, 5),
   2489     CreateMockWrite(*req3, 8),
   2490   };
   2491 
   2492   // Set up the socket so we read a SETTINGS frame that sets max concurrent
   2493   // streams to 1.
   2494   scoped_ptr<SpdyFrame> settings_frame(
   2495       spdy_util_.ConstructSpdySettings(new_settings));
   2496 
   2497   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2498   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   2499 
   2500   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   2501   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
   2502 
   2503   scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
   2504   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true));
   2505 
   2506   MockRead reads[] = {
   2507     CreateMockRead(*settings_frame),
   2508     CreateMockRead(*resp1, 3),
   2509     CreateMockRead(*body1, 4),
   2510     CreateMockRead(*resp2, 6),
   2511     CreateMockRead(*body2, 7),
   2512     CreateMockRead(*resp3, 9),
   2513     CreateMockRead(*body3, 10),
   2514     MockRead(ASYNC, 0, 11)  // EOF
   2515   };
   2516 
   2517   DeterministicSocketData data(reads, arraysize(reads),
   2518                                writes, arraysize(writes));
   2519   data.set_connect_data(connect_data);
   2520   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2521 
   2522   CreateDeterministicNetworkSession();
   2523 
   2524   base::WeakPtr<SpdySession> session =
   2525       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2526 
   2527   // Read the settings frame.
   2528   data.RunFor(1);
   2529 
   2530   GURL url1(kDefaultURL);
   2531   base::WeakPtr<SpdyStream> spdy_stream1 =
   2532       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2533                                 session, url1, LOWEST, BoundNetLog());
   2534   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2535   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2536   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   2537   spdy_stream1->SetDelegate(&delegate1);
   2538 
   2539   TestCompletionCallback callback2;
   2540   GURL url2(kDefaultURL);
   2541   SpdyStreamRequest request2;
   2542   ASSERT_EQ(ERR_IO_PENDING,
   2543             request2.StartRequest(
   2544                 SPDY_REQUEST_RESPONSE_STREAM,
   2545                 session, url2, LOWEST, BoundNetLog(), callback2.callback()));
   2546 
   2547   TestCompletionCallback callback3;
   2548   GURL url3(kDefaultURL);
   2549   SpdyStreamRequest request3;
   2550   ASSERT_EQ(ERR_IO_PENDING,
   2551             request3.StartRequest(
   2552                 SPDY_REQUEST_RESPONSE_STREAM,
   2553                 session, url3, LOWEST, BoundNetLog(), callback3.callback()));
   2554 
   2555   EXPECT_EQ(0u, session->num_active_streams());
   2556   EXPECT_EQ(1u, session->num_created_streams());
   2557   EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST));
   2558 
   2559   scoped_ptr<SpdyHeaderBlock> headers(
   2560       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2561   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   2562   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2563 
   2564   // Run until 1st stream is activated and then closed.
   2565   EXPECT_EQ(0u, delegate1.stream_id());
   2566   data.RunFor(4);
   2567   EXPECT_EQ(NULL, spdy_stream1.get());
   2568   EXPECT_EQ(1u, delegate1.stream_id());
   2569 
   2570   EXPECT_EQ(0u, session->num_active_streams());
   2571   EXPECT_EQ(0u, session->num_created_streams());
   2572   EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST));
   2573 
   2574   // Pump loop for SpdySession::ProcessPendingStreamRequests() to
   2575   // create the 2nd stream.
   2576   base::MessageLoop::current()->RunUntilIdle();
   2577 
   2578   EXPECT_EQ(0u, session->num_active_streams());
   2579   EXPECT_EQ(1u, session->num_created_streams());
   2580   EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST));
   2581 
   2582   base::WeakPtr<SpdyStream> stream2 = request2.ReleaseStream();
   2583   test::StreamDelegateDoNothing delegate2(stream2);
   2584   stream2->SetDelegate(&delegate2);
   2585   scoped_ptr<SpdyHeaderBlock> headers2(
   2586       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
   2587   stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
   2588   EXPECT_TRUE(stream2->HasUrlFromHeaders());
   2589 
   2590   // Run until 2nd stream is activated and then closed.
   2591   EXPECT_EQ(0u, delegate2.stream_id());
   2592   data.RunFor(3);
   2593   EXPECT_EQ(NULL, stream2.get());
   2594   EXPECT_EQ(3u, delegate2.stream_id());
   2595 
   2596   EXPECT_EQ(0u, session->num_active_streams());
   2597   EXPECT_EQ(0u, session->num_created_streams());
   2598   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
   2599 
   2600   // Pump loop for SpdySession::ProcessPendingStreamRequests() to
   2601   // create the 3rd stream.
   2602   base::MessageLoop::current()->RunUntilIdle();
   2603 
   2604   EXPECT_EQ(0u, session->num_active_streams());
   2605   EXPECT_EQ(1u, session->num_created_streams());
   2606   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
   2607 
   2608   base::WeakPtr<SpdyStream> stream3 = request3.ReleaseStream();
   2609   test::StreamDelegateDoNothing delegate3(stream3);
   2610   stream3->SetDelegate(&delegate3);
   2611   scoped_ptr<SpdyHeaderBlock> headers3(
   2612       spdy_util_.ConstructGetHeaderBlock(url3.spec()));
   2613   stream3->SendRequestHeaders(headers3.Pass(), NO_MORE_DATA_TO_SEND);
   2614   EXPECT_TRUE(stream3->HasUrlFromHeaders());
   2615 
   2616   // Run until 2nd stream is activated and then closed.
   2617   EXPECT_EQ(0u, delegate3.stream_id());
   2618   data.RunFor(3);
   2619   EXPECT_EQ(NULL, stream3.get());
   2620   EXPECT_EQ(5u, delegate3.stream_id());
   2621 
   2622   EXPECT_EQ(0u, session->num_active_streams());
   2623   EXPECT_EQ(0u, session->num_created_streams());
   2624   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
   2625 
   2626   data.RunFor(1);
   2627 }
   2628 
   2629 TEST_P(SpdySessionTest, CancelTwoStalledCreateStream) {
   2630   session_deps_.host_resolver->set_synchronous_mode(true);
   2631 
   2632   MockRead reads[] = {
   2633     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   2634   };
   2635 
   2636   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   2637   MockConnect connect_data(SYNCHRONOUS, OK);
   2638 
   2639   data.set_connect_data(connect_data);
   2640   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2641 
   2642   CreateNetworkSession();
   2643 
   2644   base::WeakPtr<SpdySession> session =
   2645       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2646 
   2647   // Leave room for only one more stream to be created.
   2648   for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) {
   2649     base::WeakPtr<SpdyStream> spdy_stream =
   2650         CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   2651                                   session, test_url_, MEDIUM, BoundNetLog());
   2652     ASSERT_TRUE(spdy_stream != NULL);
   2653   }
   2654 
   2655   GURL url1(kDefaultURL);
   2656   base::WeakPtr<SpdyStream> spdy_stream1 =
   2657       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   2658                                 session, url1, LOWEST, BoundNetLog());
   2659   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2660   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2661 
   2662   TestCompletionCallback callback2;
   2663   GURL url2(kDefaultURL);
   2664   SpdyStreamRequest request2;
   2665   ASSERT_EQ(ERR_IO_PENDING,
   2666             request2.StartRequest(
   2667                 SPDY_BIDIRECTIONAL_STREAM, session, url2, LOWEST, BoundNetLog(),
   2668                 callback2.callback()));
   2669 
   2670   TestCompletionCallback callback3;
   2671   GURL url3(kDefaultURL);
   2672   SpdyStreamRequest request3;
   2673   ASSERT_EQ(ERR_IO_PENDING,
   2674             request3.StartRequest(
   2675                 SPDY_BIDIRECTIONAL_STREAM, session, url3, LOWEST, BoundNetLog(),
   2676                 callback3.callback()));
   2677 
   2678   EXPECT_EQ(0u, session->num_active_streams());
   2679   EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams());
   2680   EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST));
   2681 
   2682   // Cancel the first stream; this will allow the second stream to be created.
   2683   EXPECT_TRUE(spdy_stream1.get() != NULL);
   2684   spdy_stream1->Cancel();
   2685   EXPECT_EQ(NULL, spdy_stream1.get());
   2686 
   2687   EXPECT_EQ(OK, callback2.WaitForResult());
   2688   EXPECT_EQ(0u, session->num_active_streams());
   2689   EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams());
   2690   EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST));
   2691 
   2692   // Cancel the second stream; this will allow the third stream to be created.
   2693   base::WeakPtr<SpdyStream> spdy_stream2 = request2.ReleaseStream();
   2694   spdy_stream2->Cancel();
   2695   EXPECT_EQ(NULL, spdy_stream2.get());
   2696 
   2697   EXPECT_EQ(OK, callback3.WaitForResult());
   2698   EXPECT_EQ(0u, session->num_active_streams());
   2699   EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams());
   2700   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
   2701 
   2702   // Cancel the third stream.
   2703   base::WeakPtr<SpdyStream> spdy_stream3 = request3.ReleaseStream();
   2704   spdy_stream3->Cancel();
   2705   EXPECT_EQ(NULL, spdy_stream3.get());
   2706   EXPECT_EQ(0u, session->num_active_streams());
   2707   EXPECT_EQ(kInitialMaxConcurrentStreams - 1, session->num_created_streams());
   2708   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
   2709 }
   2710 
   2711 // Test that SpdySession::DoReadLoop reads data from the socket
   2712 // without yielding.  This test makes 32k - 1 bytes of data available
   2713 // on the socket for reading. It then verifies that it has read all
   2714 // the available data without yielding.
   2715 TEST_P(SpdySessionTest, ReadDataWithoutYielding) {
   2716   MockConnect connect_data(SYNCHRONOUS, OK);
   2717   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
   2718 
   2719   scoped_ptr<SpdyFrame> req1(
   2720       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   2721   MockWrite writes[] = {
   2722     CreateMockWrite(*req1, 0),
   2723   };
   2724 
   2725   // Build buffer of size kMaxReadBytesWithoutYielding / 4
   2726   // (-spdy_data_frame_size).
   2727   ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding);
   2728   const int kPayloadSize =
   2729       kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize();
   2730   TestDataStream test_stream;
   2731   scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize));
   2732   char* payload_data = payload->data();
   2733   test_stream.GetBytes(payload_data, kPayloadSize);
   2734 
   2735   scoped_ptr<SpdyFrame> partial_data_frame(
   2736       framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE));
   2737   scoped_ptr<SpdyFrame> finish_data_frame(
   2738       framer.CreateDataFrame(1, payload_data, kPayloadSize - 1, DATA_FLAG_FIN));
   2739 
   2740   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2741 
   2742   // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k
   2743   // bytes.
   2744   MockRead reads[] = {
   2745     CreateMockRead(*resp1, 1),
   2746     CreateMockRead(*partial_data_frame, 2),
   2747     CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS),
   2748     CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS),
   2749     CreateMockRead(*finish_data_frame, 5, SYNCHRONOUS),
   2750     MockRead(ASYNC, 0, 6)  // EOF
   2751   };
   2752 
   2753   // Create SpdySession and SpdyStream and send the request.
   2754   DeterministicSocketData data(reads, arraysize(reads),
   2755                                writes, arraysize(writes));
   2756   data.set_connect_data(connect_data);
   2757   session_deps_.host_resolver->set_synchronous_mode(true);
   2758   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2759 
   2760   CreateDeterministicNetworkSession();
   2761 
   2762   base::WeakPtr<SpdySession> session =
   2763       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2764 
   2765   GURL url1(kDefaultURL);
   2766   base::WeakPtr<SpdyStream> spdy_stream1 =
   2767       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2768                                 session, url1, MEDIUM, BoundNetLog());
   2769   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2770   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2771   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   2772   spdy_stream1->SetDelegate(&delegate1);
   2773 
   2774   scoped_ptr<SpdyHeaderBlock> headers1(
   2775       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2776   spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
   2777   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2778 
   2779   // Set up the TaskObserver to verify SpdySession::DoReadLoop doesn't
   2780   // post a task.
   2781   SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
   2782 
   2783   // Run until 1st read.
   2784   EXPECT_EQ(0u, delegate1.stream_id());
   2785   data.RunFor(2);
   2786   EXPECT_EQ(1u, delegate1.stream_id());
   2787   EXPECT_EQ(0u, observer.executed_count());
   2788 
   2789   // Read all the data and verify SpdySession::DoReadLoop has not
   2790   // posted a task.
   2791   data.RunFor(4);
   2792   EXPECT_EQ(NULL, spdy_stream1.get());
   2793 
   2794   // Verify task observer's executed_count is zero, which indicates DoRead read
   2795   // all the available data.
   2796   EXPECT_EQ(0u, observer.executed_count());
   2797   EXPECT_TRUE(data.at_write_eof());
   2798   EXPECT_TRUE(data.at_read_eof());
   2799 }
   2800 
   2801 // Test that SpdySession::DoReadLoop yields while reading the
   2802 // data. This test makes 32k + 1 bytes of data available on the socket
   2803 // for reading. It then verifies that DoRead has yielded even though
   2804 // there is data available for it to read (i.e, socket()->Read didn't
   2805 // return ERR_IO_PENDING during socket reads).
   2806 TEST_P(SpdySessionTest, TestYieldingDuringReadData) {
   2807   MockConnect connect_data(SYNCHRONOUS, OK);
   2808   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
   2809 
   2810   scoped_ptr<SpdyFrame> req1(
   2811       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   2812   MockWrite writes[] = {
   2813     CreateMockWrite(*req1, 0),
   2814   };
   2815 
   2816   // Build buffer of size kMaxReadBytesWithoutYielding / 4
   2817   // (-spdy_data_frame_size).
   2818   ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding);
   2819   const int kPayloadSize =
   2820       kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize();
   2821   TestDataStream test_stream;
   2822   scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize));
   2823   char* payload_data = payload->data();
   2824   test_stream.GetBytes(payload_data, kPayloadSize);
   2825 
   2826   scoped_ptr<SpdyFrame> partial_data_frame(
   2827       framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE));
   2828   scoped_ptr<SpdyFrame> finish_data_frame(
   2829       framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN));
   2830 
   2831   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2832 
   2833   // Write 1 byte more than kMaxReadBytes to check that DoRead yields.
   2834   MockRead reads[] = {
   2835     CreateMockRead(*resp1, 1),
   2836     CreateMockRead(*partial_data_frame, 2),
   2837     CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS),
   2838     CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS),
   2839     CreateMockRead(*partial_data_frame, 5, SYNCHRONOUS),
   2840     CreateMockRead(*finish_data_frame, 6, SYNCHRONOUS),
   2841     MockRead(ASYNC, 0, 7)  // EOF
   2842   };
   2843 
   2844   // Create SpdySession and SpdyStream and send the request.
   2845   DeterministicSocketData data(reads, arraysize(reads),
   2846                                writes, arraysize(writes));
   2847   data.set_connect_data(connect_data);
   2848   session_deps_.host_resolver->set_synchronous_mode(true);
   2849   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2850 
   2851   CreateDeterministicNetworkSession();
   2852 
   2853   base::WeakPtr<SpdySession> session =
   2854       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2855 
   2856   GURL url1(kDefaultURL);
   2857   base::WeakPtr<SpdyStream> spdy_stream1 =
   2858       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2859                                 session, url1, MEDIUM, BoundNetLog());
   2860   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2861   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2862   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   2863   spdy_stream1->SetDelegate(&delegate1);
   2864 
   2865   scoped_ptr<SpdyHeaderBlock> headers1(
   2866       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2867   spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
   2868   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2869 
   2870   // Set up the TaskObserver to verify SpdySession::DoReadLoop posts a
   2871   // task.
   2872   SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
   2873 
   2874   // Run until 1st read.
   2875   EXPECT_EQ(0u, delegate1.stream_id());
   2876   data.RunFor(2);
   2877   EXPECT_EQ(1u, delegate1.stream_id());
   2878   EXPECT_EQ(0u, observer.executed_count());
   2879 
   2880   // Read all the data and verify SpdySession::DoReadLoop has posted a
   2881   // task.
   2882   data.RunFor(6);
   2883   EXPECT_EQ(NULL, spdy_stream1.get());
   2884 
   2885   // Verify task observer's executed_count is 1, which indicates DoRead has
   2886   // posted only one task and thus yielded though there is data available for it
   2887   // to read.
   2888   EXPECT_EQ(1u, observer.executed_count());
   2889   EXPECT_TRUE(data.at_write_eof());
   2890   EXPECT_TRUE(data.at_read_eof());
   2891 }
   2892 
   2893 // Test that SpdySession::DoReadLoop() tests interactions of yielding
   2894 // + async, by doing the following MockReads.
   2895 //
   2896 // MockRead of SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K
   2897 // ASYNC 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K.
   2898 //
   2899 // The above reads 26K synchronously. Since that is less that 32K, we
   2900 // will attempt to read again. However, that DoRead() will return
   2901 // ERR_IO_PENDING (because of async read), so DoReadLoop() will
   2902 // yield. When we come back, DoRead() will read the results from the
   2903 // async read, and rest of the data synchronously.
   2904 TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) {
   2905   MockConnect connect_data(SYNCHRONOUS, OK);
   2906   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
   2907 
   2908   scoped_ptr<SpdyFrame> req1(
   2909       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   2910   MockWrite writes[] = {
   2911     CreateMockWrite(*req1, 0),
   2912   };
   2913 
   2914   // Build buffer of size kMaxReadBytesWithoutYielding / 4
   2915   // (-spdy_data_frame_size).
   2916   ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding);
   2917   TestDataStream test_stream;
   2918   const int kEightKPayloadSize =
   2919       kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize();
   2920   scoped_refptr<net::IOBuffer> eightk_payload(
   2921       new net::IOBuffer(kEightKPayloadSize));
   2922   char* eightk_payload_data = eightk_payload->data();
   2923   test_stream.GetBytes(eightk_payload_data, kEightKPayloadSize);
   2924 
   2925   // Build buffer of 2k size.
   2926   TestDataStream test_stream2;
   2927   const int kTwoKPayloadSize = kEightKPayloadSize - 6 * 1024;
   2928   scoped_refptr<net::IOBuffer> twok_payload(
   2929       new net::IOBuffer(kTwoKPayloadSize));
   2930   char* twok_payload_data = twok_payload->data();
   2931   test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize);
   2932 
   2933   scoped_ptr<SpdyFrame> eightk_data_frame(framer.CreateDataFrame(
   2934       1, eightk_payload_data, kEightKPayloadSize, DATA_FLAG_NONE));
   2935   scoped_ptr<SpdyFrame> twok_data_frame(framer.CreateDataFrame(
   2936       1, twok_payload_data, kTwoKPayloadSize, DATA_FLAG_NONE));
   2937   scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame(
   2938       1, "h", 1, DATA_FLAG_FIN));
   2939 
   2940   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2941 
   2942   MockRead reads[] = {
   2943     CreateMockRead(*resp1, 1),
   2944     CreateMockRead(*eightk_data_frame, 2),
   2945     CreateMockRead(*eightk_data_frame, 3, SYNCHRONOUS),
   2946     CreateMockRead(*eightk_data_frame, 4, SYNCHRONOUS),
   2947     CreateMockRead(*twok_data_frame, 5, SYNCHRONOUS),
   2948     CreateMockRead(*eightk_data_frame, 6, ASYNC),
   2949     CreateMockRead(*eightk_data_frame, 7, SYNCHRONOUS),
   2950     CreateMockRead(*eightk_data_frame, 8, SYNCHRONOUS),
   2951     CreateMockRead(*eightk_data_frame, 9, SYNCHRONOUS),
   2952     CreateMockRead(*twok_data_frame, 10, SYNCHRONOUS),
   2953     CreateMockRead(*finish_data_frame, 11, SYNCHRONOUS),
   2954     MockRead(ASYNC, 0, 12)  // EOF
   2955   };
   2956 
   2957   // Create SpdySession and SpdyStream and send the request.
   2958   DeterministicSocketData data(reads, arraysize(reads),
   2959                                writes, arraysize(writes));
   2960   data.set_connect_data(connect_data);
   2961   session_deps_.host_resolver->set_synchronous_mode(true);
   2962   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   2963 
   2964   CreateDeterministicNetworkSession();
   2965 
   2966   base::WeakPtr<SpdySession> session =
   2967       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   2968 
   2969   GURL url1(kDefaultURL);
   2970   base::WeakPtr<SpdyStream> spdy_stream1 =
   2971       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   2972                                 session, url1, MEDIUM, BoundNetLog());
   2973   ASSERT_TRUE(spdy_stream1.get() != NULL);
   2974   EXPECT_EQ(0u, spdy_stream1->stream_id());
   2975   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   2976   spdy_stream1->SetDelegate(&delegate1);
   2977 
   2978   scoped_ptr<SpdyHeaderBlock> headers1(
   2979       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   2980   spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
   2981   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   2982 
   2983   // Set up the TaskObserver to monitor SpdySession::DoReadLoop
   2984   // posting of tasks.
   2985   SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
   2986 
   2987   // Run until 1st read.
   2988   EXPECT_EQ(0u, delegate1.stream_id());
   2989   data.RunFor(2);
   2990   EXPECT_EQ(1u, delegate1.stream_id());
   2991   EXPECT_EQ(0u, observer.executed_count());
   2992 
   2993   // Read all the data and verify SpdySession::DoReadLoop has posted a
   2994   // task.
   2995   data.RunFor(12);
   2996   EXPECT_EQ(NULL, spdy_stream1.get());
   2997 
   2998   // Verify task observer's executed_count is 1, which indicates DoRead has
   2999   // posted only one task and thus yielded though there is data available for
   3000   // it to read.
   3001   EXPECT_EQ(1u, observer.executed_count());
   3002   EXPECT_TRUE(data.at_write_eof());
   3003   EXPECT_TRUE(data.at_read_eof());
   3004 }
   3005 
   3006 // Send a GoAway frame when SpdySession is in DoReadLoop. Make sure
   3007 // nothing blows up.
   3008 TEST_P(SpdySessionTest, GoAwayWhileInDoReadLoop) {
   3009   MockConnect connect_data(SYNCHRONOUS, OK);
   3010   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
   3011 
   3012   scoped_ptr<SpdyFrame> req1(
   3013       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   3014   MockWrite writes[] = {
   3015     CreateMockWrite(*req1, 0),
   3016   };
   3017 
   3018   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3019   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   3020   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway());
   3021 
   3022   MockRead reads[] = {
   3023     CreateMockRead(*resp1, 1),
   3024     CreateMockRead(*body1, 2),
   3025     CreateMockRead(*goaway, 3),
   3026   };
   3027 
   3028   // Create SpdySession and SpdyStream and send the request.
   3029   DeterministicSocketData data(reads, arraysize(reads),
   3030                                writes, arraysize(writes));
   3031   data.set_connect_data(connect_data);
   3032   session_deps_.host_resolver->set_synchronous_mode(true);
   3033   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3034 
   3035   CreateDeterministicNetworkSession();
   3036 
   3037   base::WeakPtr<SpdySession> session =
   3038       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3039 
   3040   GURL url1(kDefaultURL);
   3041   base::WeakPtr<SpdyStream> spdy_stream1 =
   3042       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   3043                                 session, url1, MEDIUM, BoundNetLog());
   3044   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   3045   spdy_stream1->SetDelegate(&delegate1);
   3046   ASSERT_TRUE(spdy_stream1.get() != NULL);
   3047   EXPECT_EQ(0u, spdy_stream1->stream_id());
   3048 
   3049   scoped_ptr<SpdyHeaderBlock> headers1(
   3050       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   3051   spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
   3052   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   3053 
   3054   // Run until 1st read.
   3055   EXPECT_EQ(0u, spdy_stream1->stream_id());
   3056   data.RunFor(1);
   3057   EXPECT_EQ(1u, spdy_stream1->stream_id());
   3058 
   3059   // Run until GoAway.
   3060   data.RunFor(3);
   3061   EXPECT_EQ(NULL, spdy_stream1.get());
   3062   EXPECT_TRUE(data.at_write_eof());
   3063   EXPECT_TRUE(data.at_read_eof());
   3064   EXPECT_TRUE(session == NULL);
   3065 }
   3066 
   3067 // Within this framework, a SpdySession should be initialized with
   3068 // flow control disabled for protocol version 2, with flow control
   3069 // enabled only for streams for protocol version 3, and with flow
   3070 // control enabled for streams and sessions for higher versions.
   3071 TEST_P(SpdySessionTest, ProtocolNegotiation) {
   3072   session_deps_.host_resolver->set_synchronous_mode(true);
   3073 
   3074   MockConnect connect_data(SYNCHRONOUS, OK);
   3075   MockRead reads[] = {
   3076     MockRead(SYNCHRONOUS, 0, 0)  // EOF
   3077   };
   3078   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   3079   data.set_connect_data(connect_data);
   3080   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3081 
   3082   CreateNetworkSession();
   3083   base::WeakPtr<SpdySession> session =
   3084       CreateFakeSpdySession(spdy_session_pool_, key_);
   3085 
   3086   EXPECT_EQ(spdy_util_.spdy_version(),
   3087             session->buffered_spdy_framer_->protocol_version());
   3088   if (GetParam() == kProtoDeprecatedSPDY2) {
   3089     EXPECT_EQ(SpdySession::FLOW_CONTROL_NONE, session->flow_control_state());
   3090     EXPECT_EQ(0, session->session_send_window_size_);
   3091     EXPECT_EQ(0, session->session_recv_window_size_);
   3092   } else if (GetParam() == kProtoSPDY3) {
   3093     EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state());
   3094     EXPECT_EQ(0, session->session_send_window_size_);
   3095     EXPECT_EQ(0, session->session_recv_window_size_);
   3096   } else {
   3097     EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   3098               session->flow_control_state());
   3099     EXPECT_EQ(kSpdySessionInitialWindowSize,
   3100               session->session_send_window_size_);
   3101     EXPECT_EQ(kSpdySessionInitialWindowSize,
   3102               session->session_recv_window_size_);
   3103   }
   3104   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3105 }
   3106 
   3107 // Tests the case of a non-SPDY request closing an idle SPDY session when no
   3108 // pointers to the idle session are currently held.
   3109 TEST_P(SpdySessionTest, CloseOneIdleConnection) {
   3110   ClientSocketPoolManager::set_max_sockets_per_group(
   3111       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   3112   ClientSocketPoolManager::set_max_sockets_per_pool(
   3113       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   3114 
   3115   MockConnect connect_data(SYNCHRONOUS, OK);
   3116   MockRead reads[] = {
   3117     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   3118   };
   3119   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   3120   data.set_connect_data(connect_data);
   3121   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3122   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3123 
   3124   CreateNetworkSession();
   3125 
   3126   TransportClientSocketPool* pool =
   3127       http_session_->GetTransportSocketPool(
   3128           HttpNetworkSession::NORMAL_SOCKET_POOL);
   3129 
   3130   // Create an idle SPDY session.
   3131   SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
   3132                       PRIVACY_MODE_DISABLED);
   3133   base::WeakPtr<SpdySession> session1 =
   3134       CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
   3135   EXPECT_FALSE(pool->IsStalled());
   3136 
   3137   // Trying to create a new connection should cause the pool to be stalled, and
   3138   // post a task asynchronously to try and close the session.
   3139   TestCompletionCallback callback2;
   3140   HostPortPair host_port2("2.com", 80);
   3141   scoped_refptr<TransportSocketParams> params2(
   3142       new TransportSocketParams(
   3143           host_port2, false, false, OnHostResolutionCallback(),
   3144           TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
   3145   scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
   3146   EXPECT_EQ(ERR_IO_PENDING,
   3147             connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
   3148                               callback2.callback(), pool, BoundNetLog()));
   3149   EXPECT_TRUE(pool->IsStalled());
   3150 
   3151   // The socket pool should close the connection asynchronously and establish a
   3152   // new connection.
   3153   EXPECT_EQ(OK, callback2.WaitForResult());
   3154   EXPECT_FALSE(pool->IsStalled());
   3155   EXPECT_TRUE(session1 == NULL);
   3156 }
   3157 
   3158 // Tests the case of a non-SPDY request closing an idle SPDY session when no
   3159 // pointers to the idle session are currently held, in the case the SPDY session
   3160 // has an alias.
   3161 TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
   3162   ClientSocketPoolManager::set_max_sockets_per_group(
   3163       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   3164   ClientSocketPoolManager::set_max_sockets_per_pool(
   3165       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   3166 
   3167   MockConnect connect_data(SYNCHRONOUS, OK);
   3168   MockRead reads[] = {
   3169     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   3170   };
   3171   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   3172   data.set_connect_data(connect_data);
   3173   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3174   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3175 
   3176   session_deps_.host_resolver->set_synchronous_mode(true);
   3177   session_deps_.host_resolver->rules()->AddIPLiteralRule(
   3178       "1.com", "192.168.0.2", std::string());
   3179   session_deps_.host_resolver->rules()->AddIPLiteralRule(
   3180       "2.com", "192.168.0.2", std::string());
   3181   // Not strictly needed.
   3182   session_deps_.host_resolver->rules()->AddIPLiteralRule(
   3183       "3.com", "192.168.0.3", std::string());
   3184 
   3185   CreateNetworkSession();
   3186 
   3187   TransportClientSocketPool* pool =
   3188       http_session_->GetTransportSocketPool(
   3189           HttpNetworkSession::NORMAL_SOCKET_POOL);
   3190 
   3191   // Create an idle SPDY session.
   3192   SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
   3193                       PRIVACY_MODE_DISABLED);
   3194   base::WeakPtr<SpdySession> session1 =
   3195       CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
   3196   EXPECT_FALSE(pool->IsStalled());
   3197 
   3198   // Set up an alias for the idle SPDY session, increasing its ref count to 2.
   3199   SpdySessionKey key2(HostPortPair("2.com", 80), ProxyServer::Direct(),
   3200                       PRIVACY_MODE_DISABLED);
   3201   HostResolver::RequestInfo info(key2.host_port_pair());
   3202   AddressList addresses;
   3203   // Pre-populate the DNS cache, since a synchronous resolution is required in
   3204   // order to create the alias.
   3205   session_deps_.host_resolver->Resolve(info,
   3206                                        DEFAULT_PRIORITY,
   3207                                        &addresses,
   3208                                        CompletionCallback(),
   3209                                        NULL,
   3210                                        BoundNetLog());
   3211   // Get a session for |key2|, which should return the session created earlier.
   3212   base::WeakPtr<SpdySession> session2 =
   3213       spdy_session_pool_->FindAvailableSession(key2, BoundNetLog());
   3214   ASSERT_EQ(session1.get(), session2.get());
   3215   EXPECT_FALSE(pool->IsStalled());
   3216 
   3217   // Trying to create a new connection should cause the pool to be stalled, and
   3218   // post a task asynchronously to try and close the session.
   3219   TestCompletionCallback callback3;
   3220   HostPortPair host_port3("3.com", 80);
   3221   scoped_refptr<TransportSocketParams> params3(
   3222       new TransportSocketParams(
   3223           host_port3, false, false, OnHostResolutionCallback(),
   3224           TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
   3225   scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle);
   3226   EXPECT_EQ(ERR_IO_PENDING,
   3227             connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY,
   3228                               callback3.callback(), pool, BoundNetLog()));
   3229   EXPECT_TRUE(pool->IsStalled());
   3230 
   3231   // The socket pool should close the connection asynchronously and establish a
   3232   // new connection.
   3233   EXPECT_EQ(OK, callback3.WaitForResult());
   3234   EXPECT_FALSE(pool->IsStalled());
   3235   EXPECT_TRUE(session1 == NULL);
   3236   EXPECT_TRUE(session2 == NULL);
   3237 }
   3238 
   3239 // Tests that when a SPDY session becomes idle, it closes itself if there is
   3240 // a lower layer pool stalled on the per-pool socket limit.
   3241 TEST_P(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) {
   3242   ClientSocketPoolManager::set_max_sockets_per_group(
   3243       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   3244   ClientSocketPoolManager::set_max_sockets_per_pool(
   3245       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   3246 
   3247   MockConnect connect_data(SYNCHRONOUS, OK);
   3248   MockRead reads[] = {
   3249     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   3250   };
   3251   scoped_ptr<SpdyFrame> req1(
   3252       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   3253   scoped_ptr<SpdyFrame> cancel1(
   3254       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   3255   MockWrite writes[] = {
   3256     CreateMockWrite(*req1, 1),
   3257     CreateMockWrite(*cancel1, 1),
   3258   };
   3259   StaticSocketDataProvider data(reads, arraysize(reads),
   3260                                 writes, arraysize(writes));
   3261   data.set_connect_data(connect_data);
   3262   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3263 
   3264   MockRead http_reads[] = {
   3265     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   3266   };
   3267   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
   3268                                      NULL, 0);
   3269   http_data.set_connect_data(connect_data);
   3270   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
   3271 
   3272 
   3273   CreateNetworkSession();
   3274 
   3275   TransportClientSocketPool* pool =
   3276       http_session_->GetTransportSocketPool(
   3277           HttpNetworkSession::NORMAL_SOCKET_POOL);
   3278 
   3279   // Create a SPDY session.
   3280   GURL url1(kDefaultURL);
   3281   SpdySessionKey key1(HostPortPair(url1.host(), 80),
   3282                       ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
   3283   base::WeakPtr<SpdySession> session1 =
   3284       CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
   3285   EXPECT_FALSE(pool->IsStalled());
   3286 
   3287   // Create a stream using the session, and send a request.
   3288 
   3289   TestCompletionCallback callback1;
   3290   base::WeakPtr<SpdyStream> spdy_stream1 =
   3291       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   3292                                 session1, url1, DEFAULT_PRIORITY,
   3293                                 BoundNetLog());
   3294   ASSERT_TRUE(spdy_stream1.get());
   3295   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   3296   spdy_stream1->SetDelegate(&delegate1);
   3297 
   3298   scoped_ptr<SpdyHeaderBlock> headers1(
   3299       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   3300   EXPECT_EQ(ERR_IO_PENDING,
   3301             spdy_stream1->SendRequestHeaders(
   3302                 headers1.Pass(), NO_MORE_DATA_TO_SEND));
   3303   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   3304 
   3305   base::MessageLoop::current()->RunUntilIdle();
   3306 
   3307   // Trying to create a new connection should cause the pool to be stalled, and
   3308   // post a task asynchronously to try and close the session.
   3309   TestCompletionCallback callback2;
   3310   HostPortPair host_port2("2.com", 80);
   3311   scoped_refptr<TransportSocketParams> params2(
   3312       new TransportSocketParams(
   3313           host_port2, false, false, OnHostResolutionCallback(),
   3314           TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
   3315   scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
   3316   EXPECT_EQ(ERR_IO_PENDING,
   3317             connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
   3318                               callback2.callback(), pool, BoundNetLog()));
   3319   EXPECT_TRUE(pool->IsStalled());
   3320 
   3321   // Running the message loop should cause the socket pool to ask the SPDY
   3322   // session to close an idle socket, but since the socket is in use, nothing
   3323   // happens.
   3324   base::RunLoop().RunUntilIdle();
   3325   EXPECT_TRUE(pool->IsStalled());
   3326   EXPECT_FALSE(callback2.have_result());
   3327 
   3328   // Cancelling the request should result in the session's socket being
   3329   // closed, since the pool is stalled.
   3330   ASSERT_TRUE(spdy_stream1.get());
   3331   spdy_stream1->Cancel();
   3332   base::RunLoop().RunUntilIdle();
   3333   ASSERT_FALSE(pool->IsStalled());
   3334   EXPECT_EQ(OK, callback2.WaitForResult());
   3335 }
   3336 
   3337 // Verify that SpdySessionKey and therefore SpdySession is different when
   3338 // privacy mode is enabled or disabled.
   3339 TEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) {
   3340   CreateDeterministicNetworkSession();
   3341 
   3342   HostPortPair host_port_pair("www.google.com", 443);
   3343   SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(),
   3344                                      PRIVACY_MODE_ENABLED);
   3345   SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(),
   3346                                      PRIVACY_MODE_DISABLED);
   3347 
   3348   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
   3349   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
   3350 
   3351   // Add SpdySession with PrivacyMode Enabled to the pool.
   3352   base::WeakPtr<SpdySession> session_privacy_enabled =
   3353       CreateFakeSpdySession(spdy_session_pool_, key_privacy_enabled);
   3354 
   3355   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
   3356   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
   3357 
   3358   // Add SpdySession with PrivacyMode Disabled to the pool.
   3359   base::WeakPtr<SpdySession> session_privacy_disabled =
   3360       CreateFakeSpdySession(spdy_session_pool_, key_privacy_disabled);
   3361 
   3362   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
   3363   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
   3364 
   3365   session_privacy_enabled->CloseSessionOnError(ERR_ABORTED, std::string());
   3366   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
   3367   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
   3368 
   3369   session_privacy_disabled->CloseSessionOnError(ERR_ABORTED, std::string());
   3370   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
   3371   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
   3372 }
   3373 
   3374 // Delegate that creates another stream when its stream is closed.
   3375 class StreamCreatingDelegate : public test::StreamDelegateDoNothing {
   3376  public:
   3377   StreamCreatingDelegate(const base::WeakPtr<SpdyStream>& stream,
   3378                          const base::WeakPtr<SpdySession>& session)
   3379       : StreamDelegateDoNothing(stream),
   3380         session_(session) {}
   3381 
   3382   virtual ~StreamCreatingDelegate() {}
   3383 
   3384   virtual void OnClose(int status) OVERRIDE {
   3385     GURL url(kDefaultURL);
   3386     ignore_result(
   3387         CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   3388                                   session_, url, MEDIUM, BoundNetLog()));
   3389   }
   3390 
   3391  private:
   3392   const base::WeakPtr<SpdySession> session_;
   3393 };
   3394 
   3395 // Create another stream in response to a stream being reset. Nothing
   3396 // should blow up. This is a regression test for
   3397 // http://crbug.com/263690 .
   3398 TEST_P(SpdySessionTest, CreateStreamOnStreamReset) {
   3399   session_deps_.host_resolver->set_synchronous_mode(true);
   3400 
   3401   MockConnect connect_data(SYNCHRONOUS, OK);
   3402 
   3403   scoped_ptr<SpdyFrame> req(
   3404       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
   3405   MockWrite writes[] = {
   3406     CreateMockWrite(*req, 0),
   3407   };
   3408 
   3409   scoped_ptr<SpdyFrame> rst(
   3410       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM));
   3411   MockRead reads[] = {
   3412     CreateMockRead(*rst, 1),
   3413     MockRead(ASYNC, 0, 2)  // EOF
   3414   };
   3415   DeterministicSocketData data(reads, arraysize(reads),
   3416                                writes, arraysize(writes));
   3417   data.set_connect_data(connect_data);
   3418   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3419 
   3420   CreateDeterministicNetworkSession();
   3421 
   3422   base::WeakPtr<SpdySession> session =
   3423       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3424 
   3425   GURL url(kDefaultURL);
   3426   base::WeakPtr<SpdyStream> spdy_stream =
   3427       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   3428                                 session, url, MEDIUM, BoundNetLog());
   3429   ASSERT_TRUE(spdy_stream.get() != NULL);
   3430   EXPECT_EQ(0u, spdy_stream->stream_id());
   3431 
   3432   StreamCreatingDelegate delegate(spdy_stream, session);
   3433   spdy_stream->SetDelegate(&delegate);
   3434 
   3435   scoped_ptr<SpdyHeaderBlock> headers(
   3436       spdy_util_.ConstructGetHeaderBlock(url.spec()));
   3437   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   3438   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
   3439 
   3440   EXPECT_EQ(0u, spdy_stream->stream_id());
   3441 
   3442   data.RunFor(1);
   3443 
   3444   EXPECT_EQ(1u, spdy_stream->stream_id());
   3445 
   3446   // Cause the stream to be reset, which should cause another stream
   3447   // to be created.
   3448   data.RunFor(1);
   3449 
   3450   EXPECT_EQ(NULL, spdy_stream.get());
   3451   EXPECT_TRUE(delegate.StreamIsClosed());
   3452   EXPECT_EQ(0u, session->num_active_streams());
   3453   EXPECT_EQ(1u, session->num_created_streams());
   3454 }
   3455 
   3456 // The tests below are only for SPDY/3 and above.
   3457 
   3458 TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
   3459   if (GetParam() < kProtoSPDY3)
   3460     return;
   3461 
   3462   // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE
   3463   // gets sent.
   3464   SettingsMap new_settings;
   3465   int32 window_size = 1;
   3466   new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
   3467       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size);
   3468 
   3469   // Set up the socket so we read a SETTINGS frame that sets
   3470   // INITIAL_WINDOW_SIZE.
   3471   MockConnect connect_data(SYNCHRONOUS, OK);
   3472   scoped_ptr<SpdyFrame> settings_frame(
   3473       spdy_util_.ConstructSpdySettings(new_settings));
   3474   MockRead reads[] = {
   3475     CreateMockRead(*settings_frame, 0),
   3476     MockRead(ASYNC, 0, 1)  // EOF
   3477   };
   3478 
   3479   scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
   3480   MockWrite writes[] = {
   3481     CreateMockWrite(*settings_ack, 2),
   3482   };
   3483 
   3484   session_deps_.host_resolver->set_synchronous_mode(true);
   3485 
   3486   DeterministicSocketData data(reads, arraysize(reads),
   3487                                writes, arraysize(writes));
   3488   data.set_connect_data(connect_data);
   3489   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3490 
   3491   CreateDeterministicNetworkSession();
   3492 
   3493   base::WeakPtr<SpdySession> session =
   3494       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3495   base::WeakPtr<SpdyStream> spdy_stream1 =
   3496       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   3497                                 session, test_url_, MEDIUM, BoundNetLog());
   3498   ASSERT_TRUE(spdy_stream1.get() != NULL);
   3499   TestCompletionCallback callback1;
   3500   EXPECT_NE(spdy_stream1->send_window_size(), window_size);
   3501 
   3502   data.RunFor(1);  // Process the SETTINGS frame, but not the EOF
   3503   base::MessageLoop::current()->RunUntilIdle();
   3504   EXPECT_EQ(session->stream_initial_send_window_size(), window_size);
   3505   EXPECT_EQ(spdy_stream1->send_window_size(), window_size);
   3506 
   3507   // Release the first one, this will allow the second to be created.
   3508   spdy_stream1->Cancel();
   3509   EXPECT_EQ(NULL, spdy_stream1.get());
   3510 
   3511   base::WeakPtr<SpdyStream> spdy_stream2 =
   3512       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   3513                                 session, test_url_, MEDIUM, BoundNetLog());
   3514   ASSERT_TRUE(spdy_stream2.get() != NULL);
   3515   EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
   3516   spdy_stream2->Cancel();
   3517   EXPECT_EQ(NULL, spdy_stream2.get());
   3518 }
   3519 
   3520 // The tests below are only for SPDY/3.1 and above.
   3521 
   3522 // SpdySession::{Increase,Decrease}RecvWindowSize should properly
   3523 // adjust the session receive window size for SPDY 3.1 and higher. In
   3524 // addition, SpdySession::IncreaseRecvWindowSize should trigger
   3525 // sending a WINDOW_UPDATE frame for a large enough delta.
   3526 TEST_P(SpdySessionTest, AdjustRecvWindowSize) {
   3527   if (GetParam() < kProtoSPDY31)
   3528     return;
   3529 
   3530   session_deps_.host_resolver->set_synchronous_mode(true);
   3531 
   3532   const int32 delta_window_size = 100;
   3533 
   3534   MockConnect connect_data(SYNCHRONOUS, OK);
   3535   MockRead reads[] = {
   3536     MockRead(ASYNC, 0, 1)  // EOF
   3537   };
   3538   scoped_ptr<SpdyFrame> window_update(
   3539       spdy_util_.ConstructSpdyWindowUpdate(
   3540           kSessionFlowControlStreamId,
   3541           kSpdySessionInitialWindowSize + delta_window_size));
   3542   MockWrite writes[] = {
   3543     CreateMockWrite(*window_update, 0),
   3544   };
   3545   DeterministicSocketData data(reads, arraysize(reads),
   3546                                writes, arraysize(writes));
   3547   data.set_connect_data(connect_data);
   3548   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3549 
   3550   CreateDeterministicNetworkSession();
   3551   base::WeakPtr<SpdySession> session =
   3552       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3553   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   3554             session->flow_control_state());
   3555 
   3556   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3557   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3558 
   3559   session->IncreaseRecvWindowSize(delta_window_size);
   3560   EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size,
   3561             session->session_recv_window_size_);
   3562   EXPECT_EQ(delta_window_size, session->session_unacked_recv_window_bytes_);
   3563 
   3564   // Should trigger sending a WINDOW_UPDATE frame.
   3565   session->IncreaseRecvWindowSize(kSpdySessionInitialWindowSize);
   3566   EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size +
   3567             kSpdySessionInitialWindowSize,
   3568             session->session_recv_window_size_);
   3569   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3570 
   3571   data.RunFor(1);
   3572 
   3573   // DecreaseRecvWindowSize() expects |in_io_loop_| to be true.
   3574   session->in_io_loop_ = true;
   3575   session->DecreaseRecvWindowSize(
   3576       kSpdySessionInitialWindowSize + delta_window_size +
   3577       kSpdySessionInitialWindowSize);
   3578   session->in_io_loop_ = false;
   3579   EXPECT_EQ(0, session->session_recv_window_size_);
   3580   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3581 }
   3582 
   3583 // SpdySession::{Increase,Decrease}SendWindowSize should properly
   3584 // adjust the session send window size when the "enable_spdy_31" flag
   3585 // is set.
   3586 TEST_P(SpdySessionTest, AdjustSendWindowSize) {
   3587   if (GetParam() < kProtoSPDY31)
   3588     return;
   3589 
   3590   session_deps_.host_resolver->set_synchronous_mode(true);
   3591 
   3592   MockConnect connect_data(SYNCHRONOUS, OK);
   3593   MockRead reads[] = {
   3594     MockRead(SYNCHRONOUS, 0, 0)  // EOF
   3595   };
   3596   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   3597   data.set_connect_data(connect_data);
   3598   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3599 
   3600   CreateNetworkSession();
   3601   base::WeakPtr<SpdySession> session =
   3602       CreateFakeSpdySession(spdy_session_pool_, key_);
   3603   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   3604             session->flow_control_state());
   3605 
   3606   const int32 delta_window_size = 100;
   3607 
   3608   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3609 
   3610   session->IncreaseSendWindowSize(delta_window_size);
   3611   EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size,
   3612             session->session_send_window_size_);
   3613 
   3614   session->DecreaseSendWindowSize(delta_window_size);
   3615   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3616 }
   3617 
   3618 // Incoming data for an inactive stream should not cause the session
   3619 // receive window size to decrease, but it should cause the unacked
   3620 // bytes to increase.
   3621 TEST_P(SpdySessionTest, SessionFlowControlInactiveStream) {
   3622   if (GetParam() < kProtoSPDY31)
   3623     return;
   3624 
   3625   session_deps_.host_resolver->set_synchronous_mode(true);
   3626 
   3627   MockConnect connect_data(SYNCHRONOUS, OK);
   3628   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyBodyFrame(1, false));
   3629   MockRead reads[] = {
   3630     CreateMockRead(*resp, 0),
   3631     MockRead(ASYNC, 0, 1)  // EOF
   3632   };
   3633   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
   3634   data.set_connect_data(connect_data);
   3635   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3636 
   3637   CreateDeterministicNetworkSession();
   3638   base::WeakPtr<SpdySession> session =
   3639       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3640   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   3641             session->flow_control_state());
   3642 
   3643   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3644   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3645 
   3646   data.RunFor(1);
   3647 
   3648   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3649   EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_);
   3650 
   3651   data.RunFor(1);
   3652 }
   3653 
   3654 // A delegate that drops any received data.
   3655 class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate {
   3656  public:
   3657   DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream,
   3658                            base::StringPiece data)
   3659       : StreamDelegateSendImmediate(stream, data) {}
   3660 
   3661   virtual ~DropReceivedDataDelegate() {}
   3662 
   3663   // Drop any received data.
   3664   virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE {}
   3665 };
   3666 
   3667 // Send data back and forth but use a delegate that drops its received
   3668 // data. The receive window should still increase to its original
   3669 // value, i.e. we shouldn't "leak" receive window bytes.
   3670 TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) {
   3671   if (GetParam() < kProtoSPDY31)
   3672     return;
   3673 
   3674   const char kStreamUrl[] = "http://www.google.com/";
   3675 
   3676   const int32 msg_data_size = 100;
   3677   const std::string msg_data(msg_data_size, 'a');
   3678 
   3679   MockConnect connect_data(SYNCHRONOUS, OK);
   3680 
   3681   scoped_ptr<SpdyFrame> req(
   3682       spdy_util_.ConstructSpdyPost(
   3683           kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0));
   3684   scoped_ptr<SpdyFrame> msg(
   3685       spdy_util_.ConstructSpdyBodyFrame(
   3686           1, msg_data.data(), msg_data_size, false));
   3687   MockWrite writes[] = {
   3688     CreateMockWrite(*req, 0),
   3689     CreateMockWrite(*msg, 2),
   3690   };
   3691 
   3692   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3693   scoped_ptr<SpdyFrame> echo(
   3694       spdy_util_.ConstructSpdyBodyFrame(
   3695           1, msg_data.data(), msg_data_size, false));
   3696   scoped_ptr<SpdyFrame> window_update(
   3697       spdy_util_.ConstructSpdyWindowUpdate(
   3698           kSessionFlowControlStreamId, msg_data_size));
   3699   MockRead reads[] = {
   3700     CreateMockRead(*resp, 1),
   3701     CreateMockRead(*echo, 3),
   3702     MockRead(ASYNC, 0, 4)  // EOF
   3703   };
   3704 
   3705   // Create SpdySession and SpdyStream and send the request.
   3706   DeterministicSocketData data(reads, arraysize(reads),
   3707                                writes, arraysize(writes));
   3708   data.set_connect_data(connect_data);
   3709   session_deps_.host_resolver->set_synchronous_mode(true);
   3710   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3711 
   3712   CreateDeterministicNetworkSession();
   3713 
   3714   base::WeakPtr<SpdySession> session =
   3715       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3716 
   3717   GURL url(kStreamUrl);
   3718   base::WeakPtr<SpdyStream> stream =
   3719       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   3720                                 session, url, MEDIUM, BoundNetLog());
   3721   ASSERT_TRUE(stream.get() != NULL);
   3722   EXPECT_EQ(0u, stream->stream_id());
   3723 
   3724   DropReceivedDataDelegate delegate(stream, msg_data);
   3725   stream->SetDelegate(&delegate);
   3726 
   3727   scoped_ptr<SpdyHeaderBlock> headers(
   3728       spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size));
   3729   EXPECT_EQ(ERR_IO_PENDING,
   3730             stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
   3731   EXPECT_TRUE(stream->HasUrlFromHeaders());
   3732 
   3733   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3734   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3735 
   3736   data.RunFor(4);
   3737 
   3738   EXPECT_TRUE(data.at_write_eof());
   3739   EXPECT_TRUE(data.at_read_eof());
   3740 
   3741   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3742   EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
   3743 
   3744   stream->Close();
   3745   EXPECT_EQ(NULL, stream.get());
   3746 
   3747   EXPECT_EQ(OK, delegate.WaitForClose());
   3748 
   3749   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3750   EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
   3751 }
   3752 
   3753 // Send data back and forth but close the stream before its data frame
   3754 // can be written to the socket. The send window should then increase
   3755 // to its original value, i.e. we shouldn't "leak" send window bytes.
   3756 TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) {
   3757   if (GetParam() < kProtoSPDY31)
   3758     return;
   3759 
   3760   const char kStreamUrl[] = "http://www.google.com/";
   3761 
   3762   const int32 msg_data_size = 100;
   3763   const std::string msg_data(msg_data_size, 'a');
   3764 
   3765   MockConnect connect_data(SYNCHRONOUS, OK);
   3766 
   3767   scoped_ptr<SpdyFrame> req(
   3768       spdy_util_.ConstructSpdyPost(
   3769           kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0));
   3770   MockWrite writes[] = {
   3771     CreateMockWrite(*req, 0),
   3772   };
   3773 
   3774   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3775   MockRead reads[] = {
   3776     CreateMockRead(*resp, 1),
   3777     MockRead(ASYNC, 0, 2)  // EOF
   3778   };
   3779 
   3780   // Create SpdySession and SpdyStream and send the request.
   3781   DeterministicSocketData data(reads, arraysize(reads),
   3782                                writes, arraysize(writes));
   3783   data.set_connect_data(connect_data);
   3784   session_deps_.host_resolver->set_synchronous_mode(true);
   3785   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3786 
   3787   CreateDeterministicNetworkSession();
   3788 
   3789   base::WeakPtr<SpdySession> session =
   3790       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3791 
   3792   GURL url(kStreamUrl);
   3793   base::WeakPtr<SpdyStream> stream =
   3794       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   3795                                 session, url, MEDIUM, BoundNetLog());
   3796   ASSERT_TRUE(stream.get() != NULL);
   3797   EXPECT_EQ(0u, stream->stream_id());
   3798 
   3799   test::StreamDelegateSendImmediate delegate(stream, msg_data);
   3800   stream->SetDelegate(&delegate);
   3801 
   3802   scoped_ptr<SpdyHeaderBlock> headers(
   3803       spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size));
   3804   EXPECT_EQ(ERR_IO_PENDING,
   3805             stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
   3806   EXPECT_TRUE(stream->HasUrlFromHeaders());
   3807 
   3808   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3809 
   3810   data.RunFor(1);
   3811 
   3812   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3813 
   3814   data.RunFor(1);
   3815 
   3816   EXPECT_TRUE(data.at_write_eof());
   3817   EXPECT_TRUE(data.at_read_eof());
   3818 
   3819   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
   3820             session->session_send_window_size_);
   3821 
   3822   // Closing the stream should increase the session's send window.
   3823   stream->Close();
   3824   EXPECT_EQ(NULL, stream.get());
   3825 
   3826   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3827 
   3828   EXPECT_EQ(OK, delegate.WaitForClose());
   3829 }
   3830 
   3831 // Send data back and forth; the send and receive windows should
   3832 // change appropriately.
   3833 TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) {
   3834   if (GetParam() < kProtoSPDY31)
   3835     return;
   3836 
   3837   const char kStreamUrl[] = "http://www.google.com/";
   3838 
   3839   const int32 msg_data_size = 100;
   3840   const std::string msg_data(msg_data_size, 'a');
   3841 
   3842   MockConnect connect_data(SYNCHRONOUS, OK);
   3843 
   3844   scoped_ptr<SpdyFrame> req(
   3845       spdy_util_.ConstructSpdyPost(
   3846           kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0));
   3847   scoped_ptr<SpdyFrame> msg(
   3848       spdy_util_.ConstructSpdyBodyFrame(
   3849           1, msg_data.data(), msg_data_size, false));
   3850   MockWrite writes[] = {
   3851     CreateMockWrite(*req, 0),
   3852     CreateMockWrite(*msg, 2),
   3853   };
   3854 
   3855   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3856   scoped_ptr<SpdyFrame> echo(
   3857       spdy_util_.ConstructSpdyBodyFrame(
   3858           1, msg_data.data(), msg_data_size, false));
   3859   scoped_ptr<SpdyFrame> window_update(
   3860       spdy_util_.ConstructSpdyWindowUpdate(
   3861           kSessionFlowControlStreamId, msg_data_size));
   3862   MockRead reads[] = {
   3863     CreateMockRead(*resp, 1),
   3864     CreateMockRead(*echo, 3),
   3865     CreateMockRead(*window_update, 4),
   3866     MockRead(ASYNC, 0, 5)  // EOF
   3867   };
   3868 
   3869   // Create SpdySession and SpdyStream and send the request.
   3870   DeterministicSocketData data(reads, arraysize(reads),
   3871                                writes, arraysize(writes));
   3872   data.set_connect_data(connect_data);
   3873   session_deps_.host_resolver->set_synchronous_mode(true);
   3874   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3875 
   3876   CreateDeterministicNetworkSession();
   3877 
   3878   base::WeakPtr<SpdySession> session =
   3879       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3880 
   3881   GURL url(kStreamUrl);
   3882   base::WeakPtr<SpdyStream> stream =
   3883       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
   3884                                 session, url, MEDIUM, BoundNetLog());
   3885   ASSERT_TRUE(stream.get() != NULL);
   3886   EXPECT_EQ(0u, stream->stream_id());
   3887 
   3888   test::StreamDelegateSendImmediate delegate(stream, msg_data);
   3889   stream->SetDelegate(&delegate);
   3890 
   3891   scoped_ptr<SpdyHeaderBlock> headers(
   3892       spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size));
   3893   EXPECT_EQ(ERR_IO_PENDING,
   3894             stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
   3895   EXPECT_TRUE(stream->HasUrlFromHeaders());
   3896 
   3897   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3898   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3899   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3900 
   3901   data.RunFor(1);
   3902 
   3903   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3904   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3905   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3906 
   3907   data.RunFor(1);
   3908 
   3909   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
   3910             session->session_send_window_size_);
   3911   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3912   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3913 
   3914   data.RunFor(1);
   3915 
   3916   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
   3917             session->session_send_window_size_);
   3918   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3919   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3920 
   3921   data.RunFor(1);
   3922 
   3923   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
   3924             session->session_send_window_size_);
   3925   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
   3926             session->session_recv_window_size_);
   3927   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3928 
   3929   data.RunFor(1);
   3930 
   3931   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3932   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
   3933             session->session_recv_window_size_);
   3934   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
   3935 
   3936   EXPECT_TRUE(data.at_write_eof());
   3937   EXPECT_TRUE(data.at_read_eof());
   3938 
   3939   EXPECT_EQ(msg_data, delegate.TakeReceivedData());
   3940 
   3941   // Draining the delegate's read queue should increase the session's
   3942   // receive window.
   3943   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3944   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3945   EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
   3946 
   3947   stream->Close();
   3948   EXPECT_EQ(NULL, stream.get());
   3949 
   3950   EXPECT_EQ(OK, delegate.WaitForClose());
   3951 
   3952   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
   3953   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
   3954   EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
   3955 }
   3956 
   3957 // Given a stall function and an unstall function, runs a test to make
   3958 // sure that a stream resumes after unstall.
   3959 void SpdySessionTest::RunResumeAfterUnstallTest(
   3960     const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function,
   3961     const base::Callback<void(SpdySession*, SpdyStream*, int32)>&
   3962         unstall_function) {
   3963   const char kStreamUrl[] = "http://www.google.com/";
   3964   GURL url(kStreamUrl);
   3965 
   3966   session_deps_.host_resolver->set_synchronous_mode(true);
   3967 
   3968   scoped_ptr<SpdyFrame> req(
   3969       spdy_util_.ConstructSpdyPost(
   3970           kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
   3971   scoped_ptr<SpdyFrame> body(
   3972       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true));
   3973   MockWrite writes[] = {
   3974     CreateMockWrite(*req, 0),
   3975     CreateMockWrite(*body, 1),
   3976   };
   3977 
   3978   scoped_ptr<SpdyFrame> resp(
   3979       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3980   scoped_ptr<SpdyFrame> echo(
   3981       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false));
   3982   MockRead reads[] = {
   3983     CreateMockRead(*resp, 2),
   3984     MockRead(ASYNC, 0, 0, 3), // EOF
   3985   };
   3986 
   3987   DeterministicSocketData data(reads, arraysize(reads),
   3988                                writes, arraysize(writes));
   3989   MockConnect connect_data(SYNCHRONOUS, OK);
   3990   data.set_connect_data(connect_data);
   3991 
   3992   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   3993 
   3994   CreateDeterministicNetworkSession();
   3995   base::WeakPtr<SpdySession> session =
   3996       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   3997   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   3998             session->flow_control_state());
   3999 
   4000   base::WeakPtr<SpdyStream> stream =
   4001       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   4002                                 session, url, LOWEST, BoundNetLog());
   4003   ASSERT_TRUE(stream.get() != NULL);
   4004 
   4005   test::StreamDelegateWithBody delegate(stream, kBodyDataStringPiece);
   4006   stream->SetDelegate(&delegate);
   4007 
   4008   EXPECT_FALSE(stream->HasUrlFromHeaders());
   4009   EXPECT_FALSE(stream->send_stalled_by_flow_control());
   4010 
   4011   scoped_ptr<SpdyHeaderBlock> headers(
   4012       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   4013   EXPECT_EQ(ERR_IO_PENDING,
   4014             stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
   4015   EXPECT_TRUE(stream->HasUrlFromHeaders());
   4016   EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
   4017 
   4018   stall_function.Run(session.get(), stream.get());
   4019 
   4020   data.RunFor(1);
   4021 
   4022   EXPECT_TRUE(stream->send_stalled_by_flow_control());
   4023 
   4024   unstall_function.Run(session.get(), stream.get(), kBodyDataSize);
   4025 
   4026   EXPECT_FALSE(stream->send_stalled_by_flow_control());
   4027 
   4028   data.RunFor(3);
   4029 
   4030   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
   4031 
   4032   EXPECT_TRUE(delegate.send_headers_completed());
   4033   EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
   4034   EXPECT_EQ(std::string(), delegate.TakeReceivedData());
   4035   EXPECT_TRUE(data.at_write_eof());
   4036 }
   4037 
   4038 // Run the resume-after-unstall test with all possible stall and
   4039 // unstall sequences.
   4040 
   4041 TEST_P(SpdySessionTest, ResumeAfterUnstallSession) {
   4042   if (GetParam() < kProtoSPDY31)
   4043     return;
   4044 
   4045   RunResumeAfterUnstallTest(
   4046       base::Bind(&SpdySessionTest::StallSessionOnly,
   4047                  base::Unretained(this)),
   4048       base::Bind(&SpdySessionTest::UnstallSessionOnly,
   4049                  base::Unretained(this)));
   4050 }
   4051 
   4052 // Equivalent to
   4053 // SpdyStreamTest.ResumeAfterSendWindowSizeIncrease.
   4054 TEST_P(SpdySessionTest, ResumeAfterUnstallStream) {
   4055   if (GetParam() < kProtoSPDY31)
   4056     return;
   4057 
   4058   RunResumeAfterUnstallTest(
   4059       base::Bind(&SpdySessionTest::StallStreamOnly,
   4060                  base::Unretained(this)),
   4061       base::Bind(&SpdySessionTest::UnstallStreamOnly,
   4062                  base::Unretained(this)));
   4063 }
   4064 
   4065 TEST_P(SpdySessionTest, StallSessionStreamResumeAfterUnstallSessionStream) {
   4066   if (GetParam() < kProtoSPDY31)
   4067     return;
   4068 
   4069   RunResumeAfterUnstallTest(
   4070       base::Bind(&SpdySessionTest::StallSessionStream,
   4071                  base::Unretained(this)),
   4072       base::Bind(&SpdySessionTest::UnstallSessionStream,
   4073                  base::Unretained(this)));
   4074 }
   4075 
   4076 TEST_P(SpdySessionTest, StallStreamSessionResumeAfterUnstallSessionStream) {
   4077   if (GetParam() < kProtoSPDY31)
   4078     return;
   4079 
   4080   RunResumeAfterUnstallTest(
   4081       base::Bind(&SpdySessionTest::StallStreamSession,
   4082                  base::Unretained(this)),
   4083       base::Bind(&SpdySessionTest::UnstallSessionStream,
   4084                  base::Unretained(this)));
   4085 }
   4086 
   4087 TEST_P(SpdySessionTest, StallStreamSessionResumeAfterUnstallStreamSession) {
   4088   if (GetParam() < kProtoSPDY31)
   4089     return;
   4090 
   4091   RunResumeAfterUnstallTest(
   4092       base::Bind(&SpdySessionTest::StallStreamSession,
   4093                  base::Unretained(this)),
   4094       base::Bind(&SpdySessionTest::UnstallStreamSession,
   4095                  base::Unretained(this)));
   4096 }
   4097 
   4098 TEST_P(SpdySessionTest, StallSessionStreamResumeAfterUnstallStreamSession) {
   4099   if (GetParam() < kProtoSPDY31)
   4100     return;
   4101 
   4102   RunResumeAfterUnstallTest(
   4103       base::Bind(&SpdySessionTest::StallSessionStream,
   4104                  base::Unretained(this)),
   4105       base::Bind(&SpdySessionTest::UnstallStreamSession,
   4106                  base::Unretained(this)));
   4107 }
   4108 
   4109 // Cause a stall by reducing the flow control send window to 0. The
   4110 // streams should resume in priority order when that window is then
   4111 // increased.
   4112 TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
   4113   if (GetParam() < kProtoSPDY31)
   4114     return;
   4115 
   4116   const char kStreamUrl[] = "http://www.google.com/";
   4117   GURL url(kStreamUrl);
   4118 
   4119   session_deps_.host_resolver->set_synchronous_mode(true);
   4120 
   4121   scoped_ptr<SpdyFrame> req1(
   4122       spdy_util_.ConstructSpdyPost(
   4123           kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
   4124   scoped_ptr<SpdyFrame> req2(
   4125       spdy_util_.ConstructSpdyPost(
   4126           kStreamUrl, 3, kBodyDataSize, MEDIUM, NULL, 0));
   4127   scoped_ptr<SpdyFrame> body1(
   4128       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true));
   4129   scoped_ptr<SpdyFrame> body2(
   4130       spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true));
   4131   MockWrite writes[] = {
   4132     CreateMockWrite(*req1, 0),
   4133     CreateMockWrite(*req2, 1),
   4134     CreateMockWrite(*body2, 2),
   4135     CreateMockWrite(*body1, 3),
   4136   };
   4137 
   4138   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   4139   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   4140   MockRead reads[] = {
   4141     CreateMockRead(*resp1, 4),
   4142     CreateMockRead(*resp2, 5),
   4143     MockRead(ASYNC, 0, 0, 6), // EOF
   4144   };
   4145 
   4146   DeterministicSocketData data(reads, arraysize(reads),
   4147                                writes, arraysize(writes));
   4148   MockConnect connect_data(SYNCHRONOUS, OK);
   4149   data.set_connect_data(connect_data);
   4150 
   4151   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   4152 
   4153   CreateDeterministicNetworkSession();
   4154   base::WeakPtr<SpdySession> session =
   4155       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   4156   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   4157             session->flow_control_state());
   4158 
   4159   base::WeakPtr<SpdyStream> stream1 =
   4160       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   4161                                 session, url, LOWEST, BoundNetLog());
   4162   ASSERT_TRUE(stream1.get() != NULL);
   4163 
   4164   test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
   4165   stream1->SetDelegate(&delegate1);
   4166 
   4167   EXPECT_FALSE(stream1->HasUrlFromHeaders());
   4168 
   4169   base::WeakPtr<SpdyStream> stream2 =
   4170       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   4171                                 session, url, MEDIUM, BoundNetLog());
   4172   ASSERT_TRUE(stream2.get() != NULL);
   4173 
   4174   test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
   4175   stream2->SetDelegate(&delegate2);
   4176 
   4177   EXPECT_FALSE(stream2->HasUrlFromHeaders());
   4178 
   4179   EXPECT_FALSE(stream1->send_stalled_by_flow_control());
   4180   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   4181 
   4182   StallSessionSend(session.get());
   4183 
   4184   scoped_ptr<SpdyHeaderBlock> headers1(
   4185       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   4186   EXPECT_EQ(ERR_IO_PENDING,
   4187             stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
   4188   EXPECT_TRUE(stream1->HasUrlFromHeaders());
   4189   EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec());
   4190 
   4191   data.RunFor(1);
   4192   EXPECT_EQ(1u, stream1->stream_id());
   4193   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
   4194 
   4195   scoped_ptr<SpdyHeaderBlock> headers2(
   4196       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   4197   EXPECT_EQ(ERR_IO_PENDING,
   4198             stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
   4199   EXPECT_TRUE(stream2->HasUrlFromHeaders());
   4200   EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec());
   4201 
   4202   data.RunFor(1);
   4203   EXPECT_EQ(3u, stream2->stream_id());
   4204   EXPECT_TRUE(stream2->send_stalled_by_flow_control());
   4205 
   4206   // This should unstall only stream2.
   4207   UnstallSessionSend(session.get(), kBodyDataSize);
   4208 
   4209   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
   4210   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   4211 
   4212   data.RunFor(1);
   4213 
   4214   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
   4215   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   4216 
   4217   // This should then unstall stream1.
   4218   UnstallSessionSend(session.get(), kBodyDataSize);
   4219 
   4220   EXPECT_FALSE(stream1->send_stalled_by_flow_control());
   4221   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   4222 
   4223   data.RunFor(4);
   4224 
   4225   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
   4226   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
   4227 
   4228   EXPECT_TRUE(delegate1.send_headers_completed());
   4229   EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
   4230   EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
   4231 
   4232   EXPECT_TRUE(delegate2.send_headers_completed());
   4233   EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
   4234   EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
   4235 
   4236   EXPECT_TRUE(data.at_write_eof());
   4237 }
   4238 
   4239 // Delegate that closes a given stream after sending its body.
   4240 class StreamClosingDelegate : public test::StreamDelegateWithBody {
   4241  public:
   4242   StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
   4243                         base::StringPiece data)
   4244       : StreamDelegateWithBody(stream, data) {}
   4245 
   4246   virtual ~StreamClosingDelegate() {}
   4247 
   4248   void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) {
   4249     stream_to_close_ = stream_to_close;
   4250   }
   4251 
   4252   virtual void OnDataSent() OVERRIDE {
   4253     test::StreamDelegateWithBody::OnDataSent();
   4254     if (stream_to_close_.get()) {
   4255       stream_to_close_->Close();
   4256       EXPECT_EQ(NULL, stream_to_close_.get());
   4257     }
   4258   }
   4259 
   4260  private:
   4261   base::WeakPtr<SpdyStream> stream_to_close_;
   4262 };
   4263 
   4264 // Cause a stall by reducing the flow control send window to
   4265 // 0. Unstalling the session should properly handle deleted streams.
   4266 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
   4267   if (GetParam() < kProtoSPDY31)
   4268     return;
   4269 
   4270   const char kStreamUrl[] = "http://www.google.com/";
   4271   GURL url(kStreamUrl);
   4272 
   4273   session_deps_.host_resolver->set_synchronous_mode(true);
   4274 
   4275   scoped_ptr<SpdyFrame> req1(
   4276       spdy_util_.ConstructSpdyPost(
   4277           kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
   4278   scoped_ptr<SpdyFrame> req2(
   4279       spdy_util_.ConstructSpdyPost(
   4280           kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0));
   4281   scoped_ptr<SpdyFrame> req3(
   4282       spdy_util_.ConstructSpdyPost(
   4283           kStreamUrl, 5, kBodyDataSize, LOWEST, NULL, 0));
   4284   scoped_ptr<SpdyFrame> body2(
   4285       spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true));
   4286   MockWrite writes[] = {
   4287     CreateMockWrite(*req1, 0),
   4288     CreateMockWrite(*req2, 1),
   4289     CreateMockWrite(*req3, 2),
   4290     CreateMockWrite(*body2, 3),
   4291   };
   4292 
   4293   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   4294   MockRead reads[] = {
   4295     CreateMockRead(*resp2, 4),
   4296     MockRead(ASYNC, 0, 0, 5), // EOF
   4297   };
   4298 
   4299   DeterministicSocketData data(reads, arraysize(reads),
   4300                                writes, arraysize(writes));
   4301   MockConnect connect_data(SYNCHRONOUS, OK);
   4302   data.set_connect_data(connect_data);
   4303 
   4304   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   4305 
   4306   CreateDeterministicNetworkSession();
   4307   base::WeakPtr<SpdySession> session =
   4308       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   4309   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   4310             session->flow_control_state());
   4311 
   4312   base::WeakPtr<SpdyStream> stream1 =
   4313       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   4314                                 session, url, LOWEST, BoundNetLog());
   4315   ASSERT_TRUE(stream1.get() != NULL);
   4316 
   4317   test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
   4318   stream1->SetDelegate(&delegate1);
   4319 
   4320   EXPECT_FALSE(stream1->HasUrlFromHeaders());
   4321 
   4322   base::WeakPtr<SpdyStream> stream2 =
   4323       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   4324                                 session, url, LOWEST, BoundNetLog());
   4325   ASSERT_TRUE(stream2.get() != NULL);
   4326 
   4327   StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece);
   4328   stream2->SetDelegate(&delegate2);
   4329 
   4330   EXPECT_FALSE(stream2->HasUrlFromHeaders());
   4331 
   4332   base::WeakPtr<SpdyStream> stream3 =
   4333       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   4334                                 session, url, LOWEST, BoundNetLog());
   4335   ASSERT_TRUE(stream3.get() != NULL);
   4336 
   4337   test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece);
   4338   stream3->SetDelegate(&delegate3);
   4339 
   4340   EXPECT_FALSE(stream3->HasUrlFromHeaders());
   4341 
   4342   EXPECT_FALSE(stream1->send_stalled_by_flow_control());
   4343   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   4344   EXPECT_FALSE(stream3->send_stalled_by_flow_control());
   4345 
   4346   StallSessionSend(session.get());
   4347 
   4348   scoped_ptr<SpdyHeaderBlock> headers1(
   4349       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   4350   EXPECT_EQ(ERR_IO_PENDING,
   4351             stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
   4352   EXPECT_TRUE(stream1->HasUrlFromHeaders());
   4353   EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec());
   4354 
   4355   data.RunFor(1);
   4356   EXPECT_EQ(1u, stream1->stream_id());
   4357   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
   4358 
   4359   scoped_ptr<SpdyHeaderBlock> headers2(
   4360       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   4361   EXPECT_EQ(ERR_IO_PENDING,
   4362             stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
   4363   EXPECT_TRUE(stream2->HasUrlFromHeaders());
   4364   EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec());
   4365 
   4366   data.RunFor(1);
   4367   EXPECT_EQ(3u, stream2->stream_id());
   4368   EXPECT_TRUE(stream2->send_stalled_by_flow_control());
   4369 
   4370   scoped_ptr<SpdyHeaderBlock> headers3(
   4371       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   4372   EXPECT_EQ(ERR_IO_PENDING,
   4373             stream3->SendRequestHeaders(headers3.Pass(), MORE_DATA_TO_SEND));
   4374   EXPECT_TRUE(stream3->HasUrlFromHeaders());
   4375   EXPECT_EQ(kStreamUrl, stream3->GetUrlFromHeaders().spec());
   4376 
   4377   data.RunFor(1);
   4378   EXPECT_EQ(5u, stream3->stream_id());
   4379   EXPECT_TRUE(stream3->send_stalled_by_flow_control());
   4380 
   4381   SpdyStreamId stream_id1 = stream1->stream_id();
   4382   SpdyStreamId stream_id2 = stream2->stream_id();
   4383   SpdyStreamId stream_id3 = stream3->stream_id();
   4384 
   4385   // Close stream1 preemptively.
   4386   session->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED);
   4387   EXPECT_EQ(NULL, stream1.get());
   4388 
   4389   EXPECT_FALSE(session->IsStreamActive(stream_id1));
   4390   EXPECT_TRUE(session->IsStreamActive(stream_id2));
   4391   EXPECT_TRUE(session->IsStreamActive(stream_id3));
   4392 
   4393   // Unstall stream2, which should then close stream3.
   4394   delegate2.set_stream_to_close(stream3);
   4395   UnstallSessionSend(session.get(), kBodyDataSize);
   4396 
   4397   data.RunFor(1);
   4398   EXPECT_EQ(NULL, stream3.get());
   4399 
   4400   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   4401   EXPECT_FALSE(session->IsStreamActive(stream_id1));
   4402   EXPECT_TRUE(session->IsStreamActive(stream_id2));
   4403   EXPECT_FALSE(session->IsStreamActive(stream_id3));
   4404 
   4405   data.RunFor(2);
   4406   EXPECT_EQ(NULL, stream2.get());
   4407 
   4408   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
   4409   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
   4410   EXPECT_EQ(OK, delegate3.WaitForClose());
   4411 
   4412   EXPECT_TRUE(delegate1.send_headers_completed());
   4413   EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
   4414 
   4415   EXPECT_TRUE(delegate2.send_headers_completed());
   4416   EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
   4417   EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
   4418 
   4419   EXPECT_TRUE(delegate3.send_headers_completed());
   4420   EXPECT_EQ(std::string(), delegate3.TakeReceivedData());
   4421 
   4422   EXPECT_TRUE(data.at_write_eof());
   4423 }
   4424 
   4425 // Cause a stall by reducing the flow control send window to
   4426 // 0. Unstalling the session should properly handle the session itself
   4427 // being closed.
   4428 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
   4429   if (GetParam() < kProtoSPDY31)
   4430     return;
   4431 
   4432   const char kStreamUrl[] = "http://www.google.com/";
   4433   GURL url(kStreamUrl);
   4434 
   4435   session_deps_.host_resolver->set_synchronous_mode(true);
   4436 
   4437   scoped_ptr<SpdyFrame> req1(
   4438       spdy_util_.ConstructSpdyPost(
   4439           kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
   4440   scoped_ptr<SpdyFrame> req2(
   4441       spdy_util_.ConstructSpdyPost(
   4442           kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0));
   4443   scoped_ptr<SpdyFrame> body1(
   4444       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false));
   4445   MockWrite writes[] = {
   4446     CreateMockWrite(*req1, 0),
   4447     CreateMockWrite(*req2, 1),
   4448   };
   4449 
   4450   MockRead reads[] = {
   4451     MockRead(ASYNC, 0, 0, 2), // EOF
   4452   };
   4453 
   4454   DeterministicSocketData data(reads, arraysize(reads),
   4455                                writes, arraysize(writes));
   4456   MockConnect connect_data(SYNCHRONOUS, OK);
   4457   data.set_connect_data(connect_data);
   4458 
   4459   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   4460 
   4461   CreateDeterministicNetworkSession();
   4462   base::WeakPtr<SpdySession> session =
   4463       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   4464   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
   4465             session->flow_control_state());
   4466 
   4467   base::WeakPtr<SpdyStream> stream1 =
   4468       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   4469                                 session, url, LOWEST, BoundNetLog());
   4470   ASSERT_TRUE(stream1.get() != NULL);
   4471 
   4472   test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
   4473   stream1->SetDelegate(&delegate1);
   4474 
   4475   EXPECT_FALSE(stream1->HasUrlFromHeaders());
   4476 
   4477   base::WeakPtr<SpdyStream> stream2 =
   4478       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
   4479                                 session, url, LOWEST, BoundNetLog());
   4480   ASSERT_TRUE(stream2.get() != NULL);
   4481 
   4482   test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
   4483   stream2->SetDelegate(&delegate2);
   4484 
   4485   EXPECT_FALSE(stream2->HasUrlFromHeaders());
   4486 
   4487   EXPECT_FALSE(stream1->send_stalled_by_flow_control());
   4488   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
   4489 
   4490   StallSessionSend(session.get());
   4491 
   4492   scoped_ptr<SpdyHeaderBlock> headers1(
   4493       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   4494   EXPECT_EQ(ERR_IO_PENDING,
   4495             stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
   4496   EXPECT_TRUE(stream1->HasUrlFromHeaders());
   4497   EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec());
   4498 
   4499   data.RunFor(1);
   4500   EXPECT_EQ(1u, stream1->stream_id());
   4501   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
   4502 
   4503   scoped_ptr<SpdyHeaderBlock> headers2(
   4504       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
   4505   EXPECT_EQ(ERR_IO_PENDING,
   4506             stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
   4507   EXPECT_TRUE(stream2->HasUrlFromHeaders());
   4508   EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec());
   4509 
   4510   data.RunFor(1);
   4511   EXPECT_EQ(3u, stream2->stream_id());
   4512   EXPECT_TRUE(stream2->send_stalled_by_flow_control());
   4513 
   4514   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
   4515 
   4516   // Unstall stream1.
   4517   UnstallSessionSend(session.get(), kBodyDataSize);
   4518 
   4519   // Close the session (since we can't do it from within the delegate
   4520   // method, since it's in the stream's loop).
   4521   session->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session");
   4522   base::RunLoop().RunUntilIdle();
   4523   EXPECT_TRUE(session == NULL);
   4524 
   4525   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
   4526 
   4527   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
   4528   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
   4529 
   4530   EXPECT_TRUE(delegate1.send_headers_completed());
   4531   EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
   4532 
   4533   EXPECT_TRUE(delegate2.send_headers_completed());
   4534   EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
   4535 
   4536   EXPECT_TRUE(data.at_write_eof());
   4537 }
   4538 
   4539 TEST_P(SpdySessionTest, GoAwayOnSessionFlowControlError) {
   4540   if (GetParam() < kProtoSPDY31)
   4541     return;
   4542 
   4543   MockConnect connect_data(SYNCHRONOUS, OK);
   4544 
   4545   scoped_ptr<SpdyFrame> req(
   4546       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   4547   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(
   4548       0,
   4549       GOAWAY_FLOW_CONTROL_ERROR,
   4550       "delta_window_size is 6 in DecreaseRecvWindowSize, which is larger than "
   4551       "the receive window size of 1"));
   4552   MockWrite writes[] = {
   4553       CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 3),
   4554   };
   4555 
   4556   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   4557   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   4558   MockRead reads[] = {
   4559       CreateMockRead(*resp, 1), CreateMockRead(*body, 2),
   4560   };
   4561 
   4562   DeterministicSocketData data(
   4563       reads, arraysize(reads), writes, arraysize(writes));
   4564   data.set_connect_data(connect_data);
   4565   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   4566 
   4567   CreateDeterministicNetworkSession();
   4568 
   4569   base::WeakPtr<SpdySession> session =
   4570       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   4571 
   4572   GURL url(kDefaultURL);
   4573   base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
   4574       SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog());
   4575   ASSERT_TRUE(spdy_stream.get() != NULL);
   4576   test::StreamDelegateDoNothing delegate(spdy_stream);
   4577   spdy_stream->SetDelegate(&delegate);
   4578 
   4579   scoped_ptr<SpdyHeaderBlock> headers(
   4580       spdy_util_.ConstructGetHeaderBlock(url.spec()));
   4581   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   4582 
   4583   data.RunFor(1);  // Write request.
   4584 
   4585   // Put session on the edge of overflowing it's recv window.
   4586   session->session_recv_window_size_ = 1;
   4587 
   4588   // Read response headers & body. Body overflows the session window, and a
   4589   // goaway is written.
   4590   data.RunFor(3);
   4591   base::MessageLoop::current()->RunUntilIdle();
   4592 
   4593   EXPECT_EQ(ERR_SPDY_FLOW_CONTROL_ERROR, delegate.WaitForClose());
   4594   EXPECT_TRUE(session == NULL);
   4595 }
   4596 
   4597 TEST_P(SpdySessionTest, SplitHeaders) {
   4598   GURL kStreamUrl("http://www.google.com/foo.dat");
   4599   SpdyHeaderBlock headers;
   4600   spdy_util_.AddUrlToHeaderBlock(kStreamUrl.spec(), &headers);
   4601   headers["alpha"] = "beta";
   4602 
   4603   SpdyHeaderBlock request_headers;
   4604   SpdyHeaderBlock response_headers;
   4605 
   4606   SplitPushedHeadersToRequestAndResponse(
   4607       headers, spdy_util_.spdy_version(), &request_headers, &response_headers);
   4608 
   4609   SpdyHeaderBlock::const_iterator it = response_headers.find("alpha");
   4610   std::string alpha_val =
   4611       (it == response_headers.end()) ? std::string() : it->second;
   4612   EXPECT_EQ("beta", alpha_val);
   4613 
   4614   GURL request_url =
   4615       GetUrlFromHeaderBlock(request_headers, spdy_util_.spdy_version(), true);
   4616   EXPECT_EQ(kStreamUrl, request_url);
   4617 }
   4618 
   4619 // Regression. Sorta. Push streams and client streams were sharing a single
   4620 // limit for a long time.
   4621 TEST_P(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) {
   4622   SettingsMap new_settings;
   4623   new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
   4624       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 2);
   4625   scoped_ptr<SpdyFrame> settings_frame(
   4626       spdy_util_.ConstructSpdySettings(new_settings));
   4627   scoped_ptr<SpdyFrame> pushed(spdy_util_.ConstructSpdyPush(
   4628       NULL, 0, 2, 1, "http://www.google.com/a.dat"));
   4629   MockRead reads[] = {
   4630       CreateMockRead(*settings_frame), CreateMockRead(*pushed, 3),
   4631       MockRead(ASYNC, 0, 4),
   4632   };
   4633 
   4634   scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
   4635   scoped_ptr<SpdyFrame> req(
   4636       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   4637   MockWrite writes[] = {
   4638       CreateMockWrite(*settings_ack, 1), CreateMockWrite(*req, 2),
   4639   };
   4640 
   4641   DeterministicSocketData data(
   4642       reads, arraysize(reads), writes, arraysize(writes));
   4643   MockConnect connect_data(SYNCHRONOUS, OK);
   4644   data.set_connect_data(connect_data);
   4645   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   4646 
   4647   CreateDeterministicNetworkSession();
   4648 
   4649   base::WeakPtr<SpdySession> session =
   4650       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   4651 
   4652   // Read the settings frame.
   4653   data.RunFor(1);
   4654 
   4655   GURL url1(kDefaultURL);
   4656   base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
   4657       SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog());
   4658   ASSERT_TRUE(spdy_stream1.get() != NULL);
   4659   EXPECT_EQ(0u, spdy_stream1->stream_id());
   4660   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   4661   spdy_stream1->SetDelegate(&delegate1);
   4662 
   4663   EXPECT_EQ(0u, session->num_active_streams());
   4664   EXPECT_EQ(1u, session->num_created_streams());
   4665   EXPECT_EQ(0u, session->num_pushed_streams());
   4666   EXPECT_EQ(0u, session->num_active_pushed_streams());
   4667 
   4668   scoped_ptr<SpdyHeaderBlock> headers(
   4669       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   4670   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   4671   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   4672 
   4673   // Run until 1st stream is activated.
   4674   EXPECT_EQ(0u, delegate1.stream_id());
   4675   data.RunFor(2);
   4676   EXPECT_EQ(1u, delegate1.stream_id());
   4677   EXPECT_EQ(1u, session->num_active_streams());
   4678   EXPECT_EQ(0u, session->num_created_streams());
   4679   EXPECT_EQ(0u, session->num_pushed_streams());
   4680   EXPECT_EQ(0u, session->num_active_pushed_streams());
   4681 
   4682   // Run until pushed stream is created.
   4683   data.RunFor(1);
   4684   EXPECT_EQ(2u, session->num_active_streams());
   4685   EXPECT_EQ(0u, session->num_created_streams());
   4686   EXPECT_EQ(1u, session->num_pushed_streams());
   4687   EXPECT_EQ(1u, session->num_active_pushed_streams());
   4688 
   4689   // Second stream should not be stalled, although we have 2 active streams, but
   4690   // one of them is push stream and should not be taken into account when we
   4691   // create streams on the client.
   4692   base::WeakPtr<SpdyStream> spdy_stream2 = CreateStreamSynchronously(
   4693       SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog());
   4694   EXPECT_TRUE(spdy_stream2.get() != NULL);
   4695   EXPECT_EQ(2u, session->num_active_streams());
   4696   EXPECT_EQ(1u, session->num_created_streams());
   4697   EXPECT_EQ(1u, session->num_pushed_streams());
   4698   EXPECT_EQ(1u, session->num_active_pushed_streams());
   4699 
   4700   // Read EOF.
   4701   data.RunFor(1);
   4702 }
   4703 
   4704 TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
   4705   scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
   4706       NULL, 0, 2, 1, "http://www.google.com/a.dat"));
   4707   scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush(
   4708       NULL, 0, 4, 1, "http://www.google.com/b.dat"));
   4709   MockRead reads[] = {
   4710       CreateMockRead(*push_a, 1), CreateMockRead(*push_b, 2),
   4711       MockRead(ASYNC, 0, 4),
   4712   };
   4713 
   4714   scoped_ptr<SpdyFrame> req(
   4715       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   4716   scoped_ptr<SpdyFrame> rst(
   4717       spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM));
   4718   MockWrite writes[] = {
   4719       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 3),
   4720   };
   4721 
   4722   DeterministicSocketData data(
   4723       reads, arraysize(reads), writes, arraysize(writes));
   4724   MockConnect connect_data(SYNCHRONOUS, OK);
   4725   data.set_connect_data(connect_data);
   4726   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   4727 
   4728   CreateDeterministicNetworkSession();
   4729 
   4730   base::WeakPtr<SpdySession> session =
   4731       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   4732   session->set_max_concurrent_pushed_streams(1);
   4733 
   4734   GURL url1(kDefaultURL);
   4735   base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
   4736       SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog());
   4737   ASSERT_TRUE(spdy_stream1.get() != NULL);
   4738   EXPECT_EQ(0u, spdy_stream1->stream_id());
   4739   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   4740   spdy_stream1->SetDelegate(&delegate1);
   4741 
   4742   EXPECT_EQ(0u, session->num_active_streams());
   4743   EXPECT_EQ(1u, session->num_created_streams());
   4744   EXPECT_EQ(0u, session->num_pushed_streams());
   4745   EXPECT_EQ(0u, session->num_active_pushed_streams());
   4746 
   4747   scoped_ptr<SpdyHeaderBlock> headers(
   4748       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   4749   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   4750   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   4751 
   4752   // Run until 1st stream is activated.
   4753   EXPECT_EQ(0u, delegate1.stream_id());
   4754   data.RunFor(1);
   4755   EXPECT_EQ(1u, delegate1.stream_id());
   4756   EXPECT_EQ(1u, session->num_active_streams());
   4757   EXPECT_EQ(0u, session->num_created_streams());
   4758   EXPECT_EQ(0u, session->num_pushed_streams());
   4759   EXPECT_EQ(0u, session->num_active_pushed_streams());
   4760 
   4761   // Run until pushed stream is created.
   4762   data.RunFor(1);
   4763   EXPECT_EQ(2u, session->num_active_streams());
   4764   EXPECT_EQ(0u, session->num_created_streams());
   4765   EXPECT_EQ(1u, session->num_pushed_streams());
   4766   EXPECT_EQ(1u, session->num_active_pushed_streams());
   4767 
   4768   // Reset incoming pushed stream.
   4769   data.RunFor(2);
   4770   EXPECT_EQ(2u, session->num_active_streams());
   4771   EXPECT_EQ(0u, session->num_created_streams());
   4772   EXPECT_EQ(1u, session->num_pushed_streams());
   4773   EXPECT_EQ(1u, session->num_active_pushed_streams());
   4774 
   4775   // Read EOF.
   4776   data.RunFor(1);
   4777 }
   4778 
   4779 TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
   4780   // Streams in reserved remote state exist only in SPDY4.
   4781   if (spdy_util_.spdy_version() < SPDY4)
   4782     return;
   4783 
   4784   scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
   4785       NULL, 0, 2, 1, "http://www.google.com/a.dat"));
   4786   scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock);
   4787   spdy_util_.AddUrlToHeaderBlock("http://www.google.com/b.dat",
   4788                                  push_headers.get());
   4789   scoped_ptr<SpdyFrame> push_b(
   4790       spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 4, 1));
   4791   scoped_ptr<SpdyFrame> headers_b(
   4792       spdy_util_.ConstructSpdyPushHeaders(4, NULL, 0));
   4793   MockRead reads[] = {
   4794       CreateMockRead(*push_a, 1), CreateMockRead(*push_b, 2),
   4795       CreateMockRead(*headers_b, 3), MockRead(ASYNC, 0, 5),
   4796   };
   4797 
   4798   scoped_ptr<SpdyFrame> req(
   4799       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   4800   scoped_ptr<SpdyFrame> rst(
   4801       spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM));
   4802   MockWrite writes[] = {
   4803       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4),
   4804   };
   4805 
   4806   DeterministicSocketData data(
   4807       reads, arraysize(reads), writes, arraysize(writes));
   4808   MockConnect connect_data(SYNCHRONOUS, OK);
   4809   data.set_connect_data(connect_data);
   4810   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   4811 
   4812   CreateDeterministicNetworkSession();
   4813 
   4814   base::WeakPtr<SpdySession> session =
   4815       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   4816   session->set_max_concurrent_pushed_streams(1);
   4817 
   4818   GURL url1(kDefaultURL);
   4819   base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
   4820       SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog());
   4821   ASSERT_TRUE(spdy_stream1.get() != NULL);
   4822   EXPECT_EQ(0u, spdy_stream1->stream_id());
   4823   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   4824   spdy_stream1->SetDelegate(&delegate1);
   4825 
   4826   EXPECT_EQ(0u, session->num_active_streams());
   4827   EXPECT_EQ(1u, session->num_created_streams());
   4828   EXPECT_EQ(0u, session->num_pushed_streams());
   4829   EXPECT_EQ(0u, session->num_active_pushed_streams());
   4830 
   4831   scoped_ptr<SpdyHeaderBlock> headers(
   4832       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   4833   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   4834   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   4835 
   4836   // Run until 1st stream is activated.
   4837   EXPECT_EQ(0u, delegate1.stream_id());
   4838   data.RunFor(1);
   4839   EXPECT_EQ(1u, delegate1.stream_id());
   4840   EXPECT_EQ(1u, session->num_active_streams());
   4841   EXPECT_EQ(0u, session->num_created_streams());
   4842   EXPECT_EQ(0u, session->num_pushed_streams());
   4843   EXPECT_EQ(0u, session->num_active_pushed_streams());
   4844 
   4845   // Run until pushed stream is created.
   4846   data.RunFor(1);
   4847   EXPECT_EQ(2u, session->num_active_streams());
   4848   EXPECT_EQ(0u, session->num_created_streams());
   4849   EXPECT_EQ(1u, session->num_pushed_streams());
   4850   EXPECT_EQ(1u, session->num_active_pushed_streams());
   4851 
   4852   // Accept promised stream. It should not count towards pushed stream limit.
   4853   data.RunFor(1);
   4854   EXPECT_EQ(3u, session->num_active_streams());
   4855   EXPECT_EQ(0u, session->num_created_streams());
   4856   EXPECT_EQ(2u, session->num_pushed_streams());
   4857   EXPECT_EQ(1u, session->num_active_pushed_streams());
   4858 
   4859   // Reset last pushed stream upon headers reception as it is going to be 2nd,
   4860   // while we accept only one.
   4861   data.RunFor(2);
   4862   EXPECT_EQ(2u, session->num_active_streams());
   4863   EXPECT_EQ(0u, session->num_created_streams());
   4864   EXPECT_EQ(1u, session->num_pushed_streams());
   4865   EXPECT_EQ(1u, session->num_active_pushed_streams());
   4866 
   4867   // Read EOF.
   4868   data.RunFor(1);
   4869 }
   4870 
   4871 TEST_P(SpdySessionTest, CancelReservedStreamOnHeadersReceived) {
   4872   // Streams in reserved remote state exist only in SPDY4.
   4873   if (spdy_util_.spdy_version() < SPDY4)
   4874     return;
   4875 
   4876   const char kPushedUrl[] = "http://www.google.com/a.dat";
   4877   scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock);
   4878   spdy_util_.AddUrlToHeaderBlock(kPushedUrl, push_headers.get());
   4879   scoped_ptr<SpdyFrame> push_promise(
   4880       spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 2, 1));
   4881   scoped_ptr<SpdyFrame> headers_frame(
   4882       spdy_util_.ConstructSpdyPushHeaders(2, NULL, 0));
   4883   MockRead reads[] = {
   4884       CreateMockRead(*push_promise, 1), CreateMockRead(*headers_frame, 2),
   4885       MockRead(ASYNC, 0, 4),
   4886   };
   4887 
   4888   scoped_ptr<SpdyFrame> req(
   4889       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   4890   scoped_ptr<SpdyFrame> rst(
   4891       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL));
   4892   MockWrite writes[] = {
   4893       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 3),
   4894   };
   4895 
   4896   DeterministicSocketData data(
   4897       reads, arraysize(reads), writes, arraysize(writes));
   4898   MockConnect connect_data(SYNCHRONOUS, OK);
   4899   data.set_connect_data(connect_data);
   4900   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
   4901 
   4902   CreateDeterministicNetworkSession();
   4903 
   4904   base::WeakPtr<SpdySession> session =
   4905       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   4906 
   4907   GURL url1(kDefaultURL);
   4908   base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
   4909       SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog());
   4910   ASSERT_TRUE(spdy_stream1.get() != NULL);
   4911   EXPECT_EQ(0u, spdy_stream1->stream_id());
   4912   test::StreamDelegateDoNothing delegate1(spdy_stream1);
   4913   spdy_stream1->SetDelegate(&delegate1);
   4914 
   4915   EXPECT_EQ(0u, session->num_active_streams());
   4916   EXPECT_EQ(1u, session->num_created_streams());
   4917   EXPECT_EQ(0u, session->num_pushed_streams());
   4918   EXPECT_EQ(0u, session->num_active_pushed_streams());
   4919 
   4920   scoped_ptr<SpdyHeaderBlock> headers(
   4921       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
   4922   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
   4923   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
   4924 
   4925   // Run until 1st stream is activated.
   4926   EXPECT_EQ(0u, delegate1.stream_id());
   4927   data.RunFor(1);
   4928   EXPECT_EQ(1u, delegate1.stream_id());
   4929   EXPECT_EQ(1u, session->num_active_streams());
   4930   EXPECT_EQ(0u, session->num_created_streams());
   4931   EXPECT_EQ(0u, session->num_pushed_streams());
   4932   EXPECT_EQ(0u, session->num_active_pushed_streams());
   4933 
   4934   // Run until pushed stream is created.
   4935   data.RunFor(1);
   4936   EXPECT_EQ(2u, session->num_active_streams());
   4937   EXPECT_EQ(0u, session->num_created_streams());
   4938   EXPECT_EQ(1u, session->num_pushed_streams());
   4939   EXPECT_EQ(0u, session->num_active_pushed_streams());
   4940 
   4941   base::WeakPtr<SpdyStream> pushed_stream;
   4942   int rv =
   4943       session->GetPushStream(GURL(kPushedUrl), &pushed_stream, BoundNetLog());
   4944   ASSERT_EQ(OK, rv);
   4945   ASSERT_TRUE(pushed_stream.get() != NULL);
   4946   test::StreamDelegateCloseOnHeaders delegate2(pushed_stream);
   4947   pushed_stream->SetDelegate(&delegate2);
   4948 
   4949   // Receive headers for pushed stream. Delegate will cancel the stream, ensure
   4950   // that all our counters are in consistent state.
   4951   data.RunFor(1);
   4952   EXPECT_EQ(1u, session->num_active_streams());
   4953   EXPECT_EQ(0u, session->num_created_streams());
   4954   EXPECT_EQ(0u, session->num_pushed_streams());
   4955   EXPECT_EQ(0u, session->num_active_pushed_streams());
   4956 
   4957   // Read EOF.
   4958   data.RunFor(2);
   4959 }
   4960 
   4961 TEST_P(SpdySessionTest, RejectInvalidUnknownFrames) {
   4962   session_deps_.host_resolver->set_synchronous_mode(true);
   4963 
   4964   MockRead reads[] = {
   4965       MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   4966   };
   4967 
   4968   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
   4969 
   4970   MockConnect connect_data(SYNCHRONOUS, OK);
   4971   data.set_connect_data(connect_data);
   4972   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4973 
   4974   CreateNetworkSession();
   4975   base::WeakPtr<SpdySession> session =
   4976       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
   4977 
   4978   session->stream_hi_water_mark_ = 5;
   4979   // Low client (odd) ids are fine.
   4980   EXPECT_TRUE(session->OnUnknownFrame(3, 0));
   4981   // Client id exceeding watermark.
   4982   EXPECT_FALSE(session->OnUnknownFrame(9, 0));
   4983 
   4984   session->last_accepted_push_stream_id_ = 6;
   4985   // Low server (even) ids are fine.
   4986   EXPECT_TRUE(session->OnUnknownFrame(2, 0));
   4987   // Server id exceeding last accepted id.
   4988   EXPECT_FALSE(session->OnUnknownFrame(8, 0));
   4989 }
   4990 
   4991 TEST(MapFramerErrorToProtocolError, MapsValues) {
   4992   CHECK_EQ(
   4993       SPDY_ERROR_INVALID_CONTROL_FRAME,
   4994       MapFramerErrorToProtocolError(SpdyFramer::SPDY_INVALID_CONTROL_FRAME));
   4995   CHECK_EQ(
   4996       SPDY_ERROR_INVALID_DATA_FRAME_FLAGS,
   4997       MapFramerErrorToProtocolError(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS));
   4998   CHECK_EQ(
   4999       SPDY_ERROR_GOAWAY_FRAME_CORRUPT,
   5000       MapFramerErrorToProtocolError(SpdyFramer::SPDY_GOAWAY_FRAME_CORRUPT));
   5001   CHECK_EQ(SPDY_ERROR_UNEXPECTED_FRAME,
   5002            MapFramerErrorToProtocolError(SpdyFramer::SPDY_UNEXPECTED_FRAME));
   5003 }
   5004 
   5005 TEST(MapFramerErrorToNetError, MapsValue) {
   5006   CHECK_EQ(ERR_SPDY_PROTOCOL_ERROR,
   5007            MapFramerErrorToNetError(SpdyFramer::SPDY_INVALID_CONTROL_FRAME));
   5008   CHECK_EQ(ERR_SPDY_COMPRESSION_ERROR,
   5009            MapFramerErrorToNetError(SpdyFramer::SPDY_COMPRESS_FAILURE));
   5010   CHECK_EQ(ERR_SPDY_COMPRESSION_ERROR,
   5011            MapFramerErrorToNetError(SpdyFramer::SPDY_DECOMPRESS_FAILURE));
   5012   CHECK_EQ(
   5013       ERR_SPDY_FRAME_SIZE_ERROR,
   5014       MapFramerErrorToNetError(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE));
   5015 }
   5016 
   5017 TEST(MapRstStreamStatusToProtocolError, MapsValues) {
   5018   CHECK_EQ(STATUS_CODE_PROTOCOL_ERROR,
   5019            MapRstStreamStatusToProtocolError(RST_STREAM_PROTOCOL_ERROR));
   5020   CHECK_EQ(STATUS_CODE_FRAME_SIZE_ERROR,
   5021            MapRstStreamStatusToProtocolError(RST_STREAM_FRAME_SIZE_ERROR));
   5022   CHECK_EQ(STATUS_CODE_ENHANCE_YOUR_CALM,
   5023            MapRstStreamStatusToProtocolError(RST_STREAM_ENHANCE_YOUR_CALM));
   5024 }
   5025 
   5026 TEST(MapNetErrorToGoAwayStatus, MapsValue) {
   5027   CHECK_EQ(GOAWAY_INADEQUATE_SECURITY,
   5028            MapNetErrorToGoAwayStatus(ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY));
   5029   CHECK_EQ(GOAWAY_FLOW_CONTROL_ERROR,
   5030            MapNetErrorToGoAwayStatus(ERR_SPDY_FLOW_CONTROL_ERROR));
   5031   CHECK_EQ(GOAWAY_PROTOCOL_ERROR,
   5032            MapNetErrorToGoAwayStatus(ERR_SPDY_PROTOCOL_ERROR));
   5033   CHECK_EQ(GOAWAY_COMPRESSION_ERROR,
   5034            MapNetErrorToGoAwayStatus(ERR_SPDY_COMPRESSION_ERROR));
   5035   CHECK_EQ(GOAWAY_FRAME_SIZE_ERROR,
   5036            MapNetErrorToGoAwayStatus(ERR_SPDY_FRAME_SIZE_ERROR));
   5037   CHECK_EQ(GOAWAY_PROTOCOL_ERROR, MapNetErrorToGoAwayStatus(ERR_UNEXPECTED));
   5038 }
   5039 
   5040 TEST(CanPoolTest, CanPool) {
   5041   // Load a cert that is valid for:
   5042   //   www.example.org
   5043   //   mail.example.org
   5044   //   www.example.com
   5045 
   5046   TransportSecurityState tss;
   5047   SSLInfo ssl_info;
   5048   ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
   5049                                      "spdy_pooling.pem");
   5050 
   5051   EXPECT_TRUE(SpdySession::CanPool(
   5052       &tss, ssl_info, "www.example.org", "www.example.org"));
   5053   EXPECT_TRUE(SpdySession::CanPool(
   5054       &tss, ssl_info, "www.example.org", "mail.example.org"));
   5055   EXPECT_TRUE(SpdySession::CanPool(
   5056       &tss, ssl_info, "www.example.org", "mail.example.com"));
   5057   EXPECT_FALSE(SpdySession::CanPool(
   5058       &tss, ssl_info, "www.example.org", "mail.google.com"));
   5059 }
   5060 
   5061 TEST(CanPoolTest, CanNotPoolWithCertErrors) {
   5062   // Load a cert that is valid for:
   5063   //   www.example.org
   5064   //   mail.example.org
   5065   //   www.example.com
   5066 
   5067   TransportSecurityState tss;
   5068   SSLInfo ssl_info;
   5069   ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
   5070                                      "spdy_pooling.pem");
   5071   ssl_info.cert_status = CERT_STATUS_REVOKED;
   5072 
   5073   EXPECT_FALSE(SpdySession::CanPool(
   5074       &tss, ssl_info, "www.example.org", "mail.example.org"));
   5075 }
   5076 
   5077 TEST(CanPoolTest, CanNotPoolWithClientCerts) {
   5078   // Load a cert that is valid for:
   5079   //   www.example.org
   5080   //   mail.example.org
   5081   //   www.example.com
   5082 
   5083   TransportSecurityState tss;
   5084   SSLInfo ssl_info;
   5085   ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
   5086                                      "spdy_pooling.pem");
   5087   ssl_info.client_cert_sent = true;
   5088 
   5089   EXPECT_FALSE(SpdySession::CanPool(
   5090       &tss, ssl_info, "www.example.org", "mail.example.org"));
   5091 }
   5092 
   5093 TEST(CanPoolTest, CanNotPoolAcrossETLDsWithChannelID) {
   5094   // Load a cert that is valid for:
   5095   //   www.example.org
   5096   //   mail.example.org
   5097   //   www.example.com
   5098 
   5099   TransportSecurityState tss;
   5100   SSLInfo ssl_info;
   5101   ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
   5102                                      "spdy_pooling.pem");
   5103   ssl_info.channel_id_sent = true;
   5104 
   5105   EXPECT_TRUE(SpdySession::CanPool(
   5106       &tss, ssl_info, "www.example.org", "mail.example.org"));
   5107   EXPECT_FALSE(SpdySession::CanPool(
   5108       &tss, ssl_info, "www.example.org", "www.example.com"));
   5109 }
   5110 
   5111 TEST(CanPoolTest, CanNotPoolWithBadPins) {
   5112   uint8 primary_pin = 1;
   5113   uint8 backup_pin = 2;
   5114   uint8 bad_pin = 3;
   5115   TransportSecurityState tss;
   5116   test::AddPin(&tss, "mail.example.org", primary_pin, backup_pin);
   5117 
   5118   SSLInfo ssl_info;
   5119   ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
   5120                                      "spdy_pooling.pem");
   5121   ssl_info.is_issued_by_known_root = true;
   5122   ssl_info.public_key_hashes.push_back(test::GetTestHashValue(bad_pin));
   5123 
   5124   EXPECT_FALSE(SpdySession::CanPool(
   5125       &tss, ssl_info, "www.example.org", "mail.example.org"));
   5126 }
   5127 
   5128 TEST(CanPoolTest, CanPoolWithAcceptablePins) {
   5129   uint8 primary_pin = 1;
   5130   uint8 backup_pin = 2;
   5131   TransportSecurityState tss;
   5132   test::AddPin(&tss, "mail.example.org", primary_pin, backup_pin);
   5133 
   5134   SSLInfo ssl_info;
   5135   ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
   5136                                      "spdy_pooling.pem");
   5137   ssl_info.is_issued_by_known_root = true;
   5138   ssl_info.public_key_hashes.push_back(test::GetTestHashValue(primary_pin));
   5139 
   5140   EXPECT_TRUE(SpdySession::CanPool(
   5141       &tss, ssl_info, "www.example.org", "mail.example.org"));
   5142 }
   5143 
   5144 }  // namespace net
   5145