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