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