Home | History | Annotate | Download | only in spdy
      1 // Copyright (c) 2011 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/http/http_network_transaction.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "net/base/auth.h"
     11 #include "net/base/net_log_unittest.h"
     12 #include "net/http/http_network_session_peer.h"
     13 #include "net/http/http_transaction_unittest.h"
     14 #include "net/socket/client_socket_pool_base.h"
     15 #include "net/spdy/spdy_http_stream.h"
     16 #include "net/spdy/spdy_http_utils.h"
     17 #include "net/spdy/spdy_session.h"
     18 #include "net/spdy/spdy_session_pool.h"
     19 #include "net/spdy/spdy_test_util.h"
     20 #include "net/url_request/url_request_test_util.h"
     21 #include "testing/platform_test.h"
     22 
     23 //-----------------------------------------------------------------------------
     24 
     25 namespace net {
     26 
     27 // This is the expected list of advertised protocols from the browser's NPN
     28 // list.
     29 static const char kExpectedNPNString[] = "\x08http/1.1\x06spdy/2";
     30 
     31 enum SpdyNetworkTransactionTestTypes {
     32   SPDYNPN,
     33   SPDYNOSSL,
     34   SPDYSSL,
     35 };
     36 class SpdyNetworkTransactionTest
     37     : public ::testing::TestWithParam<SpdyNetworkTransactionTestTypes> {
     38  protected:
     39 
     40   virtual void SetUp() {
     41     // By default, all tests turn off compression.
     42     EnableCompression(false);
     43     google_get_request_initialized_ = false;
     44     google_post_request_initialized_ = false;
     45     google_chunked_post_request_initialized_ = false;
     46   }
     47 
     48   virtual void TearDown() {
     49     // Empty the current queue.
     50     MessageLoop::current()->RunAllPending();
     51   }
     52 
     53   struct TransactionHelperResult {
     54     int rv;
     55     std::string status_line;
     56     std::string response_data;
     57     HttpResponseInfo response_info;
     58   };
     59 
     60   void EnableCompression(bool enabled) {
     61     spdy::SpdyFramer::set_enable_compression_default(enabled);
     62   }
     63 
     64   class StartTransactionCallback;
     65   class DeleteSessionCallback;
     66 
     67   // A helper class that handles all the initial npn/ssl setup.
     68   class NormalSpdyTransactionHelper {
     69    public:
     70     NormalSpdyTransactionHelper(const HttpRequestInfo& request,
     71                                 const BoundNetLog& log,
     72                                 SpdyNetworkTransactionTestTypes test_type)
     73         : request_(request),
     74           session_deps_(new SpdySessionDependencies()),
     75           session_(SpdySessionDependencies::SpdyCreateSession(
     76               session_deps_.get())),
     77           log_(log),
     78           test_type_(test_type),
     79           deterministic_(false),
     80           spdy_enabled_(true) {
     81             switch (test_type_) {
     82               case SPDYNOSSL:
     83               case SPDYSSL:
     84                 port_ = 80;
     85                 break;
     86               case SPDYNPN:
     87                 port_ = 443;
     88                 break;
     89               default:
     90                 NOTREACHED();
     91             }
     92           }
     93 
     94     ~NormalSpdyTransactionHelper() {
     95       // Any test which doesn't close the socket by sending it an EOF will
     96       // have a valid session left open, which leaks the entire session pool.
     97       // This is just fine - in fact, some of our tests intentionally do this
     98       // so that we can check consistency of the SpdySessionPool as the test
     99       // finishes.  If we had put an EOF on the socket, the SpdySession would
    100       // have closed and we wouldn't be able to check the consistency.
    101 
    102       // Forcefully close existing sessions here.
    103       session()->spdy_session_pool()->CloseAllSessions();
    104     }
    105 
    106     void SetDeterministic() {
    107       session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
    108           session_deps_.get());
    109       deterministic_ = true;
    110     }
    111 
    112     void SetSpdyDisabled() {
    113       spdy_enabled_ = false;
    114     }
    115 
    116     void RunPreTestSetup() {
    117       if (!session_deps_.get())
    118         session_deps_.reset(new SpdySessionDependencies());
    119       if (!session_.get())
    120         session_ = SpdySessionDependencies::SpdyCreateSession(
    121             session_deps_.get());
    122       HttpStreamFactory::set_use_alternate_protocols(false);
    123       HttpStreamFactory::set_force_spdy_over_ssl(false);
    124       HttpStreamFactory::set_force_spdy_always(false);
    125       switch (test_type_) {
    126         case SPDYNPN:
    127           session_->mutable_alternate_protocols()->SetAlternateProtocolFor(
    128               HostPortPair("www.google.com", 80), 443,
    129               HttpAlternateProtocols::NPN_SPDY_2);
    130           HttpStreamFactory::set_use_alternate_protocols(true);
    131           HttpStreamFactory::set_next_protos(kExpectedNPNString);
    132           break;
    133         case SPDYNOSSL:
    134           HttpStreamFactory::set_force_spdy_over_ssl(false);
    135           HttpStreamFactory::set_force_spdy_always(true);
    136           break;
    137         case SPDYSSL:
    138           HttpStreamFactory::set_force_spdy_over_ssl(true);
    139           HttpStreamFactory::set_force_spdy_always(true);
    140           break;
    141         default:
    142           NOTREACHED();
    143       }
    144 
    145       // We're now ready to use SSL-npn SPDY.
    146       trans_.reset(new HttpNetworkTransaction(session_));
    147     }
    148 
    149     // Start the transaction, read some data, finish.
    150     void RunDefaultTest() {
    151       output_.rv = trans_->Start(&request_, &callback, log_);
    152 
    153       // We expect an IO Pending or some sort of error.
    154       EXPECT_LT(output_.rv, 0);
    155       if (output_.rv != ERR_IO_PENDING)
    156         return;
    157 
    158       output_.rv = callback.WaitForResult();
    159       if (output_.rv != OK) {
    160         session_->spdy_session_pool()->CloseCurrentSessions();
    161         return;
    162       }
    163 
    164       // Verify responses.
    165       const HttpResponseInfo* response = trans_->GetResponseInfo();
    166       ASSERT_TRUE(response != NULL);
    167       ASSERT_TRUE(response->headers != NULL);
    168       EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
    169       EXPECT_EQ(spdy_enabled_, response->was_fetched_via_spdy);
    170       if (test_type_ == SPDYNPN && spdy_enabled_) {
    171         EXPECT_TRUE(response->was_npn_negotiated);
    172       } else {
    173         EXPECT_TRUE(!response->was_npn_negotiated);
    174       }
    175       // If SPDY is not enabled, a HTTP request should not be diverted
    176       // over a SSL session.
    177       if (!spdy_enabled_) {
    178         EXPECT_EQ(request_.url.SchemeIs("https"),
    179                   response->was_npn_negotiated);
    180       }
    181       EXPECT_EQ("192.0.2.33", response->socket_address.host());
    182       EXPECT_EQ(0, response->socket_address.port());
    183       output_.status_line = response->headers->GetStatusLine();
    184       output_.response_info = *response;  // Make a copy so we can verify.
    185       output_.rv = ReadTransaction(trans_.get(), &output_.response_data);
    186     }
    187 
    188     // Most tests will want to call this function. In particular, the MockReads
    189     // should end with an empty read, and that read needs to be processed to
    190     // ensure proper deletion of the spdy_session_pool.
    191     void VerifyDataConsumed() {
    192       for (DataVector::iterator it = data_vector_.begin();
    193           it != data_vector_.end(); ++it) {
    194         EXPECT_TRUE((*it)->at_read_eof()) << "Read count: "
    195                                           << (*it)->read_count()
    196                                           << " Read index: "
    197                                           << (*it)->read_index();
    198         EXPECT_TRUE((*it)->at_write_eof()) << "Write count: "
    199                                            << (*it)->write_count()
    200                                            << " Write index: "
    201                                            << (*it)->write_index();
    202       }
    203     }
    204 
    205     // Occasionally a test will expect to error out before certain reads are
    206     // processed. In that case we want to explicitly ensure that the reads were
    207     // not processed.
    208     void VerifyDataNotConsumed() {
    209       for (DataVector::iterator it = data_vector_.begin();
    210           it != data_vector_.end(); ++it) {
    211         EXPECT_TRUE(!(*it)->at_read_eof()) << "Read count: "
    212                                            << (*it)->read_count()
    213                                            << " Read index: "
    214                                            << (*it)->read_index();
    215         EXPECT_TRUE(!(*it)->at_write_eof()) << "Write count: "
    216                                             << (*it)->write_count()
    217                                             << " Write index: "
    218                                             << (*it)->write_index();
    219       }
    220     }
    221 
    222     void RunToCompletion(StaticSocketDataProvider* data) {
    223       RunPreTestSetup();
    224       AddData(data);
    225       RunDefaultTest();
    226       VerifyDataConsumed();
    227     }
    228 
    229     void AddData(StaticSocketDataProvider* data) {
    230       DCHECK(!deterministic_);
    231       data_vector_.push_back(data);
    232       linked_ptr<SSLSocketDataProvider> ssl_(
    233           new SSLSocketDataProvider(true, OK));
    234       if (test_type_ == SPDYNPN) {
    235         ssl_->next_proto_status = SSLClientSocket::kNextProtoNegotiated;
    236         ssl_->next_proto = "spdy/2";
    237         ssl_->was_npn_negotiated = true;
    238       }
    239       ssl_vector_.push_back(ssl_);
    240       if (test_type_ == SPDYNPN || test_type_ == SPDYSSL)
    241         session_deps_->socket_factory->AddSSLSocketDataProvider(ssl_.get());
    242       session_deps_->socket_factory->AddSocketDataProvider(data);
    243       if (test_type_ == SPDYNPN) {
    244         MockConnect never_finishing_connect(false, ERR_IO_PENDING);
    245         linked_ptr<StaticSocketDataProvider>
    246             hanging_non_alternate_protocol_socket(
    247                 new StaticSocketDataProvider(NULL, 0, NULL, 0));
    248         hanging_non_alternate_protocol_socket->set_connect_data(
    249             never_finishing_connect);
    250         session_deps_->socket_factory->AddSocketDataProvider(
    251             hanging_non_alternate_protocol_socket.get());
    252         alternate_vector_.push_back(hanging_non_alternate_protocol_socket);
    253       }
    254     }
    255 
    256     void AddDeterministicData(DeterministicSocketData* data) {
    257       DCHECK(deterministic_);
    258       data_vector_.push_back(data);
    259       linked_ptr<SSLSocketDataProvider> ssl_(
    260           new SSLSocketDataProvider(true, OK));
    261       if (test_type_ == SPDYNPN) {
    262         ssl_->next_proto_status = SSLClientSocket::kNextProtoNegotiated;
    263         ssl_->next_proto = "spdy/2";
    264         ssl_->was_npn_negotiated = true;
    265       }
    266       ssl_vector_.push_back(ssl_);
    267       if (test_type_ == SPDYNPN || test_type_ == SPDYSSL) {
    268         session_deps_->deterministic_socket_factory->
    269             AddSSLSocketDataProvider(ssl_.get());
    270       }
    271       session_deps_->deterministic_socket_factory->AddSocketDataProvider(data);
    272       if (test_type_ == SPDYNPN) {
    273         MockConnect never_finishing_connect(false, ERR_IO_PENDING);
    274         scoped_refptr<DeterministicSocketData>
    275             hanging_non_alternate_protocol_socket(
    276             new DeterministicSocketData(NULL, 0, NULL, 0));
    277         hanging_non_alternate_protocol_socket->set_connect_data(
    278             never_finishing_connect);
    279         session_deps_->deterministic_socket_factory->AddSocketDataProvider(
    280             hanging_non_alternate_protocol_socket);
    281         alternate_deterministic_vector_.push_back(
    282             hanging_non_alternate_protocol_socket);
    283       }
    284     }
    285 
    286     // This can only be called after RunPreTestSetup. It adds a Data Provider,
    287     // but not a corresponding SSL data provider
    288     void AddDataNoSSL(StaticSocketDataProvider* data) {
    289       DCHECK(!deterministic_);
    290       session_deps_->socket_factory->AddSocketDataProvider(data);
    291     }
    292     void AddDataNoSSL(DeterministicSocketData* data) {
    293       DCHECK(deterministic_);
    294       session_deps_->deterministic_socket_factory->AddSocketDataProvider(data);
    295     }
    296 
    297     void SetSession(const scoped_refptr<HttpNetworkSession>& session) {
    298       session_ = session;
    299     }
    300     HttpNetworkTransaction* trans() { return trans_.get(); }
    301     void ResetTrans() { trans_.reset(); }
    302     TransactionHelperResult& output() { return output_; }
    303     const HttpRequestInfo& request() const { return request_; }
    304     const scoped_refptr<HttpNetworkSession>& session() const {
    305       return session_;
    306     }
    307     scoped_ptr<SpdySessionDependencies>& session_deps() {
    308       return session_deps_;
    309     }
    310     int port() const { return port_; }
    311     SpdyNetworkTransactionTestTypes test_type() const { return test_type_; }
    312 
    313    private:
    314     typedef std::vector<StaticSocketDataProvider*> DataVector;
    315     typedef std::vector<linked_ptr<SSLSocketDataProvider> > SSLVector;
    316     typedef std::vector<linked_ptr<StaticSocketDataProvider> > AlternateVector;
    317     typedef std::vector<scoped_refptr<DeterministicSocketData> >
    318         AlternateDeterministicVector;
    319     HttpRequestInfo request_;
    320     scoped_ptr<SpdySessionDependencies> session_deps_;
    321     scoped_refptr<HttpNetworkSession> session_;
    322     TransactionHelperResult output_;
    323     scoped_ptr<StaticSocketDataProvider> first_transaction_;
    324     SSLVector ssl_vector_;
    325     TestCompletionCallback callback;
    326     scoped_ptr<HttpNetworkTransaction> trans_;
    327     scoped_ptr<HttpNetworkTransaction> trans_http_;
    328     DataVector data_vector_;
    329     AlternateVector alternate_vector_;
    330     AlternateDeterministicVector alternate_deterministic_vector_;
    331     const BoundNetLog& log_;
    332     SpdyNetworkTransactionTestTypes test_type_;
    333     int port_;
    334     bool deterministic_;
    335     bool spdy_enabled_;
    336   };
    337 
    338   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
    339                                              int expected_status);
    340 
    341   void ConnectStatusHelper(const MockRead& status);
    342 
    343   const HttpRequestInfo& CreateGetPushRequest() {
    344     google_get_push_request_.method = "GET";
    345     google_get_push_request_.url = GURL("http://www.google.com/foo.dat");
    346     google_get_push_request_.load_flags = 0;
    347     return google_get_push_request_;
    348   }
    349 
    350   const HttpRequestInfo& CreateGetRequest() {
    351     if (!google_get_request_initialized_) {
    352       google_get_request_.method = "GET";
    353       google_get_request_.url = GURL(kDefaultURL);
    354       google_get_request_.load_flags = 0;
    355       google_get_request_initialized_ = true;
    356     }
    357     return google_get_request_;
    358   }
    359 
    360   const HttpRequestInfo& CreateGetRequestWithUserAgent() {
    361     if (!google_get_request_initialized_) {
    362       google_get_request_.method = "GET";
    363       google_get_request_.url = GURL(kDefaultURL);
    364       google_get_request_.load_flags = 0;
    365       google_get_request_.extra_headers.SetHeader("User-Agent", "Chrome");
    366       google_get_request_initialized_ = true;
    367     }
    368     return google_get_request_;
    369   }
    370 
    371   const HttpRequestInfo& CreatePostRequest() {
    372     if (!google_post_request_initialized_) {
    373       google_post_request_.method = "POST";
    374       google_post_request_.url = GURL(kDefaultURL);
    375       google_post_request_.upload_data = new UploadData();
    376       google_post_request_.upload_data->AppendBytes(kUploadData,
    377                                                     kUploadDataSize);
    378       google_post_request_initialized_ = true;
    379     }
    380     return google_post_request_;
    381   }
    382 
    383   const HttpRequestInfo& CreateChunkedPostRequest() {
    384     if (!google_chunked_post_request_initialized_) {
    385       google_chunked_post_request_.method = "POST";
    386       google_chunked_post_request_.url = GURL(kDefaultURL);
    387       google_chunked_post_request_.upload_data = new UploadData();
    388       google_chunked_post_request_.upload_data->set_is_chunked(true);
    389       google_chunked_post_request_.upload_data->AppendChunk(
    390           kUploadData, kUploadDataSize, false);
    391       google_chunked_post_request_.upload_data->AppendChunk(
    392           kUploadData, kUploadDataSize, true);
    393       google_chunked_post_request_initialized_ = true;
    394     }
    395     return google_chunked_post_request_;
    396   }
    397 
    398   // Read the result of a particular transaction, knowing that we've got
    399   // multiple transactions in the read pipeline; so as we read, we may have
    400   // to skip over data destined for other transactions while we consume
    401   // the data for |trans|.
    402   int ReadResult(HttpNetworkTransaction* trans,
    403                  StaticSocketDataProvider* data,
    404                  std::string* result) {
    405     const int kSize = 3000;
    406 
    407     int bytes_read = 0;
    408     scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(kSize));
    409     TestCompletionCallback callback;
    410     while (true) {
    411       int rv = trans->Read(buf, kSize, &callback);
    412       if (rv == ERR_IO_PENDING) {
    413         // Multiple transactions may be in the data set.  Keep pulling off
    414         // reads until we complete our callback.
    415         while (!callback.have_result()) {
    416           data->CompleteRead();
    417           MessageLoop::current()->RunAllPending();
    418         }
    419         rv = callback.WaitForResult();
    420       } else if (rv <= 0) {
    421         break;
    422       }
    423       result->append(buf->data(), rv);
    424       bytes_read += rv;
    425     }
    426     return bytes_read;
    427   }
    428 
    429   void VerifyStreamsClosed(const NormalSpdyTransactionHelper& helper) {
    430     // This lengthy block is reaching into the pool to dig out the active
    431     // session.  Once we have the session, we verify that the streams are
    432     // all closed and not leaked at this point.
    433     const GURL& url = helper.request().url;
    434     int port = helper.test_type() == SPDYNPN ? 443 : 80;
    435     HostPortPair host_port_pair(url.host(), port);
    436     HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
    437     BoundNetLog log;
    438     const scoped_refptr<HttpNetworkSession>& session = helper.session();
    439     SpdySessionPool* pool(session->spdy_session_pool());
    440     EXPECT_TRUE(pool->HasSession(pair));
    441     scoped_refptr<SpdySession> spdy_session(pool->Get(pair, log));
    442     ASSERT_TRUE(spdy_session.get() != NULL);
    443     EXPECT_EQ(0u, spdy_session->num_active_streams());
    444     EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams());
    445   }
    446 
    447   void RunServerPushTest(OrderedSocketData* data,
    448                          HttpResponseInfo* response,
    449                          HttpResponseInfo* push_response,
    450                          std::string& expected) {
    451     NormalSpdyTransactionHelper helper(CreateGetRequest(),
    452                                        BoundNetLog(), GetParam());
    453     helper.RunPreTestSetup();
    454     helper.AddData(data);
    455 
    456     HttpNetworkTransaction* trans = helper.trans();
    457 
    458     // Start the transaction with basic parameters.
    459     TestCompletionCallback callback;
    460     int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
    461     EXPECT_EQ(ERR_IO_PENDING, rv);
    462     rv = callback.WaitForResult();
    463 
    464     // Request the pushed path.
    465     scoped_ptr<HttpNetworkTransaction> trans2(
    466         new HttpNetworkTransaction(helper.session()));
    467     rv = trans2->Start(&CreateGetPushRequest(), &callback, BoundNetLog());
    468     EXPECT_EQ(ERR_IO_PENDING, rv);
    469     MessageLoop::current()->RunAllPending();
    470 
    471     // The data for the pushed path may be coming in more than 1 packet. Compile
    472     // the results into a single string.
    473 
    474     // Read the server push body.
    475     std::string result2;
    476     ReadResult(trans2.get(), data, &result2);
    477     // Read the response body.
    478     std::string result;
    479     ReadResult(trans, data, &result);
    480 
    481     // Verify that we consumed all test data.
    482     EXPECT_TRUE(data->at_read_eof());
    483     EXPECT_TRUE(data->at_write_eof());
    484 
    485     // Verify that the received push data is same as the expected push data.
    486     EXPECT_EQ(result2.compare(expected), 0) << "Received data: "
    487                                             << result2
    488                                             << "||||| Expected data: "
    489                                             << expected;
    490 
    491     // Verify the SYN_REPLY.
    492     // Copy the response info, because trans goes away.
    493     *response = *trans->GetResponseInfo();
    494     *push_response = *trans2->GetResponseInfo();
    495 
    496     VerifyStreamsClosed(helper);
    497   }
    498 
    499  private:
    500   bool google_get_request_initialized_;
    501   bool google_post_request_initialized_;
    502   bool google_chunked_post_request_initialized_;
    503   HttpRequestInfo google_get_request_;
    504   HttpRequestInfo google_post_request_;
    505   HttpRequestInfo google_chunked_post_request_;
    506   HttpRequestInfo google_get_push_request_;
    507 };
    508 
    509 //-----------------------------------------------------------------------------
    510 // All tests are run with three different connection types: SPDY after NPN
    511 // negotiation, SPDY without SSL, and SPDY with SSL.
    512 INSTANTIATE_TEST_CASE_P(Spdy,
    513                         SpdyNetworkTransactionTest,
    514                         ::testing::Values(SPDYNOSSL, SPDYSSL, SPDYNPN));
    515 
    516 
    517 // Verify HttpNetworkTransaction constructor.
    518 TEST_P(SpdyNetworkTransactionTest, Constructor) {
    519   SpdySessionDependencies session_deps;
    520   scoped_refptr<HttpNetworkSession> session(
    521       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    522   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
    523 }
    524 
    525 TEST_P(SpdyNetworkTransactionTest, Get) {
    526   // Construct the request.
    527   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
    528   MockWrite writes[] = { CreateMockWrite(*req) };
    529 
    530   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
    531   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
    532   MockRead reads[] = {
    533     CreateMockRead(*resp),
    534     CreateMockRead(*body),
    535     MockRead(true, 0, 0)  // EOF
    536   };
    537 
    538   scoped_refptr<DelayedSocketData> data(
    539       new DelayedSocketData(1, reads, arraysize(reads),
    540                             writes, arraysize(writes)));
    541   NormalSpdyTransactionHelper helper(CreateGetRequest(),
    542                                      BoundNetLog(), GetParam());
    543   helper.RunToCompletion(data.get());
    544   TransactionHelperResult out = helper.output();
    545   EXPECT_EQ(OK, out.rv);
    546   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    547   EXPECT_EQ("hello!", out.response_data);
    548 }
    549 
    550 TEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) {
    551   for (RequestPriority p = HIGHEST; p < NUM_PRIORITIES;
    552        p = RequestPriority(p+1)) {
    553     // Construct the request.
    554     scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, p));
    555     MockWrite writes[] = { CreateMockWrite(*req) };
    556 
    557     const int spdy_prio = reinterpret_cast<spdy::SpdySynStreamControlFrame*>(
    558         req.get())->priority();
    559     // this repeats the RequestPriority-->SpdyPriority mapping from
    560     // SpdyFramer::ConvertRequestPriorityToSpdyPriority to make
    561     // sure it's being done right.
    562     switch(p) {
    563       case HIGHEST:
    564         EXPECT_EQ(0, spdy_prio);
    565         break;
    566       case MEDIUM:
    567         EXPECT_EQ(1, spdy_prio);
    568         break;
    569       case LOW:
    570       case LOWEST:
    571         EXPECT_EQ(2, spdy_prio);
    572         break;
    573       case IDLE:
    574         EXPECT_EQ(3, spdy_prio);
    575         break;
    576       default:
    577         FAIL();
    578     }
    579 
    580     scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
    581     scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
    582     MockRead reads[] = {
    583       CreateMockRead(*resp),
    584       CreateMockRead(*body),
    585       MockRead(true, 0, 0)  // EOF
    586     };
    587 
    588     scoped_refptr<DelayedSocketData> data(
    589         new DelayedSocketData(1, reads, arraysize(reads),
    590                               writes, arraysize(writes)));
    591     HttpRequestInfo http_req = CreateGetRequest();
    592     http_req.priority = p;
    593 
    594     NormalSpdyTransactionHelper helper(http_req, BoundNetLog(), GetParam());
    595     helper.RunToCompletion(data.get());
    596     TransactionHelperResult out = helper.output();
    597     EXPECT_EQ(OK, out.rv);
    598     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    599     EXPECT_EQ("hello!", out.response_data);
    600   }
    601 }
    602 
    603 // Start three gets simultaniously; making sure that multiplexed
    604 // streams work properly.
    605 
    606 // This can't use the TransactionHelper method, since it only
    607 // handles a single transaction, and finishes them as soon
    608 // as it launches them.
    609 
    610 // TODO(gavinp): create a working generalized TransactionHelper that
    611 // can allow multiple streams in flight.
    612 
    613 TEST_P(SpdyNetworkTransactionTest, ThreeGets) {
    614   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
    615   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
    616   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
    617   scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
    618 
    619   scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
    620   scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
    621   scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
    622   scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
    623 
    624   scoped_ptr<spdy::SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, LOWEST));
    625   scoped_ptr<spdy::SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5));
    626   scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(5, false));
    627   scoped_ptr<spdy::SpdyFrame> fbody3(ConstructSpdyBodyFrame(5, true));
    628 
    629   MockWrite writes[] = {
    630     CreateMockWrite(*req),
    631     CreateMockWrite(*req2),
    632     CreateMockWrite(*req3),
    633   };
    634   MockRead reads[] = {
    635     CreateMockRead(*resp, 1),
    636     CreateMockRead(*body),
    637     CreateMockRead(*resp2, 4),
    638     CreateMockRead(*body2),
    639     CreateMockRead(*resp3, 7),
    640     CreateMockRead(*body3),
    641 
    642     CreateMockRead(*fbody),
    643     CreateMockRead(*fbody2),
    644     CreateMockRead(*fbody3),
    645 
    646     MockRead(true, 0, 0),  // EOF
    647   };
    648   scoped_refptr<OrderedSocketData> data(
    649       new OrderedSocketData(reads, arraysize(reads),
    650                             writes, arraysize(writes)));
    651   scoped_refptr<OrderedSocketData> data_placeholder(
    652       new OrderedSocketData(NULL, 0, NULL, 0));
    653 
    654   BoundNetLog log;
    655   TransactionHelperResult out;
    656   NormalSpdyTransactionHelper helper(CreateGetRequest(),
    657                                      BoundNetLog(), GetParam());
    658   helper.RunPreTestSetup();
    659   helper.AddData(data.get());
    660   // We require placeholder data because three get requests are sent out, so
    661   // there needs to be three sets of SSL connection data.
    662   helper.AddData(data_placeholder.get());
    663   helper.AddData(data_placeholder.get());
    664   scoped_ptr<HttpNetworkTransaction> trans1(
    665       new HttpNetworkTransaction(helper.session()));
    666   scoped_ptr<HttpNetworkTransaction> trans2(
    667       new HttpNetworkTransaction(helper.session()));
    668   scoped_ptr<HttpNetworkTransaction> trans3(
    669       new HttpNetworkTransaction(helper.session()));
    670 
    671   TestCompletionCallback callback1;
    672   TestCompletionCallback callback2;
    673   TestCompletionCallback callback3;
    674 
    675   HttpRequestInfo httpreq1 = CreateGetRequest();
    676   HttpRequestInfo httpreq2 = CreateGetRequest();
    677   HttpRequestInfo httpreq3 = CreateGetRequest();
    678 
    679   out.rv = trans1->Start(&httpreq1, &callback1, log);
    680   ASSERT_EQ(ERR_IO_PENDING, out.rv);
    681   out.rv = trans2->Start(&httpreq2, &callback2, log);
    682   ASSERT_EQ(ERR_IO_PENDING, out.rv);
    683   out.rv = trans3->Start(&httpreq3, &callback3, log);
    684   ASSERT_EQ(ERR_IO_PENDING, out.rv);
    685 
    686   out.rv = callback1.WaitForResult();
    687   ASSERT_EQ(OK, out.rv);
    688   out.rv = callback3.WaitForResult();
    689   ASSERT_EQ(OK, out.rv);
    690 
    691   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
    692   EXPECT_TRUE(response1->headers != NULL);
    693   EXPECT_TRUE(response1->was_fetched_via_spdy);
    694   out.status_line = response1->headers->GetStatusLine();
    695   out.response_info = *response1;
    696 
    697   trans2->GetResponseInfo();
    698 
    699   out.rv = ReadTransaction(trans1.get(), &out.response_data);
    700   helper.VerifyDataConsumed();
    701   EXPECT_EQ(OK, out.rv);
    702 
    703   EXPECT_EQ(OK, out.rv);
    704   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    705   EXPECT_EQ("hello!hello!", out.response_data);
    706 }
    707 
    708 TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) {
    709   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
    710   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
    711   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
    712   scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
    713 
    714   scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
    715   scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
    716   scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
    717   scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
    718 
    719   MockWrite writes[] = {
    720     CreateMockWrite(*req),
    721     CreateMockWrite(*req2),
    722   };
    723   MockRead reads[] = {
    724     CreateMockRead(*resp, 1),
    725     CreateMockRead(*body),
    726     CreateMockRead(*resp2, 4),
    727     CreateMockRead(*body2),
    728     CreateMockRead(*fbody),
    729     CreateMockRead(*fbody2),
    730     MockRead(true, 0, 0),  // EOF
    731   };
    732   scoped_refptr<OrderedSocketData> data(
    733       new OrderedSocketData(reads, arraysize(reads),
    734                             writes, arraysize(writes)));
    735 
    736   MockConnect never_finishing_connect(false, ERR_IO_PENDING);
    737 
    738   scoped_refptr<OrderedSocketData> data_placeholder(
    739       new OrderedSocketData(NULL, 0, NULL, 0));
    740   data_placeholder->set_connect_data(never_finishing_connect);
    741 
    742   BoundNetLog log;
    743   TransactionHelperResult out;
    744   NormalSpdyTransactionHelper helper(CreateGetRequest(),
    745                                      BoundNetLog(), GetParam());
    746   helper.RunPreTestSetup();
    747   helper.AddData(data.get());
    748   // We require placeholder data because two get requests are sent out, so
    749   // there needs to be two sets of SSL connection data.
    750   helper.AddData(data_placeholder.get());
    751   scoped_ptr<HttpNetworkTransaction> trans1(
    752       new HttpNetworkTransaction(helper.session()));
    753   scoped_ptr<HttpNetworkTransaction> trans2(
    754       new HttpNetworkTransaction(helper.session()));
    755 
    756   TestCompletionCallback callback1;
    757   TestCompletionCallback callback2;
    758 
    759   HttpRequestInfo httpreq1 = CreateGetRequest();
    760   HttpRequestInfo httpreq2 = CreateGetRequest();
    761 
    762   out.rv = trans1->Start(&httpreq1, &callback1, log);
    763   ASSERT_EQ(ERR_IO_PENDING, out.rv);
    764   out.rv = trans2->Start(&httpreq2, &callback2, log);
    765   ASSERT_EQ(ERR_IO_PENDING, out.rv);
    766 
    767   out.rv = callback1.WaitForResult();
    768   ASSERT_EQ(OK, out.rv);
    769   out.rv = callback2.WaitForResult();
    770   ASSERT_EQ(OK, out.rv);
    771 
    772   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
    773   EXPECT_TRUE(response1->headers != NULL);
    774   EXPECT_TRUE(response1->was_fetched_via_spdy);
    775   out.status_line = response1->headers->GetStatusLine();
    776   out.response_info = *response1;
    777   out.rv = ReadTransaction(trans1.get(), &out.response_data);
    778   EXPECT_EQ(OK, out.rv);
    779   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    780   EXPECT_EQ("hello!hello!", out.response_data);
    781 
    782   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
    783   EXPECT_TRUE(response2->headers != NULL);
    784   EXPECT_TRUE(response2->was_fetched_via_spdy);
    785   out.status_line = response2->headers->GetStatusLine();
    786   out.response_info = *response2;
    787   out.rv = ReadTransaction(trans2.get(), &out.response_data);
    788   EXPECT_EQ(OK, out.rv);
    789   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    790   EXPECT_EQ("hello!hello!", out.response_data);
    791 
    792   helper.VerifyDataConsumed();
    793 }
    794 
    795 TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
    796   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
    797   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
    798   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
    799   scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
    800 
    801   scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
    802   scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
    803   scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
    804   scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
    805 
    806   MockWrite writes[] = {
    807     CreateMockWrite(*req),
    808     CreateMockWrite(*req2),
    809   };
    810   MockRead reads[] = {
    811     CreateMockRead(*resp, 1),
    812     CreateMockRead(*body),
    813     CreateMockRead(*resp2, 4),
    814     CreateMockRead(*body2),
    815     CreateMockRead(*fbody),
    816     CreateMockRead(*fbody2),
    817     MockRead(true, 0, 0),  // EOF
    818   };
    819   scoped_refptr<OrderedSocketData> preconnect_data(
    820       new OrderedSocketData(reads, arraysize(reads),
    821                             writes, arraysize(writes)));
    822 
    823   MockConnect never_finishing_connect(true, ERR_IO_PENDING);
    824 
    825   scoped_refptr<OrderedSocketData> data_placeholder(
    826       new OrderedSocketData(NULL, 0, NULL, 0));
    827   data_placeholder->set_connect_data(never_finishing_connect);
    828 
    829   BoundNetLog log;
    830   TransactionHelperResult out;
    831   NormalSpdyTransactionHelper helper(CreateGetRequest(),
    832                                      BoundNetLog(), GetParam());
    833   helper.RunPreTestSetup();
    834   helper.AddData(preconnect_data.get());
    835   // We require placeholder data because 3 connections are attempted (first is
    836   // the preconnect, 2nd and 3rd are the never finished connections.
    837   helper.AddData(data_placeholder.get());
    838   helper.AddData(data_placeholder.get());
    839 
    840   scoped_ptr<HttpNetworkTransaction> trans1(
    841       new HttpNetworkTransaction(helper.session()));
    842   scoped_ptr<HttpNetworkTransaction> trans2(
    843       new HttpNetworkTransaction(helper.session()));
    844 
    845   TestCompletionCallback callback1;
    846   TestCompletionCallback callback2;
    847 
    848   HttpRequestInfo httpreq = CreateGetRequest();
    849 
    850   // Preconnect the first.
    851   SSLConfig preconnect_ssl_config;
    852   helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config);
    853   HttpStreamFactory* http_stream_factory =
    854       helper.session()->http_stream_factory();
    855   if (http_stream_factory->next_protos()) {
    856     preconnect_ssl_config.next_protos = *http_stream_factory->next_protos();
    857   }
    858 
    859   http_stream_factory->PreconnectStreams(
    860       1, httpreq, preconnect_ssl_config, log);
    861 
    862   out.rv = trans1->Start(&httpreq, &callback1, log);
    863   ASSERT_EQ(ERR_IO_PENDING, out.rv);
    864   out.rv = trans2->Start(&httpreq, &callback2, log);
    865   ASSERT_EQ(ERR_IO_PENDING, out.rv);
    866 
    867   out.rv = callback1.WaitForResult();
    868   ASSERT_EQ(OK, out.rv);
    869   out.rv = callback2.WaitForResult();
    870   ASSERT_EQ(OK, out.rv);
    871 
    872   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
    873   EXPECT_TRUE(response1->headers != NULL);
    874   EXPECT_TRUE(response1->was_fetched_via_spdy);
    875   out.status_line = response1->headers->GetStatusLine();
    876   out.response_info = *response1;
    877   out.rv = ReadTransaction(trans1.get(), &out.response_data);
    878   EXPECT_EQ(OK, out.rv);
    879   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    880   EXPECT_EQ("hello!hello!", out.response_data);
    881 
    882   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
    883   EXPECT_TRUE(response2->headers != NULL);
    884   EXPECT_TRUE(response2->was_fetched_via_spdy);
    885   out.status_line = response2->headers->GetStatusLine();
    886   out.response_info = *response2;
    887   out.rv = ReadTransaction(trans2.get(), &out.response_data);
    888   EXPECT_EQ(OK, out.rv);
    889   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    890   EXPECT_EQ("hello!hello!", out.response_data);
    891 
    892   helper.VerifyDataConsumed();
    893 }
    894 
    895 // Similar to ThreeGets above, however this test adds a SETTINGS
    896 // frame.  The SETTINGS frame is read during the IO loop waiting on
    897 // the first transaction completion, and sets a maximum concurrent
    898 // stream limit of 1.  This means that our IO loop exists after the
    899 // second transaction completes, so we can assert on read_index().
    900 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
    901   // Construct the request.
    902   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
    903   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
    904   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
    905   scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
    906 
    907   scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
    908   scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
    909   scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
    910   scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
    911 
    912   scoped_ptr<spdy::SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, LOWEST));
    913   scoped_ptr<spdy::SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5));
    914   scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(5, false));
    915   scoped_ptr<spdy::SpdyFrame> fbody3(ConstructSpdyBodyFrame(5, true));
    916 
    917   spdy::SpdySettings settings;
    918   spdy::SettingsFlagsAndId id(0);
    919   id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
    920   const size_t max_concurrent_streams = 1;
    921 
    922   settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
    923   scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings));
    924 
    925   MockWrite writes[] = {
    926     CreateMockWrite(*req),
    927     CreateMockWrite(*req2),
    928     CreateMockWrite(*req3),
    929   };
    930 
    931   MockRead reads[] = {
    932     CreateMockRead(*settings_frame, 1),
    933     CreateMockRead(*resp),
    934     CreateMockRead(*body),
    935     CreateMockRead(*fbody),
    936     CreateMockRead(*resp2, 7),
    937     CreateMockRead(*body2),
    938     CreateMockRead(*fbody2),
    939     CreateMockRead(*resp3, 12),
    940     CreateMockRead(*body3),
    941     CreateMockRead(*fbody3),
    942 
    943     MockRead(true, 0, 0),  // EOF
    944   };
    945 
    946   scoped_refptr<OrderedSocketData> data(
    947       new OrderedSocketData(reads, arraysize(reads),
    948                             writes, arraysize(writes)));
    949   scoped_refptr<OrderedSocketData> data_placeholder(
    950       new OrderedSocketData(NULL, 0, NULL, 0));
    951 
    952   BoundNetLog log;
    953   TransactionHelperResult out;
    954   {
    955     NormalSpdyTransactionHelper helper(CreateGetRequest(),
    956                                        BoundNetLog(), GetParam());
    957     helper.RunPreTestSetup();
    958     helper.AddData(data.get());
    959     // We require placeholder data because three get requests are sent out, so
    960     // there needs to be three sets of SSL connection data.
    961     helper.AddData(data_placeholder.get());
    962     helper.AddData(data_placeholder.get());
    963     scoped_ptr<HttpNetworkTransaction> trans1(
    964         new HttpNetworkTransaction(helper.session()));
    965     scoped_ptr<HttpNetworkTransaction> trans2(
    966         new HttpNetworkTransaction(helper.session()));
    967     scoped_ptr<HttpNetworkTransaction> trans3(
    968         new HttpNetworkTransaction(helper.session()));
    969 
    970     TestCompletionCallback callback1;
    971     TestCompletionCallback callback2;
    972     TestCompletionCallback callback3;
    973 
    974     HttpRequestInfo httpreq1 = CreateGetRequest();
    975     HttpRequestInfo httpreq2 = CreateGetRequest();
    976     HttpRequestInfo httpreq3 = CreateGetRequest();
    977 
    978     out.rv = trans1->Start(&httpreq1, &callback1, log);
    979     ASSERT_EQ(out.rv, ERR_IO_PENDING);
    980     // run transaction 1 through quickly to force a read of our SETTINGS
    981     // frame
    982     out.rv = callback1.WaitForResult();
    983     ASSERT_EQ(OK, out.rv);
    984 
    985     out.rv = trans2->Start(&httpreq2, &callback2, log);
    986     ASSERT_EQ(out.rv, ERR_IO_PENDING);
    987     out.rv = trans3->Start(&httpreq3, &callback3, log);
    988     ASSERT_EQ(out.rv, ERR_IO_PENDING);
    989     out.rv = callback2.WaitForResult();
    990     ASSERT_EQ(OK, out.rv);
    991     EXPECT_EQ(7U, data->read_index());  // i.e. the third trans was queued
    992 
    993     out.rv = callback3.WaitForResult();
    994     ASSERT_EQ(OK, out.rv);
    995 
    996     const HttpResponseInfo* response1 = trans1->GetResponseInfo();
    997     ASSERT_TRUE(response1 != NULL);
    998     EXPECT_TRUE(response1->headers != NULL);
    999     EXPECT_TRUE(response1->was_fetched_via_spdy);
   1000     out.status_line = response1->headers->GetStatusLine();
   1001     out.response_info = *response1;
   1002     out.rv = ReadTransaction(trans1.get(), &out.response_data);
   1003     EXPECT_EQ(OK, out.rv);
   1004     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1005     EXPECT_EQ("hello!hello!", out.response_data);
   1006 
   1007     const HttpResponseInfo* response2 = trans2->GetResponseInfo();
   1008     out.status_line = response2->headers->GetStatusLine();
   1009     out.response_info = *response2;
   1010     out.rv = ReadTransaction(trans2.get(), &out.response_data);
   1011     EXPECT_EQ(OK, out.rv);
   1012     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1013     EXPECT_EQ("hello!hello!", out.response_data);
   1014 
   1015     const HttpResponseInfo* response3 = trans3->GetResponseInfo();
   1016     out.status_line = response3->headers->GetStatusLine();
   1017     out.response_info = *response3;
   1018     out.rv = ReadTransaction(trans3.get(), &out.response_data);
   1019     EXPECT_EQ(OK, out.rv);
   1020     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1021     EXPECT_EQ("hello!hello!", out.response_data);
   1022 
   1023     helper.VerifyDataConsumed();
   1024   }
   1025   EXPECT_EQ(OK, out.rv);
   1026 }
   1027 
   1028 // Similar to ThreeGetsWithMaxConcurrent above, however this test adds
   1029 // a fourth transaction.  The third and fourth transactions have
   1030 // different data ("hello!" vs "hello!hello!") and because of the
   1031 // user specified priority, we expect to see them inverted in
   1032 // the response from the server.
   1033 TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
   1034   // Construct the request.
   1035   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   1036   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   1037   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
   1038   scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
   1039 
   1040   scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
   1041   scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
   1042   scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
   1043   scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
   1044 
   1045   scoped_ptr<spdy::SpdyFrame> req4(
   1046       ConstructSpdyGet(NULL, 0, false, 5, HIGHEST));
   1047   scoped_ptr<spdy::SpdyFrame> resp4(ConstructSpdyGetSynReply(NULL, 0, 5));
   1048   scoped_ptr<spdy::SpdyFrame> fbody4(ConstructSpdyBodyFrame(5, true));
   1049 
   1050   scoped_ptr<spdy::SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 7, LOWEST));
   1051   scoped_ptr<spdy::SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 7));
   1052   scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(7, false));
   1053   scoped_ptr<spdy::SpdyFrame> fbody3(ConstructSpdyBodyFrame(7, true));
   1054 
   1055 
   1056   spdy::SpdySettings settings;
   1057   spdy::SettingsFlagsAndId id(0);
   1058   id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
   1059   const size_t max_concurrent_streams = 1;
   1060 
   1061   settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
   1062   scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings));
   1063 
   1064   MockWrite writes[] = { CreateMockWrite(*req),
   1065     CreateMockWrite(*req2),
   1066     CreateMockWrite(*req4),
   1067     CreateMockWrite(*req3),
   1068   };
   1069   MockRead reads[] = {
   1070     CreateMockRead(*settings_frame, 1),
   1071     CreateMockRead(*resp),
   1072     CreateMockRead(*body),
   1073     CreateMockRead(*fbody),
   1074     CreateMockRead(*resp2, 7),
   1075     CreateMockRead(*body2),
   1076     CreateMockRead(*fbody2),
   1077     CreateMockRead(*resp4, 13),
   1078     CreateMockRead(*fbody4),
   1079     CreateMockRead(*resp3, 16),
   1080     CreateMockRead(*body3),
   1081     CreateMockRead(*fbody3),
   1082 
   1083     MockRead(true, 0, 0),  // EOF
   1084   };
   1085 
   1086   scoped_refptr<OrderedSocketData> data(
   1087       new OrderedSocketData(reads, arraysize(reads),
   1088         writes, arraysize(writes)));
   1089   scoped_refptr<OrderedSocketData> data_placeholder(
   1090       new OrderedSocketData(NULL, 0, NULL, 0));
   1091 
   1092   BoundNetLog log;
   1093   TransactionHelperResult out;
   1094   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   1095       BoundNetLog(), GetParam());
   1096   helper.RunPreTestSetup();
   1097   helper.AddData(data.get());
   1098   // We require placeholder data because four get requests are sent out, so
   1099   // there needs to be four sets of SSL connection data.
   1100   helper.AddData(data_placeholder.get());
   1101   helper.AddData(data_placeholder.get());
   1102   helper.AddData(data_placeholder.get());
   1103   scoped_ptr<HttpNetworkTransaction> trans1(
   1104       new HttpNetworkTransaction(helper.session()));
   1105   scoped_ptr<HttpNetworkTransaction> trans2(
   1106       new HttpNetworkTransaction(helper.session()));
   1107   scoped_ptr<HttpNetworkTransaction> trans3(
   1108       new HttpNetworkTransaction(helper.session()));
   1109   scoped_ptr<HttpNetworkTransaction> trans4(
   1110       new HttpNetworkTransaction(helper.session()));
   1111 
   1112   TestCompletionCallback callback1;
   1113   TestCompletionCallback callback2;
   1114   TestCompletionCallback callback3;
   1115   TestCompletionCallback callback4;
   1116 
   1117   HttpRequestInfo httpreq1 = CreateGetRequest();
   1118   HttpRequestInfo httpreq2 = CreateGetRequest();
   1119   HttpRequestInfo httpreq3 = CreateGetRequest();
   1120   HttpRequestInfo httpreq4 = CreateGetRequest();
   1121   httpreq4.priority = HIGHEST;
   1122 
   1123   out.rv = trans1->Start(&httpreq1, &callback1, log);
   1124   ASSERT_EQ(ERR_IO_PENDING, out.rv);
   1125   // run transaction 1 through quickly to force a read of our SETTINGS
   1126   // frame
   1127   out.rv = callback1.WaitForResult();
   1128   ASSERT_EQ(OK, out.rv);
   1129 
   1130   out.rv = trans2->Start(&httpreq2, &callback2, log);
   1131   ASSERT_EQ(ERR_IO_PENDING, out.rv);
   1132   out.rv = trans3->Start(&httpreq3, &callback3, log);
   1133   ASSERT_EQ(ERR_IO_PENDING, out.rv);
   1134   out.rv = trans4->Start(&httpreq4, &callback4, log);
   1135   ASSERT_EQ(ERR_IO_PENDING, out.rv);
   1136 
   1137   out.rv = callback2.WaitForResult();
   1138   ASSERT_EQ(OK, out.rv);
   1139   EXPECT_EQ(data->read_index(), 7U);  // i.e. the third & fourth trans queued
   1140 
   1141   out.rv = callback3.WaitForResult();
   1142   ASSERT_EQ(OK, out.rv);
   1143 
   1144   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
   1145   EXPECT_TRUE(response1->headers != NULL);
   1146   EXPECT_TRUE(response1->was_fetched_via_spdy);
   1147   out.status_line = response1->headers->GetStatusLine();
   1148   out.response_info = *response1;
   1149   out.rv = ReadTransaction(trans1.get(), &out.response_data);
   1150   EXPECT_EQ(OK, out.rv);
   1151   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1152   EXPECT_EQ("hello!hello!", out.response_data);
   1153 
   1154   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
   1155   out.status_line = response2->headers->GetStatusLine();
   1156   out.response_info = *response2;
   1157   out.rv = ReadTransaction(trans2.get(), &out.response_data);
   1158   EXPECT_EQ(OK, out.rv);
   1159   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1160   EXPECT_EQ("hello!hello!", out.response_data);
   1161 
   1162   // notice: response3 gets two hellos, response4 gets one
   1163   // hello, so we know dequeuing priority was respected.
   1164   const HttpResponseInfo* response3 = trans3->GetResponseInfo();
   1165   out.status_line = response3->headers->GetStatusLine();
   1166   out.response_info = *response3;
   1167   out.rv = ReadTransaction(trans3.get(), &out.response_data);
   1168   EXPECT_EQ(OK, out.rv);
   1169   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1170   EXPECT_EQ("hello!hello!", out.response_data);
   1171 
   1172   out.rv = callback4.WaitForResult();
   1173   EXPECT_EQ(OK, out.rv);
   1174   const HttpResponseInfo* response4 = trans4->GetResponseInfo();
   1175   out.status_line = response4->headers->GetStatusLine();
   1176   out.response_info = *response4;
   1177   out.rv = ReadTransaction(trans4.get(), &out.response_data);
   1178   EXPECT_EQ(OK, out.rv);
   1179   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1180   EXPECT_EQ("hello!", out.response_data);
   1181   helper.VerifyDataConsumed();
   1182   EXPECT_EQ(OK, out.rv);
   1183 }
   1184 
   1185 // Similar to ThreeGetsMaxConcurrrent above, however, this test
   1186 // deletes a session in the middle of the transaction to insure
   1187 // that we properly remove pendingcreatestream objects from
   1188 // the spdy_session
   1189 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
   1190   // Construct the request.
   1191   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   1192   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   1193   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
   1194   scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
   1195 
   1196   scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
   1197   scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
   1198   scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
   1199   scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
   1200 
   1201   spdy::SpdySettings settings;
   1202   spdy::SettingsFlagsAndId id(0);
   1203   id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
   1204   const size_t max_concurrent_streams = 1;
   1205 
   1206   settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
   1207   scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings));
   1208 
   1209   MockWrite writes[] = { CreateMockWrite(*req),
   1210     CreateMockWrite(*req2),
   1211   };
   1212   MockRead reads[] = {
   1213     CreateMockRead(*settings_frame, 1),
   1214     CreateMockRead(*resp),
   1215     CreateMockRead(*body),
   1216     CreateMockRead(*fbody),
   1217     CreateMockRead(*resp2, 7),
   1218     CreateMockRead(*body2),
   1219     CreateMockRead(*fbody2),
   1220     MockRead(true, 0, 0),  // EOF
   1221   };
   1222 
   1223   scoped_refptr<OrderedSocketData> data(
   1224       new OrderedSocketData(reads, arraysize(reads),
   1225         writes, arraysize(writes)));
   1226   scoped_refptr<OrderedSocketData> data_placeholder(
   1227       new OrderedSocketData(NULL, 0, NULL, 0));
   1228 
   1229   BoundNetLog log;
   1230   TransactionHelperResult out;
   1231   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   1232       BoundNetLog(), GetParam());
   1233   helper.RunPreTestSetup();
   1234   helper.AddData(data.get());
   1235   // We require placeholder data because three get requests are sent out, so
   1236   // there needs to be three sets of SSL connection data.
   1237   helper.AddData(data_placeholder.get());
   1238   helper.AddData(data_placeholder.get());
   1239   scoped_ptr<HttpNetworkTransaction> trans1(
   1240       new HttpNetworkTransaction(helper.session()));
   1241   scoped_ptr<HttpNetworkTransaction> trans2(
   1242       new HttpNetworkTransaction(helper.session()));
   1243   scoped_ptr<HttpNetworkTransaction> trans3(
   1244       new HttpNetworkTransaction(helper.session()));
   1245 
   1246   TestCompletionCallback callback1;
   1247   TestCompletionCallback callback2;
   1248   TestCompletionCallback callback3;
   1249 
   1250   HttpRequestInfo httpreq1 = CreateGetRequest();
   1251   HttpRequestInfo httpreq2 = CreateGetRequest();
   1252   HttpRequestInfo httpreq3 = CreateGetRequest();
   1253 
   1254   out.rv = trans1->Start(&httpreq1, &callback1, log);
   1255   ASSERT_EQ(out.rv, ERR_IO_PENDING);
   1256   // run transaction 1 through quickly to force a read of our SETTINGS
   1257   // frame
   1258   out.rv = callback1.WaitForResult();
   1259   ASSERT_EQ(OK, out.rv);
   1260 
   1261   out.rv = trans2->Start(&httpreq2, &callback2, log);
   1262   ASSERT_EQ(out.rv, ERR_IO_PENDING);
   1263   out.rv = trans3->Start(&httpreq3, &callback3, log);
   1264   delete trans3.release();
   1265   ASSERT_EQ(out.rv, ERR_IO_PENDING);
   1266   out.rv = callback2.WaitForResult();
   1267   ASSERT_EQ(OK, out.rv);
   1268 
   1269   EXPECT_EQ(8U, data->read_index());
   1270 
   1271   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
   1272   ASSERT_TRUE(response1 != NULL);
   1273   EXPECT_TRUE(response1->headers != NULL);
   1274   EXPECT_TRUE(response1->was_fetched_via_spdy);
   1275   out.status_line = response1->headers->GetStatusLine();
   1276   out.response_info = *response1;
   1277   out.rv = ReadTransaction(trans1.get(), &out.response_data);
   1278   EXPECT_EQ(OK, out.rv);
   1279   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1280   EXPECT_EQ("hello!hello!", out.response_data);
   1281 
   1282   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
   1283   ASSERT_TRUE(response2 != NULL);
   1284   out.status_line = response2->headers->GetStatusLine();
   1285   out.response_info = *response2;
   1286   out.rv = ReadTransaction(trans2.get(), &out.response_data);
   1287   EXPECT_EQ(OK, out.rv);
   1288   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1289   EXPECT_EQ("hello!hello!", out.response_data);
   1290   helper.VerifyDataConsumed();
   1291   EXPECT_EQ(OK, out.rv);
   1292 }
   1293 
   1294 // The KillerCallback will delete the transaction on error as part of the
   1295 // callback.
   1296 class KillerCallback : public TestCompletionCallback {
   1297  public:
   1298   explicit KillerCallback(HttpNetworkTransaction* transaction)
   1299       : transaction_(transaction) {}
   1300 
   1301   virtual void RunWithParams(const Tuple1<int>& params) {
   1302     if (params.a < 0)
   1303       delete transaction_;
   1304     TestCompletionCallback::RunWithParams(params);
   1305   }
   1306 
   1307  private:
   1308   HttpNetworkTransaction* transaction_;
   1309 };
   1310 
   1311 // Similar to ThreeGetsMaxConcurrrentDelete above, however, this test
   1312 // closes the socket while we have a pending transaction waiting for
   1313 // a pending stream creation.  http://crbug.com/52901
   1314 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) {
   1315   // Construct the request.
   1316   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   1317   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   1318   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false));
   1319   scoped_ptr<spdy::SpdyFrame> fin_body(ConstructSpdyBodyFrame(1, true));
   1320 
   1321   scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
   1322   scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
   1323 
   1324   spdy::SpdySettings settings;
   1325   spdy::SettingsFlagsAndId id(0);
   1326   id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
   1327   const size_t max_concurrent_streams = 1;
   1328 
   1329   settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
   1330   scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings));
   1331 
   1332   MockWrite writes[] = { CreateMockWrite(*req),
   1333     CreateMockWrite(*req2),
   1334   };
   1335   MockRead reads[] = {
   1336     CreateMockRead(*settings_frame, 1),
   1337     CreateMockRead(*resp),
   1338     CreateMockRead(*body),
   1339     CreateMockRead(*fin_body),
   1340     CreateMockRead(*resp2, 7),
   1341     MockRead(true, ERR_CONNECTION_RESET, 0),  // Abort!
   1342   };
   1343 
   1344   scoped_refptr<OrderedSocketData> data(
   1345       new OrderedSocketData(reads, arraysize(reads),
   1346         writes, arraysize(writes)));
   1347   scoped_refptr<OrderedSocketData> data_placeholder(
   1348       new OrderedSocketData(NULL, 0, NULL, 0));
   1349 
   1350   BoundNetLog log;
   1351   TransactionHelperResult out;
   1352   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   1353       BoundNetLog(), GetParam());
   1354   helper.RunPreTestSetup();
   1355   helper.AddData(data.get());
   1356   // We require placeholder data because three get requests are sent out, so
   1357   // there needs to be three sets of SSL connection data.
   1358   helper.AddData(data_placeholder.get());
   1359   helper.AddData(data_placeholder.get());
   1360   HttpNetworkTransaction trans1(helper.session());
   1361   HttpNetworkTransaction trans2(helper.session());
   1362   HttpNetworkTransaction* trans3(new HttpNetworkTransaction(helper.session()));
   1363 
   1364   TestCompletionCallback callback1;
   1365   TestCompletionCallback callback2;
   1366   KillerCallback callback3(trans3);
   1367 
   1368   HttpRequestInfo httpreq1 = CreateGetRequest();
   1369   HttpRequestInfo httpreq2 = CreateGetRequest();
   1370   HttpRequestInfo httpreq3 = CreateGetRequest();
   1371 
   1372   out.rv = trans1.Start(&httpreq1, &callback1, log);
   1373   ASSERT_EQ(out.rv, ERR_IO_PENDING);
   1374   // run transaction 1 through quickly to force a read of our SETTINGS
   1375   // frame
   1376   out.rv = callback1.WaitForResult();
   1377   ASSERT_EQ(OK, out.rv);
   1378 
   1379   out.rv = trans2.Start(&httpreq2, &callback2, log);
   1380   ASSERT_EQ(out.rv, ERR_IO_PENDING);
   1381   out.rv = trans3->Start(&httpreq3, &callback3, log);
   1382   ASSERT_EQ(out.rv, ERR_IO_PENDING);
   1383   out.rv = callback3.WaitForResult();
   1384   ASSERT_EQ(ERR_ABORTED, out.rv);
   1385 
   1386   EXPECT_EQ(6U, data->read_index());
   1387 
   1388   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
   1389   ASSERT_TRUE(response1 != NULL);
   1390   EXPECT_TRUE(response1->headers != NULL);
   1391   EXPECT_TRUE(response1->was_fetched_via_spdy);
   1392   out.status_line = response1->headers->GetStatusLine();
   1393   out.response_info = *response1;
   1394   out.rv = ReadTransaction(&trans1, &out.response_data);
   1395   EXPECT_EQ(OK, out.rv);
   1396 
   1397   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
   1398   ASSERT_TRUE(response2 != NULL);
   1399   out.status_line = response2->headers->GetStatusLine();
   1400   out.response_info = *response2;
   1401   out.rv = ReadTransaction(&trans2, &out.response_data);
   1402   EXPECT_EQ(ERR_CONNECTION_RESET, out.rv);
   1403 
   1404   helper.VerifyDataConsumed();
   1405 }
   1406 
   1407 // Test that a simple PUT request works.
   1408 TEST_P(SpdyNetworkTransactionTest, Put) {
   1409   // Setup the request
   1410   HttpRequestInfo request;
   1411   request.method = "PUT";
   1412   request.url = GURL("http://www.google.com/");
   1413 
   1414   const SpdyHeaderInfo kSynStartHeader = {
   1415     spdy::SYN_STREAM,             // Kind = Syn
   1416     1,                            // Stream ID
   1417     0,                            // Associated stream ID
   1418     net::ConvertRequestPriorityToSpdyPriority(LOWEST),  // Priority
   1419     spdy::CONTROL_FLAG_FIN,       // Control Flags
   1420     false,                        // Compressed
   1421     spdy::INVALID,                // Status
   1422     NULL,                         // Data
   1423     0,                            // Length
   1424     spdy::DATA_FLAG_NONE          // Data Flags
   1425   };
   1426   const char* const kPutHeaders[] = {
   1427     "method", "PUT",
   1428     "url", "/",
   1429     "host", "www.google.com",
   1430     "scheme", "http",
   1431     "version", "HTTP/1.1",
   1432     "content-length", "0"
   1433   };
   1434   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPacket(kSynStartHeader, NULL, 0,
   1435     kPutHeaders, arraysize(kPutHeaders) / 2));
   1436   MockWrite writes[] = {
   1437     CreateMockWrite(*req)
   1438   };
   1439 
   1440   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   1441   const SpdyHeaderInfo kSynReplyHeader = {
   1442     spdy::SYN_REPLY,              // Kind = SynReply
   1443     1,                            // Stream ID
   1444     0,                            // Associated stream ID
   1445     net::ConvertRequestPriorityToSpdyPriority(LOWEST),  // Priority
   1446     spdy::CONTROL_FLAG_NONE,      // Control Flags
   1447     false,                        // Compressed
   1448     spdy::INVALID,                // Status
   1449     NULL,                         // Data
   1450     0,                            // Length
   1451     spdy::DATA_FLAG_NONE          // Data Flags
   1452   };
   1453   static const char* const kStandardGetHeaders[] = {
   1454     "status", "200",
   1455     "version", "HTTP/1.1"
   1456     "content-length", "1234"
   1457   };
   1458   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPacket(kSynReplyHeader,
   1459       NULL, 0, kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2));
   1460   MockRead reads[] = {
   1461     CreateMockRead(*resp),
   1462     CreateMockRead(*body),
   1463     MockRead(true, 0, 0)  // EOF
   1464   };
   1465 
   1466   scoped_refptr<DelayedSocketData> data(
   1467       new DelayedSocketData(1, reads, arraysize(reads),
   1468                             writes, arraysize(writes)));
   1469   NormalSpdyTransactionHelper helper(request,
   1470                                      BoundNetLog(), GetParam());
   1471   helper.RunToCompletion(data.get());
   1472   TransactionHelperResult out = helper.output();
   1473 
   1474   EXPECT_EQ(OK, out.rv);
   1475   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1476 }
   1477 
   1478 // Test that a simple HEAD request works.
   1479 TEST_P(SpdyNetworkTransactionTest, Head) {
   1480   // Setup the request
   1481   HttpRequestInfo request;
   1482   request.method = "HEAD";
   1483   request.url = GURL("http://www.google.com/");
   1484 
   1485   const SpdyHeaderInfo kSynStartHeader = {
   1486     spdy::SYN_STREAM,             // Kind = Syn
   1487     1,                            // Stream ID
   1488     0,                            // Associated stream ID
   1489     net::ConvertRequestPriorityToSpdyPriority(LOWEST),  // Priority
   1490     spdy::CONTROL_FLAG_FIN,       // Control Flags
   1491     false,                        // Compressed
   1492     spdy::INVALID,                // Status
   1493     NULL,                         // Data
   1494     0,                            // Length
   1495     spdy::DATA_FLAG_NONE          // Data Flags
   1496   };
   1497   const char* const kHeadHeaders[] = {
   1498     "method", "HEAD",
   1499     "url", "/",
   1500     "host", "www.google.com",
   1501     "scheme", "http",
   1502     "version", "HTTP/1.1",
   1503     "content-length", "0"
   1504   };
   1505   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPacket(kSynStartHeader, NULL, 0,
   1506     kHeadHeaders, arraysize(kHeadHeaders) / 2));
   1507   MockWrite writes[] = {
   1508     CreateMockWrite(*req)
   1509   };
   1510 
   1511   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   1512   const SpdyHeaderInfo kSynReplyHeader = {
   1513     spdy::SYN_REPLY,              // Kind = SynReply
   1514     1,                            // Stream ID
   1515     0,                            // Associated stream ID
   1516     net::ConvertRequestPriorityToSpdyPriority(LOWEST),  // Priority
   1517     spdy::CONTROL_FLAG_NONE,      // Control Flags
   1518     false,                        // Compressed
   1519     spdy::INVALID,                // Status
   1520     NULL,                         // Data
   1521     0,                            // Length
   1522     spdy::DATA_FLAG_NONE          // Data Flags
   1523   };
   1524   static const char* const kStandardGetHeaders[] = {
   1525     "status", "200",
   1526     "version", "HTTP/1.1"
   1527     "content-length", "1234"
   1528   };
   1529   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPacket(kSynReplyHeader,
   1530       NULL, 0, kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2));
   1531   MockRead reads[] = {
   1532     CreateMockRead(*resp),
   1533     CreateMockRead(*body),
   1534     MockRead(true, 0, 0)  // EOF
   1535   };
   1536 
   1537   scoped_refptr<DelayedSocketData> data(
   1538       new DelayedSocketData(1, reads, arraysize(reads),
   1539                             writes, arraysize(writes)));
   1540   NormalSpdyTransactionHelper helper(request,
   1541                                      BoundNetLog(), GetParam());
   1542   helper.RunToCompletion(data.get());
   1543   TransactionHelperResult out = helper.output();
   1544 
   1545   EXPECT_EQ(OK, out.rv);
   1546   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1547 }
   1548 
   1549 // Test that a simple POST works.
   1550 TEST_P(SpdyNetworkTransactionTest, Post) {
   1551   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost(kUploadDataSize, NULL, 0));
   1552   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   1553   MockWrite writes[] = {
   1554     CreateMockWrite(*req),
   1555     CreateMockWrite(*body),  // POST upload frame
   1556   };
   1557 
   1558   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
   1559   MockRead reads[] = {
   1560     CreateMockRead(*resp),
   1561     CreateMockRead(*body),
   1562     MockRead(true, 0, 0)  // EOF
   1563   };
   1564 
   1565   scoped_refptr<DelayedSocketData> data(
   1566       new DelayedSocketData(2, reads, arraysize(reads),
   1567                             writes, arraysize(writes)));
   1568   NormalSpdyTransactionHelper helper(CreatePostRequest(),
   1569                                      BoundNetLog(), GetParam());
   1570   helper.RunToCompletion(data.get());
   1571   TransactionHelperResult out = helper.output();
   1572   EXPECT_EQ(OK, out.rv);
   1573   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1574   EXPECT_EQ("hello!", out.response_data);
   1575 }
   1576 
   1577 // Test that a chunked POST works.
   1578 TEST_P(SpdyNetworkTransactionTest, ChunkedPost) {
   1579   UploadDataStream::set_merge_chunks(false);
   1580   scoped_ptr<spdy::SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
   1581   scoped_ptr<spdy::SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
   1582   scoped_ptr<spdy::SpdyFrame> chunk2(ConstructSpdyBodyFrame(1, true));
   1583   MockWrite writes[] = {
   1584     CreateMockWrite(*req),
   1585     CreateMockWrite(*chunk1),
   1586     CreateMockWrite(*chunk2),
   1587   };
   1588 
   1589   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
   1590   MockRead reads[] = {
   1591     CreateMockRead(*resp),
   1592     CreateMockRead(*chunk1),
   1593     CreateMockRead(*chunk2),
   1594     MockRead(true, 0, 0)  // EOF
   1595   };
   1596 
   1597   scoped_refptr<DelayedSocketData> data(
   1598       new DelayedSocketData(2, reads, arraysize(reads),
   1599                             writes, arraysize(writes)));
   1600   NormalSpdyTransactionHelper helper(CreateChunkedPostRequest(),
   1601                                      BoundNetLog(), GetParam());
   1602   helper.RunToCompletion(data.get());
   1603   TransactionHelperResult out = helper.output();
   1604   EXPECT_EQ(OK, out.rv);
   1605   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1606   EXPECT_EQ("hello!hello!", out.response_data);
   1607 }
   1608 
   1609 // Test that a POST without any post data works.
   1610 TEST_P(SpdyNetworkTransactionTest, NullPost) {
   1611   // Setup the request
   1612   HttpRequestInfo request;
   1613   request.method = "POST";
   1614   request.url = GURL("http://www.google.com/");
   1615   // Create an empty UploadData.
   1616   request.upload_data = NULL;
   1617 
   1618   // When request.upload_data is NULL for post, content-length is
   1619   // expected to be 0.
   1620   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost(0, NULL, 0));
   1621   // Set the FIN bit since there will be no body.
   1622   req->set_flags(spdy::CONTROL_FLAG_FIN);
   1623   MockWrite writes[] = {
   1624     CreateMockWrite(*req),
   1625   };
   1626 
   1627   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
   1628   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   1629   MockRead reads[] = {
   1630     CreateMockRead(*resp),
   1631     CreateMockRead(*body),
   1632     MockRead(true, 0, 0)  // EOF
   1633   };
   1634 
   1635   scoped_refptr<DelayedSocketData> data(
   1636       new DelayedSocketData(1, reads, arraysize(reads),
   1637                             writes, arraysize(writes)));
   1638 
   1639   NormalSpdyTransactionHelper helper(request,
   1640                                      BoundNetLog(), GetParam());
   1641   helper.RunToCompletion(data.get());
   1642   TransactionHelperResult out = helper.output();
   1643   EXPECT_EQ(OK, out.rv);
   1644   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1645   EXPECT_EQ("hello!", out.response_data);
   1646 }
   1647 
   1648 // Test that a simple POST works.
   1649 TEST_P(SpdyNetworkTransactionTest, EmptyPost) {
   1650   // Setup the request
   1651   HttpRequestInfo request;
   1652   request.method = "POST";
   1653   request.url = GURL("http://www.google.com/");
   1654   // Create an empty UploadData.
   1655   request.upload_data = new UploadData();
   1656 
   1657   // Http POST Content-Length is using UploadDataStream::size().
   1658   // It is the same as request.upload_data->GetContentLength().
   1659   scoped_ptr<UploadDataStream> stream(UploadDataStream::Create(
   1660       request.upload_data, NULL));
   1661   ASSERT_EQ(request.upload_data->GetContentLength(), stream->size());
   1662 
   1663   scoped_ptr<spdy::SpdyFrame>
   1664       req(ConstructSpdyPost(request.upload_data->GetContentLength(), NULL, 0));
   1665   // Set the FIN bit since there will be no body.
   1666   req->set_flags(spdy::CONTROL_FLAG_FIN);
   1667   MockWrite writes[] = {
   1668     CreateMockWrite(*req),
   1669   };
   1670 
   1671   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
   1672   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   1673   MockRead reads[] = {
   1674     CreateMockRead(*resp),
   1675     CreateMockRead(*body),
   1676     MockRead(true, 0, 0)  // EOF
   1677   };
   1678 
   1679   scoped_refptr<DelayedSocketData> data(
   1680       new DelayedSocketData(1, reads, arraysize(reads),
   1681                             writes, arraysize(writes)));
   1682 
   1683   NormalSpdyTransactionHelper helper(request,
   1684                                      BoundNetLog(), GetParam());
   1685   helper.RunToCompletion(data.get());
   1686   TransactionHelperResult out = helper.output();
   1687   EXPECT_EQ(OK, out.rv);
   1688   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   1689   EXPECT_EQ("hello!", out.response_data);
   1690 }
   1691 
   1692 // While we're doing a post, the server sends back a SYN_REPLY.
   1693 TEST_P(SpdyNetworkTransactionTest, PostWithEarlySynReply) {
   1694   static const char upload[] = { "hello!" };
   1695 
   1696   // Setup the request
   1697   HttpRequestInfo request;
   1698   request.method = "POST";
   1699   request.url = GURL("http://www.google.com/");
   1700   request.upload_data = new UploadData();
   1701   request.upload_data->AppendBytes(upload, sizeof(upload));
   1702 
   1703   // Http POST Content-Length is using UploadDataStream::size().
   1704   // It is the same as request.upload_data->GetContentLength().
   1705   scoped_ptr<UploadDataStream> stream(UploadDataStream::Create(
   1706       request.upload_data, NULL));
   1707   ASSERT_EQ(request.upload_data->GetContentLength(), stream->size());
   1708   scoped_ptr<spdy::SpdyFrame> stream_reply(ConstructSpdyPostSynReply(NULL, 0));
   1709   scoped_ptr<spdy::SpdyFrame> stream_body(ConstructSpdyBodyFrame(1, true));
   1710   MockRead reads[] = {
   1711     CreateMockRead(*stream_reply, 2),
   1712     CreateMockRead(*stream_body, 3),
   1713     MockRead(false, 0, 0)  // EOF
   1714   };
   1715 
   1716   scoped_refptr<DelayedSocketData> data(
   1717       new DelayedSocketData(0, reads, arraysize(reads), NULL, 0));
   1718   NormalSpdyTransactionHelper helper(request,
   1719                                      BoundNetLog(), GetParam());
   1720   helper.RunPreTestSetup();
   1721   helper.AddData(data.get());
   1722   helper.RunDefaultTest();
   1723   helper.VerifyDataConsumed();
   1724 
   1725   TransactionHelperResult out = helper.output();
   1726   EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv);
   1727 }
   1728 
   1729 // The client upon cancellation tries to send a RST_STREAM frame. The mock
   1730 // socket causes the TCP write to return zero. This test checks that the client
   1731 // tries to queue up the RST_STREAM frame again.
   1732 TEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) {
   1733   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   1734   scoped_ptr<spdy::SpdyFrame> rst(
   1735       ConstructSpdyRstStream(1, spdy::CANCEL));
   1736   MockWrite writes[] = {
   1737     CreateMockWrite(*req.get(), 0, false),
   1738     MockWrite(false, 0, 0, 2),
   1739     CreateMockWrite(*rst.get(), 3, false),
   1740   };
   1741 
   1742   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   1743   MockRead reads[] = {
   1744     CreateMockRead(*resp.get(), 1, true),
   1745     MockRead(true, 0, 0, 4)  // EOF
   1746   };
   1747 
   1748   scoped_refptr<DeterministicSocketData> data(
   1749       new DeterministicSocketData(reads, arraysize(reads),
   1750                                   writes, arraysize(writes)));
   1751   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   1752                                      BoundNetLog(), GetParam());
   1753   helper.SetDeterministic();
   1754   helper.RunPreTestSetup();
   1755   helper.AddDeterministicData(data.get());
   1756   HttpNetworkTransaction* trans = helper.trans();
   1757 
   1758   TestCompletionCallback callback;
   1759   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   1760   EXPECT_EQ(ERR_IO_PENDING, rv);
   1761 
   1762   data->SetStop(2);
   1763   data->Run();
   1764   helper.ResetTrans();
   1765   data->SetStop(20);
   1766   data->Run();
   1767 
   1768   helper.VerifyDataConsumed();
   1769 }
   1770 
   1771 // Test that the transaction doesn't crash when we don't have a reply.
   1772 TEST_P(SpdyNetworkTransactionTest, ResponseWithoutSynReply) {
   1773   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   1774   MockRead reads[] = {
   1775     CreateMockRead(*body),
   1776     MockRead(true, 0, 0)  // EOF
   1777   };
   1778 
   1779   scoped_refptr<DelayedSocketData> data(
   1780       new DelayedSocketData(1, reads, arraysize(reads), NULL, 0));
   1781   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   1782                                      BoundNetLog(), GetParam());
   1783   helper.RunToCompletion(data.get());
   1784   TransactionHelperResult out = helper.output();
   1785   EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv);
   1786 }
   1787 
   1788 // Test that the transaction doesn't crash when we get two replies on the same
   1789 // stream ID. See http://crbug.com/45639.
   1790 TEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) {
   1791   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   1792   MockWrite writes[] = { CreateMockWrite(*req) };
   1793 
   1794   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   1795   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   1796   MockRead reads[] = {
   1797     CreateMockRead(*resp),
   1798     CreateMockRead(*resp),
   1799     CreateMockRead(*body),
   1800     MockRead(true, 0, 0)  // EOF
   1801   };
   1802 
   1803   scoped_refptr<DelayedSocketData> data(
   1804       new DelayedSocketData(1, reads, arraysize(reads),
   1805                             writes, arraysize(writes)));
   1806 
   1807   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   1808                                      BoundNetLog(), GetParam());
   1809   helper.RunPreTestSetup();
   1810   helper.AddData(data.get());
   1811 
   1812   HttpNetworkTransaction* trans = helper.trans();
   1813 
   1814   TestCompletionCallback callback;
   1815   int rv = trans->Start(&helper.request(), &callback, BoundNetLog());
   1816   EXPECT_EQ(ERR_IO_PENDING, rv);
   1817   rv = callback.WaitForResult();
   1818   EXPECT_EQ(OK, rv);
   1819 
   1820   const HttpResponseInfo* response = trans->GetResponseInfo();
   1821   ASSERT_TRUE(response != NULL);
   1822   EXPECT_TRUE(response->headers != NULL);
   1823   EXPECT_TRUE(response->was_fetched_via_spdy);
   1824   std::string response_data;
   1825   rv = ReadTransaction(trans, &response_data);
   1826   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
   1827 
   1828   helper.VerifyDataConsumed();
   1829 }
   1830 
   1831 // Test that sent data frames and received WINDOW_UPDATE frames change
   1832 // the send_window_size_ correctly.
   1833 
   1834 // WINDOW_UPDATE is different than most other frames in that it can arrive
   1835 // while the client is still sending the request body.  In order to enforce
   1836 // this scenario, we feed a couple of dummy frames and give a delay of 0 to
   1837 // socket data provider, so that initial read that is done as soon as the
   1838 // stream is created, succeeds and schedules another read.  This way reads
   1839 // and writes are interleaved; after doing a full frame write, SpdyStream
   1840 // will break out of DoLoop and will read and process a WINDOW_UPDATE.
   1841 // Once our WINDOW_UPDATE is read, we cannot send SYN_REPLY right away
   1842 // since request has not been completely written, therefore we feed
   1843 // enough number of WINDOW_UPDATEs to finish the first read and cause a
   1844 // write, leading to a complete write of request body; after that we send
   1845 // a reply with a body, to cause a graceful shutdown.
   1846 
   1847 // TODO(agayev): develop a socket data provider where both, reads and
   1848 // writes are ordered so that writing tests like these are easy and rewrite
   1849 // all these tests using it.  Right now we are working around the
   1850 // limitations as described above and it's not deterministic, tests may
   1851 // fail under specific circumstances.
   1852 TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
   1853   SpdySession::set_flow_control(true);
   1854 
   1855   static int kFrameCount = 2;
   1856   scoped_ptr<std::string> content(
   1857       new std::string(kMaxSpdyFrameChunkSize, 'a'));
   1858   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost(
   1859       kMaxSpdyFrameChunkSize * kFrameCount, NULL, 0));
   1860   scoped_ptr<spdy::SpdyFrame> body(
   1861       ConstructSpdyBodyFrame(1, content->c_str(), content->size(), false));
   1862   scoped_ptr<spdy::SpdyFrame> body_end(
   1863       ConstructSpdyBodyFrame(1, content->c_str(), content->size(), true));
   1864 
   1865   MockWrite writes[] = {
   1866     CreateMockWrite(*req),
   1867     CreateMockWrite(*body),
   1868     CreateMockWrite(*body_end),
   1869   };
   1870 
   1871   static const int kDeltaWindowSize = 0xff;
   1872   static const int kDeltaCount = 4;
   1873   scoped_ptr<spdy::SpdyFrame> window_update(
   1874       ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
   1875   scoped_ptr<spdy::SpdyFrame> window_update_dummy(
   1876       ConstructSpdyWindowUpdate(2, kDeltaWindowSize));
   1877   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
   1878   MockRead reads[] = {
   1879     CreateMockRead(*window_update_dummy),
   1880     CreateMockRead(*window_update_dummy),
   1881     CreateMockRead(*window_update_dummy),
   1882     CreateMockRead(*window_update),     // Four updates, therefore window
   1883     CreateMockRead(*window_update),     // size should increase by
   1884     CreateMockRead(*window_update),     // kDeltaWindowSize * 4
   1885     CreateMockRead(*window_update),
   1886     CreateMockRead(*resp),
   1887     CreateMockRead(*body_end),
   1888     MockRead(true, 0, 0)  // EOF
   1889   };
   1890 
   1891   scoped_refptr<DelayedSocketData> data(
   1892       new DelayedSocketData(0, reads, arraysize(reads),
   1893                             writes, arraysize(writes)));
   1894 
   1895   // Setup the request
   1896   HttpRequestInfo request;
   1897   request.method = "POST";
   1898   request.url = GURL(kDefaultURL);
   1899   request.upload_data = new UploadData();
   1900   for (int i = 0; i < kFrameCount; ++i)
   1901     request.upload_data->AppendBytes(content->c_str(), content->size());
   1902 
   1903   NormalSpdyTransactionHelper helper(request, BoundNetLog(), GetParam());
   1904   helper.AddData(data.get());
   1905   helper.RunPreTestSetup();
   1906 
   1907   HttpNetworkTransaction* trans = helper.trans();
   1908 
   1909   TestCompletionCallback callback;
   1910   int rv = trans->Start(&helper.request(), &callback, BoundNetLog());
   1911 
   1912   EXPECT_EQ(ERR_IO_PENDING, rv);
   1913   rv = callback.WaitForResult();
   1914   EXPECT_EQ(OK, rv);
   1915 
   1916   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
   1917   ASSERT_TRUE(stream != NULL);
   1918   ASSERT_TRUE(stream->stream() != NULL);
   1919   EXPECT_EQ(static_cast<int>(spdy::kSpdyStreamInitialWindowSize) +
   1920             kDeltaWindowSize * kDeltaCount -
   1921             kMaxSpdyFrameChunkSize * kFrameCount,
   1922             stream->stream()->send_window_size());
   1923   helper.VerifyDataConsumed();
   1924   SpdySession::set_flow_control(false);
   1925 }
   1926 
   1927 // Test that received data frames and sent WINDOW_UPDATE frames change
   1928 // the recv_window_size_ correctly.
   1929 TEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) {
   1930   SpdySession::set_flow_control(true);
   1931 
   1932   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   1933   scoped_ptr<spdy::SpdyFrame> window_update(
   1934       ConstructSpdyWindowUpdate(1, kUploadDataSize));
   1935 
   1936   MockWrite writes[] = {
   1937     CreateMockWrite(*req),
   1938     CreateMockWrite(*window_update),
   1939   };
   1940 
   1941   scoped_ptr<spdy::SpdyFrame> resp(
   1942       ConstructSpdyGetSynReply(NULL, 0, 1));
   1943   scoped_ptr<spdy::SpdyFrame> body_no_fin(
   1944       ConstructSpdyBodyFrame(1, false));
   1945   scoped_ptr<spdy::SpdyFrame> body_fin(
   1946       ConstructSpdyBodyFrame(1, NULL, 0, true));
   1947   MockRead reads[] = {
   1948     CreateMockRead(*resp),
   1949     CreateMockRead(*body_no_fin),
   1950     MockRead(true, ERR_IO_PENDING, 0),  // Force a pause
   1951     CreateMockRead(*body_fin),
   1952     MockRead(true, ERR_IO_PENDING, 0),  // Force a pause
   1953     MockRead(true, 0, 0)  // EOF
   1954   };
   1955 
   1956   scoped_refptr<DelayedSocketData> data(
   1957       new DelayedSocketData(1, reads, arraysize(reads),
   1958                             writes, arraysize(writes)));
   1959 
   1960   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   1961                                      BoundNetLog(), GetParam());
   1962   helper.AddData(data.get());
   1963   helper.RunPreTestSetup();
   1964   HttpNetworkTransaction* trans = helper.trans();
   1965 
   1966   TestCompletionCallback callback;
   1967   int rv = trans->Start(&helper.request(), &callback, BoundNetLog());
   1968 
   1969   EXPECT_EQ(ERR_IO_PENDING, rv);
   1970   rv = callback.WaitForResult();
   1971   EXPECT_EQ(OK, rv);
   1972 
   1973   SpdyHttpStream* stream =
   1974       static_cast<SpdyHttpStream*>(trans->stream_.get());
   1975   ASSERT_TRUE(stream != NULL);
   1976   ASSERT_TRUE(stream->stream() != NULL);
   1977 
   1978   EXPECT_EQ(
   1979       static_cast<int>(spdy::kSpdyStreamInitialWindowSize) - kUploadDataSize,
   1980       stream->stream()->recv_window_size());
   1981 
   1982   const HttpResponseInfo* response = trans->GetResponseInfo();
   1983   ASSERT_TRUE(response != NULL);
   1984   ASSERT_TRUE(response->headers != NULL);
   1985   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1986   EXPECT_TRUE(response->was_fetched_via_spdy);
   1987 
   1988   // Issue a read which will cause a WINDOW_UPDATE to be sent and window
   1989   // size increased to default.
   1990   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kUploadDataSize));
   1991   rv = trans->Read(buf, kUploadDataSize, NULL);
   1992   EXPECT_EQ(kUploadDataSize, rv);
   1993   std::string content(buf->data(), buf->data()+kUploadDataSize);
   1994   EXPECT_STREQ(kUploadData, content.c_str());
   1995 
   1996   // Schedule the reading of empty data frame with FIN
   1997   data->CompleteRead();
   1998 
   1999   // Force write of WINDOW_UPDATE which was scheduled during the above
   2000   // read.
   2001   MessageLoop::current()->RunAllPending();
   2002 
   2003   // Read EOF.
   2004   data->CompleteRead();
   2005 
   2006   helper.VerifyDataConsumed();
   2007   SpdySession::set_flow_control(false);
   2008 }
   2009 
   2010 // Test that WINDOW_UPDATE frame causing overflow is handled correctly.  We
   2011 // use the same trick as in the above test to enforce our scenario.
   2012 TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
   2013   SpdySession::set_flow_control(true);
   2014 
   2015   // number of full frames we hope to write (but will not, used to
   2016   // set content-length header correctly)
   2017   static int kFrameCount = 3;
   2018 
   2019   scoped_ptr<std::string> content(
   2020       new std::string(kMaxSpdyFrameChunkSize, 'a'));
   2021   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost(
   2022       kMaxSpdyFrameChunkSize * kFrameCount, NULL, 0));
   2023   scoped_ptr<spdy::SpdyFrame> body(
   2024       ConstructSpdyBodyFrame(1, content->c_str(), content->size(), false));
   2025   scoped_ptr<spdy::SpdyFrame> rst(
   2026       ConstructSpdyRstStream(1, spdy::FLOW_CONTROL_ERROR));
   2027 
   2028   // We're not going to write a data frame with FIN, we'll receive a bad
   2029   // WINDOW_UPDATE while sending a request and will send a RST_STREAM frame.
   2030   MockWrite writes[] = {
   2031     CreateMockWrite(*req),
   2032     CreateMockWrite(*body),
   2033     CreateMockWrite(*rst),
   2034   };
   2035 
   2036   static const int kDeltaWindowSize = 0x7fffffff;  // cause an overflow
   2037   scoped_ptr<spdy::SpdyFrame> window_update(
   2038       ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
   2039   scoped_ptr<spdy::SpdyFrame> window_update2(
   2040       ConstructSpdyWindowUpdate(2, kDeltaWindowSize));
   2041   scoped_ptr<spdy::SpdyFrame> reply(ConstructSpdyPostSynReply(NULL, 0));
   2042 
   2043   MockRead reads[] = {
   2044     CreateMockRead(*window_update2),
   2045     CreateMockRead(*window_update2),
   2046     CreateMockRead(*window_update),
   2047     CreateMockRead(*window_update),
   2048     CreateMockRead(*window_update),
   2049     MockRead(true, ERR_IO_PENDING, 0),  // Wait for the RST to be written.
   2050     MockRead(true, 0, 0)  // EOF
   2051   };
   2052 
   2053   scoped_refptr<DelayedSocketData> data(
   2054       new DelayedSocketData(0, reads, arraysize(reads),
   2055                             writes, arraysize(writes)));
   2056 
   2057   // Setup the request
   2058   HttpRequestInfo request;
   2059   request.method = "POST";
   2060   request.url = GURL("http://www.google.com/");
   2061   request.upload_data = new UploadData();
   2062   for (int i = 0; i < kFrameCount; ++i)
   2063     request.upload_data->AppendBytes(content->c_str(), content->size());
   2064 
   2065   NormalSpdyTransactionHelper helper(request,
   2066                                      BoundNetLog(), GetParam());
   2067   helper.AddData(data.get());
   2068   helper.RunPreTestSetup();
   2069 
   2070   HttpNetworkTransaction* trans = helper.trans();
   2071 
   2072   TestCompletionCallback callback;
   2073   int rv = trans->Start(&helper.request(), &callback, BoundNetLog());
   2074 
   2075   EXPECT_EQ(ERR_IO_PENDING, rv);
   2076   rv = callback.WaitForResult();
   2077   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
   2078 
   2079   data->CompleteRead();
   2080 
   2081   ASSERT_TRUE(helper.session() != NULL);
   2082   ASSERT_TRUE(helper.session()->spdy_session_pool() != NULL);
   2083   helper.session()->spdy_session_pool()->CloseAllSessions();
   2084   helper.VerifyDataConsumed();
   2085 
   2086   SpdySession::set_flow_control(false);
   2087 }
   2088 
   2089 // Test that after hitting a send window size of 0, the write process
   2090 // stalls and upon receiving WINDOW_UPDATE frame write resumes.
   2091 
   2092 // This test constructs a POST request followed by enough data frames
   2093 // containing 'a' that would make the window size 0, followed by another
   2094 // data frame containing default content (which is "hello!") and this frame
   2095 // also contains a FIN flag.  DelayedSocketData is used to enforce all
   2096 // writes go through before a read could happen.  However, the last frame
   2097 // ("hello!")  is not supposed to go through since by the time its turn
   2098 // arrives, window size is 0.  At this point MessageLoop::Run() called via
   2099 // callback would block.  Therefore we call MessageLoop::RunAllPending()
   2100 // which returns after performing all possible writes.  We use DCHECKS to
   2101 // ensure that last data frame is still there and stream has stalled.
   2102 // After that, next read is artifically enforced, which causes a
   2103 // WINDOW_UPDATE to be read and I/O process resumes.
   2104 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) {
   2105   SpdySession::set_flow_control(true);
   2106 
   2107   // Number of frames we need to send to zero out the window size: data
   2108   // frames plus SYN_STREAM plus the last data frame; also we need another
   2109   // data frame that we will send once the WINDOW_UPDATE is received,
   2110   // therefore +3.
   2111   size_t nwrites =
   2112       spdy::kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
   2113 
   2114   // Calculate last frame's size; 0 size data frame is legal.
   2115   size_t last_frame_size =
   2116       spdy::kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
   2117 
   2118   // Construct content for a data frame of maximum size.
   2119   scoped_ptr<std::string> content(
   2120       new std::string(kMaxSpdyFrameChunkSize, 'a'));
   2121 
   2122   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost(
   2123       spdy::kSpdyStreamInitialWindowSize + kUploadDataSize, NULL, 0));
   2124 
   2125   // Full frames.
   2126   scoped_ptr<spdy::SpdyFrame> body1(
   2127       ConstructSpdyBodyFrame(1, content->c_str(), content->size(), false));
   2128 
   2129   // Last frame to zero out the window size.
   2130   scoped_ptr<spdy::SpdyFrame> body2(
   2131       ConstructSpdyBodyFrame(1, content->c_str(), last_frame_size, false));
   2132 
   2133   // Data frame to be sent once WINDOW_UPDATE frame is received.
   2134   scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(1, true));
   2135 
   2136   // Fill in mock writes.
   2137   scoped_array<MockWrite> writes(new MockWrite[nwrites]);
   2138   size_t i = 0;
   2139   writes[i] = CreateMockWrite(*req);
   2140   for (i = 1; i < nwrites-2; i++)
   2141     writes[i] = CreateMockWrite(*body1);
   2142   writes[i++] = CreateMockWrite(*body2);
   2143   writes[i] = CreateMockWrite(*body3);
   2144 
   2145   // Construct read frame, give enough space to upload the rest of the
   2146   // data.
   2147   scoped_ptr<spdy::SpdyFrame> window_update(
   2148       ConstructSpdyWindowUpdate(1, kUploadDataSize));
   2149   scoped_ptr<spdy::SpdyFrame> reply(ConstructSpdyPostSynReply(NULL, 0));
   2150   MockRead reads[] = {
   2151     CreateMockRead(*window_update),
   2152     CreateMockRead(*window_update),
   2153     CreateMockRead(*reply),
   2154     CreateMockRead(*body2),
   2155     CreateMockRead(*body3),
   2156     MockRead(true, 0, 0)  // EOF
   2157   };
   2158 
   2159   // Force all writes to happen before any read, last write will not
   2160   // actually queue a frame, due to window size being 0.
   2161   scoped_refptr<DelayedSocketData> data(
   2162       new DelayedSocketData(nwrites, reads, arraysize(reads),
   2163                             writes.get(), nwrites));
   2164 
   2165   HttpRequestInfo request;
   2166   request.method = "POST";
   2167   request.url = GURL("http://www.google.com/");
   2168   request.upload_data = new UploadData();
   2169   scoped_ptr<std::string> upload_data(
   2170       new std::string(spdy::kSpdyStreamInitialWindowSize, 'a'));
   2171   upload_data->append(kUploadData, kUploadDataSize);
   2172   request.upload_data->AppendBytes(upload_data->c_str(), upload_data->size());
   2173   NormalSpdyTransactionHelper helper(request,
   2174                                      BoundNetLog(), GetParam());
   2175   helper.AddData(data.get());
   2176   helper.RunPreTestSetup();
   2177 
   2178   HttpNetworkTransaction* trans = helper.trans();
   2179 
   2180   TestCompletionCallback callback;
   2181   int rv = trans->Start(&helper.request(), &callback, BoundNetLog());
   2182   EXPECT_EQ(ERR_IO_PENDING, rv);
   2183 
   2184   MessageLoop::current()->RunAllPending(); // Write as much as we can.
   2185 
   2186   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
   2187   ASSERT_TRUE(stream != NULL);
   2188   ASSERT_TRUE(stream->stream() != NULL);
   2189   EXPECT_EQ(0, stream->stream()->send_window_size());
   2190   EXPECT_FALSE(stream->request_body_stream_->eof());
   2191 
   2192   data->ForceNextRead();   // Read in WINDOW_UPDATE frame.
   2193   rv = callback.WaitForResult();
   2194   helper.VerifyDataConsumed();
   2195 
   2196   SpdySession::set_flow_control(false);
   2197 }
   2198 
   2199 TEST_P(SpdyNetworkTransactionTest, CancelledTransaction) {
   2200   // Construct the request.
   2201   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   2202   MockWrite writes[] = {
   2203     CreateMockWrite(*req),
   2204   };
   2205 
   2206   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   2207   MockRead reads[] = {
   2208     CreateMockRead(*resp),
   2209     // This following read isn't used by the test, except during the
   2210     // RunAllPending() call at the end since the SpdySession survives the
   2211     // HttpNetworkTransaction and still tries to continue Read()'ing.  Any
   2212     // MockRead will do here.
   2213     MockRead(true, 0, 0)  // EOF
   2214   };
   2215 
   2216   StaticSocketDataProvider data(reads, arraysize(reads),
   2217                                 writes, arraysize(writes));
   2218 
   2219   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   2220                                      BoundNetLog(), GetParam());
   2221   helper.RunPreTestSetup();
   2222   helper.AddData(&data);
   2223   HttpNetworkTransaction* trans = helper.trans();
   2224 
   2225   TestCompletionCallback callback;
   2226   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   2227   EXPECT_EQ(ERR_IO_PENDING, rv);
   2228   helper.ResetTrans();  // Cancel the transaction.
   2229 
   2230   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
   2231   // MockClientSocketFactory) are still alive.
   2232   MessageLoop::current()->RunAllPending();
   2233   helper.VerifyDataNotConsumed();
   2234 }
   2235 
   2236 // Verify that the client sends a Rst Frame upon cancelling the stream.
   2237 TEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) {
   2238   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   2239   scoped_ptr<spdy::SpdyFrame> rst(
   2240       ConstructSpdyRstStream(1, spdy::CANCEL));
   2241   MockWrite writes[] = {
   2242     CreateMockWrite(*req, 0, false),
   2243     CreateMockWrite(*rst, 2, false),
   2244   };
   2245 
   2246   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   2247   MockRead reads[] = {
   2248     CreateMockRead(*resp, 1, true),
   2249     MockRead(true, 0, 0, 3)  // EOF
   2250   };
   2251 
   2252   scoped_refptr<DeterministicSocketData> data(
   2253       new DeterministicSocketData(reads, arraysize(reads),
   2254                             writes, arraysize(writes)));
   2255 
   2256   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   2257                                      BoundNetLog(),
   2258                                      GetParam());
   2259   helper.SetDeterministic();
   2260   helper.RunPreTestSetup();
   2261   helper.AddDeterministicData(data.get());
   2262   HttpNetworkTransaction* trans = helper.trans();
   2263 
   2264   TestCompletionCallback callback;
   2265 
   2266   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   2267   EXPECT_EQ(ERR_IO_PENDING, rv);
   2268 
   2269   data->SetStop(2);
   2270   data->Run();
   2271   helper.ResetTrans();
   2272   data->SetStop(20);
   2273   data->Run();
   2274 
   2275   helper.VerifyDataConsumed();
   2276 }
   2277 
   2278 class SpdyNetworkTransactionTest::StartTransactionCallback
   2279     : public CallbackRunner< Tuple1<int> > {
   2280  public:
   2281   explicit StartTransactionCallback(
   2282       const scoped_refptr<HttpNetworkSession>& session,
   2283       NormalSpdyTransactionHelper& helper)
   2284       : session_(session), helper_(helper) {}
   2285 
   2286   // We try to start another transaction, which should succeed.
   2287   virtual void RunWithParams(const Tuple1<int>& params) {
   2288     scoped_ptr<HttpNetworkTransaction> trans(
   2289         new HttpNetworkTransaction(session_));
   2290     TestCompletionCallback callback;
   2291     HttpRequestInfo request;
   2292     request.method = "GET";
   2293     request.url = GURL("http://www.google.com/");
   2294     request.load_flags = 0;
   2295     int rv = trans->Start(&request, &callback, BoundNetLog());
   2296     EXPECT_EQ(ERR_IO_PENDING, rv);
   2297     rv = callback.WaitForResult();
   2298   }
   2299 
   2300  private:
   2301   const scoped_refptr<HttpNetworkSession>& session_;
   2302   NormalSpdyTransactionHelper& helper_;
   2303 };
   2304 
   2305 // Verify that the client can correctly deal with the user callback attempting
   2306 // to start another transaction on a session that is closing down. See
   2307 // http://crbug.com/47455
   2308 TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) {
   2309   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   2310   MockWrite writes[] = { CreateMockWrite(*req) };
   2311   MockWrite writes2[] = { CreateMockWrite(*req) };
   2312 
   2313   // The indicated length of this packet is longer than its actual length. When
   2314   // the session receives an empty packet after this one, it shuts down the
   2315   // session, and calls the read callback with the incomplete data.
   2316   const uint8 kGetBodyFrame2[] = {
   2317     0x00, 0x00, 0x00, 0x01,
   2318     0x01, 0x00, 0x00, 0x07,
   2319     'h', 'e', 'l', 'l', 'o', '!',
   2320   };
   2321 
   2322   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   2323   MockRead reads[] = {
   2324     CreateMockRead(*resp, 2),
   2325     MockRead(true, ERR_IO_PENDING, 3),  // Force a pause
   2326     MockRead(true, reinterpret_cast<const char*>(kGetBodyFrame2),
   2327              arraysize(kGetBodyFrame2), 4),
   2328     MockRead(true, ERR_IO_PENDING, 5),  // Force a pause
   2329     MockRead(true, 0, 0, 6),  // EOF
   2330   };
   2331   MockRead reads2[] = {
   2332     CreateMockRead(*resp, 2),
   2333     MockRead(true, 0, 0, 3),  // EOF
   2334   };
   2335 
   2336   scoped_refptr<OrderedSocketData> data(
   2337       new OrderedSocketData(reads, arraysize(reads),
   2338                             writes, arraysize(writes)));
   2339   scoped_refptr<DelayedSocketData> data2(
   2340       new DelayedSocketData(1, reads2, arraysize(reads2),
   2341                             writes2, arraysize(writes2)));
   2342 
   2343   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   2344                                      BoundNetLog(), GetParam());
   2345   helper.RunPreTestSetup();
   2346   helper.AddData(data.get());
   2347   helper.AddData(data2.get());
   2348   HttpNetworkTransaction* trans = helper.trans();
   2349 
   2350   // Start the transaction with basic parameters.
   2351   TestCompletionCallback callback;
   2352   int rv = trans->Start(&helper.request(), &callback, BoundNetLog());
   2353   EXPECT_EQ(ERR_IO_PENDING, rv);
   2354   rv = callback.WaitForResult();
   2355 
   2356   StartTransactionCallback callback2(helper.session(), helper);
   2357   const int kSize = 3000;
   2358   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
   2359   rv = trans->Read(buf, kSize, &callback2);
   2360   // This forces an err_IO_pending, which sets the callback.
   2361   data->CompleteRead();
   2362   // This finishes the read.
   2363   data->CompleteRead();
   2364   helper.VerifyDataConsumed();
   2365 }
   2366 
   2367 class SpdyNetworkTransactionTest::DeleteSessionCallback
   2368     : public CallbackRunner< Tuple1<int> > {
   2369  public:
   2370   explicit DeleteSessionCallback(NormalSpdyTransactionHelper& helper) :
   2371       helper_(helper) {}
   2372 
   2373   // We kill the transaction, which deletes the session and stream.
   2374   virtual void RunWithParams(const Tuple1<int>& params) {
   2375     helper_.ResetTrans();
   2376   }
   2377 
   2378  private:
   2379   NormalSpdyTransactionHelper& helper_;
   2380 };
   2381 
   2382 // Verify that the client can correctly deal with the user callback deleting the
   2383 // transaction. Failures will usually be valgrind errors. See
   2384 // http://crbug.com/46925
   2385 TEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) {
   2386   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   2387   MockWrite writes[] = { CreateMockWrite(*req) };
   2388 
   2389   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   2390   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   2391   MockRead reads[] = {
   2392     CreateMockRead(*resp.get(), 2),
   2393     MockRead(true, ERR_IO_PENDING, 3),  // Force a pause
   2394     CreateMockRead(*body.get(), 4),
   2395     MockRead(true, 0, 0, 5),  // EOF
   2396   };
   2397 
   2398   scoped_refptr<OrderedSocketData> data(
   2399       new OrderedSocketData(reads, arraysize(reads),
   2400                             writes, arraysize(writes)));
   2401 
   2402   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   2403                                      BoundNetLog(), GetParam());
   2404   helper.RunPreTestSetup();
   2405   helper.AddData(data.get());
   2406   HttpNetworkTransaction* trans = helper.trans();
   2407 
   2408   // Start the transaction with basic parameters.
   2409   TestCompletionCallback callback;
   2410   int rv = trans->Start(&helper.request(), &callback, BoundNetLog());
   2411   EXPECT_EQ(ERR_IO_PENDING, rv);
   2412   rv = callback.WaitForResult();
   2413 
   2414   // Setup a user callback which will delete the session, and clear out the
   2415   // memory holding the stream object. Note that the callback deletes trans.
   2416   DeleteSessionCallback callback2(helper);
   2417   const int kSize = 3000;
   2418   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
   2419   rv = trans->Read(buf, kSize, &callback2);
   2420   ASSERT_EQ(ERR_IO_PENDING, rv);
   2421   data->CompleteRead();
   2422 
   2423   // Finish running rest of tasks.
   2424   MessageLoop::current()->RunAllPending();
   2425   helper.VerifyDataConsumed();
   2426 }
   2427 
   2428 // Send a spdy request to www.google.com that gets redirected to www.foo.com.
   2429 TEST_P(SpdyNetworkTransactionTest, RedirectGetRequest) {
   2430   // These are headers which the net::URLRequest tacks on.
   2431   const char* const kExtraHeaders[] = {
   2432     "accept-encoding",
   2433     "gzip,deflate",
   2434   };
   2435   const SpdyHeaderInfo kSynStartHeader = make_spdy_header(spdy::SYN_STREAM);
   2436   const char* const kStandardGetHeaders[] = {
   2437     "host",
   2438     "www.google.com",
   2439     "method",
   2440     "GET",
   2441     "scheme",
   2442     "http",
   2443     "url",
   2444     "/",
   2445     "user-agent",
   2446     "",
   2447     "version",
   2448     "HTTP/1.1"
   2449   };
   2450   const char* const kStandardGetHeaders2[] = {
   2451     "host",
   2452     "www.foo.com",
   2453     "method",
   2454     "GET",
   2455     "scheme",
   2456     "http",
   2457     "url",
   2458     "/index.php",
   2459     "user-agent",
   2460     "",
   2461     "version",
   2462     "HTTP/1.1"
   2463   };
   2464 
   2465   // Setup writes/reads to www.google.com
   2466   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPacket(
   2467       kSynStartHeader, kExtraHeaders, arraysize(kExtraHeaders) / 2,
   2468       kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2));
   2469   scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyPacket(
   2470       kSynStartHeader, kExtraHeaders, arraysize(kExtraHeaders) / 2,
   2471       kStandardGetHeaders2, arraysize(kStandardGetHeaders2) / 2));
   2472   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReplyRedirect(1));
   2473   MockWrite writes[] = {
   2474     CreateMockWrite(*req, 1),
   2475   };
   2476   MockRead reads[] = {
   2477     CreateMockRead(*resp, 2),
   2478     MockRead(true, 0, 0, 3)  // EOF
   2479   };
   2480 
   2481   // Setup writes/reads to www.foo.com
   2482   scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
   2483   scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
   2484   MockWrite writes2[] = {
   2485     CreateMockWrite(*req2, 1),
   2486   };
   2487   MockRead reads2[] = {
   2488     CreateMockRead(*resp2, 2),
   2489     CreateMockRead(*body2, 3),
   2490     MockRead(true, 0, 0, 4)  // EOF
   2491   };
   2492   scoped_refptr<OrderedSocketData> data(
   2493       new OrderedSocketData(reads, arraysize(reads),
   2494                             writes, arraysize(writes)));
   2495   scoped_refptr<OrderedSocketData> data2(
   2496       new OrderedSocketData(reads2, arraysize(reads2),
   2497                             writes2, arraysize(writes2)));
   2498 
   2499   // TODO(erikchen): Make test support SPDYSSL, SPDYNPN
   2500   HttpStreamFactory::set_force_spdy_over_ssl(false);
   2501   HttpStreamFactory::set_force_spdy_always(true);
   2502   TestDelegate d;
   2503   {
   2504     net::URLRequest r(GURL("http://www.google.com/"), &d);
   2505     SpdyURLRequestContext* spdy_url_request_context =
   2506         new SpdyURLRequestContext();
   2507     r.set_context(spdy_url_request_context);
   2508     spdy_url_request_context->socket_factory().
   2509         AddSocketDataProvider(data.get());
   2510     spdy_url_request_context->socket_factory().
   2511         AddSocketDataProvider(data2.get());
   2512 
   2513     d.set_quit_on_redirect(true);
   2514     r.Start();
   2515     MessageLoop::current()->Run();
   2516 
   2517     EXPECT_EQ(1, d.received_redirect_count());
   2518 
   2519     r.FollowDeferredRedirect();
   2520     MessageLoop::current()->Run();
   2521     EXPECT_EQ(1, d.response_started_count());
   2522     EXPECT_FALSE(d.received_data_before_response());
   2523     EXPECT_EQ(net::URLRequestStatus::SUCCESS, r.status().status());
   2524     std::string contents("hello!");
   2525     EXPECT_EQ(contents, d.data_received());
   2526   }
   2527   EXPECT_TRUE(data->at_read_eof());
   2528   EXPECT_TRUE(data->at_write_eof());
   2529   EXPECT_TRUE(data2->at_read_eof());
   2530   EXPECT_TRUE(data2->at_write_eof());
   2531 }
   2532 
   2533 // Send a spdy request to www.google.com. Get a pushed stream that redirects to
   2534 // www.foo.com.
   2535 TEST_P(SpdyNetworkTransactionTest, RedirectServerPush) {
   2536   // These are headers which the net::URLRequest tacks on.
   2537   const char* const kExtraHeaders[] = {
   2538     "accept-encoding",
   2539     "gzip,deflate",
   2540   };
   2541   const SpdyHeaderInfo kSynStartHeader = make_spdy_header(spdy::SYN_STREAM);
   2542   const char* const kStandardGetHeaders[] = {
   2543     "host",
   2544     "www.google.com",
   2545     "method",
   2546     "GET",
   2547     "scheme",
   2548     "http",
   2549     "url",
   2550     "/",
   2551     "user-agent",
   2552     "",
   2553     "version",
   2554     "HTTP/1.1"
   2555   };
   2556 
   2557   // Setup writes/reads to www.google.com
   2558   scoped_ptr<spdy::SpdyFrame> req(
   2559       ConstructSpdyPacket(kSynStartHeader,
   2560                           kExtraHeaders,
   2561                           arraysize(kExtraHeaders) / 2,
   2562                           kStandardGetHeaders,
   2563                           arraysize(kStandardGetHeaders) / 2));
   2564   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   2565   scoped_ptr<spdy::SpdyFrame> rep(
   2566       ConstructSpdyPush(NULL,
   2567                         0,
   2568                         2,
   2569                         1,
   2570                         "http://www.google.com/foo.dat",
   2571                         "301 Moved Permanently",
   2572                         "http://www.foo.com/index.php"));
   2573   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   2574   scoped_ptr<spdy::SpdyFrame> rst(ConstructSpdyRstStream(2, spdy::CANCEL));
   2575   MockWrite writes[] = {
   2576     CreateMockWrite(*req, 1),
   2577     CreateMockWrite(*rst, 6),
   2578   };
   2579   MockRead reads[] = {
   2580     CreateMockRead(*resp, 2),
   2581     CreateMockRead(*rep, 3),
   2582     CreateMockRead(*body, 4),
   2583     MockRead(true, ERR_IO_PENDING, 5),  // Force a pause
   2584     MockRead(true, 0, 0, 7)  // EOF
   2585   };
   2586 
   2587   // Setup writes/reads to www.foo.com
   2588   const char* const kStandardGetHeaders2[] = {
   2589     "host",
   2590     "www.foo.com",
   2591     "method",
   2592     "GET",
   2593     "scheme",
   2594     "http",
   2595     "url",
   2596     "/index.php",
   2597     "user-agent",
   2598     "",
   2599     "version",
   2600     "HTTP/1.1"
   2601   };
   2602   scoped_ptr<spdy::SpdyFrame> req2(
   2603       ConstructSpdyPacket(kSynStartHeader,
   2604                           kExtraHeaders,
   2605                           arraysize(kExtraHeaders) / 2,
   2606                           kStandardGetHeaders2,
   2607                           arraysize(kStandardGetHeaders2) / 2));
   2608   scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
   2609   scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
   2610   MockWrite writes2[] = {
   2611     CreateMockWrite(*req2, 1),
   2612   };
   2613   MockRead reads2[] = {
   2614     CreateMockRead(*resp2, 2),
   2615     CreateMockRead(*body2, 3),
   2616     MockRead(true, 0, 0, 5)  // EOF
   2617   };
   2618   scoped_refptr<OrderedSocketData> data(
   2619       new OrderedSocketData(reads, arraysize(reads),
   2620                             writes, arraysize(writes)));
   2621   scoped_refptr<OrderedSocketData> data2(
   2622       new OrderedSocketData(reads2, arraysize(reads2),
   2623                             writes2, arraysize(writes2)));
   2624 
   2625   // TODO(erikchen): Make test support SPDYSSL, SPDYNPN
   2626   HttpStreamFactory::set_force_spdy_over_ssl(false);
   2627   HttpStreamFactory::set_force_spdy_always(true);
   2628   TestDelegate d;
   2629   TestDelegate d2;
   2630   scoped_refptr<SpdyURLRequestContext> spdy_url_request_context(
   2631       new SpdyURLRequestContext());
   2632   {
   2633     net::URLRequest r(GURL("http://www.google.com/"), &d);
   2634     r.set_context(spdy_url_request_context);
   2635     spdy_url_request_context->socket_factory().
   2636         AddSocketDataProvider(data.get());
   2637 
   2638     r.Start();
   2639     MessageLoop::current()->Run();
   2640 
   2641     EXPECT_EQ(0, d.received_redirect_count());
   2642     std::string contents("hello!");
   2643     EXPECT_EQ(contents, d.data_received());
   2644 
   2645     net::URLRequest r2(GURL("http://www.google.com/foo.dat"), &d2);
   2646     r2.set_context(spdy_url_request_context);
   2647     spdy_url_request_context->socket_factory().
   2648         AddSocketDataProvider(data2.get());
   2649 
   2650     d2.set_quit_on_redirect(true);
   2651     r2.Start();
   2652     MessageLoop::current()->Run();
   2653     EXPECT_EQ(1, d2.received_redirect_count());
   2654 
   2655     r2.FollowDeferredRedirect();
   2656     MessageLoop::current()->Run();
   2657     EXPECT_EQ(1, d2.response_started_count());
   2658     EXPECT_FALSE(d2.received_data_before_response());
   2659     EXPECT_EQ(net::URLRequestStatus::SUCCESS, r2.status().status());
   2660     std::string contents2("hello!");
   2661     EXPECT_EQ(contents2, d2.data_received());
   2662   }
   2663   data->CompleteRead();
   2664   data2->CompleteRead();
   2665   EXPECT_TRUE(data->at_read_eof());
   2666   EXPECT_TRUE(data->at_write_eof());
   2667   EXPECT_TRUE(data2->at_read_eof());
   2668   EXPECT_TRUE(data2->at_write_eof());
   2669 }
   2670 
   2671 TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) {
   2672   static const unsigned char kPushBodyFrame[] = {
   2673     0x00, 0x00, 0x00, 0x02,                                      // header, ID
   2674     0x01, 0x00, 0x00, 0x06,                                      // FIN, length
   2675     'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
   2676   };
   2677   scoped_ptr<spdy::SpdyFrame>
   2678       stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   2679   scoped_ptr<spdy::SpdyFrame>
   2680       stream1_body(ConstructSpdyBodyFrame(1, true));
   2681   MockWrite writes[] = {
   2682     CreateMockWrite(*stream1_syn, 1),
   2683   };
   2684 
   2685   scoped_ptr<spdy::SpdyFrame>
   2686       stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   2687   scoped_ptr<spdy::SpdyFrame>
   2688       stream2_syn(ConstructSpdyPush(NULL,
   2689                                     0,
   2690                                     2,
   2691                                     1,
   2692                                     "http://www.google.com/foo.dat"));
   2693   MockRead reads[] = {
   2694     CreateMockRead(*stream1_reply, 2),
   2695     CreateMockRead(*stream2_syn, 3),
   2696     CreateMockRead(*stream1_body, 4, false),
   2697     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame),
   2698              arraysize(kPushBodyFrame), 5),
   2699     MockRead(true, ERR_IO_PENDING, 6),  // Force a pause
   2700   };
   2701 
   2702   HttpResponseInfo response;
   2703   HttpResponseInfo response2;
   2704   std::string expected_push_result("pushed");
   2705   scoped_refptr<OrderedSocketData> data(new OrderedSocketData(
   2706       reads,
   2707       arraysize(reads),
   2708       writes,
   2709       arraysize(writes)));
   2710   RunServerPushTest(data.get(),
   2711                     &response,
   2712                     &response2,
   2713                     expected_push_result);
   2714 
   2715   // Verify the SYN_REPLY.
   2716   EXPECT_TRUE(response.headers != NULL);
   2717   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   2718 
   2719   // Verify the pushed stream.
   2720   EXPECT_TRUE(response2.headers != NULL);
   2721   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
   2722 }
   2723 
   2724 TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) {
   2725   static const unsigned char kPushBodyFrame[] = {
   2726     0x00, 0x00, 0x00, 0x02,                                      // header, ID
   2727     0x01, 0x00, 0x00, 0x06,                                      // FIN, length
   2728     'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
   2729   };
   2730   scoped_ptr<spdy::SpdyFrame>
   2731       stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   2732   MockWrite writes[] = {
   2733     CreateMockWrite(*stream1_syn, 1),
   2734   };
   2735 
   2736   scoped_ptr<spdy::SpdyFrame>
   2737       stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   2738   scoped_ptr<spdy::SpdyFrame>
   2739       stream2_syn(ConstructSpdyPush(NULL,
   2740                                     0,
   2741                                     2,
   2742                                     1,
   2743                                     "http://www.google.com/foo.dat"));
   2744   scoped_ptr<spdy::SpdyFrame>
   2745       stream1_body(ConstructSpdyBodyFrame(1, true));
   2746   MockRead reads[] = {
   2747     CreateMockRead(*stream1_reply, 2),
   2748     CreateMockRead(*stream2_syn, 3),
   2749     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame),
   2750              arraysize(kPushBodyFrame), 5),
   2751     CreateMockRead(*stream1_body, 4, false),
   2752     MockRead(true, ERR_IO_PENDING, 6),  // Force a pause
   2753   };
   2754 
   2755   HttpResponseInfo response;
   2756   HttpResponseInfo response2;
   2757   std::string expected_push_result("pushed");
   2758   scoped_refptr<OrderedSocketData> data(new OrderedSocketData(
   2759       reads,
   2760       arraysize(reads),
   2761       writes,
   2762       arraysize(writes)));
   2763   RunServerPushTest(data.get(),
   2764                     &response,
   2765                     &response2,
   2766                     expected_push_result);
   2767 
   2768   // Verify the SYN_REPLY.
   2769   EXPECT_TRUE(response.headers != NULL);
   2770   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   2771 
   2772   // Verify the pushed stream.
   2773   EXPECT_TRUE(response2.headers != NULL);
   2774   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
   2775 }
   2776 
   2777 TEST_P(SpdyNetworkTransactionTest, ServerPushServerAborted) {
   2778   scoped_ptr<spdy::SpdyFrame>
   2779       stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   2780   scoped_ptr<spdy::SpdyFrame>
   2781       stream1_body(ConstructSpdyBodyFrame(1, true));
   2782   MockWrite writes[] = {
   2783     CreateMockWrite(*stream1_syn, 1),
   2784   };
   2785 
   2786   scoped_ptr<spdy::SpdyFrame>
   2787       stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   2788   scoped_ptr<spdy::SpdyFrame>
   2789       stream2_syn(ConstructSpdyPush(NULL,
   2790                                     0,
   2791                                     2,
   2792                                     1,
   2793                                     "http://www.google.com/foo.dat"));
   2794   scoped_ptr<spdy::SpdyFrame>
   2795     stream2_rst(ConstructSpdyRstStream(2, spdy::PROTOCOL_ERROR));
   2796   MockRead reads[] = {
   2797     CreateMockRead(*stream1_reply, 2),
   2798     CreateMockRead(*stream2_syn, 3),
   2799     CreateMockRead(*stream2_rst, 4),
   2800     CreateMockRead(*stream1_body, 5, false),
   2801     MockRead(true, ERR_IO_PENDING, 6),  // Force a pause
   2802   };
   2803 
   2804   scoped_refptr<OrderedSocketData> data(
   2805       new OrderedSocketData(reads, arraysize(reads),
   2806                             writes, arraysize(writes)));
   2807   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   2808                                      BoundNetLog(), GetParam());
   2809 
   2810   helper.RunPreTestSetup();
   2811   helper.AddData(data.get());
   2812 
   2813   HttpNetworkTransaction* trans = helper.trans();
   2814 
   2815   // Start the transaction with basic parameters.
   2816   TestCompletionCallback callback;
   2817   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   2818   EXPECT_EQ(ERR_IO_PENDING, rv);
   2819   rv = callback.WaitForResult();
   2820   EXPECT_EQ(OK, rv);
   2821 
   2822   // Verify that we consumed all test data.
   2823   EXPECT_TRUE(data->at_read_eof()) << "Read count: "
   2824                                    << data->read_count()
   2825                                    << " Read index: "
   2826                                    << data->read_index();
   2827   EXPECT_TRUE(data->at_write_eof()) << "Write count: "
   2828                                     << data->write_count()
   2829                                     << " Write index: "
   2830                                     << data->write_index();
   2831 
   2832   // Verify the SYN_REPLY.
   2833   HttpResponseInfo response = *trans->GetResponseInfo();
   2834   EXPECT_TRUE(response.headers != NULL);
   2835   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   2836 }
   2837 
   2838 TEST_P(SpdyNetworkTransactionTest, ServerPushDuplicate) {
   2839   // Verify that we don't leak streams and that we properly send a reset
   2840   // if the server pushes the same stream twice.
   2841   static const unsigned char kPushBodyFrame[] = {
   2842     0x00, 0x00, 0x00, 0x02,                                      // header, ID
   2843     0x01, 0x00, 0x00, 0x06,                                      // FIN, length
   2844     'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
   2845   };
   2846 
   2847   scoped_ptr<spdy::SpdyFrame>
   2848       stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   2849   scoped_ptr<spdy::SpdyFrame>
   2850       stream1_body(ConstructSpdyBodyFrame(1, true));
   2851   scoped_ptr<spdy::SpdyFrame>
   2852       stream3_rst(ConstructSpdyRstStream(4, spdy::PROTOCOL_ERROR));
   2853   MockWrite writes[] = {
   2854     CreateMockWrite(*stream1_syn, 1),
   2855     CreateMockWrite(*stream3_rst, 5),
   2856   };
   2857 
   2858   scoped_ptr<spdy::SpdyFrame>
   2859       stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   2860   scoped_ptr<spdy::SpdyFrame>
   2861       stream2_syn(ConstructSpdyPush(NULL,
   2862                                     0,
   2863                                     2,
   2864                                     1,
   2865                                     "http://www.google.com/foo.dat"));
   2866   scoped_ptr<spdy::SpdyFrame>
   2867       stream3_syn(ConstructSpdyPush(NULL,
   2868                                     0,
   2869                                     4,
   2870                                     1,
   2871                                     "http://www.google.com/foo.dat"));
   2872   MockRead reads[] = {
   2873     CreateMockRead(*stream1_reply, 2),
   2874     CreateMockRead(*stream2_syn, 3),
   2875     CreateMockRead(*stream3_syn, 4),
   2876     CreateMockRead(*stream1_body, 6, false),
   2877     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame),
   2878              arraysize(kPushBodyFrame), 7),
   2879     MockRead(true, ERR_IO_PENDING, 8),  // Force a pause
   2880   };
   2881 
   2882   HttpResponseInfo response;
   2883   HttpResponseInfo response2;
   2884   std::string expected_push_result("pushed");
   2885   scoped_refptr<OrderedSocketData> data(new OrderedSocketData(
   2886       reads,
   2887       arraysize(reads),
   2888       writes,
   2889       arraysize(writes)));
   2890   RunServerPushTest(data.get(),
   2891                     &response,
   2892                     &response2,
   2893                     expected_push_result);
   2894 
   2895   // Verify the SYN_REPLY.
   2896   EXPECT_TRUE(response.headers != NULL);
   2897   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   2898 
   2899   // Verify the pushed stream.
   2900   EXPECT_TRUE(response2.headers != NULL);
   2901   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
   2902 }
   2903 
   2904 TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) {
   2905   static const unsigned char kPushBodyFrame1[] = {
   2906     0x00, 0x00, 0x00, 0x02,                                      // header, ID
   2907     0x01, 0x00, 0x00, 0x1F,                                      // FIN, length
   2908     'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
   2909   };
   2910   static const char kPushBodyFrame2[] = " my darling";
   2911   static const char kPushBodyFrame3[] = " hello";
   2912   static const char kPushBodyFrame4[] = " my baby";
   2913 
   2914   scoped_ptr<spdy::SpdyFrame>
   2915       stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   2916   scoped_ptr<spdy::SpdyFrame>
   2917       stream1_body(ConstructSpdyBodyFrame(1, true));
   2918   MockWrite writes[] = {
   2919     CreateMockWrite(*stream1_syn, 1),
   2920   };
   2921 
   2922   scoped_ptr<spdy::SpdyFrame>
   2923       stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   2924   scoped_ptr<spdy::SpdyFrame>
   2925       stream2_syn(ConstructSpdyPush(NULL,
   2926                                     0,
   2927                                     2,
   2928                                     1,
   2929                                     "http://www.google.com/foo.dat"));
   2930   MockRead reads[] = {
   2931     CreateMockRead(*stream1_reply, 2),
   2932     CreateMockRead(*stream2_syn, 3),
   2933     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame1),
   2934              arraysize(kPushBodyFrame1), 4),
   2935     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame2),
   2936              arraysize(kPushBodyFrame2) - 1, 5),
   2937     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame3),
   2938              arraysize(kPushBodyFrame3) - 1, 6),
   2939     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame4),
   2940              arraysize(kPushBodyFrame4) - 1, 7),
   2941     CreateMockRead(*stream1_body, 8, false),
   2942     MockRead(true, ERR_IO_PENDING, 9),  // Force a pause
   2943   };
   2944 
   2945   HttpResponseInfo response;
   2946   HttpResponseInfo response2;
   2947   std::string expected_push_result("pushed my darling hello my baby");
   2948   scoped_refptr<OrderedSocketData> data(new OrderedSocketData(
   2949       reads,
   2950       arraysize(reads),
   2951       writes,
   2952       arraysize(writes)));
   2953   RunServerPushTest(data.get(),
   2954                     &response,
   2955                     &response2,
   2956                     expected_push_result);
   2957 
   2958   // Verify the SYN_REPLY.
   2959   EXPECT_TRUE(response.headers != NULL);
   2960   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   2961 
   2962   // Verify the pushed stream.
   2963   EXPECT_TRUE(response2.headers != NULL);
   2964   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
   2965 }
   2966 
   2967 TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) {
   2968   static const unsigned char kPushBodyFrame1[] = {
   2969     0x00, 0x00, 0x00, 0x02,                                      // header, ID
   2970     0x01, 0x00, 0x00, 0x1F,                                      // FIN, length
   2971     'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
   2972   };
   2973   static const char kPushBodyFrame2[] = " my darling";
   2974   static const char kPushBodyFrame3[] = " hello";
   2975   static const char kPushBodyFrame4[] = " my baby";
   2976 
   2977   scoped_ptr<spdy::SpdyFrame>
   2978       stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   2979   scoped_ptr<spdy::SpdyFrame>
   2980       stream1_body(ConstructSpdyBodyFrame(1, true));
   2981   MockWrite writes[] = {
   2982     CreateMockWrite(*stream1_syn, 1),
   2983   };
   2984 
   2985   scoped_ptr<spdy::SpdyFrame>
   2986       stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   2987   scoped_ptr<spdy::SpdyFrame>
   2988       stream2_syn(ConstructSpdyPush(NULL,
   2989                                     0,
   2990                                     2,
   2991                                     1,
   2992                                     "http://www.google.com/foo.dat"));
   2993   MockRead reads[] = {
   2994     CreateMockRead(*stream1_reply, 2),
   2995     CreateMockRead(*stream2_syn, 3),
   2996     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame1),
   2997              arraysize(kPushBodyFrame1), 4),
   2998     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame2),
   2999              arraysize(kPushBodyFrame2) - 1, 5),
   3000     MockRead(true, ERR_IO_PENDING, 6),  // Force a pause
   3001     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame3),
   3002              arraysize(kPushBodyFrame3) - 1, 7),
   3003     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame4),
   3004              arraysize(kPushBodyFrame4) - 1, 8),
   3005     CreateMockRead(*stream1_body.get(), 9, false),
   3006     MockRead(true, ERR_IO_PENDING, 10)  // Force a pause.
   3007   };
   3008 
   3009   HttpResponseInfo response;
   3010   HttpResponseInfo response2;
   3011   std::string expected_push_result("pushed my darling hello my baby");
   3012   scoped_refptr<OrderedSocketData> data(new OrderedSocketData(
   3013       reads,
   3014       arraysize(reads),
   3015       writes,
   3016       arraysize(writes)));
   3017   RunServerPushTest(data.get(),
   3018                     &response,
   3019                     &response2,
   3020                     expected_push_result);
   3021 
   3022   // Verify the SYN_REPLY.
   3023   EXPECT_TRUE(response.headers != NULL);
   3024   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   3025 
   3026   // Verify the pushed stream.
   3027   EXPECT_TRUE(response2.headers != NULL);
   3028   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
   3029 }
   3030 
   3031 TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) {
   3032   scoped_ptr<spdy::SpdyFrame>
   3033       stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   3034   scoped_ptr<spdy::SpdyFrame>
   3035       stream1_body(ConstructSpdyBodyFrame(1, true));
   3036   scoped_ptr<spdy::SpdyFrame>
   3037       stream2_rst(ConstructSpdyRstStream(2, spdy::INVALID_STREAM));
   3038   MockWrite writes[] = {
   3039     CreateMockWrite(*stream1_syn, 1),
   3040     CreateMockWrite(*stream2_rst, 4),
   3041   };
   3042 
   3043   scoped_ptr<spdy::SpdyFrame>
   3044       stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   3045   scoped_ptr<spdy::SpdyFrame>
   3046       stream2_syn(ConstructSpdyPush(NULL,
   3047                                     0,
   3048                                     2,
   3049                                     0,
   3050                                     "http://www.google.com/foo.dat"));
   3051   MockRead reads[] = {
   3052     CreateMockRead(*stream1_reply, 2),
   3053     CreateMockRead(*stream2_syn, 3),
   3054     CreateMockRead(*stream1_body, 4),
   3055     MockRead(true, ERR_IO_PENDING, 5)  // Force a pause
   3056   };
   3057 
   3058   scoped_refptr<OrderedSocketData> data(
   3059       new OrderedSocketData(reads, arraysize(reads),
   3060                             writes, arraysize(writes)));
   3061   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   3062                                      BoundNetLog(), GetParam());
   3063 
   3064   helper.RunPreTestSetup();
   3065   helper.AddData(data.get());
   3066 
   3067   HttpNetworkTransaction* trans = helper.trans();
   3068 
   3069   // Start the transaction with basic parameters.
   3070   TestCompletionCallback callback;
   3071   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   3072   EXPECT_EQ(ERR_IO_PENDING, rv);
   3073   rv = callback.WaitForResult();
   3074   EXPECT_EQ(OK, rv);
   3075 
   3076   // Verify that we consumed all test data.
   3077   EXPECT_TRUE(data->at_read_eof()) << "Read count: "
   3078                                    << data->read_count()
   3079                                    << " Read index: "
   3080                                    << data->read_index();
   3081   EXPECT_TRUE(data->at_write_eof()) << "Write count: "
   3082                                     << data->write_count()
   3083                                     << " Write index: "
   3084                                     << data->write_index();
   3085 
   3086   // Verify the SYN_REPLY.
   3087   HttpResponseInfo response = *trans->GetResponseInfo();
   3088   EXPECT_TRUE(response.headers != NULL);
   3089   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   3090 }
   3091 
   3092 TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) {
   3093   scoped_ptr<spdy::SpdyFrame>
   3094       stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   3095   scoped_ptr<spdy::SpdyFrame>
   3096       stream1_body(ConstructSpdyBodyFrame(1, true));
   3097   scoped_ptr<spdy::SpdyFrame>
   3098       stream2_rst(ConstructSpdyRstStream(2, spdy::INVALID_ASSOCIATED_STREAM));
   3099   MockWrite writes[] = {
   3100     CreateMockWrite(*stream1_syn, 1),
   3101     CreateMockWrite(*stream2_rst, 4),
   3102   };
   3103 
   3104   scoped_ptr<spdy::SpdyFrame>
   3105       stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   3106   scoped_ptr<spdy::SpdyFrame>
   3107       stream2_syn(ConstructSpdyPush(NULL,
   3108                                     0,
   3109                                     2,
   3110                                     9,
   3111                                     "http://www.google.com/foo.dat"));
   3112   MockRead reads[] = {
   3113     CreateMockRead(*stream1_reply, 2),
   3114     CreateMockRead(*stream2_syn, 3),
   3115     CreateMockRead(*stream1_body, 4),
   3116     MockRead(true, ERR_IO_PENDING, 5),  // Force a pause
   3117   };
   3118 
   3119   scoped_refptr<OrderedSocketData> data(
   3120       new OrderedSocketData(reads, arraysize(reads),
   3121                             writes, arraysize(writes)));
   3122   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   3123                                      BoundNetLog(), GetParam());
   3124 
   3125   helper.RunPreTestSetup();
   3126   helper.AddData(data.get());
   3127 
   3128   HttpNetworkTransaction* trans = helper.trans();
   3129 
   3130   // Start the transaction with basic parameters.
   3131   TestCompletionCallback callback;
   3132   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   3133   EXPECT_EQ(ERR_IO_PENDING, rv);
   3134   rv = callback.WaitForResult();
   3135   EXPECT_EQ(OK, rv);
   3136 
   3137   // Verify that we consumed all test data.
   3138   EXPECT_TRUE(data->at_read_eof()) << "Read count: "
   3139                                    << data->read_count()
   3140                                    << " Read index: "
   3141                                    << data->read_index();
   3142   EXPECT_TRUE(data->at_write_eof()) << "Write count: "
   3143                                     << data->write_count()
   3144                                     << " Write index: "
   3145                                     << data->write_index();
   3146 
   3147   // Verify the SYN_REPLY.
   3148   HttpResponseInfo response = *trans->GetResponseInfo();
   3149   EXPECT_TRUE(response.headers != NULL);
   3150   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   3151 }
   3152 
   3153 TEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) {
   3154   scoped_ptr<spdy::SpdyFrame>
   3155       stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   3156   scoped_ptr<spdy::SpdyFrame>
   3157       stream1_body(ConstructSpdyBodyFrame(1, true));
   3158   scoped_ptr<spdy::SpdyFrame>
   3159       stream2_rst(ConstructSpdyRstStream(2, spdy::PROTOCOL_ERROR));
   3160   MockWrite writes[] = {
   3161     CreateMockWrite(*stream1_syn, 1),
   3162     CreateMockWrite(*stream2_rst, 4),
   3163   };
   3164 
   3165   scoped_ptr<spdy::SpdyFrame>
   3166       stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   3167   scoped_ptr<spdy::SpdyFrame>
   3168       stream2_syn(ConstructSpdyPush(NULL, 0, 2, 1));
   3169   MockRead reads[] = {
   3170     CreateMockRead(*stream1_reply, 2),
   3171     CreateMockRead(*stream2_syn, 3),
   3172     CreateMockRead(*stream1_body, 4),
   3173     MockRead(true, ERR_IO_PENDING, 5)  // Force a pause
   3174   };
   3175 
   3176   scoped_refptr<OrderedSocketData> data(
   3177       new OrderedSocketData(reads, arraysize(reads),
   3178                             writes, arraysize(writes)));
   3179   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   3180                                      BoundNetLog(), GetParam());
   3181 
   3182   helper.RunPreTestSetup();
   3183   helper.AddData(data.get());
   3184 
   3185   HttpNetworkTransaction* trans = helper.trans();
   3186 
   3187   // Start the transaction with basic parameters.
   3188   TestCompletionCallback callback;
   3189   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   3190   EXPECT_EQ(ERR_IO_PENDING, rv);
   3191   rv = callback.WaitForResult();
   3192   EXPECT_EQ(OK, rv);
   3193   // Verify that we consumed all test data.
   3194   EXPECT_TRUE(data->at_read_eof()) << "Read count: "
   3195                                    << data->read_count()
   3196                                    << " Read index: "
   3197                                    << data->read_index();
   3198   EXPECT_TRUE(data->at_write_eof()) << "Write count: "
   3199                                     << data->write_count()
   3200                                     << " Write index: "
   3201                                     << data->write_index();
   3202 
   3203   // Verify the SYN_REPLY.
   3204   HttpResponseInfo response = *trans->GetResponseInfo();
   3205   EXPECT_TRUE(response.headers != NULL);
   3206   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   3207 }
   3208 
   3209 // Verify that various SynReply headers parse correctly through the
   3210 // HTTP layer.
   3211 TEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) {
   3212   struct SynReplyHeadersTests {
   3213     int num_headers;
   3214     const char* extra_headers[5];
   3215     const char* expected_headers;
   3216   } test_cases[] = {
   3217     // This uses a multi-valued cookie header.
   3218     { 2,
   3219       { "cookie", "val1",
   3220         "cookie", "val2",  // will get appended separated by NULL
   3221         NULL
   3222       },
   3223       "cookie: val1\n"
   3224       "cookie: val2\n"
   3225       "hello: bye\n"
   3226       "status: 200\n"
   3227       "version: HTTP/1.1\n"
   3228     },
   3229     // This is the minimalist set of headers.
   3230     { 0,
   3231       { NULL },
   3232       "hello: bye\n"
   3233       "status: 200\n"
   3234       "version: HTTP/1.1\n"
   3235     },
   3236     // Headers with a comma separated list.
   3237     { 1,
   3238       { "cookie", "val1,val2",
   3239         NULL
   3240       },
   3241       "cookie: val1,val2\n"
   3242       "hello: bye\n"
   3243       "status: 200\n"
   3244       "version: HTTP/1.1\n"
   3245     }
   3246   };
   3247 
   3248   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
   3249     scoped_ptr<spdy::SpdyFrame> req(
   3250         ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   3251     MockWrite writes[] = { CreateMockWrite(*req) };
   3252 
   3253     scoped_ptr<spdy::SpdyFrame> resp(
   3254         ConstructSpdyGetSynReply(test_cases[i].extra_headers,
   3255                                  test_cases[i].num_headers,
   3256                                  1));
   3257     scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   3258     MockRead reads[] = {
   3259       CreateMockRead(*resp),
   3260       CreateMockRead(*body),
   3261       MockRead(true, 0, 0)  // EOF
   3262     };
   3263 
   3264     scoped_refptr<DelayedSocketData> data(
   3265         new DelayedSocketData(1, reads, arraysize(reads),
   3266                               writes, arraysize(writes)));
   3267     NormalSpdyTransactionHelper helper(CreateGetRequest(),
   3268                                        BoundNetLog(), GetParam());
   3269     helper.RunToCompletion(data.get());
   3270     TransactionHelperResult out = helper.output();
   3271 
   3272     EXPECT_EQ(OK, out.rv);
   3273     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   3274     EXPECT_EQ("hello!", out.response_data);
   3275 
   3276     scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
   3277     EXPECT_TRUE(headers.get() != NULL);
   3278     void* iter = NULL;
   3279     std::string name, value, lines;
   3280     while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
   3281       lines.append(name);
   3282       lines.append(": ");
   3283       lines.append(value);
   3284       lines.append("\n");
   3285     }
   3286     EXPECT_EQ(std::string(test_cases[i].expected_headers), lines);
   3287   }
   3288 }
   3289 
   3290 // Verify that various SynReply headers parse vary fields correctly
   3291 // through the HTTP layer, and the response matches the request.
   3292 TEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) {
   3293   static const SpdyHeaderInfo syn_reply_info = {
   3294     spdy::SYN_REPLY,                              // Syn Reply
   3295     1,                                            // Stream ID
   3296     0,                                            // Associated Stream ID
   3297     net::ConvertRequestPriorityToSpdyPriority(LOWEST),
   3298                                                   // Priority
   3299     spdy::CONTROL_FLAG_NONE,                      // Control Flags
   3300     false,                                        // Compressed
   3301     spdy::INVALID,                                // Status
   3302     NULL,                                         // Data
   3303     0,                                            // Data Length
   3304     spdy::DATA_FLAG_NONE                          // Data Flags
   3305   };
   3306   // Modify the following data to change/add test cases:
   3307   struct SynReplyTests {
   3308     const SpdyHeaderInfo* syn_reply;
   3309     bool vary_matches;
   3310     int num_headers[2];
   3311     const char* extra_headers[2][16];
   3312   } test_cases[] = {
   3313     // Test the case of a multi-valued cookie.  When the value is delimited
   3314     // with NUL characters, it needs to be unfolded into multiple headers.
   3315     {
   3316       &syn_reply_info,
   3317       true,
   3318       { 1, 4 },
   3319       { { "cookie",   "val1,val2",
   3320           NULL
   3321         },
   3322         { "vary",     "cookie",
   3323           "status",   "200",
   3324           "url",      "/index.php",
   3325           "version",  "HTTP/1.1",
   3326           NULL
   3327         }
   3328       }
   3329     }, {    // Multiple vary fields.
   3330       &syn_reply_info,
   3331       true,
   3332       { 2, 5 },
   3333       { { "friend",   "barney",
   3334           "enemy",    "snaggletooth",
   3335           NULL
   3336         },
   3337         { "vary",     "friend",
   3338           "vary",     "enemy",
   3339           "status",   "200",
   3340           "url",      "/index.php",
   3341           "version",  "HTTP/1.1",
   3342           NULL
   3343         }
   3344       }
   3345     }, {    // Test a '*' vary field.
   3346       &syn_reply_info,
   3347       false,
   3348       { 1, 4 },
   3349       { { "cookie",   "val1,val2",
   3350           NULL
   3351         },
   3352         { "vary",     "*",
   3353           "status",   "200",
   3354           "url",      "/index.php",
   3355           "version",  "HTTP/1.1",
   3356           NULL
   3357         }
   3358       }
   3359     }, {    // Multiple comma-separated vary fields.
   3360       &syn_reply_info,
   3361       true,
   3362       { 2, 4 },
   3363       { { "friend",   "barney",
   3364           "enemy",    "snaggletooth",
   3365           NULL
   3366         },
   3367         { "vary",     "friend,enemy",
   3368           "status",   "200",
   3369           "url",      "/index.php",
   3370           "version",  "HTTP/1.1",
   3371           NULL
   3372         }
   3373       }
   3374     }
   3375   };
   3376 
   3377   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
   3378     // Construct the request.
   3379     scoped_ptr<spdy::SpdyFrame> frame_req(
   3380       ConstructSpdyGet(test_cases[i].extra_headers[0],
   3381                        test_cases[i].num_headers[0],
   3382                        false, 1, LOWEST));
   3383 
   3384     MockWrite writes[] = {
   3385       CreateMockWrite(*frame_req),
   3386     };
   3387 
   3388     // Construct the reply.
   3389     scoped_ptr<spdy::SpdyFrame> frame_reply(
   3390       ConstructSpdyPacket(*test_cases[i].syn_reply,
   3391                           test_cases[i].extra_headers[1],
   3392                           test_cases[i].num_headers[1],
   3393                           NULL,
   3394                           0));
   3395 
   3396     scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   3397     MockRead reads[] = {
   3398       CreateMockRead(*frame_reply),
   3399       CreateMockRead(*body),
   3400       MockRead(true, 0, 0)  // EOF
   3401     };
   3402 
   3403     // Attach the headers to the request.
   3404     int header_count = test_cases[i].num_headers[0];
   3405 
   3406     HttpRequestInfo request = CreateGetRequest();
   3407     for (int ct = 0; ct < header_count; ct++) {
   3408       const char* header_key = test_cases[i].extra_headers[0][ct * 2];
   3409       const char* header_value = test_cases[i].extra_headers[0][ct * 2 + 1];
   3410       request.extra_headers.SetHeader(header_key, header_value);
   3411     }
   3412 
   3413     scoped_refptr<DelayedSocketData> data(
   3414         new DelayedSocketData(1, reads, arraysize(reads),
   3415                               writes, arraysize(writes)));
   3416     NormalSpdyTransactionHelper helper(request,
   3417                                        BoundNetLog(), GetParam());
   3418     helper.RunToCompletion(data.get());
   3419     TransactionHelperResult out = helper.output();
   3420 
   3421     EXPECT_EQ(OK, out.rv) << i;
   3422     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line) << i;
   3423     EXPECT_EQ("hello!", out.response_data) << i;
   3424 
   3425     // Test the response information.
   3426     EXPECT_TRUE(out.response_info.response_time >
   3427                 out.response_info.request_time) << i;
   3428     base::TimeDelta test_delay = out.response_info.response_time -
   3429                                  out.response_info.request_time;
   3430     base::TimeDelta min_expected_delay;
   3431     min_expected_delay.FromMilliseconds(10);
   3432     EXPECT_GT(test_delay.InMillisecondsF(),
   3433               min_expected_delay.InMillisecondsF()) << i;
   3434     EXPECT_EQ(out.response_info.vary_data.is_valid(),
   3435               test_cases[i].vary_matches) << i;
   3436 
   3437     // Check the headers.
   3438     scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
   3439     ASSERT_TRUE(headers.get() != NULL) << i;
   3440     void* iter = NULL;
   3441     std::string name, value, lines;
   3442     while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
   3443       lines.append(name);
   3444       lines.append(": ");
   3445       lines.append(value);
   3446       lines.append("\n");
   3447     }
   3448 
   3449     // Construct the expected header reply string.
   3450     char reply_buffer[256] = "";
   3451     ConstructSpdyReplyString(test_cases[i].extra_headers[1],
   3452                              test_cases[i].num_headers[1],
   3453                              reply_buffer,
   3454                              256);
   3455 
   3456     EXPECT_EQ(std::string(reply_buffer), lines) << i;
   3457   }
   3458 }
   3459 
   3460 // Verify that we don't crash on invalid SynReply responses.
   3461 TEST_P(SpdyNetworkTransactionTest, InvalidSynReply) {
   3462   const SpdyHeaderInfo kSynStartHeader = {
   3463     spdy::SYN_REPLY,              // Kind = SynReply
   3464     1,                            // Stream ID
   3465     0,                            // Associated stream ID
   3466     net::ConvertRequestPriorityToSpdyPriority(LOWEST),
   3467                                   // Priority
   3468     spdy::CONTROL_FLAG_NONE,      // Control Flags
   3469     false,                        // Compressed
   3470     spdy::INVALID,                // Status
   3471     NULL,                         // Data
   3472     0,                            // Length
   3473     spdy::DATA_FLAG_NONE          // Data Flags
   3474   };
   3475 
   3476   struct InvalidSynReplyTests {
   3477     int num_headers;
   3478     const char* headers[10];
   3479   } test_cases[] = {
   3480     // SYN_REPLY missing status header
   3481     { 4,
   3482       { "cookie", "val1",
   3483         "cookie", "val2",
   3484         "url", "/index.php",
   3485         "version", "HTTP/1.1",
   3486         NULL
   3487       },
   3488     },
   3489     // SYN_REPLY missing version header
   3490     { 2,
   3491       { "status", "200",
   3492         "url", "/index.php",
   3493         NULL
   3494       },
   3495     },
   3496     // SYN_REPLY with no headers
   3497     { 0, { NULL }, },
   3498   };
   3499 
   3500   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
   3501     scoped_ptr<spdy::SpdyFrame> req(
   3502         ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   3503     MockWrite writes[] = {
   3504       CreateMockWrite(*req),
   3505     };
   3506 
   3507     scoped_ptr<spdy::SpdyFrame> resp(
   3508         ConstructSpdyPacket(kSynStartHeader,
   3509                             NULL, 0,
   3510                             test_cases[i].headers,
   3511                             test_cases[i].num_headers));
   3512     scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   3513     MockRead reads[] = {
   3514       CreateMockRead(*resp),
   3515       CreateMockRead(*body),
   3516       MockRead(true, 0, 0)  // EOF
   3517     };
   3518 
   3519     scoped_refptr<DelayedSocketData> data(
   3520         new DelayedSocketData(1, reads, arraysize(reads),
   3521                               writes, arraysize(writes)));
   3522     NormalSpdyTransactionHelper helper(CreateGetRequest(),
   3523                                        BoundNetLog(), GetParam());
   3524     helper.RunToCompletion(data.get());
   3525     TransactionHelperResult out = helper.output();
   3526     EXPECT_EQ(ERR_INCOMPLETE_SPDY_HEADERS, out.rv);
   3527   }
   3528 }
   3529 
   3530 // Verify that we don't crash on some corrupt frames.
   3531 TEST_P(SpdyNetworkTransactionTest, CorruptFrameSessionError) {
   3532   // This is the length field that's too short.
   3533   scoped_ptr<spdy::SpdyFrame> syn_reply_wrong_length(
   3534       ConstructSpdyGetSynReply(NULL, 0, 1));
   3535   syn_reply_wrong_length->set_length(syn_reply_wrong_length->length() - 4);
   3536 
   3537   struct SynReplyTests {
   3538     const spdy::SpdyFrame* syn_reply;
   3539   } test_cases[] = {
   3540     { syn_reply_wrong_length.get(), },
   3541   };
   3542 
   3543   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
   3544     scoped_ptr<spdy::SpdyFrame> req(
   3545         ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   3546     MockWrite writes[] = {
   3547       CreateMockWrite(*req),
   3548       MockWrite(true, 0, 0)  // EOF
   3549     };
   3550 
   3551     scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   3552     MockRead reads[] = {
   3553       CreateMockRead(*test_cases[i].syn_reply),
   3554       CreateMockRead(*body),
   3555       MockRead(true, 0, 0)  // EOF
   3556     };
   3557 
   3558     scoped_refptr<DelayedSocketData> data(
   3559         new DelayedSocketData(1, reads, arraysize(reads),
   3560                               writes, arraysize(writes)));
   3561     NormalSpdyTransactionHelper helper(CreateGetRequest(),
   3562                                        BoundNetLog(), GetParam());
   3563     helper.RunToCompletion(data.get());
   3564     TransactionHelperResult out = helper.output();
   3565     EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
   3566   }
   3567 }
   3568 
   3569 // Test that we shutdown correctly on write errors.
   3570 TEST_P(SpdyNetworkTransactionTest, WriteError) {
   3571   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   3572   MockWrite writes[] = {
   3573     // We'll write 10 bytes successfully
   3574     MockWrite(true, req->data(), 10),
   3575     // Followed by ERROR!
   3576     MockWrite(true, ERR_FAILED),
   3577   };
   3578 
   3579   scoped_refptr<DelayedSocketData> data(
   3580       new DelayedSocketData(2, NULL, 0,
   3581                             writes, arraysize(writes)));
   3582   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   3583                                      BoundNetLog(), GetParam());
   3584   helper.RunToCompletion(data.get());
   3585   TransactionHelperResult out = helper.output();
   3586   EXPECT_EQ(ERR_FAILED, out.rv);
   3587   data->Reset();
   3588 }
   3589 
   3590 // Test that partial writes work.
   3591 TEST_P(SpdyNetworkTransactionTest, PartialWrite) {
   3592   // Chop the SYN_STREAM frame into 5 chunks.
   3593   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   3594   const int kChunks = 5;
   3595   scoped_array<MockWrite> writes(ChopWriteFrame(*req.get(), kChunks));
   3596 
   3597   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   3598   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   3599   MockRead reads[] = {
   3600     CreateMockRead(*resp),
   3601     CreateMockRead(*body),
   3602     MockRead(true, 0, 0)  // EOF
   3603   };
   3604 
   3605   scoped_refptr<DelayedSocketData> data(
   3606       new DelayedSocketData(kChunks, reads, arraysize(reads),
   3607                             writes.get(), kChunks));
   3608   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   3609                                      BoundNetLog(), GetParam());
   3610   helper.RunToCompletion(data.get());
   3611   TransactionHelperResult out = helper.output();
   3612   EXPECT_EQ(OK, out.rv);
   3613   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   3614   EXPECT_EQ("hello!", out.response_data);
   3615 }
   3616 
   3617 // In this test, we enable compression, but get a uncompressed SynReply from
   3618 // the server.  Verify that teardown is all clean.
   3619 TEST_P(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) {
   3620   // For this test, we turn on the normal compression.
   3621   EnableCompression(true);
   3622 
   3623   scoped_ptr<spdy::SpdyFrame> compressed(
   3624       ConstructSpdyGet(NULL, 0, true, 1, LOWEST));
   3625   scoped_ptr<spdy::SpdyFrame> rst(
   3626       ConstructSpdyRstStream(1, spdy::PROTOCOL_ERROR));
   3627   MockWrite writes[] = {
   3628     CreateMockWrite(*compressed),
   3629     CreateMockWrite(*rst),
   3630   };
   3631 
   3632   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   3633   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   3634   MockRead reads[] = {
   3635     CreateMockRead(*resp),
   3636     CreateMockRead(*body),
   3637     MockRead(true, 0, 0)
   3638   };
   3639 
   3640   scoped_refptr<DelayedSocketData> data(
   3641       new DelayedSocketData(1, reads, arraysize(reads),
   3642                             writes, arraysize(writes)));
   3643   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   3644                                      BoundNetLog(), GetParam());
   3645   helper.RunToCompletion(data.get());
   3646   TransactionHelperResult out = helper.output();
   3647   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
   3648   data->Reset();
   3649 
   3650   EnableCompression(false);
   3651 }
   3652 
   3653 // Test that the NetLog contains good data for a simple GET request.
   3654 TEST_P(SpdyNetworkTransactionTest, NetLog) {
   3655   static const char* const kExtraHeaders[] = {
   3656     "user-agent",   "Chrome",
   3657   };
   3658   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(kExtraHeaders, 1, false, 1,
   3659                                                    LOWEST));
   3660   MockWrite writes[] = { CreateMockWrite(*req) };
   3661 
   3662   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   3663   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   3664   MockRead reads[] = {
   3665     CreateMockRead(*resp),
   3666     CreateMockRead(*body),
   3667     MockRead(true, 0, 0)  // EOF
   3668   };
   3669 
   3670   net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
   3671 
   3672   scoped_refptr<DelayedSocketData> data(
   3673       new DelayedSocketData(1, reads, arraysize(reads),
   3674                             writes, arraysize(writes)));
   3675   NormalSpdyTransactionHelper helper(CreateGetRequestWithUserAgent(),
   3676                                      log.bound(), GetParam());
   3677   helper.RunToCompletion(data.get());
   3678   TransactionHelperResult out = helper.output();
   3679   EXPECT_EQ(OK, out.rv);
   3680   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   3681   EXPECT_EQ("hello!", out.response_data);
   3682 
   3683   // Check that the NetLog was filled reasonably.
   3684   // This test is intentionally non-specific about the exact ordering of the
   3685   // log; instead we just check to make sure that certain events exist, and that
   3686   // they are in the right order.
   3687   net::CapturingNetLog::EntryList entries;
   3688   log.GetEntries(&entries);
   3689 
   3690   EXPECT_LT(0u, entries.size());
   3691   int pos = 0;
   3692   pos = net::ExpectLogContainsSomewhere(entries, 0,
   3693       net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST,
   3694       net::NetLog::PHASE_BEGIN);
   3695   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
   3696       net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST,
   3697       net::NetLog::PHASE_END);
   3698   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
   3699       net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS,
   3700       net::NetLog::PHASE_BEGIN);
   3701   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
   3702       net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS,
   3703       net::NetLog::PHASE_END);
   3704   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
   3705       net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY,
   3706       net::NetLog::PHASE_BEGIN);
   3707   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
   3708       net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY,
   3709       net::NetLog::PHASE_END);
   3710 
   3711   // Check that we logged all the headers correctly
   3712   pos = net::ExpectLogContainsSomewhere(
   3713       entries, 0,
   3714       net::NetLog::TYPE_SPDY_SESSION_SYN_STREAM,
   3715       net::NetLog::PHASE_NONE);
   3716   CapturingNetLog::Entry entry = entries[pos];
   3717   NetLogSpdySynParameter* request_params =
   3718       static_cast<NetLogSpdySynParameter*>(entry.extra_parameters.get());
   3719   spdy::SpdyHeaderBlock* headers =
   3720       request_params->GetHeaders().get();
   3721 
   3722   spdy::SpdyHeaderBlock expected;
   3723   expected["host"] = "www.google.com";
   3724   expected["url"] = "/";
   3725   expected["scheme"] = "http";
   3726   expected["version"] = "HTTP/1.1";
   3727   expected["method"] = "GET";
   3728   expected["user-agent"] = "Chrome";
   3729   EXPECT_EQ(expected.size(), headers->size());
   3730   spdy::SpdyHeaderBlock::const_iterator end = expected.end();
   3731   for (spdy::SpdyHeaderBlock::const_iterator it = expected.begin();
   3732       it != end;
   3733       ++it) {
   3734     EXPECT_EQ(it->second, (*headers)[it->first]);
   3735   }
   3736 }
   3737 
   3738 // Since we buffer the IO from the stream to the renderer, this test verifies
   3739 // that when we read out the maximum amount of data (e.g. we received 50 bytes
   3740 // on the network, but issued a Read for only 5 of those bytes) that the data
   3741 // flow still works correctly.
   3742 TEST_P(SpdyNetworkTransactionTest, BufferFull) {
   3743   spdy::SpdyFramer framer;
   3744 
   3745   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   3746   MockWrite writes[] = { CreateMockWrite(*req) };
   3747 
   3748   // 2 data frames in a single read.
   3749   scoped_ptr<spdy::SpdyFrame> data_frame_1(
   3750       framer.CreateDataFrame(1, "goodby", 6, spdy::DATA_FLAG_NONE));
   3751   scoped_ptr<spdy::SpdyFrame> data_frame_2(
   3752       framer.CreateDataFrame(1, "e worl", 6, spdy::DATA_FLAG_NONE));
   3753   const spdy::SpdyFrame* data_frames[2] = {
   3754     data_frame_1.get(),
   3755     data_frame_2.get(),
   3756   };
   3757   char combined_data_frames[100];
   3758   int combined_data_frames_len =
   3759       CombineFrames(data_frames, arraysize(data_frames),
   3760                     combined_data_frames, arraysize(combined_data_frames));
   3761   scoped_ptr<spdy::SpdyFrame> last_frame(
   3762       framer.CreateDataFrame(1, "d", 1, spdy::DATA_FLAG_FIN));
   3763 
   3764   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   3765   MockRead reads[] = {
   3766     CreateMockRead(*resp),
   3767     MockRead(true, ERR_IO_PENDING),  // Force a pause
   3768     MockRead(true, combined_data_frames, combined_data_frames_len),
   3769     MockRead(true, ERR_IO_PENDING),  // Force a pause
   3770     CreateMockRead(*last_frame),
   3771     MockRead(true, 0, 0)  // EOF
   3772   };
   3773 
   3774   scoped_refptr<DelayedSocketData> data(
   3775       new DelayedSocketData(1, reads, arraysize(reads),
   3776                             writes, arraysize(writes)));
   3777 
   3778 
   3779   TestCompletionCallback callback;
   3780 
   3781   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   3782                                      BoundNetLog(), GetParam());
   3783   helper.RunPreTestSetup();
   3784   helper.AddData(data.get());
   3785   HttpNetworkTransaction* trans = helper.trans();
   3786   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   3787   EXPECT_EQ(ERR_IO_PENDING, rv);
   3788 
   3789   TransactionHelperResult out = helper.output();
   3790   out.rv = callback.WaitForResult();
   3791   EXPECT_EQ(out.rv, OK);
   3792 
   3793   const HttpResponseInfo* response = trans->GetResponseInfo();
   3794   EXPECT_TRUE(response->headers != NULL);
   3795   EXPECT_TRUE(response->was_fetched_via_spdy);
   3796   out.status_line = response->headers->GetStatusLine();
   3797   out.response_info = *response;  // Make a copy so we can verify.
   3798 
   3799   // Read Data
   3800   TestCompletionCallback read_callback;
   3801 
   3802   std::string content;
   3803   do {
   3804     // Read small chunks at a time.
   3805     const int kSmallReadSize = 3;
   3806     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
   3807     rv = trans->Read(buf, kSmallReadSize, &read_callback);
   3808     if (rv == net::ERR_IO_PENDING) {
   3809       data->CompleteRead();
   3810       rv = read_callback.WaitForResult();
   3811     }
   3812     if (rv > 0) {
   3813       content.append(buf->data(), rv);
   3814     } else if (rv < 0) {
   3815       NOTREACHED();
   3816     }
   3817   } while (rv > 0);
   3818 
   3819   out.response_data.swap(content);
   3820 
   3821   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
   3822   // MockClientSocketFactory) are still alive.
   3823   MessageLoop::current()->RunAllPending();
   3824 
   3825   // Verify that we consumed all test data.
   3826   helper.VerifyDataConsumed();
   3827 
   3828   EXPECT_EQ(OK, out.rv);
   3829   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   3830   EXPECT_EQ("goodbye world", out.response_data);
   3831 }
   3832 
   3833 // Verify that basic buffering works; when multiple data frames arrive
   3834 // at the same time, ensure that we don't notify a read completion for
   3835 // each data frame individually.
   3836 TEST_P(SpdyNetworkTransactionTest, Buffering) {
   3837   spdy::SpdyFramer framer;
   3838 
   3839   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   3840   MockWrite writes[] = { CreateMockWrite(*req) };
   3841 
   3842   // 4 data frames in a single read.
   3843   scoped_ptr<spdy::SpdyFrame> data_frame(
   3844       framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_NONE));
   3845   scoped_ptr<spdy::SpdyFrame> data_frame_fin(
   3846       framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_FIN));
   3847   const spdy::SpdyFrame* data_frames[4] = {
   3848     data_frame.get(),
   3849     data_frame.get(),
   3850     data_frame.get(),
   3851     data_frame_fin.get()
   3852   };
   3853   char combined_data_frames[100];
   3854   int combined_data_frames_len =
   3855       CombineFrames(data_frames, arraysize(data_frames),
   3856                     combined_data_frames, arraysize(combined_data_frames));
   3857 
   3858   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   3859   MockRead reads[] = {
   3860     CreateMockRead(*resp),
   3861     MockRead(true, ERR_IO_PENDING),  // Force a pause
   3862     MockRead(true, combined_data_frames, combined_data_frames_len),
   3863     MockRead(true, 0, 0)  // EOF
   3864   };
   3865 
   3866   scoped_refptr<DelayedSocketData> data(
   3867       new DelayedSocketData(1, reads, arraysize(reads),
   3868                             writes, arraysize(writes)));
   3869 
   3870   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   3871                                      BoundNetLog(), GetParam());
   3872   helper.RunPreTestSetup();
   3873   helper.AddData(data.get());
   3874   HttpNetworkTransaction* trans = helper.trans();
   3875 
   3876   TestCompletionCallback callback;
   3877   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   3878   EXPECT_EQ(ERR_IO_PENDING, rv);
   3879 
   3880   TransactionHelperResult out = helper.output();
   3881   out.rv = callback.WaitForResult();
   3882   EXPECT_EQ(out.rv, OK);
   3883 
   3884   const HttpResponseInfo* response = trans->GetResponseInfo();
   3885   EXPECT_TRUE(response->headers != NULL);
   3886   EXPECT_TRUE(response->was_fetched_via_spdy);
   3887   out.status_line = response->headers->GetStatusLine();
   3888   out.response_info = *response;  // Make a copy so we can verify.
   3889 
   3890   // Read Data
   3891   TestCompletionCallback read_callback;
   3892 
   3893   std::string content;
   3894   int reads_completed = 0;
   3895   do {
   3896     // Read small chunks at a time.
   3897     const int kSmallReadSize = 14;
   3898     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
   3899     rv = trans->Read(buf, kSmallReadSize, &read_callback);
   3900     if (rv == net::ERR_IO_PENDING) {
   3901       data->CompleteRead();
   3902       rv = read_callback.WaitForResult();
   3903     }
   3904     if (rv > 0) {
   3905       EXPECT_EQ(kSmallReadSize, rv);
   3906       content.append(buf->data(), rv);
   3907     } else if (rv < 0) {
   3908       FAIL() << "Unexpected read error: " << rv;
   3909     }
   3910     reads_completed++;
   3911   } while (rv > 0);
   3912 
   3913   EXPECT_EQ(3, reads_completed);  // Reads are: 14 bytes, 14 bytes, 0 bytes.
   3914 
   3915   out.response_data.swap(content);
   3916 
   3917   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
   3918   // MockClientSocketFactory) are still alive.
   3919   MessageLoop::current()->RunAllPending();
   3920 
   3921   // Verify that we consumed all test data.
   3922   helper.VerifyDataConsumed();
   3923 
   3924   EXPECT_EQ(OK, out.rv);
   3925   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   3926   EXPECT_EQ("messagemessagemessagemessage", out.response_data);
   3927 }
   3928 
   3929 // Verify the case where we buffer data but read it after it has been buffered.
   3930 TEST_P(SpdyNetworkTransactionTest, BufferedAll) {
   3931   spdy::SpdyFramer framer;
   3932 
   3933   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   3934   MockWrite writes[] = { CreateMockWrite(*req) };
   3935 
   3936   // 5 data frames in a single read.
   3937   scoped_ptr<spdy::SpdyFrame> syn_reply(
   3938       ConstructSpdyGetSynReply(NULL, 0, 1));
   3939   syn_reply->set_flags(spdy::CONTROL_FLAG_NONE);  // turn off FIN bit
   3940   scoped_ptr<spdy::SpdyFrame> data_frame(
   3941       framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_NONE));
   3942   scoped_ptr<spdy::SpdyFrame> data_frame_fin(
   3943       framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_FIN));
   3944   const spdy::SpdyFrame* frames[5] = {
   3945     syn_reply.get(),
   3946     data_frame.get(),
   3947     data_frame.get(),
   3948     data_frame.get(),
   3949     data_frame_fin.get()
   3950   };
   3951   char combined_frames[200];
   3952   int combined_frames_len =
   3953       CombineFrames(frames, arraysize(frames),
   3954                     combined_frames, arraysize(combined_frames));
   3955 
   3956   MockRead reads[] = {
   3957     MockRead(true, combined_frames, combined_frames_len),
   3958     MockRead(true, 0, 0)  // EOF
   3959   };
   3960 
   3961   scoped_refptr<DelayedSocketData> data(
   3962       new DelayedSocketData(1, reads, arraysize(reads),
   3963                             writes, arraysize(writes)));
   3964 
   3965   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   3966                                      BoundNetLog(), GetParam());
   3967   helper.RunPreTestSetup();
   3968   helper.AddData(data.get());
   3969   HttpNetworkTransaction* trans = helper.trans();
   3970 
   3971   TestCompletionCallback callback;
   3972   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   3973   EXPECT_EQ(ERR_IO_PENDING, rv);
   3974 
   3975   TransactionHelperResult out = helper.output();
   3976   out.rv = callback.WaitForResult();
   3977   EXPECT_EQ(out.rv, OK);
   3978 
   3979   const HttpResponseInfo* response = trans->GetResponseInfo();
   3980   EXPECT_TRUE(response->headers != NULL);
   3981   EXPECT_TRUE(response->was_fetched_via_spdy);
   3982   out.status_line = response->headers->GetStatusLine();
   3983   out.response_info = *response;  // Make a copy so we can verify.
   3984 
   3985   // Read Data
   3986   TestCompletionCallback read_callback;
   3987 
   3988   std::string content;
   3989   int reads_completed = 0;
   3990   do {
   3991     // Read small chunks at a time.
   3992     const int kSmallReadSize = 14;
   3993     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
   3994     rv = trans->Read(buf, kSmallReadSize, &read_callback);
   3995     if (rv > 0) {
   3996       EXPECT_EQ(kSmallReadSize, rv);
   3997       content.append(buf->data(), rv);
   3998     } else if (rv < 0) {
   3999       FAIL() << "Unexpected read error: " << rv;
   4000     }
   4001     reads_completed++;
   4002   } while (rv > 0);
   4003 
   4004   EXPECT_EQ(3, reads_completed);
   4005 
   4006   out.response_data.swap(content);
   4007 
   4008   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
   4009   // MockClientSocketFactory) are still alive.
   4010   MessageLoop::current()->RunAllPending();
   4011 
   4012   // Verify that we consumed all test data.
   4013   helper.VerifyDataConsumed();
   4014 
   4015   EXPECT_EQ(OK, out.rv);
   4016   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   4017   EXPECT_EQ("messagemessagemessagemessage", out.response_data);
   4018 }
   4019 
   4020 // Verify the case where we buffer data and close the connection.
   4021 TEST_P(SpdyNetworkTransactionTest, BufferedClosed) {
   4022   spdy::SpdyFramer framer;
   4023 
   4024   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   4025   MockWrite writes[] = { CreateMockWrite(*req) };
   4026 
   4027   // All data frames in a single read.
   4028   // NOTE: We don't FIN the stream.
   4029   scoped_ptr<spdy::SpdyFrame> data_frame(
   4030       framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_NONE));
   4031   const spdy::SpdyFrame* data_frames[4] = {
   4032     data_frame.get(),
   4033     data_frame.get(),
   4034     data_frame.get(),
   4035     data_frame.get()
   4036   };
   4037   char combined_data_frames[100];
   4038   int combined_data_frames_len =
   4039       CombineFrames(data_frames, arraysize(data_frames),
   4040                     combined_data_frames, arraysize(combined_data_frames));
   4041   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   4042   MockRead reads[] = {
   4043     CreateMockRead(*resp),
   4044     MockRead(true, ERR_IO_PENDING),  // Force a wait
   4045     MockRead(true, combined_data_frames, combined_data_frames_len),
   4046     MockRead(true, 0, 0)  // EOF
   4047   };
   4048 
   4049   scoped_refptr<DelayedSocketData> data(
   4050       new DelayedSocketData(1, reads, arraysize(reads),
   4051                             writes, arraysize(writes)));
   4052 
   4053   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   4054                                      BoundNetLog(), GetParam());
   4055   helper.RunPreTestSetup();
   4056   helper.AddData(data.get());
   4057   HttpNetworkTransaction* trans = helper.trans();
   4058 
   4059   TestCompletionCallback callback;
   4060 
   4061   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   4062   EXPECT_EQ(ERR_IO_PENDING, rv);
   4063 
   4064   TransactionHelperResult out = helper.output();
   4065   out.rv = callback.WaitForResult();
   4066   EXPECT_EQ(out.rv, OK);
   4067 
   4068   const HttpResponseInfo* response = trans->GetResponseInfo();
   4069   EXPECT_TRUE(response->headers != NULL);
   4070   EXPECT_TRUE(response->was_fetched_via_spdy);
   4071   out.status_line = response->headers->GetStatusLine();
   4072   out.response_info = *response;  // Make a copy so we can verify.
   4073 
   4074   // Read Data
   4075   TestCompletionCallback read_callback;
   4076 
   4077   std::string content;
   4078   int reads_completed = 0;
   4079   do {
   4080     // Read small chunks at a time.
   4081     const int kSmallReadSize = 14;
   4082     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
   4083     rv = trans->Read(buf, kSmallReadSize, &read_callback);
   4084     if (rv == net::ERR_IO_PENDING) {
   4085       data->CompleteRead();
   4086       rv = read_callback.WaitForResult();
   4087     }
   4088     if (rv > 0) {
   4089       content.append(buf->data(), rv);
   4090     } else if (rv < 0) {
   4091       // This test intentionally closes the connection, and will get an error.
   4092       EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
   4093       break;
   4094     }
   4095     reads_completed++;
   4096   } while (rv > 0);
   4097 
   4098   EXPECT_EQ(0, reads_completed);
   4099 
   4100   out.response_data.swap(content);
   4101 
   4102   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
   4103   // MockClientSocketFactory) are still alive.
   4104   MessageLoop::current()->RunAllPending();
   4105 
   4106   // Verify that we consumed all test data.
   4107   helper.VerifyDataConsumed();
   4108 }
   4109 
   4110 // Verify the case where we buffer data and cancel the transaction.
   4111 TEST_P(SpdyNetworkTransactionTest, BufferedCancelled) {
   4112   spdy::SpdyFramer framer;
   4113 
   4114   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   4115   MockWrite writes[] = { CreateMockWrite(*req) };
   4116 
   4117   // NOTE: We don't FIN the stream.
   4118   scoped_ptr<spdy::SpdyFrame> data_frame(
   4119       framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_NONE));
   4120 
   4121   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   4122   MockRead reads[] = {
   4123     CreateMockRead(*resp),
   4124     MockRead(true, ERR_IO_PENDING),  // Force a wait
   4125     CreateMockRead(*data_frame),
   4126     MockRead(true, 0, 0)  // EOF
   4127   };
   4128 
   4129   scoped_refptr<DelayedSocketData> data(
   4130       new DelayedSocketData(1, reads, arraysize(reads),
   4131                             writes, arraysize(writes)));
   4132 
   4133   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   4134                                      BoundNetLog(), GetParam());
   4135   helper.RunPreTestSetup();
   4136   helper.AddData(data.get());
   4137   HttpNetworkTransaction* trans = helper.trans();
   4138   TestCompletionCallback callback;
   4139 
   4140   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   4141   EXPECT_EQ(ERR_IO_PENDING, rv);
   4142 
   4143   TransactionHelperResult out = helper.output();
   4144   out.rv = callback.WaitForResult();
   4145   EXPECT_EQ(out.rv, OK);
   4146 
   4147   const HttpResponseInfo* response = trans->GetResponseInfo();
   4148   EXPECT_TRUE(response->headers != NULL);
   4149   EXPECT_TRUE(response->was_fetched_via_spdy);
   4150   out.status_line = response->headers->GetStatusLine();
   4151   out.response_info = *response;  // Make a copy so we can verify.
   4152 
   4153   // Read Data
   4154   TestCompletionCallback read_callback;
   4155 
   4156   do {
   4157     const int kReadSize = 256;
   4158     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kReadSize));
   4159     rv = trans->Read(buf, kReadSize, &read_callback);
   4160     if (rv == net::ERR_IO_PENDING) {
   4161       // Complete the read now, which causes buffering to start.
   4162       data->CompleteRead();
   4163       // Destroy the transaction, causing the stream to get cancelled
   4164       // and orphaning the buffered IO task.
   4165       helper.ResetTrans();
   4166       break;
   4167     }
   4168     // We shouldn't get here in this test.
   4169     FAIL() << "Unexpected read: " << rv;
   4170   } while (rv > 0);
   4171 
   4172   // Flush the MessageLoop; this will cause the buffered IO task
   4173   // to run for the final time.
   4174   MessageLoop::current()->RunAllPending();
   4175 
   4176   // Verify that we consumed all test data.
   4177   helper.VerifyDataConsumed();
   4178 }
   4179 
   4180 // Test that if the server requests persistence of settings, that we save
   4181 // the settings in the SpdySettingsStorage.
   4182 TEST_P(SpdyNetworkTransactionTest, SettingsSaved) {
   4183   static const SpdyHeaderInfo kSynReplyInfo = {
   4184     spdy::SYN_REPLY,                              // Syn Reply
   4185     1,                                            // Stream ID
   4186     0,                                            // Associated Stream ID
   4187     net::ConvertRequestPriorityToSpdyPriority(LOWEST),
   4188                                                   // Priority
   4189     spdy::CONTROL_FLAG_NONE,                      // Control Flags
   4190     false,                                        // Compressed
   4191     spdy::INVALID,                                // Status
   4192     NULL,                                         // Data
   4193     0,                                            // Data Length
   4194     spdy::DATA_FLAG_NONE                          // Data Flags
   4195   };
   4196   static const char* const kExtraHeaders[] = {
   4197     "status",   "200",
   4198     "version",  "HTTP/1.1"
   4199   };
   4200 
   4201   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   4202                                      BoundNetLog(), GetParam());
   4203   helper.RunPreTestSetup();
   4204 
   4205   // Verify that no settings exist initially.
   4206   HostPortPair host_port_pair("www.google.com", helper.port());
   4207   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
   4208   EXPECT_TRUE(spdy_session_pool->spdy_settings().Get(host_port_pair).empty());
   4209 
   4210   // Construct the request.
   4211   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   4212   MockWrite writes[] = { CreateMockWrite(*req) };
   4213 
   4214   // Construct the reply.
   4215   scoped_ptr<spdy::SpdyFrame> reply(
   4216     ConstructSpdyPacket(kSynReplyInfo,
   4217                         kExtraHeaders,
   4218                         arraysize(kExtraHeaders) / 2,
   4219                         NULL,
   4220                         0));
   4221 
   4222   unsigned int kSampleId1 = 0x1;
   4223   unsigned int kSampleValue1 = 0x0a0a0a0a;
   4224   unsigned int kSampleId2 = 0x2;
   4225   unsigned int kSampleValue2 = 0x0b0b0b0b;
   4226   unsigned int kSampleId3 = 0xababab;
   4227   unsigned int kSampleValue3 = 0x0c0c0c0c;
   4228   scoped_ptr<spdy::SpdyFrame> settings_frame;
   4229   {
   4230     // Construct the SETTINGS frame.
   4231     spdy::SpdySettings settings;
   4232     spdy::SettingsFlagsAndId setting(0);
   4233     // First add a persisted setting
   4234     setting.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
   4235     setting.set_id(kSampleId1);
   4236     settings.push_back(std::make_pair(setting, kSampleValue1));
   4237     // Next add a non-persisted setting
   4238     setting.set_flags(0);
   4239     setting.set_id(kSampleId2);
   4240     settings.push_back(std::make_pair(setting, kSampleValue2));
   4241     // Next add another persisted setting
   4242     setting.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
   4243     setting.set_id(kSampleId3);
   4244     settings.push_back(std::make_pair(setting, kSampleValue3));
   4245     settings_frame.reset(ConstructSpdySettings(settings));
   4246   }
   4247 
   4248   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   4249   MockRead reads[] = {
   4250     CreateMockRead(*reply),
   4251     CreateMockRead(*body),
   4252     CreateMockRead(*settings_frame),
   4253     MockRead(true, 0, 0)  // EOF
   4254   };
   4255 
   4256   scoped_refptr<DelayedSocketData> data(
   4257       new DelayedSocketData(1, reads, arraysize(reads),
   4258                             writes, arraysize(writes)));
   4259   helper.AddData(data.get());
   4260   helper.RunDefaultTest();
   4261   helper.VerifyDataConsumed();
   4262   TransactionHelperResult out = helper.output();
   4263   EXPECT_EQ(OK, out.rv);
   4264   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   4265   EXPECT_EQ("hello!", out.response_data);
   4266 
   4267   {
   4268     // Verify we had two persisted settings.
   4269     spdy::SpdySettings saved_settings =
   4270         spdy_session_pool->spdy_settings().Get(host_port_pair);
   4271     ASSERT_EQ(2u, saved_settings.size());
   4272 
   4273     // Verify the first persisted setting.
   4274     spdy::SpdySetting setting = saved_settings.front();
   4275     saved_settings.pop_front();
   4276     EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, setting.first.flags());
   4277     EXPECT_EQ(kSampleId1, setting.first.id());
   4278     EXPECT_EQ(kSampleValue1, setting.second);
   4279 
   4280     // Verify the second persisted setting.
   4281     setting = saved_settings.front();
   4282     saved_settings.pop_front();
   4283     EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, setting.first.flags());
   4284     EXPECT_EQ(kSampleId3, setting.first.id());
   4285     EXPECT_EQ(kSampleValue3, setting.second);
   4286   }
   4287 }
   4288 
   4289 // Test that when there are settings saved that they are sent back to the
   4290 // server upon session establishment.
   4291 TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
   4292   static const SpdyHeaderInfo kSynReplyInfo = {
   4293     spdy::SYN_REPLY,                              // Syn Reply
   4294     1,                                            // Stream ID
   4295     0,                                            // Associated Stream ID
   4296     net::ConvertRequestPriorityToSpdyPriority(LOWEST),
   4297                                                   // Priority
   4298     spdy::CONTROL_FLAG_NONE,                      // Control Flags
   4299     false,                                        // Compressed
   4300     spdy::INVALID,                                // Status
   4301     NULL,                                         // Data
   4302     0,                                            // Data Length
   4303     spdy::DATA_FLAG_NONE                          // Data Flags
   4304   };
   4305   static const char* kExtraHeaders[] = {
   4306     "status",   "200",
   4307     "version",  "HTTP/1.1"
   4308   };
   4309 
   4310   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   4311                                      BoundNetLog(), GetParam());
   4312   helper.RunPreTestSetup();
   4313 
   4314   // Verify that no settings exist initially.
   4315   HostPortPair host_port_pair("www.google.com", helper.port());
   4316   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
   4317   EXPECT_TRUE(spdy_session_pool->spdy_settings().Get(host_port_pair).empty());
   4318 
   4319   unsigned int kSampleId1 = 0x1;
   4320   unsigned int kSampleValue1 = 0x0a0a0a0a;
   4321   unsigned int kSampleId2 = 0xababab;
   4322   unsigned int kSampleValue2 = 0x0c0c0c0c;
   4323   // Manually insert settings into the SpdySettingsStorage here.
   4324   {
   4325     spdy::SpdySettings settings;
   4326     spdy::SettingsFlagsAndId setting(0);
   4327     // First add a persisted setting
   4328     setting.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
   4329     setting.set_id(kSampleId1);
   4330     settings.push_back(std::make_pair(setting, kSampleValue1));
   4331     // Next add another persisted setting
   4332     setting.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
   4333     setting.set_id(kSampleId2);
   4334     settings.push_back(std::make_pair(setting, kSampleValue2));
   4335 
   4336     spdy_session_pool->mutable_spdy_settings()->Set(host_port_pair, settings);
   4337   }
   4338 
   4339   EXPECT_EQ(2u, spdy_session_pool->spdy_settings().Get(host_port_pair).size());
   4340 
   4341   // Construct the SETTINGS frame.
   4342   const spdy::SpdySettings& settings =
   4343       spdy_session_pool->spdy_settings().Get(host_port_pair);
   4344   scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings));
   4345 
   4346   // Construct the request.
   4347   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   4348 
   4349   MockWrite writes[] = {
   4350     CreateMockWrite(*settings_frame),
   4351     CreateMockWrite(*req),
   4352   };
   4353 
   4354   // Construct the reply.
   4355   scoped_ptr<spdy::SpdyFrame> reply(
   4356     ConstructSpdyPacket(kSynReplyInfo,
   4357                         kExtraHeaders,
   4358                         arraysize(kExtraHeaders) / 2,
   4359                         NULL,
   4360                         0));
   4361 
   4362   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   4363   MockRead reads[] = {
   4364     CreateMockRead(*reply),
   4365     CreateMockRead(*body),
   4366     MockRead(true, 0, 0)  // EOF
   4367   };
   4368 
   4369   scoped_refptr<DelayedSocketData> data(
   4370       new DelayedSocketData(2, reads, arraysize(reads),
   4371                             writes, arraysize(writes)));
   4372   helper.AddData(data.get());
   4373   helper.RunDefaultTest();
   4374   helper.VerifyDataConsumed();
   4375   TransactionHelperResult out = helper.output();
   4376   EXPECT_EQ(OK, out.rv);
   4377   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   4378   EXPECT_EQ("hello!", out.response_data);
   4379 
   4380   {
   4381     // Verify we had two persisted settings.
   4382     spdy::SpdySettings saved_settings =
   4383         spdy_session_pool->spdy_settings().Get(host_port_pair);
   4384     ASSERT_EQ(2u, saved_settings.size());
   4385 
   4386     // Verify the first persisted setting.
   4387     spdy::SpdySetting setting = saved_settings.front();
   4388     saved_settings.pop_front();
   4389     EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, setting.first.flags());
   4390     EXPECT_EQ(kSampleId1, setting.first.id());
   4391     EXPECT_EQ(kSampleValue1, setting.second);
   4392 
   4393     // Verify the second persisted setting.
   4394     setting = saved_settings.front();
   4395     saved_settings.pop_front();
   4396     EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, setting.first.flags());
   4397     EXPECT_EQ(kSampleId2, setting.first.id());
   4398     EXPECT_EQ(kSampleValue2, setting.second);
   4399   }
   4400 }
   4401 
   4402 TEST_P(SpdyNetworkTransactionTest, GoAwayWithActiveStream) {
   4403   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   4404   MockWrite writes[] = { CreateMockWrite(*req) };
   4405 
   4406   scoped_ptr<spdy::SpdyFrame> go_away(ConstructSpdyGoAway());
   4407   MockRead reads[] = {
   4408     CreateMockRead(*go_away),
   4409     MockRead(true, 0, 0),  // EOF
   4410   };
   4411 
   4412   scoped_refptr<DelayedSocketData> data(
   4413       new DelayedSocketData(1, reads, arraysize(reads),
   4414                             writes, arraysize(writes)));
   4415   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   4416                                      BoundNetLog(), GetParam());
   4417   helper.AddData(data);
   4418   helper.RunToCompletion(data.get());
   4419   TransactionHelperResult out = helper.output();
   4420   EXPECT_EQ(ERR_ABORTED, out.rv);
   4421 }
   4422 
   4423 TEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) {
   4424   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   4425   MockWrite writes[] = { CreateMockWrite(*req) };
   4426 
   4427   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   4428   MockRead reads[] = {
   4429     CreateMockRead(*resp),
   4430     MockRead(false, 0, 0)  // EOF
   4431   };
   4432 
   4433   scoped_refptr<DelayedSocketData> data(
   4434       new DelayedSocketData(1, reads, arraysize(reads),
   4435                             writes, arraysize(writes)));
   4436   BoundNetLog log;
   4437   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   4438                                      log, GetParam());
   4439   helper.RunPreTestSetup();
   4440   helper.AddData(data.get());
   4441   HttpNetworkTransaction* trans = helper.trans();
   4442 
   4443   TestCompletionCallback callback;
   4444   TransactionHelperResult out;
   4445   out.rv = trans->Start(&CreateGetRequest(), &callback, log);
   4446 
   4447   EXPECT_EQ(out.rv, ERR_IO_PENDING);
   4448   out.rv = callback.WaitForResult();
   4449   EXPECT_EQ(out.rv, OK);
   4450 
   4451   const HttpResponseInfo* response = trans->GetResponseInfo();
   4452   EXPECT_TRUE(response->headers != NULL);
   4453   EXPECT_TRUE(response->was_fetched_via_spdy);
   4454   out.rv = ReadTransaction(trans, &out.response_data);
   4455   EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv);
   4456 
   4457   // Verify that we consumed all test data.
   4458   helper.VerifyDataConsumed();
   4459 }
   4460 
   4461 // Test to make sure we can correctly connect through a proxy.
   4462 TEST_P(SpdyNetworkTransactionTest, ProxyConnect) {
   4463   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   4464                                      BoundNetLog(), GetParam());
   4465   helper.session_deps().reset(new SpdySessionDependencies(
   4466       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")));
   4467   helper.SetSession(make_scoped_refptr(
   4468       SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
   4469   helper.RunPreTestSetup();
   4470   HttpNetworkTransaction* trans = helper.trans();
   4471 
   4472   const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n"
   4473                            "Host: www.google.com\r\n"
   4474                            "Proxy-Connection: keep-alive\r\n\r\n"};
   4475   const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n"
   4476                            "Host: www.google.com\r\n"
   4477                            "Proxy-Connection: keep-alive\r\n\r\n"};
   4478   const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
   4479   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   4480   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   4481   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   4482 
   4483   MockWrite writes_SPDYNPN[] = {
   4484     MockWrite(false, kConnect443, arraysize(kConnect443) - 1, 0),
   4485     CreateMockWrite(*req, 2),
   4486   };
   4487   MockRead reads_SPDYNPN[] = {
   4488     MockRead(false, kHTTP200, arraysize(kHTTP200) - 1, 1),
   4489     CreateMockRead(*resp, 3),
   4490     CreateMockRead(*body.get(), 4),
   4491     MockRead(true, 0, 0, 5),
   4492   };
   4493 
   4494   MockWrite writes_SPDYSSL[] = {
   4495     MockWrite(false, kConnect80, arraysize(kConnect80) - 1, 0),
   4496     CreateMockWrite(*req, 2),
   4497   };
   4498   MockRead reads_SPDYSSL[] = {
   4499     MockRead(false, kHTTP200, arraysize(kHTTP200) - 1, 1),
   4500     CreateMockRead(*resp, 3),
   4501     CreateMockRead(*body.get(), 4),
   4502     MockRead(true, 0, 0, 5),
   4503   };
   4504 
   4505   MockWrite writes_SPDYNOSSL[] = {
   4506     CreateMockWrite(*req, 0),
   4507   };
   4508 
   4509   MockRead reads_SPDYNOSSL[] = {
   4510     CreateMockRead(*resp, 1),
   4511     CreateMockRead(*body.get(), 2),
   4512     MockRead(true, 0, 0, 3),
   4513   };
   4514 
   4515   scoped_refptr<OrderedSocketData> data;
   4516   switch(GetParam()) {
   4517     case SPDYNOSSL:
   4518       data = new OrderedSocketData(reads_SPDYNOSSL,
   4519                                    arraysize(reads_SPDYNOSSL),
   4520                                    writes_SPDYNOSSL,
   4521                                    arraysize(writes_SPDYNOSSL));
   4522       break;
   4523     case SPDYSSL:
   4524       data = new OrderedSocketData(reads_SPDYSSL, arraysize(reads_SPDYSSL),
   4525                                    writes_SPDYSSL, arraysize(writes_SPDYSSL));
   4526       break;
   4527     case SPDYNPN:
   4528       data = new OrderedSocketData(reads_SPDYNPN, arraysize(reads_SPDYNPN),
   4529                                    writes_SPDYNPN, arraysize(writes_SPDYNPN));
   4530       break;
   4531     default:
   4532       NOTREACHED();
   4533   }
   4534 
   4535   helper.AddData(data.get());
   4536   TestCompletionCallback callback;
   4537 
   4538   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   4539   EXPECT_EQ(ERR_IO_PENDING, rv);
   4540 
   4541   rv = callback.WaitForResult();
   4542   EXPECT_EQ(0, rv);
   4543 
   4544   // Verify the SYN_REPLY.
   4545   HttpResponseInfo response = *trans->GetResponseInfo();
   4546   EXPECT_TRUE(response.headers != NULL);
   4547   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   4548 
   4549   std::string response_data;
   4550   ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
   4551   EXPECT_EQ("hello!", response_data);
   4552   helper.VerifyDataConsumed();
   4553 }
   4554 
   4555 // Test to make sure we can correctly connect through a proxy to www.google.com,
   4556 // if there already exists a direct spdy connection to www.google.com. See
   4557 // http://crbug.com/49874
   4558 TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
   4559   // When setting up the first transaction, we store the SpdySessionPool so that
   4560   // we can use the same pool in the second transaction.
   4561   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   4562                                      BoundNetLog(), GetParam());
   4563 
   4564   // Use a proxy service which returns a proxy fallback list from DIRECT to
   4565   // myproxy:70. For this test there will be no fallback, so it is equivalent
   4566   // to simply DIRECT. The reason for appending the second proxy is to verify
   4567   // that the session pool key used does is just "DIRECT".
   4568   helper.session_deps().reset(new SpdySessionDependencies(
   4569       ProxyService::CreateFixedFromPacResult("DIRECT; PROXY myproxy:70")));
   4570   helper.SetSession(make_scoped_refptr(
   4571       SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
   4572 
   4573   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
   4574   helper.RunPreTestSetup();
   4575 
   4576   // Construct and send a simple GET request.
   4577   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   4578   MockWrite writes[] = {
   4579     CreateMockWrite(*req, 1),
   4580   };
   4581 
   4582   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   4583   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   4584   MockRead reads[] = {
   4585     CreateMockRead(*resp, 2),
   4586     CreateMockRead(*body, 3),
   4587     MockRead(true, ERR_IO_PENDING, 4),  // Force a pause
   4588     MockRead(true, 0, 5)  // EOF
   4589   };
   4590   scoped_refptr<OrderedSocketData> data(
   4591       new OrderedSocketData(reads, arraysize(reads),
   4592                             writes, arraysize(writes)));
   4593   helper.AddData(data.get());
   4594   HttpNetworkTransaction* trans = helper.trans();
   4595 
   4596   TestCompletionCallback callback;
   4597   TransactionHelperResult out;
   4598   out.rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   4599 
   4600   EXPECT_EQ(out.rv, ERR_IO_PENDING);
   4601   out.rv = callback.WaitForResult();
   4602   EXPECT_EQ(out.rv, OK);
   4603 
   4604   const HttpResponseInfo* response = trans->GetResponseInfo();
   4605   EXPECT_TRUE(response->headers != NULL);
   4606   EXPECT_TRUE(response->was_fetched_via_spdy);
   4607   out.rv = ReadTransaction(trans, &out.response_data);
   4608   EXPECT_EQ(OK, out.rv);
   4609   out.status_line = response->headers->GetStatusLine();
   4610   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   4611   EXPECT_EQ("hello!", out.response_data);
   4612 
   4613   // Check that the SpdySession is still in the SpdySessionPool.
   4614   HostPortPair host_port_pair("www.google.com", helper.port());
   4615   HostPortProxyPair session_pool_key_direct(
   4616       host_port_pair, ProxyServer::Direct());
   4617   EXPECT_TRUE(spdy_session_pool->HasSession(session_pool_key_direct));
   4618   HostPortProxyPair session_pool_key_proxy(
   4619       host_port_pair,
   4620       ProxyServer::FromURI("www.foo.com", ProxyServer::SCHEME_HTTP));
   4621   EXPECT_FALSE(spdy_session_pool->HasSession(session_pool_key_proxy));
   4622 
   4623   // Set up data for the proxy connection.
   4624   const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n"
   4625                            "Host: www.google.com\r\n"
   4626                            "Proxy-Connection: keep-alive\r\n\r\n"};
   4627   const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n"
   4628                            "Host: www.google.com\r\n"
   4629                            "Proxy-Connection: keep-alive\r\n\r\n"};
   4630   const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
   4631   scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(
   4632       "http://www.google.com/foo.dat", false, 1, LOWEST));
   4633   scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
   4634   scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
   4635 
   4636   MockWrite writes_SPDYNPN[] = {
   4637     MockWrite(false, kConnect443, arraysize(kConnect443) - 1, 0),
   4638     CreateMockWrite(*req2, 2),
   4639   };
   4640   MockRead reads_SPDYNPN[] = {
   4641     MockRead(false, kHTTP200, arraysize(kHTTP200) - 1, 1),
   4642     CreateMockRead(*resp2, 3),
   4643     CreateMockRead(*body2, 4),
   4644     MockRead(true, 0, 5)  // EOF
   4645   };
   4646 
   4647   MockWrite writes_SPDYNOSSL[] = {
   4648     CreateMockWrite(*req2, 0),
   4649   };
   4650   MockRead reads_SPDYNOSSL[] = {
   4651     CreateMockRead(*resp2, 1),
   4652     CreateMockRead(*body2, 2),
   4653     MockRead(true, 0, 3)  // EOF
   4654   };
   4655 
   4656   MockWrite writes_SPDYSSL[] = {
   4657     MockWrite(false, kConnect80, arraysize(kConnect80) - 1, 0),
   4658     CreateMockWrite(*req2, 2),
   4659   };
   4660   MockRead reads_SPDYSSL[] = {
   4661     MockRead(false, kHTTP200, arraysize(kHTTP200) - 1, 1),
   4662     CreateMockRead(*resp2, 3),
   4663     CreateMockRead(*body2, 4),
   4664     MockRead(true, 0, 0, 5),
   4665   };
   4666 
   4667   scoped_refptr<OrderedSocketData> data_proxy;
   4668   switch(GetParam()) {
   4669     case SPDYNPN:
   4670       data_proxy = new OrderedSocketData(reads_SPDYNPN,
   4671                                          arraysize(reads_SPDYNPN),
   4672                                          writes_SPDYNPN,
   4673                                          arraysize(writes_SPDYNPN));
   4674       break;
   4675     case SPDYNOSSL:
   4676       data_proxy = new OrderedSocketData(reads_SPDYNOSSL,
   4677                                          arraysize(reads_SPDYNOSSL),
   4678                                          writes_SPDYNOSSL,
   4679                                          arraysize(writes_SPDYNOSSL));
   4680       break;
   4681     case SPDYSSL:
   4682       data_proxy = new OrderedSocketData(reads_SPDYSSL,
   4683                                          arraysize(reads_SPDYSSL),
   4684                                          writes_SPDYSSL,
   4685                                          arraysize(writes_SPDYSSL));
   4686       break;
   4687     default:
   4688       NOTREACHED();
   4689   }
   4690 
   4691   // Create another request to www.google.com, but this time through a proxy.
   4692   HttpRequestInfo request_proxy;
   4693   request_proxy.method = "GET";
   4694   request_proxy.url = GURL("http://www.google.com/foo.dat");
   4695   request_proxy.load_flags = 0;
   4696   scoped_ptr<SpdySessionDependencies> ssd_proxy(new SpdySessionDependencies());
   4697   // Ensure that this transaction uses the same SpdySessionPool.
   4698   scoped_refptr<HttpNetworkSession> session_proxy(
   4699       SpdySessionDependencies::SpdyCreateSession(ssd_proxy.get()));
   4700   NormalSpdyTransactionHelper helper_proxy(request_proxy,
   4701                                            BoundNetLog(), GetParam());
   4702   HttpNetworkSessionPeer session_peer(session_proxy);
   4703   session_peer.SetProxyService(
   4704           ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   4705   helper_proxy.session_deps().swap(ssd_proxy);
   4706   helper_proxy.SetSession(session_proxy);
   4707   helper_proxy.RunPreTestSetup();
   4708   helper_proxy.AddData(data_proxy.get());
   4709 
   4710   HttpNetworkTransaction* trans_proxy = helper_proxy.trans();
   4711   TestCompletionCallback callback_proxy;
   4712   int rv = trans_proxy->Start(&request_proxy, &callback_proxy, BoundNetLog());
   4713   EXPECT_EQ(ERR_IO_PENDING, rv);
   4714   rv = callback_proxy.WaitForResult();
   4715   EXPECT_EQ(0, rv);
   4716 
   4717   HttpResponseInfo response_proxy = *trans_proxy->GetResponseInfo();
   4718   EXPECT_TRUE(response_proxy.headers != NULL);
   4719   EXPECT_EQ("HTTP/1.1 200 OK", response_proxy.headers->GetStatusLine());
   4720 
   4721   std::string response_data;
   4722   ASSERT_EQ(OK, ReadTransaction(trans_proxy, &response_data));
   4723   EXPECT_EQ("hello!", response_data);
   4724 
   4725   data->CompleteRead();
   4726   helper_proxy.VerifyDataConsumed();
   4727 }
   4728 
   4729 // When we get a TCP-level RST, we need to retry a HttpNetworkTransaction
   4730 // on a new connection, if the connection was previously known to be good.
   4731 // This can happen when a server reboots without saying goodbye, or when
   4732 // we're behind a NAT that masked the RST.
   4733 TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) {
   4734   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   4735   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   4736   MockRead reads[] = {
   4737     CreateMockRead(*resp),
   4738     CreateMockRead(*body),
   4739     MockRead(true, ERR_IO_PENDING),
   4740     MockRead(true, ERR_CONNECTION_RESET),
   4741   };
   4742 
   4743   MockRead reads2[] = {
   4744     CreateMockRead(*resp),
   4745     CreateMockRead(*body),
   4746     MockRead(true, 0, 0)  // EOF
   4747   };
   4748 
   4749   // This test has a couple of variants.
   4750   enum {
   4751     // Induce the RST while waiting for our transaction to send.
   4752     VARIANT_RST_DURING_SEND_COMPLETION,
   4753     // Induce the RST while waiting for our transaction to read.
   4754     // In this case, the send completed - everything copied into the SNDBUF.
   4755     VARIANT_RST_DURING_READ_COMPLETION
   4756   };
   4757 
   4758   for (int variant = VARIANT_RST_DURING_SEND_COMPLETION;
   4759        variant <= VARIANT_RST_DURING_READ_COMPLETION;
   4760        ++variant) {
   4761     scoped_refptr<DelayedSocketData> data1(
   4762         new DelayedSocketData(1, reads, arraysize(reads),
   4763                               NULL, 0));
   4764 
   4765     scoped_refptr<DelayedSocketData> data2(
   4766         new DelayedSocketData(1, reads2, arraysize(reads2),
   4767                                NULL, 0));
   4768 
   4769     NormalSpdyTransactionHelper helper(CreateGetRequest(),
   4770                                        BoundNetLog(), GetParam());
   4771     helper.AddData(data1.get());
   4772     helper.AddData(data2.get());
   4773     helper.RunPreTestSetup();
   4774 
   4775     for (int i = 0; i < 2; ++i) {
   4776       scoped_ptr<HttpNetworkTransaction> trans(
   4777           new HttpNetworkTransaction(helper.session()));
   4778 
   4779       TestCompletionCallback callback;
   4780       int rv = trans->Start(&helper.request(), &callback, BoundNetLog());
   4781       EXPECT_EQ(ERR_IO_PENDING, rv);
   4782       // On the second transaction, we trigger the RST.
   4783       if (i == 1) {
   4784         if (variant == VARIANT_RST_DURING_READ_COMPLETION) {
   4785           // Writes to the socket complete asynchronously on SPDY by running
   4786           // through the message loop.  Complete the write here.
   4787           MessageLoop::current()->RunAllPending();
   4788         }
   4789 
   4790         // Now schedule the ERR_CONNECTION_RESET.
   4791         EXPECT_EQ(3u, data1->read_index());
   4792         data1->CompleteRead();
   4793         EXPECT_EQ(4u, data1->read_index());
   4794       }
   4795       rv = callback.WaitForResult();
   4796       EXPECT_EQ(OK, rv);
   4797 
   4798       const HttpResponseInfo* response = trans->GetResponseInfo();
   4799       ASSERT_TRUE(response != NULL);
   4800       EXPECT_TRUE(response->headers != NULL);
   4801       EXPECT_TRUE(response->was_fetched_via_spdy);
   4802       std::string response_data;
   4803       rv = ReadTransaction(trans.get(), &response_data);
   4804       EXPECT_EQ(OK, rv);
   4805       EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4806       EXPECT_EQ("hello!", response_data);
   4807     }
   4808 
   4809     helper.VerifyDataConsumed();
   4810   }
   4811 }
   4812 
   4813 // Test that turning SPDY on and off works properly.
   4814 TEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) {
   4815   net::HttpStreamFactory::set_spdy_enabled(true);
   4816   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   4817   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   4818 
   4819   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   4820   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   4821   MockRead spdy_reads[] = {
   4822     CreateMockRead(*resp),
   4823     CreateMockRead(*body),
   4824     MockRead(true, 0, 0)  // EOF
   4825   };
   4826 
   4827   scoped_refptr<DelayedSocketData> data(
   4828       new DelayedSocketData(1,
   4829                             spdy_reads, arraysize(spdy_reads),
   4830                             spdy_writes, arraysize(spdy_writes)));
   4831   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   4832                                      BoundNetLog(), GetParam());
   4833   helper.RunToCompletion(data.get());
   4834   TransactionHelperResult out = helper.output();
   4835   EXPECT_EQ(OK, out.rv);
   4836   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   4837   EXPECT_EQ("hello!", out.response_data);
   4838 
   4839   net::HttpStreamFactory::set_spdy_enabled(false);
   4840   MockRead http_reads[] = {
   4841     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   4842     MockRead("hello from http"),
   4843     MockRead(false, OK),
   4844   };
   4845   scoped_refptr<DelayedSocketData> data2(
   4846       new DelayedSocketData(1, http_reads, arraysize(http_reads),
   4847                             NULL, 0));
   4848   NormalSpdyTransactionHelper helper2(CreateGetRequest(),
   4849                                      BoundNetLog(), GetParam());
   4850   helper2.SetSpdyDisabled();
   4851   helper2.RunToCompletion(data2.get());
   4852   TransactionHelperResult out2 = helper2.output();
   4853   EXPECT_EQ(OK, out2.rv);
   4854   EXPECT_EQ("HTTP/1.1 200 OK", out2.status_line);
   4855   EXPECT_EQ("hello from http", out2.response_data);
   4856 
   4857   net::HttpStreamFactory::set_spdy_enabled(true);
   4858 }
   4859 
   4860 // Tests that Basic authentication works over SPDY
   4861 TEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) {
   4862   net::HttpStreamFactory::set_spdy_enabled(true);
   4863 
   4864   // The first request will be a bare GET, the second request will be a
   4865   // GET with an Authorization header.
   4866   scoped_ptr<spdy::SpdyFrame> req_get(
   4867       ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   4868   const char* const kExtraAuthorizationHeaders[] = {
   4869     "authorization",
   4870     "Basic Zm9vOmJhcg==",
   4871   };
   4872   scoped_ptr<spdy::SpdyFrame> req_get_authorization(
   4873       ConstructSpdyGet(
   4874           kExtraAuthorizationHeaders,
   4875           arraysize(kExtraAuthorizationHeaders) / 2,
   4876           false, 3, LOWEST));
   4877   MockWrite spdy_writes[] = {
   4878     CreateMockWrite(*req_get, 1),
   4879     CreateMockWrite(*req_get_authorization, 4),
   4880   };
   4881 
   4882   // The first response is a 401 authentication challenge, and the second
   4883   // response will be a 200 response since the second request includes a valid
   4884   // Authorization header.
   4885   const char* const kExtraAuthenticationHeaders[] = {
   4886     "WWW-Authenticate",
   4887     "Basic realm=\"MyRealm\""
   4888   };
   4889   scoped_ptr<spdy::SpdyFrame> resp_authentication(
   4890       ConstructSpdySynReplyError(
   4891           "401 Authentication Required",
   4892           kExtraAuthenticationHeaders,
   4893           arraysize(kExtraAuthenticationHeaders) / 2,
   4894           1));
   4895   scoped_ptr<spdy::SpdyFrame> body_authentication(
   4896       ConstructSpdyBodyFrame(1, true));
   4897   scoped_ptr<spdy::SpdyFrame> resp_data(ConstructSpdyGetSynReply(NULL, 0, 3));
   4898   scoped_ptr<spdy::SpdyFrame> body_data(ConstructSpdyBodyFrame(3, true));
   4899   MockRead spdy_reads[] = {
   4900     CreateMockRead(*resp_authentication, 2),
   4901     CreateMockRead(*body_authentication, 3),
   4902     CreateMockRead(*resp_data, 5),
   4903     CreateMockRead(*body_data, 6),
   4904     MockRead(true, 0, 7),
   4905   };
   4906 
   4907   scoped_refptr<OrderedSocketData> data(
   4908       new OrderedSocketData(spdy_reads, arraysize(spdy_reads),
   4909                             spdy_writes, arraysize(spdy_writes)));
   4910   HttpRequestInfo request(CreateGetRequest());
   4911   BoundNetLog net_log;
   4912   NormalSpdyTransactionHelper helper(request, net_log, GetParam());
   4913 
   4914   helper.RunPreTestSetup();
   4915   helper.AddData(data.get());
   4916   HttpNetworkTransaction* trans = helper.trans();
   4917   TestCompletionCallback callback_start;
   4918   const int rv_start = trans->Start(&request, &callback_start, net_log);
   4919   EXPECT_EQ(ERR_IO_PENDING, rv_start);
   4920   const int rv_start_complete = callback_start.WaitForResult();
   4921   EXPECT_EQ(OK, rv_start_complete);
   4922 
   4923   // Make sure the response has an auth challenge.
   4924   const HttpResponseInfo* const response_start = trans->GetResponseInfo();
   4925   ASSERT_TRUE(response_start != NULL);
   4926   ASSERT_TRUE(response_start->headers != NULL);
   4927   EXPECT_EQ(401, response_start->headers->response_code());
   4928   EXPECT_TRUE(response_start->was_fetched_via_spdy);
   4929   ASSERT_TRUE(response_start->auth_challenge.get() != NULL);
   4930   EXPECT_FALSE(response_start->auth_challenge->is_proxy);
   4931   EXPECT_EQ(L"basic", response_start->auth_challenge->scheme);
   4932   EXPECT_EQ(L"MyRealm", response_start->auth_challenge->realm);
   4933 
   4934   // Restart with a username/password.
   4935   const string16 kFoo(ASCIIToUTF16("foo"));
   4936   const string16 kBar(ASCIIToUTF16("bar"));
   4937   TestCompletionCallback callback_restart;
   4938   const int rv_restart = trans->RestartWithAuth(kFoo, kBar, &callback_restart);
   4939   EXPECT_EQ(ERR_IO_PENDING, rv_restart);
   4940   const int rv_restart_complete = callback_restart.WaitForResult();
   4941   EXPECT_EQ(OK, rv_restart_complete);
   4942   // TODO(cbentzel): This is actually the same response object as before, but
   4943   // data has changed.
   4944   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
   4945   ASSERT_TRUE(response_restart != NULL);
   4946   ASSERT_TRUE(response_restart->headers != NULL);
   4947   EXPECT_EQ(200, response_restart->headers->response_code());
   4948   EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
   4949 }
   4950 
   4951 TEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) {
   4952   static const unsigned char kPushBodyFrame[] = {
   4953     0x00, 0x00, 0x00, 0x02,                                      // header, ID
   4954     0x01, 0x00, 0x00, 0x06,                                      // FIN, length
   4955     'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
   4956   };
   4957   scoped_ptr<spdy::SpdyFrame>
   4958       stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   4959   scoped_ptr<spdy::SpdyFrame>
   4960       stream1_body(ConstructSpdyBodyFrame(1, true));
   4961   MockWrite writes[] = {
   4962     CreateMockWrite(*stream1_syn, 1),
   4963   };
   4964 
   4965   static const char* const kInitialHeaders[] = {
   4966     "url",
   4967     "http://www.google.com/foo.dat",
   4968   };
   4969   static const char* const kLateHeaders[] = {
   4970     "hello",
   4971     "bye",
   4972     "status",
   4973     "200",
   4974     "version",
   4975     "HTTP/1.1"
   4976   };
   4977   scoped_ptr<spdy::SpdyFrame>
   4978     stream2_syn(ConstructSpdyControlFrame(kInitialHeaders,
   4979                                           arraysize(kInitialHeaders) / 2,
   4980                                           false,
   4981                                           2,
   4982                                           LOWEST,
   4983                                           spdy::SYN_STREAM,
   4984                                           spdy::CONTROL_FLAG_NONE,
   4985                                           NULL,
   4986                                           0,
   4987                                           1));
   4988   scoped_ptr<spdy::SpdyFrame>
   4989       stream2_headers(ConstructSpdyControlFrame(kLateHeaders,
   4990                                                 arraysize(kLateHeaders) / 2,
   4991                                                 false,
   4992                                                 2,
   4993                                                 LOWEST,
   4994                                                 spdy::HEADERS,
   4995                                                 spdy::CONTROL_FLAG_NONE,
   4996                                                 NULL,
   4997                                                 0,
   4998                                                 0));
   4999 
   5000   scoped_ptr<spdy::SpdyFrame>
   5001       stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   5002   MockRead reads[] = {
   5003     CreateMockRead(*stream1_reply, 2),
   5004     CreateMockRead(*stream2_syn, 3),
   5005     CreateMockRead(*stream2_headers, 4),
   5006     CreateMockRead(*stream1_body, 5, false),
   5007     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame),
   5008              arraysize(kPushBodyFrame), 6),
   5009     MockRead(true, ERR_IO_PENDING, 7),  // Force a pause
   5010   };
   5011 
   5012   HttpResponseInfo response;
   5013   HttpResponseInfo response2;
   5014   std::string expected_push_result("pushed");
   5015   scoped_refptr<OrderedSocketData> data(new OrderedSocketData(
   5016       reads,
   5017       arraysize(reads),
   5018       writes,
   5019       arraysize(writes)));
   5020   RunServerPushTest(data.get(),
   5021                     &response,
   5022                     &response2,
   5023                     expected_push_result);
   5024 
   5025   // Verify the SYN_REPLY.
   5026   EXPECT_TRUE(response.headers != NULL);
   5027   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   5028 
   5029   // Verify the pushed stream.
   5030   EXPECT_TRUE(response2.headers != NULL);
   5031   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
   5032 }
   5033 
   5034 TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) {
   5035   // We push a stream and attempt to claim it before the headers come down.
   5036   static const unsigned char kPushBodyFrame[] = {
   5037     0x00, 0x00, 0x00, 0x02,                                      // header, ID
   5038     0x01, 0x00, 0x00, 0x06,                                      // FIN, length
   5039     'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
   5040   };
   5041   scoped_ptr<spdy::SpdyFrame>
   5042       stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   5043   scoped_ptr<spdy::SpdyFrame>
   5044       stream1_body(ConstructSpdyBodyFrame(1, true));
   5045   MockWrite writes[] = {
   5046     CreateMockWrite(*stream1_syn, 0, false),
   5047   };
   5048 
   5049   static const char* const kInitialHeaders[] = {
   5050     "url",
   5051     "http://www.google.com/foo.dat",
   5052   };
   5053   static const char* const kLateHeaders[] = {
   5054     "hello",
   5055     "bye",
   5056     "status",
   5057     "200",
   5058     "version",
   5059     "HTTP/1.1"
   5060   };
   5061   scoped_ptr<spdy::SpdyFrame>
   5062       stream2_syn(ConstructSpdyControlFrame(kInitialHeaders,
   5063                                             arraysize(kInitialHeaders) / 2,
   5064                                             false,
   5065                                             2,
   5066                                             LOWEST,
   5067                                             spdy::SYN_STREAM,
   5068                                             spdy::CONTROL_FLAG_NONE,
   5069                                             NULL,
   5070                                             0,
   5071                                             1));
   5072   scoped_ptr<spdy::SpdyFrame>
   5073       stream2_headers(ConstructSpdyControlFrame(kLateHeaders,
   5074                                                 arraysize(kLateHeaders) / 2,
   5075                                                 false,
   5076                                                 2,
   5077                                                 LOWEST,
   5078                                                 spdy::HEADERS,
   5079                                                 spdy::CONTROL_FLAG_NONE,
   5080                                                 NULL,
   5081                                                 0,
   5082                                                 0));
   5083 
   5084   scoped_ptr<spdy::SpdyFrame>
   5085       stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   5086   MockRead reads[] = {
   5087     CreateMockRead(*stream1_reply, 1),
   5088     CreateMockRead(*stream2_syn, 2),
   5089     CreateMockRead(*stream1_body, 3),
   5090     CreateMockRead(*stream2_headers, 4),
   5091     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame),
   5092              arraysize(kPushBodyFrame), 5),
   5093     MockRead(true, 0, 5),  // EOF
   5094   };
   5095 
   5096   HttpResponseInfo response;
   5097   HttpResponseInfo response2;
   5098   std::string expected_push_result("pushed");
   5099   scoped_refptr<DeterministicSocketData> data(new DeterministicSocketData(
   5100       reads,
   5101       arraysize(reads),
   5102       writes,
   5103       arraysize(writes)));
   5104 
   5105   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   5106                                      BoundNetLog(), GetParam());
   5107   helper.SetDeterministic();
   5108   helper.AddDeterministicData(static_cast<DeterministicSocketData*>(data));
   5109   helper.RunPreTestSetup();
   5110 
   5111   HttpNetworkTransaction* trans = helper.trans();
   5112 
   5113   // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
   5114   // and the body of the primary stream, but before we've received the HEADERS
   5115   // for the pushed stream.
   5116   data->SetStop(3);
   5117 
   5118   // Start the transaction.
   5119   TestCompletionCallback callback;
   5120   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   5121   EXPECT_EQ(ERR_IO_PENDING, rv);
   5122   data->Run();
   5123   rv = callback.WaitForResult();
   5124   EXPECT_EQ(0, rv);
   5125 
   5126   // Request the pushed path.  At this point, we've received the push, but the
   5127   // headers are not yet complete.
   5128   scoped_ptr<HttpNetworkTransaction> trans2(
   5129       new HttpNetworkTransaction(helper.session()));
   5130   rv = trans2->Start(&CreateGetPushRequest(), &callback, BoundNetLog());
   5131   EXPECT_EQ(ERR_IO_PENDING, rv);
   5132   data->RunFor(3);
   5133   MessageLoop::current()->RunAllPending();
   5134 
   5135   // Read the server push body.
   5136   std::string result2;
   5137   ReadResult(trans2.get(), data.get(), &result2);
   5138   // Read the response body.
   5139   std::string result;
   5140   ReadResult(trans, data, &result);
   5141 
   5142   // Verify that we consumed all test data.
   5143   EXPECT_TRUE(data->at_read_eof());
   5144   EXPECT_TRUE(data->at_write_eof());
   5145 
   5146   // Verify that the received push data is same as the expected push data.
   5147   EXPECT_EQ(result2.compare(expected_push_result), 0)
   5148       << "Received data: "
   5149       << result2
   5150       << "||||| Expected data: "
   5151       << expected_push_result;
   5152 
   5153   // Verify the SYN_REPLY.
   5154   // Copy the response info, because trans goes away.
   5155   response = *trans->GetResponseInfo();
   5156   response2 = *trans2->GetResponseInfo();
   5157 
   5158   VerifyStreamsClosed(helper);
   5159 
   5160   // Verify the SYN_REPLY.
   5161   EXPECT_TRUE(response.headers != NULL);
   5162   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   5163 
   5164   // Verify the pushed stream.
   5165   EXPECT_TRUE(response2.headers != NULL);
   5166   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
   5167 }
   5168 
   5169 TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) {
   5170   // We push a stream and attempt to claim it before the headers come down.
   5171   static const unsigned char kPushBodyFrame[] = {
   5172     0x00, 0x00, 0x00, 0x02,                                      // header, ID
   5173     0x01, 0x00, 0x00, 0x06,                                      // FIN, length
   5174     'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
   5175   };
   5176   scoped_ptr<spdy::SpdyFrame>
   5177       stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   5178   scoped_ptr<spdy::SpdyFrame>
   5179       stream1_body(ConstructSpdyBodyFrame(1, true));
   5180   MockWrite writes[] = {
   5181     CreateMockWrite(*stream1_syn, 0, false),
   5182   };
   5183 
   5184   static const char* const kInitialHeaders[] = {
   5185     "url",
   5186     "http://www.google.com/foo.dat",
   5187   };
   5188   static const char* const kMiddleHeaders[] = {
   5189     "hello",
   5190     "bye",
   5191   };
   5192   static const char* const kLateHeaders[] = {
   5193     "status",
   5194     "200",
   5195     "version",
   5196     "HTTP/1.1"
   5197   };
   5198   scoped_ptr<spdy::SpdyFrame>
   5199       stream2_syn(ConstructSpdyControlFrame(kInitialHeaders,
   5200                                             arraysize(kInitialHeaders) / 2,
   5201                                             false,
   5202                                             2,
   5203                                             LOWEST,
   5204                                             spdy::SYN_STREAM,
   5205                                             spdy::CONTROL_FLAG_NONE,
   5206                                             NULL,
   5207                                             0,
   5208                                             1));
   5209   scoped_ptr<spdy::SpdyFrame>
   5210       stream2_headers1(ConstructSpdyControlFrame(kMiddleHeaders,
   5211                                                  arraysize(kMiddleHeaders) / 2,
   5212                                                  false,
   5213                                                  2,
   5214                                                  LOWEST,
   5215                                                  spdy::HEADERS,
   5216                                                  spdy::CONTROL_FLAG_NONE,
   5217                                                  NULL,
   5218                                                  0,
   5219                                                  0));
   5220   scoped_ptr<spdy::SpdyFrame>
   5221       stream2_headers2(ConstructSpdyControlFrame(kLateHeaders,
   5222                                                  arraysize(kLateHeaders) / 2,
   5223                                                  false,
   5224                                                  2,
   5225                                                  LOWEST,
   5226                                                  spdy::HEADERS,
   5227                                                  spdy::CONTROL_FLAG_NONE,
   5228                                                  NULL,
   5229                                                  0,
   5230                                                  0));
   5231 
   5232   scoped_ptr<spdy::SpdyFrame>
   5233       stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   5234   MockRead reads[] = {
   5235     CreateMockRead(*stream1_reply, 1),
   5236     CreateMockRead(*stream2_syn, 2),
   5237     CreateMockRead(*stream1_body, 3),
   5238     CreateMockRead(*stream2_headers1, 4),
   5239     CreateMockRead(*stream2_headers2, 5),
   5240     MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame),
   5241              arraysize(kPushBodyFrame), 6),
   5242     MockRead(true, 0, 6),  // EOF
   5243   };
   5244 
   5245   HttpResponseInfo response;
   5246   HttpResponseInfo response2;
   5247   std::string expected_push_result("pushed");
   5248   scoped_refptr<DeterministicSocketData> data(new DeterministicSocketData(
   5249       reads,
   5250       arraysize(reads),
   5251       writes,
   5252       arraysize(writes)));
   5253 
   5254   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   5255                                      BoundNetLog(), GetParam());
   5256   helper.SetDeterministic();
   5257   helper.AddDeterministicData(static_cast<DeterministicSocketData*>(data));
   5258   helper.RunPreTestSetup();
   5259 
   5260   HttpNetworkTransaction* trans = helper.trans();
   5261 
   5262   // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
   5263   // the first HEADERS frame, and the body of the primary stream, but before
   5264   // we've received the final HEADERS for the pushed stream.
   5265   data->SetStop(4);
   5266 
   5267   // Start the transaction.
   5268   TestCompletionCallback callback;
   5269   int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
   5270   EXPECT_EQ(ERR_IO_PENDING, rv);
   5271   data->Run();
   5272   rv = callback.WaitForResult();
   5273   EXPECT_EQ(0, rv);
   5274 
   5275   // Request the pushed path.  At this point, we've received the push, but the
   5276   // headers are not yet complete.
   5277   scoped_ptr<HttpNetworkTransaction> trans2(
   5278       new HttpNetworkTransaction(helper.session()));
   5279   rv = trans2->Start(&CreateGetPushRequest(), &callback, BoundNetLog());
   5280   EXPECT_EQ(ERR_IO_PENDING, rv);
   5281   data->RunFor(3);
   5282   MessageLoop::current()->RunAllPending();
   5283 
   5284   // Read the server push body.
   5285   std::string result2;
   5286   ReadResult(trans2.get(), data, &result2);
   5287   // Read the response body.
   5288   std::string result;
   5289   ReadResult(trans, data, &result);
   5290 
   5291   // Verify that we consumed all test data.
   5292   EXPECT_TRUE(data->at_read_eof());
   5293   EXPECT_TRUE(data->at_write_eof());
   5294 
   5295   // Verify that the received push data is same as the expected push data.
   5296   EXPECT_EQ(result2.compare(expected_push_result), 0)
   5297       << "Received data: "
   5298       << result2
   5299       << "||||| Expected data: "
   5300       << expected_push_result;
   5301 
   5302   // Verify the SYN_REPLY.
   5303   // Copy the response info, because trans goes away.
   5304   response = *trans->GetResponseInfo();
   5305   response2 = *trans2->GetResponseInfo();
   5306 
   5307   VerifyStreamsClosed(helper);
   5308 
   5309   // Verify the SYN_REPLY.
   5310   EXPECT_TRUE(response.headers != NULL);
   5311   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   5312 
   5313   // Verify the pushed stream.
   5314   EXPECT_TRUE(response2.headers != NULL);
   5315   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
   5316 
   5317   // Verify we got all the headers
   5318   EXPECT_TRUE(response2.headers->HasHeaderValue(
   5319       "url",
   5320       "http://www.google.com/foo.dat"));
   5321   EXPECT_TRUE(response2.headers->HasHeaderValue("hello", "bye"));
   5322   EXPECT_TRUE(response2.headers->HasHeaderValue("status", "200"));
   5323   EXPECT_TRUE(response2.headers->HasHeaderValue("version", "HTTP/1.1"));
   5324 }
   5325 
   5326 TEST_P(SpdyNetworkTransactionTest, SynReplyWithHeaders) {
   5327   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   5328   MockWrite writes[] = { CreateMockWrite(*req) };
   5329 
   5330   static const char* const kInitialHeaders[] = {
   5331     "status",
   5332     "200 OK",
   5333     "version",
   5334     "HTTP/1.1"
   5335   };
   5336   static const char* const kLateHeaders[] = {
   5337     "hello",
   5338     "bye",
   5339   };
   5340   scoped_ptr<spdy::SpdyFrame>
   5341       stream1_reply(ConstructSpdyControlFrame(kInitialHeaders,
   5342                                               arraysize(kInitialHeaders) / 2,
   5343                                               false,
   5344                                               1,
   5345                                               LOWEST,
   5346                                               spdy::SYN_REPLY,
   5347                                               spdy::CONTROL_FLAG_NONE,
   5348                                               NULL,
   5349                                               0,
   5350                                               0));
   5351   scoped_ptr<spdy::SpdyFrame>
   5352       stream1_headers(ConstructSpdyControlFrame(kLateHeaders,
   5353                                                 arraysize(kLateHeaders) / 2,
   5354                                                 false,
   5355                                                 1,
   5356                                                 LOWEST,
   5357                                                 spdy::HEADERS,
   5358                                                 spdy::CONTROL_FLAG_NONE,
   5359                                                 NULL,
   5360                                                 0,
   5361                                                 0));
   5362   scoped_ptr<spdy::SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, true));
   5363   MockRead reads[] = {
   5364     CreateMockRead(*stream1_reply),
   5365     CreateMockRead(*stream1_headers),
   5366     CreateMockRead(*stream1_body),
   5367     MockRead(true, 0, 0)  // EOF
   5368   };
   5369 
   5370   scoped_refptr<DelayedSocketData> data(
   5371       new DelayedSocketData(1, reads, arraysize(reads),
   5372                             writes, arraysize(writes)));
   5373   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   5374                                      BoundNetLog(), GetParam());
   5375   helper.RunToCompletion(data.get());
   5376   TransactionHelperResult out = helper.output();
   5377   EXPECT_EQ(OK, out.rv);
   5378   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   5379   EXPECT_EQ("hello!", out.response_data);
   5380 }
   5381 
   5382 TEST_P(SpdyNetworkTransactionTest, SynReplyWithLateHeaders) {
   5383   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   5384   MockWrite writes[] = { CreateMockWrite(*req) };
   5385 
   5386   static const char* const kInitialHeaders[] = {
   5387     "status",
   5388     "200 OK",
   5389     "version",
   5390     "HTTP/1.1"
   5391   };
   5392   static const char* const kLateHeaders[] = {
   5393     "hello",
   5394     "bye",
   5395   };
   5396   scoped_ptr<spdy::SpdyFrame>
   5397       stream1_reply(ConstructSpdyControlFrame(kInitialHeaders,
   5398                                               arraysize(kInitialHeaders) / 2,
   5399                                               false,
   5400                                               1,
   5401                                               LOWEST,
   5402                                               spdy::SYN_REPLY,
   5403                                               spdy::CONTROL_FLAG_NONE,
   5404                                               NULL,
   5405                                               0,
   5406                                               0));
   5407   scoped_ptr<spdy::SpdyFrame>
   5408       stream1_headers(ConstructSpdyControlFrame(kLateHeaders,
   5409                                                 arraysize(kLateHeaders) / 2,
   5410                                                 false,
   5411                                                 1,
   5412                                                 LOWEST,
   5413                                                 spdy::HEADERS,
   5414                                                 spdy::CONTROL_FLAG_NONE,
   5415                                                 NULL,
   5416                                                 0,
   5417                                                 0));
   5418   scoped_ptr<spdy::SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, false));
   5419   scoped_ptr<spdy::SpdyFrame> stream1_body2(ConstructSpdyBodyFrame(1, true));
   5420   MockRead reads[] = {
   5421     CreateMockRead(*stream1_reply),
   5422     CreateMockRead(*stream1_body),
   5423     CreateMockRead(*stream1_headers),
   5424     CreateMockRead(*stream1_body2),
   5425     MockRead(true, 0, 0)  // EOF
   5426   };
   5427 
   5428   scoped_refptr<DelayedSocketData> data(
   5429       new DelayedSocketData(1, reads, arraysize(reads),
   5430                             writes, arraysize(writes)));
   5431   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   5432                                      BoundNetLog(), GetParam());
   5433   helper.RunToCompletion(data.get());
   5434   TransactionHelperResult out = helper.output();
   5435   EXPECT_EQ(OK, out.rv);
   5436   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
   5437   EXPECT_EQ("hello!hello!", out.response_data);
   5438 }
   5439 
   5440 TEST_P(SpdyNetworkTransactionTest, SynReplyWithDuplicateLateHeaders) {
   5441   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   5442   MockWrite writes[] = { CreateMockWrite(*req) };
   5443 
   5444   static const char* const kInitialHeaders[] = {
   5445     "status",
   5446     "200 OK",
   5447     "version",
   5448     "HTTP/1.1"
   5449   };
   5450   static const char* const kLateHeaders[] = {
   5451     "status",
   5452     "500 Server Error",
   5453   };
   5454   scoped_ptr<spdy::SpdyFrame>
   5455       stream1_reply(ConstructSpdyControlFrame(kInitialHeaders,
   5456                                               arraysize(kInitialHeaders) / 2,
   5457                                               false,
   5458                                               1,
   5459                                               LOWEST,
   5460                                               spdy::SYN_REPLY,
   5461                                               spdy::CONTROL_FLAG_NONE,
   5462                                               NULL,
   5463                                               0,
   5464                                               0));
   5465   scoped_ptr<spdy::SpdyFrame>
   5466       stream1_headers(ConstructSpdyControlFrame(kLateHeaders,
   5467                                                 arraysize(kLateHeaders) / 2,
   5468                                                 false,
   5469                                                 1,
   5470                                                 LOWEST,
   5471                                                 spdy::HEADERS,
   5472                                                 spdy::CONTROL_FLAG_NONE,
   5473                                                 NULL,
   5474                                                 0,
   5475                                                 0));
   5476   scoped_ptr<spdy::SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, false));
   5477   scoped_ptr<spdy::SpdyFrame> stream1_body2(ConstructSpdyBodyFrame(1, true));
   5478   MockRead reads[] = {
   5479     CreateMockRead(*stream1_reply),
   5480     CreateMockRead(*stream1_body),
   5481     CreateMockRead(*stream1_headers),
   5482     CreateMockRead(*stream1_body2),
   5483     MockRead(true, 0, 0)  // EOF
   5484   };
   5485 
   5486   scoped_refptr<DelayedSocketData> data(
   5487       new DelayedSocketData(1, reads, arraysize(reads),
   5488                             writes, arraysize(writes)));
   5489   NormalSpdyTransactionHelper helper(CreateGetRequest(),
   5490                                      BoundNetLog(), GetParam());
   5491   helper.RunToCompletion(data.get());
   5492   TransactionHelperResult out = helper.output();
   5493   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
   5494 }
   5495 
   5496 TEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) {
   5497   // In this test we want to verify that we can't accidentally push content
   5498   // which can't be pushed by this content server.
   5499   // This test assumes that:
   5500   //   - if we're requesting http://www.foo.com/barbaz
   5501   //   - the browser has made a connection to "www.foo.com".
   5502 
   5503   // A list of the URL to fetch, followed by the URL being pushed.
   5504   static const char* const kTestCases[] = {
   5505     "http://www.google.com/foo.html",
   5506     "http://www.google.com:81/foo.js",     // Bad port
   5507 
   5508     "http://www.google.com/foo.html",
   5509     "https://www.google.com/foo.js",       // Bad protocol
   5510 
   5511     "http://www.google.com/foo.html",
   5512     "ftp://www.google.com/foo.js",         // Invalid Protocol
   5513 
   5514     "http://www.google.com/foo.html",
   5515     "http://blat.www.google.com/foo.js",   // Cross subdomain
   5516 
   5517     "http://www.google.com/foo.html",
   5518     "http://www.foo.com/foo.js",           // Cross domain
   5519   };
   5520 
   5521 
   5522   static const unsigned char kPushBodyFrame[] = {
   5523     0x00, 0x00, 0x00, 0x02,                                      // header, ID
   5524     0x01, 0x00, 0x00, 0x06,                                      // FIN, length
   5525     'p', 'u', 's', 'h', 'e', 'd'                                 // "pushed"
   5526   };
   5527 
   5528   for (size_t index = 0; index < arraysize(kTestCases); index += 2) {
   5529     const char* url_to_fetch = kTestCases[index];
   5530     const char* url_to_push = kTestCases[index + 1];
   5531 
   5532     scoped_ptr<spdy::SpdyFrame>
   5533         stream1_syn(ConstructSpdyGet(url_to_fetch, false, 1, LOWEST));
   5534     scoped_ptr<spdy::SpdyFrame>
   5535         stream1_body(ConstructSpdyBodyFrame(1, true));
   5536     scoped_ptr<spdy::SpdyFrame> push_rst(
   5537         ConstructSpdyRstStream(2, spdy::REFUSED_STREAM));
   5538     MockWrite writes[] = {
   5539       CreateMockWrite(*stream1_syn, 1),
   5540       CreateMockWrite(*push_rst, 4),
   5541     };
   5542 
   5543     scoped_ptr<spdy::SpdyFrame>
   5544         stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
   5545     scoped_ptr<spdy::SpdyFrame>
   5546         stream2_syn(ConstructSpdyPush(NULL,
   5547                                       0,
   5548                                       2,
   5549                                       1,
   5550                                       url_to_push));
   5551     scoped_ptr<spdy::SpdyFrame> rst(
   5552         ConstructSpdyRstStream(2, spdy::CANCEL));
   5553 
   5554     MockRead reads[] = {
   5555       CreateMockRead(*stream1_reply, 2),
   5556       CreateMockRead(*stream2_syn, 3),
   5557       CreateMockRead(*stream1_body, 5, false),
   5558       MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame),
   5559                arraysize(kPushBodyFrame), 6),
   5560       MockRead(true, ERR_IO_PENDING, 7),  // Force a pause
   5561     };
   5562 
   5563     HttpResponseInfo response;
   5564     scoped_refptr<OrderedSocketData> data(new OrderedSocketData(
   5565         reads,
   5566         arraysize(reads),
   5567         writes,
   5568         arraysize(writes)));
   5569 
   5570     HttpRequestInfo request;
   5571     request.method = "GET";
   5572     request.url = GURL(url_to_fetch);
   5573     request.load_flags = 0;
   5574     NormalSpdyTransactionHelper helper(request,
   5575                                        BoundNetLog(), GetParam());
   5576     helper.RunPreTestSetup();
   5577     helper.AddData(data);
   5578 
   5579     HttpNetworkTransaction* trans = helper.trans();
   5580 
   5581     // Start the transaction with basic parameters.
   5582     TestCompletionCallback callback;
   5583 
   5584     int rv = trans->Start(&request, &callback, BoundNetLog());
   5585     EXPECT_EQ(ERR_IO_PENDING, rv);
   5586     rv = callback.WaitForResult();
   5587 
   5588     // Read the response body.
   5589     std::string result;
   5590     ReadResult(trans, data, &result);
   5591 
   5592     // Verify that we consumed all test data.
   5593     EXPECT_TRUE(data->at_read_eof());
   5594     EXPECT_TRUE(data->at_write_eof());
   5595 
   5596     // Verify the SYN_REPLY.
   5597     // Copy the response info, because trans goes away.
   5598     response = *trans->GetResponseInfo();
   5599 
   5600     VerifyStreamsClosed(helper);
   5601 
   5602     // Verify the SYN_REPLY.
   5603     EXPECT_TRUE(response.headers != NULL);
   5604     EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
   5605   }
   5606 }
   5607 
   5608 }  // namespace net
   5609