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