spdy_network_transaction_unittest.cc revision dc0f95d653279beabeb9817299e2902918ba123e
172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/http/http_network_transaction.h" 672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <string> 83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <vector> 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "net/base/auth.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log_unittest.h" 12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/http/http_network_session_peer.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_transaction_unittest.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_http_stream.h" 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/spdy/spdy_http_utils.h" 163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/spdy/spdy_session.h" 173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/spdy/spdy_session_pool.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_test_util.h" 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/url_request/url_request_test_util.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/platform_test.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//----------------------------------------------------------------------------- 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net { 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// This is the expected list of advertised protocols from the browser's NPN 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// list. 283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char kExpectedNPNString[] = "\x08http/1.1\x06spdy/2"; 293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickenum SpdyNetworkTransactionTestTypes { 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SPDYNPN, 323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SPDYNOSSL, 33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SPDYSSL, 343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass SpdyNetworkTransactionTest 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : public ::testing::TestWithParam<SpdyNetworkTransactionTestTypes> { 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void SetUp() { 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // By default, all tests turn off compression. 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EnableCompression(false); 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch google_get_request_initialized_ = false; 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_post_request_initialized_ = false; 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_initialized_ = false; 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void TearDown() { 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Empty the current queue. 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct TransactionHelperResult { 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv; 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string status_line; 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpResponseInfo response_info; 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void EnableCompression(bool enabled) { 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer::set_enable_compression_default(enabled); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class StartTransactionCallback; 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class DeleteSessionCallback; 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // A helper class that handles all the initial npn/ssl setup. 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class NormalSpdyTransactionHelper { 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper(const HttpRequestInfo& request, 693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const BoundNetLog& log, 703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyNetworkTransactionTestTypes test_type) 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : request_(request), 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_(new SpdySessionDependencies()), 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_(SpdySessionDependencies::SpdyCreateSession( 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_.get())), 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick log_(log), 763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick test_type_(test_type), 77731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick deterministic_(false), 78731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_enabled_(true) { 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch (test_type_) { 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNOSSL: 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYSSL: 823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick port_ = 80; 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNPN: 853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick port_ = 443; 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ~NormalSpdyTransactionHelper() { 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Any test which doesn't close the socket by sending it an EOF will 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // have a valid session left open, which leaks the entire session pool. 953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This is just fine - in fact, some of our tests intentionally do this 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // so that we can check consistency of the SpdySessionPool as the test 973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // finishes. If we had put an EOF on the socket, the SpdySession would 983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // have closed and we wouldn't be able to check the consistency. 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Forcefully close existing sessions here. 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session()->spdy_session_pool()->CloseAllSessions(); 1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void SetDeterministic() { 1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic( 1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_.get()); 1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick deterministic_ = true; 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void SetSpdyDisabled() { 111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_enabled_ = false; 112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void RunPreTestSetup() { 1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!session_deps_.get()) 1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_.reset(new SpdySessionDependencies()); 1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!session_.get()) 1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_ = SpdySessionDependencies::SpdyCreateSession( 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_.get()); 1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_over_ssl(false); 1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_always(false); 1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch (test_type_) { 1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNPN: 1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_->mutable_alternate_protocols()->SetAlternateProtocolFor( 1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair("www.google.com", 80), 443, 1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAlternateProtocols::NPN_SPDY_2); 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(kExpectedNPNString); 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNOSSL: 1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_over_ssl(false); 1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_always(true); 1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYSSL: 1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_over_ssl(true); 1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_always(true); 1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We're now ready to use SSL-npn SPDY. 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch trans_.reset(new HttpNetworkTransaction(session_)); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Start the transaction, read some data, finish. 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RunDefaultTest() { 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_.rv = trans_->Start(&request_, &callback, log_); 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We expect an IO Pending or some sort of error. 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_LT(output_.rv, 0); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (output_.rv != ERR_IO_PENDING) 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_.rv = callback.WaitForResult(); 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (output_.rv != OK) { 1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_->spdy_session_pool()->CloseCurrentSessions(); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify responses. 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans_->GetResponseInfo(); 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(spdy_enabled_, response->was_fetched_via_spdy); 168731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (test_type_ == SPDYNPN && spdy_enabled_) { 1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->was_npn_negotiated); 1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->was_alternate_protocol_available); 1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(!response->was_npn_negotiated); 1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(!response->was_alternate_protocol_available); 1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // If SPDY is not enabled, a HTTP request should not be diverted 176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // over a SSL session. 177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!spdy_enabled_) { 178731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(request_.url.SchemeIs("https"), 179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick response->was_npn_negotiated); 180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("192.0.2.33", response->socket_address.host()); 182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(0, response->socket_address.port()); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_.status_line = response->headers->GetStatusLine(); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_.response_info = *response; // Make a copy so we can verify. 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_.rv = ReadTransaction(trans_.get(), &output_.response_data); 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Most tests will want to call this function. In particular, the MockReads 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // should end with an empty read, and that read needs to be processed to 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ensure proper deletion of the spdy_session_pool. 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void VerifyDataConsumed() { 1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (DataVector::iterator it = data_vector_.begin(); 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != data_vector_.end(); ++it) { 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE((*it)->at_read_eof()) << "Read count: " 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << (*it)->read_count() 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << " Read index: " 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << (*it)->read_index(); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE((*it)->at_write_eof()) << "Write count: " 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << (*it)->write_count() 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << " Write index: " 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << (*it)->write_index(); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Occasionally a test will expect to error out before certain reads are 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // processed. In that case we want to explicitly ensure that the reads were 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // not processed. 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void VerifyDataNotConsumed() { 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (DataVector::iterator it = data_vector_.begin(); 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != data_vector_.end(); ++it) { 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(!(*it)->at_read_eof()) << "Read count: " 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << (*it)->read_count() 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << " Read index: " 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << (*it)->read_index(); 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(!(*it)->at_write_eof()) << "Write count: " 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << (*it)->write_count() 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << " Write index: " 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << (*it)->write_index(); 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RunToCompletion(StaticSocketDataProvider* data) { 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RunPreTestSetup(); 2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddData(data); 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RunDefaultTest(); 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyDataConsumed(); 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void AddData(StaticSocketDataProvider* data) { 2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!deterministic_); 2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_vector_.push_back(data); 2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick linked_ptr<SSLSocketDataProvider> ssl_( 2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new SSLSocketDataProvider(true, OK)); 2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (test_type_ == SPDYNPN) { 2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_->next_proto_status = SSLClientSocket::kNextProtoNegotiated; 2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_->next_proto = "spdy/2"; 2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_->was_npn_negotiated = true; 2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_vector_.push_back(ssl_); 2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if(test_type_ == SPDYNPN || test_type_ == SPDYSSL) 2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_->socket_factory->AddSSLSocketDataProvider(ssl_.get()); 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_->socket_factory->AddSocketDataProvider(data); 2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void AddDeterministicData(DeterministicSocketData* data) { 2463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(deterministic_); 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_vector_.push_back(data); 2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick linked_ptr<SSLSocketDataProvider> ssl_( 2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new SSLSocketDataProvider(true, OK)); 2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (test_type_ == SPDYNPN) { 2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_->next_proto_status = SSLClientSocket::kNextProtoNegotiated; 2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_->next_proto = "spdy/2"; 2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_->was_npn_negotiated = true; 2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_vector_.push_back(ssl_); 2563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if(test_type_ == SPDYNPN || test_type_ == SPDYSSL) 2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_->deterministic_socket_factory-> 2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddSSLSocketDataProvider(ssl_.get()); 2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_->deterministic_socket_factory->AddSocketDataProvider(data); 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This can only be called after RunPreTestSetup. It adds a Data Provider, 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // but not a corresponding SSL data provider 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void AddDataNoSSL(StaticSocketDataProvider* data) { 2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!deterministic_); 2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_->socket_factory->AddSocketDataProvider(data); 2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void AddDataNoSSL(DeterministicSocketData* data) { 2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(deterministic_); 2703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_->deterministic_socket_factory->AddSocketDataProvider(data); 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void SetSession(const scoped_refptr<HttpNetworkSession>& session) { 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_ = session; 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans() { return trans_.get(); } 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ResetTrans() { trans_.reset(); } 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult& output() { return output_; } 2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpRequestInfo& request() const { return request_; } 2803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const scoped_refptr<HttpNetworkSession>& session() const { 2813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return session_; 2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<SpdySessionDependencies>& session_deps() { 2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return session_deps_; 2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int port() const { return port_; } 2873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyNetworkTransactionTestTypes test_type() const { return test_type_; } 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::vector<StaticSocketDataProvider*> DataVector; 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::vector<linked_ptr<SSLSocketDataProvider> > SSLVector; 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request_; 2933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<SpdySessionDependencies> session_deps_; 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session_; 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult output_; 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<StaticSocketDataProvider> first_transaction_; 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLVector ssl_vector_; 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpNetworkTransaction> trans_; 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpNetworkTransaction> trans_http_; 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DataVector data_vector_; 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& log_; 3033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyNetworkTransactionTestTypes test_type_; 3043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int port_; 3053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool deterministic_; 306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool spdy_enabled_; 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ConnectStatusHelperWithExpectedStatus(const MockRead& status, 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int expected_status); 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ConnectStatusHelper(const MockRead& status); 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpRequestInfo& CreateGetPushRequest() { 3153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_get_push_request_.method = "GET"; 3163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_get_push_request_.url = GURL("http://www.google.com/foo.dat"); 3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_get_push_request_.load_flags = 0; 3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return google_get_push_request_; 3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpRequestInfo& CreateGetRequest() { 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!google_get_request_initialized_) { 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch google_get_request_.method = "GET"; 3243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_get_request_.url = GURL(kDefaultURL); 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch google_get_request_.load_flags = 0; 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch google_get_request_initialized_ = true; 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return google_get_request_; 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const HttpRequestInfo& CreateGetRequestWithUserAgent() { 3324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!google_get_request_initialized_) { 3334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch google_get_request_.method = "GET"; 3344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch google_get_request_.url = GURL(kDefaultURL); 3354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch google_get_request_.load_flags = 0; 3364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch google_get_request_.extra_headers.SetHeader("User-Agent", "Chrome"); 3374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch google_get_request_initialized_ = true; 3384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 3394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return google_get_request_; 3404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 3414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 3423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpRequestInfo& CreatePostRequest() { 3433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!google_post_request_initialized_) { 3443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_post_request_.method = "POST"; 3453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_post_request_.url = GURL(kDefaultURL); 3463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_post_request_.upload_data = new UploadData(); 3473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_post_request_.upload_data->AppendBytes(kUploadData, 3483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kUploadDataSize); 3493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_post_request_initialized_ = true; 3503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return google_post_request_; 3523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 354dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HttpRequestInfo& CreateChunkedPostRequest() { 355dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!google_chunked_post_request_initialized_) { 356dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_.method = "POST"; 357dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_.url = GURL(kDefaultURL); 358dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_.upload_data = new UploadData(); 359dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_.upload_data->set_is_chunked(true); 360dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_.upload_data->AppendChunk( 361dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kUploadData, kUploadDataSize, false); 362dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_.upload_data->AppendChunk( 363dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kUploadData, kUploadDataSize, true); 364dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_initialized_ = true; 365dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 366dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return google_chunked_post_request_; 367dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 368dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Read the result of a particular transaction, knowing that we've got 3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // multiple transactions in the read pipeline; so as we read, we may have 3713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // to skip over data destined for other transactions while we consume 3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // the data for |trans|. 3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int ReadResult(HttpNetworkTransaction* trans, 374201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch StaticSocketDataProvider* data, 3753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string* result) { 3763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const int kSize = 3000; 3773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int bytes_read = 0; 379513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(kSize)); 3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 3813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick while (true) { 3823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Read(buf, kSize, &callback); 3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (rv == ERR_IO_PENDING) { 3843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Multiple transactions may be in the data set. Keep pulling off 3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // reads until we complete our callback. 3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick while (!callback.have_result()) { 3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (rv <= 0) { 3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick result->append(buf->data(), rv); 3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bytes_read += rv; 3963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return bytes_read; 3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void VerifyStreamsClosed(const NormalSpdyTransactionHelper& helper) { 4013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This lengthy block is reaching into the pool to dig out the active 4023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // session. Once we have the session, we verify that the streams are 4033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // all closed and not leaked at this point. 4043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const GURL& url = helper.request().url; 4053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int port = helper.test_type() == SPDYNPN ? 443 : 80; 4063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair host_port_pair(url.host(), port); 4073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortProxyPair pair(host_port_pair, ProxyServer::Direct()); 4083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog log; 4093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const scoped_refptr<HttpNetworkSession>& session = helper.session(); 410731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SpdySessionPool* pool(session->spdy_session_pool()); 4113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(pool->HasSession(pair)); 412dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<SpdySession> spdy_session(pool->Get(pair, log)); 4133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(spdy_session.get() != NULL); 4143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0u, spdy_session->num_active_streams()); 4153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams()); 4163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 418201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void RunServerPushTest(OrderedSocketData* data, 4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo* response, 420201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo* push_response, 4213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string& expected) { 4223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 4233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 425201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.AddData(data); 4263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 4283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Start the transaction with basic parameters. 4303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 4313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 4323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 4333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 4343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Request the pushed path. 4363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans2( 4373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 4383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans2->Start(&CreateGetPushRequest(), &callback, BoundNetLog()); 4393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 4403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 4413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The data for the pushed path may be coming in more than 1 packet. Compile 4433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // the results into a single string. 4443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Read the server push body. 4463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string result2; 4473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ReadResult(trans2.get(), data, &result2); 4483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Read the response body. 4493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string result; 4503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ReadResult(trans, data, &result); 4513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we consumed all test data. 4533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()); 4543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()); 4553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that the received push data is same as the expected push data. 4573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(result2.compare(expected), 0) << "Received data: " 4583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << result2 4593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << "||||| Expected data: " 4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << expected; 4613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Copy the response info, because trans goes away. 4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *response = *trans->GetResponseInfo(); 465201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch *push_response = *trans2->GetResponseInfo(); 4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick VerifyStreamsClosed(helper); 4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool google_get_request_initialized_; 4723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool google_post_request_initialized_; 473dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool google_chunked_post_request_initialized_; 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo google_get_request_; 4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo google_post_request_; 476dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpRequestInfo google_chunked_post_request_; 4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo google_get_push_request_; 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//----------------------------------------------------------------------------- 4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// All tests are run with three different connection types: SPDY after NPN 4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// negotiation, SPDY without SSL, and SPDY with SSL. 4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickINSTANTIATE_TEST_CASE_P(Spdy, 4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyNetworkTransactionTest, 4853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ::testing::Values(SPDYNOSSL, SPDYSSL, SPDYNPN)); 4863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify HttpNetworkTransaction constructor. 4893345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, Constructor) { 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdySessionDependencies session_deps; 491513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpNetworkSession> session( 492513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SpdySessionDependencies::SpdyCreateSession(&session_deps)); 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4963345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, Get) { 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 5133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5213345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) { 5223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (RequestPriority p = HIGHEST; p < NUM_PRIORITIES; 5233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick p = RequestPriority(p+1)) { 5243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Construct the request. 5253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, p)); 5263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { CreateMockWrite(*req) }; 5273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const int spdy_prio = reinterpret_cast<spdy::SpdySynStreamControlFrame*>( 5293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick req.get())->priority(); 5303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // this repeats the RequestPriority-->SpdyPriority mapping from 5313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // SpdyFramer::ConvertRequestPriorityToSpdyPriority to make 5323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // sure it's being done right. 5333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch(p) { 5343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case HIGHEST: 5353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, spdy_prio); 5363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 5373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case MEDIUM: 5383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, spdy_prio); 5393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 5403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case LOW: 5413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case LOWEST: 5423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(2, spdy_prio); 5433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 5443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case IDLE: 5453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(3, spdy_prio); 5463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 5473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 5483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FAIL(); 5493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 5503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 5523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 5533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 5543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 5553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 5563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 5573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 5583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data( 5603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads, arraysize(reads), 5613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 5623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo http_req = CreateGetRequest(); 5633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick http_req.priority = p; 5643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(http_req, BoundNetLog(), GetParam()); 5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunToCompletion(data.get()); 5673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TransactionHelperResult out = helper.output(); 5683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 5693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 5703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", out.response_data); 5713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 5723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 5733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Start three gets simultaniously; making sure that multiplexed 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// streams work properly. 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This can't use the TransactionHelper method, since it only 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// handles a single transaction, and finishes them as soon 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// as it launches them. 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(gavinp): create a working generalized TransactionHelper that 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// can allow multiple streams in flight. 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5843345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ThreeGets) { 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, LOWEST)); 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5)); 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(5, false)); 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody3(ConstructSpdyBodyFrame(5, true)); 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 600dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockWrite writes[] = { 601dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req), 602dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req2), 603dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req3), 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp, 1), 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp2, 4), 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body2), 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp3, 7), 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body3), 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody), 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody2), 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody3), 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0), // EOF 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> data( 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData(reads, arraysize(reads), 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 6223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_placeholder( 6233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(NULL, 0, NULL, 0)); 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog log; 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out; 6273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 6283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 6293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 6303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 6313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We require placeholder data because three get requests are sent out, so 6323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // there needs to be three sets of SSL connection data. 6333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 6343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 6353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans1( 6363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 6373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans2( 6383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 6393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans3( 6403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 6413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 6433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback2; 6443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback3; 6453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq1 = CreateGetRequest(); 6473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq2 = CreateGetRequest(); 6483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq3 = CreateGetRequest(); 6493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans1->Start(&httpreq1, &callback1, log); 6513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 6523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans2->Start(&httpreq2, &callback2, log); 6533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 6543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans3->Start(&httpreq3, &callback3, log); 6553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 6563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback1.WaitForResult(); 6583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 6593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback3.WaitForResult(); 6603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 6613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 6633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->headers != NULL); 6643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->was_fetched_via_spdy); 6653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response1->headers->GetStatusLine(); 6663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response1; 6673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick trans2->GetResponseInfo(); 6693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans1.get(), &out.response_data); 6713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!hello!", out.response_data); 677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 679dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) { 680dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 681dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 682dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 683dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); 684dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 685dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 686dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 687dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); 688dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); 689dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 690dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockWrite writes[] = { 691dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req), 692dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req2), 693dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 694dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockRead reads[] = { 695dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*resp, 1), 696dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*body), 697dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*resp2, 4), 698dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*body2), 699dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*fbody), 700dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*fbody2), 701dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockRead(true, 0, 0), // EOF 702dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 703dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<OrderedSocketData> data( 704dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new OrderedSocketData(reads, arraysize(reads), 705dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen writes, arraysize(writes))); 706dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 707dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockConnect never_finishing_connect(true, ERR_IO_PENDING); 708dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 709dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<OrderedSocketData> data_placeholder( 710dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new OrderedSocketData(NULL, 0, NULL, 0)); 711dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen data_placeholder->set_connect_data(never_finishing_connect); 712dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 713dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BoundNetLog log; 714dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TransactionHelperResult out; 715dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NormalSpdyTransactionHelper helper(CreateGetRequest(), 716dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BoundNetLog(), GetParam()); 717dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.RunPreTestSetup(); 718dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.AddData(data.get()); 719dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // We require placeholder data because two get requests are sent out, so 720dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // there needs to be two sets of SSL connection data. 721dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.AddData(data_placeholder.get()); 722dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<HttpNetworkTransaction> trans1( 723dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new HttpNetworkTransaction(helper.session())); 724dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<HttpNetworkTransaction> trans2( 725dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new HttpNetworkTransaction(helper.session())); 726dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 727dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TestCompletionCallback callback1; 728dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TestCompletionCallback callback2; 729dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 730dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpRequestInfo httpreq1 = CreateGetRequest(); 731dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpRequestInfo httpreq2 = CreateGetRequest(); 732dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 733dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = trans1->Start(&httpreq1, &callback1, log); 734dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(ERR_IO_PENDING, out.rv); 735dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = trans2->Start(&httpreq2, &callback2, log); 736dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(ERR_IO_PENDING, out.rv); 737dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 738dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = callback1.WaitForResult(); 739dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(OK, out.rv); 740dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = callback2.WaitForResult(); 741dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(OK, out.rv); 742dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 743dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 744dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response1->headers != NULL); 745dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response1->was_fetched_via_spdy); 746dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.status_line = response1->headers->GetStatusLine(); 747dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.response_info = *response1; 748dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = ReadTransaction(trans1.get(), &out.response_data); 749dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(OK, out.rv); 750dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 751dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("hello!hello!", out.response_data); 752dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 753dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 754dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response2->headers != NULL); 755dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response2->was_fetched_via_spdy); 756dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.status_line = response2->headers->GetStatusLine(); 757dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.response_info = *response2; 758dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = ReadTransaction(trans2.get(), &out.response_data); 759dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(OK, out.rv); 760dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 761dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("hello!hello!", out.response_data); 762dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 763dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.VerifyDataConsumed(); 764dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 765dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 766dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) { 767dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 768dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 769dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 770dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); 771dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 772dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 773dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 774dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); 775dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); 776dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 777dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockWrite writes[] = { 778dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req), 779dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req2), 780dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 781dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockRead reads[] = { 782dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*resp, 1), 783dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*body), 784dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*resp2, 4), 785dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*body2), 786dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*fbody), 787dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*fbody2), 788dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockRead(true, 0, 0), // EOF 789dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 790dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<OrderedSocketData> preconnect_data( 791dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new OrderedSocketData(reads, arraysize(reads), 792dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen writes, arraysize(writes))); 793dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 794dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockConnect never_finishing_connect(true, ERR_IO_PENDING); 795dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 796dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<OrderedSocketData> data_placeholder( 797dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new OrderedSocketData(NULL, 0, NULL, 0)); 798dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen data_placeholder->set_connect_data(never_finishing_connect); 799dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 800dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BoundNetLog log; 801dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TransactionHelperResult out; 802dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NormalSpdyTransactionHelper helper(CreateGetRequest(), 803dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BoundNetLog(), GetParam()); 804dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.RunPreTestSetup(); 805dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.AddData(preconnect_data.get()); 806dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // We require placeholder data because 3 connections are attempted (first is 807dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // the preconnect, 2nd and 3rd are the never finished connections. 808dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.AddData(data_placeholder.get()); 809dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.AddData(data_placeholder.get()); 810dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 811dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<HttpNetworkTransaction> trans1( 812dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new HttpNetworkTransaction(helper.session())); 813dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<HttpNetworkTransaction> trans2( 814dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new HttpNetworkTransaction(helper.session())); 815dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 816dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TestCompletionCallback callback1; 817dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TestCompletionCallback callback2; 818dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 819dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpRequestInfo httpreq = CreateGetRequest(); 820dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 821dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Preconnect the first. 822dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSLConfig preconnect_ssl_config; 823dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config); 824dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpStreamFactory* http_stream_factory = 825dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.session()->http_stream_factory(); 826dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (http_stream_factory->next_protos()) { 827dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen preconnect_ssl_config.next_protos = *http_stream_factory->next_protos(); 828dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 829dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 830dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen http_stream_factory->PreconnectStreams( 831dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1, httpreq, preconnect_ssl_config, log); 832dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 833dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = trans1->Start(&httpreq, &callback1, log); 834dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(ERR_IO_PENDING, out.rv); 835dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = trans2->Start(&httpreq, &callback2, log); 836dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(ERR_IO_PENDING, out.rv); 837dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 838dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = callback1.WaitForResult(); 839dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(OK, out.rv); 840dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = callback2.WaitForResult(); 841dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(OK, out.rv); 842dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 843dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 844dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response1->headers != NULL); 845dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response1->was_fetched_via_spdy); 846dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.status_line = response1->headers->GetStatusLine(); 847dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.response_info = *response1; 848dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = ReadTransaction(trans1.get(), &out.response_data); 849dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(OK, out.rv); 850dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 851dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("hello!hello!", out.response_data); 852dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 853dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 854dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response2->headers != NULL); 855dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response2->was_fetched_via_spdy); 856dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.status_line = response2->headers->GetStatusLine(); 857dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.response_info = *response2; 858dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = ReadTransaction(trans2.get(), &out.response_data); 859dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(OK, out.rv); 860dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 861dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("hello!hello!", out.response_data); 862dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 863dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.VerifyDataConsumed(); 864dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 865dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Similar to ThreeGets above, however this test adds a SETTINGS 867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// frame. The SETTINGS frame is read during the IO loop waiting on 868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the first transaction completion, and sets a maximum concurrent 869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// stream limit of 1. This means that our IO loop exists after the 870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// second transaction completes, so we can assert on read_index(). 8713345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) { 872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); 877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); 881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); 882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, LOWEST)); 884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5)); 885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(5, false)); 886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody3(ConstructSpdyBodyFrame(5, true)); 887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings settings; 889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SettingsFlagsAndId id(0); 890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); 891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t max_concurrent_streams = 1; 892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(spdy::SpdySetting(id, max_concurrent_streams)); 894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); 895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req), 897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req2), 898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req3), 899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 9013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*settings_frame, 1), 902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody), 9053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 7), 906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body2), 907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody2), 9083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp3, 12), 909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body3), 910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody3), 911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0), // EOF 913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> data( 916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData(reads, arraysize(reads), 917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 9183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_placeholder( 9193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(NULL, 0, NULL, 0)); 920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog log; 922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out; 923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 9243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 9253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 9263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 9273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 9283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We require placeholder data because three get requests are sent out, so 9293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // there needs to be three sets of SSL connection data. 9303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 9313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 9323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans1( 9333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 9343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans2( 9353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 9363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans3( 9373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback1; 940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback2; 941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback3; 942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo httpreq1 = CreateGetRequest(); 944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo httpreq2 = CreateGetRequest(); 945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo httpreq3 = CreateGetRequest(); 946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = trans1->Start(&httpreq1, &callback1, log); 948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(out.rv, ERR_IO_PENDING); 949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // run transaction 1 through quickly to force a read of our SETTINGS 950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // frame 951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback1.WaitForResult(); 9523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = trans2->Start(&httpreq2, &callback2, log); 955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(out.rv, ERR_IO_PENDING); 956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = trans3->Start(&httpreq3, &callback3, log); 957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(out.rv, ERR_IO_PENDING); 958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback2.WaitForResult(); 959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, out.rv); 960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(7U, data->read_index()); // i.e. the third trans was queued 961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback3.WaitForResult(); 963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, out.rv); 964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 9663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response1 != NULL); 967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response1->headers != NULL); 968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response1->was_fetched_via_spdy); 969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response1->headers->GetStatusLine(); 970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response1; 971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = ReadTransaction(trans1.get(), &out.response_data); 972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!hello!", out.response_data); 975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response2->headers->GetStatusLine(); 978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response2; 979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = ReadTransaction(trans2.get(), &out.response_data); 980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!hello!", out.response_data); 983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response3 = trans3->GetResponseInfo(); 985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response3->headers->GetStatusLine(); 986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response3; 987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = ReadTransaction(trans3.get(), &out.response_data); 988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!hello!", out.response_data); 9913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Similar to ThreeGetsWithMaxConcurrent above, however this test adds 998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a fourth transaction. The third and fourth transactions have 999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// different data ("hello!" vs "hello!hello!") and because of the 1000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// user specified priority, we expect to see them inverted in 1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the response from the server. 10023345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) { 1003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 1004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 1006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); 1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); 1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); 1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req4( 1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(NULL, 0, false, 5, HIGHEST)); 1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp4(ConstructSpdyGetSynReply(NULL, 0, 5)); 1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody4(ConstructSpdyBodyFrame(5, true)); 1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 7, LOWEST)); 1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 7)); 1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(7, false)); 1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody3(ConstructSpdyBodyFrame(7, true)); 1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings settings; 1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SettingsFlagsAndId id(0); 1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); 1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t max_concurrent_streams = 1; 1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(spdy::SpdySetting(id, max_concurrent_streams)); 1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); 1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req), 10343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2), 10353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req4), 10363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req3), 1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 10393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*settings_frame, 1), 1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody), 10433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 7), 1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body2), 1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody2), 10463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp4, 13), 1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody4), 10483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp3, 16), 1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body3), 1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody3), 1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0), // EOF 1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> data( 1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData(reads, arraysize(reads), 10573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 10583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_placeholder( 10593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(NULL, 0, NULL, 0)); 1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog log; 1062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out; 10633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 10643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 10653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 10663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 10673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We require placeholder data because four get requests are sent out, so 10683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // there needs to be four sets of SSL connection data. 10693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 10703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 10713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 10723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans1( 10733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 10743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans2( 10753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 10763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans3( 10773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 10783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans4( 10793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 10803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 10823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback2; 10833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback3; 10843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback4; 10853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq1 = CreateGetRequest(); 10873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq2 = CreateGetRequest(); 10883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq3 = CreateGetRequest(); 10893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq4 = CreateGetRequest(); 10903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick httpreq4.priority = HIGHEST; 10913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans1->Start(&httpreq1, &callback1, log); 10933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 10943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // run transaction 1 through quickly to force a read of our SETTINGS 10953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // frame 10963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback1.WaitForResult(); 10973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 10983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans2->Start(&httpreq2, &callback2, log); 11003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 11013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans3->Start(&httpreq3, &callback3, log); 11023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 11033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans4->Start(&httpreq4, &callback4, log); 11043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 11053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback2.WaitForResult(); 11073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 11083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(data->read_index(), 7U); // i.e. the third & fourth trans queued 11093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback3.WaitForResult(); 11113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 11123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 11143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->headers != NULL); 11153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->was_fetched_via_spdy); 11163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response1->headers->GetStatusLine(); 11173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response1; 11183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans1.get(), &out.response_data); 11193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 11203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 11213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!hello!", out.response_data); 1122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 11243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response2->headers->GetStatusLine(); 11253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response2; 11263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans2.get(), &out.response_data); 11273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 11283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 11293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!hello!", out.response_data); 1130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // notice: response3 gets two hellos, response4 gets one 11323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // hello, so we know dequeuing priority was respected. 11333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response3 = trans3->GetResponseInfo(); 11343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response3->headers->GetStatusLine(); 11353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response3; 11363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans3.get(), &out.response_data); 1137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 11383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 11393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!hello!", out.response_data); 1140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback4.WaitForResult(); 11423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 11433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response4 = trans4->GetResponseInfo(); 11443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response4->headers->GetStatusLine(); 11453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response4; 11463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans4.get(), &out.response_data); 11473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 11483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 11493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", out.response_data); 11503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 11513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 1152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Similar to ThreeGetsMaxConcurrrent above, however, this test 1155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// deletes a session in the middle of the transaction to insure 1156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// that we properly remove pendingcreatestream objects from 1157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the spdy_session 11583345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) { 1159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 1160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 1161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 1162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 1163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); 1164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 1166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 1167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); 1168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); 1169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings settings; 1171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SettingsFlagsAndId id(0); 1172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); 1173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t max_concurrent_streams = 1; 1174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(spdy::SpdySetting(id, max_concurrent_streams)); 1176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); 1177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req), 11793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2), 1180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 11823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*settings_frame, 1), 1183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 1184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 1185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody), 11863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 7), 1187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body2), 1188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody2), 1189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0), // EOF 1190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> data( 1193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData(reads, arraysize(reads), 11943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 11953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_placeholder( 11963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(NULL, 0, NULL, 0)); 1197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog log; 1199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out; 12003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 12013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 12023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 12033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 12043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We require placeholder data because three get requests are sent out, so 12053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // there needs to be three sets of SSL connection data. 12063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 12073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 12083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans1( 12093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 12103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans2( 12113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 12123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans3( 12133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 12143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 12163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback2; 12173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback3; 12183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq1 = CreateGetRequest(); 12203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq2 = CreateGetRequest(); 12213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq3 = CreateGetRequest(); 12223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans1->Start(&httpreq1, &callback1, log); 12243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(out.rv, ERR_IO_PENDING); 12253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // run transaction 1 through quickly to force a read of our SETTINGS 12263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // frame 12273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback1.WaitForResult(); 12283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 12293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans2->Start(&httpreq2, &callback2, log); 12313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(out.rv, ERR_IO_PENDING); 12323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans3->Start(&httpreq3, &callback3, log); 12333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick delete trans3.release(); 12343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(out.rv, ERR_IO_PENDING); 12353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback2.WaitForResult(); 12363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 12373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(8U, data->read_index()); 12393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 12413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response1 != NULL); 12423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->headers != NULL); 12433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->was_fetched_via_spdy); 12443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response1->headers->GetStatusLine(); 12453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response1; 12463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans1.get(), &out.response_data); 12473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 12483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 12493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!hello!", out.response_data); 1250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 12523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response2 != NULL); 12533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response2->headers->GetStatusLine(); 12543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response2; 12553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans2.get(), &out.response_data); 12563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 12573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 12583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!hello!", out.response_data); 12593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 12603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 12613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The KillerCallback will delete the transaction on error as part of the 12643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// callback. 12653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass KillerCallback : public TestCompletionCallback { 12663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public: 12673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick explicit KillerCallback(HttpNetworkTransaction* transaction) 12683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : transaction_(transaction) {} 1269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void RunWithParams(const Tuple1<int>& params) { 12713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (params.a < 0) 12723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick delete transaction_; 12733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback::RunWithParams(params); 12743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 12773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* transaction_; 12783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 1279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Similar to ThreeGetsMaxConcurrrentDelete above, however, this test 12813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// closes the socket while we have a pending transaction waiting for 12823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// a pending stream creation. http://crbug.com/52901 12833345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) { 12843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Construct the request. 12853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 12863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 12873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 12883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> fin_body(ConstructSpdyBodyFrame(1, true)); 1289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 12913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 12923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SpdySettings settings; 12943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SettingsFlagsAndId id(0); 12953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); 12963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const size_t max_concurrent_streams = 1; 12973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick settings.push_back(spdy::SpdySetting(id, max_concurrent_streams)); 12993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); 13003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { CreateMockWrite(*req), 13023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2), 13033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 13043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 13053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*settings_frame, 1), 13063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 13073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 13083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*fin_body), 13093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 7), 13103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_CONNECTION_RESET, 0), // Abort! 13113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 13123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 13143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 13153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 13163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_placeholder( 13173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(NULL, 0, NULL, 0)); 13183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog log; 13203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TransactionHelperResult out; 13213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 13223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 13233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 13243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 13253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We require placeholder data because three get requests are sent out, so 13263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // there needs to be three sets of SSL connection data. 13273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 13283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 13293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction trans1(helper.session()); 13303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction trans2(helper.session()); 13313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans3(new HttpNetworkTransaction(helper.session())); 13323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 13343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback2; 13353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick KillerCallback callback3(trans3); 13363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq1 = CreateGetRequest(); 13383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq2 = CreateGetRequest(); 13393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq3 = CreateGetRequest(); 13403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans1.Start(&httpreq1, &callback1, log); 13423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(out.rv, ERR_IO_PENDING); 13433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // run transaction 1 through quickly to force a read of our SETTINGS 13443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // frame 13453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback1.WaitForResult(); 13463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 13473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans2.Start(&httpreq2, &callback2, log); 13493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(out.rv, ERR_IO_PENDING); 13503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans3->Start(&httpreq3, &callback3, log); 13513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(out.rv, ERR_IO_PENDING); 13523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback3.WaitForResult(); 13533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_ABORTED, out.rv); 13543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(6U, data->read_index()); 13563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response1 = trans1.GetResponseInfo(); 13583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response1 != NULL); 13593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->headers != NULL); 13603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->was_fetched_via_spdy); 13613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response1->headers->GetStatusLine(); 13623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response1; 13633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(&trans1, &out.response_data); 1364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 1365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response2 = trans2.GetResponseInfo(); 13673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response2 != NULL); 13683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response2->headers->GetStatusLine(); 13693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response2; 13703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(&trans2, &out.response_data); 13713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_CONNECTION_RESET, out.rv); 13723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 1374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that a simple PUT request works. 13773345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, Put) { 13783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup the request 13793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 13803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "PUT"; 13813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 13823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynStartHeader = { 13843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_STREAM, // Kind = Syn 13853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, // Stream ID 13863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Associated stream ID 13873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), // Priority 13883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_FIN, // Control Flags 13893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, // Compressed 13903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::INVALID, // Status 13913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, // Data 13923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Length 13933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::DATA_FLAG_NONE // Data Flags 13943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 13953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kPutHeaders[] = { 13963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "method", "PUT", 13973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", "/", 13983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", "www.google.com", 13993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", "http", 14003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", "HTTP/1.1", 14013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "content-length", "0" 14023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPacket(kSynStartHeader, NULL, 0, 1404201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kPutHeaders, arraysize(kPutHeaders) / 2)); 14053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 14063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req) 14073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 14093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 14103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynReplyHeader = { 14113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_REPLY, // Kind = SynReply 14123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, // Stream ID 14133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Associated stream ID 14143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), // Priority 14153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_NONE, // Control Flags 14163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, // Compressed 14173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::INVALID, // Status 14183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, // Data 14193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Length 14203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::DATA_FLAG_NONE // Data Flags 14213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char* const kStandardGetHeaders[] = { 14233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "status", "200", 14243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", "HTTP/1.1" 14253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "content-length", "1234" 14263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPacket(kSynReplyHeader, 1428201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 0, kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2)); 14293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 14303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 14313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 14323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 14333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 14353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data( 14363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads, arraysize(reads), 14373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 14383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(request, 14393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 14403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunToCompletion(data.get()); 14413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TransactionHelperResult out = helper.output(); 14423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 14433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 14443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 14453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 14473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that a simple HEAD request works. 14483345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, Head) { 1449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Setup the request 1450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 14513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "HEAD"; 1452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 1453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 14543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynStartHeader = { 14553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_STREAM, // Kind = Syn 14563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, // Stream ID 14573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Associated stream ID 14583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), // Priority 14593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_FIN, // Control Flags 14603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, // Compressed 14613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::INVALID, // Status 14623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, // Data 14633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Length 14643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::DATA_FLAG_NONE // Data Flags 14653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kHeadHeaders[] = { 14673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "method", "HEAD", 14683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", "/", 14693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", "www.google.com", 14703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", "http", 14713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", "HTTP/1.1", 14723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "content-length", "0" 14733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPacket(kSynStartHeader, NULL, 0, 1475201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kHeadHeaders, arraysize(kHeadHeaders) / 2)); 14763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 14773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req) 14783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 14803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 14813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynReplyHeader = { 14823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_REPLY, // Kind = SynReply 14833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, // Stream ID 14843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Associated stream ID 14853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), // Priority 14863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_NONE, // Control Flags 14873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, // Compressed 14883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::INVALID, // Status 14893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, // Data 14903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Length 14913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::DATA_FLAG_NONE // Data Flags 14923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char* const kStandardGetHeaders[] = { 14943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "status", "200", 14953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", "HTTP/1.1" 14963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "content-length", "1234" 14973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPacket(kSynReplyHeader, 1499201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 0, kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2)); 15003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 15013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 15023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 15033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 15043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 15053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data( 15073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads, arraysize(reads), 15083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 15093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(request, 15103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 15113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunToCompletion(data.get()); 15123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TransactionHelperResult out = helper.output(); 15133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 15153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 15163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 15173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that a simple POST works. 15193345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, Post) { 15203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost(kUploadDataSize, NULL, 0)); 1521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 1522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 1523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 1524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*body), // POST upload frame 1525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0)); 1528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 1529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 1530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 1531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 1532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 1535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(2, reads, arraysize(reads), 1536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 15373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreatePostRequest(), 15383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 15393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunToCompletion(data.get()); 15403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TransactionHelperResult out = helper.output(); 15413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 15423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 15433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", out.response_data); 15443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 15453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1546dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Test that a chunked POST works. 1547dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_P(SpdyNetworkTransactionTest, ChunkedPost) { 1548dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UploadDataStream::set_merge_chunks(false); 1549dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0)); 1550dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false)); 1551dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> chunk2(ConstructSpdyBodyFrame(1, true)); 1552dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockWrite writes[] = { 1553dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req), 1554dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*chunk1), 1555dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*chunk2), 1556dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 1557dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1558dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0)); 1559dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockRead reads[] = { 1560dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*resp), 1561dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*chunk1), 1562dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*chunk2), 1563dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockRead(true, 0, 0) // EOF 1564dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 1565dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1566dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<DelayedSocketData> data( 1567dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new DelayedSocketData(2, reads, arraysize(reads), 1568dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen writes, arraysize(writes))); 1569dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NormalSpdyTransactionHelper helper(CreateChunkedPostRequest(), 1570dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BoundNetLog(), GetParam()); 1571dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.RunToCompletion(data.get()); 1572dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TransactionHelperResult out = helper.output(); 1573dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(OK, out.rv); 1574dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1575dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("hello!hello!", out.response_data); 1576dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 1577dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 15783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that a POST without any post data works. 15793345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, NullPost) { 15803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup the request 15813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 15823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "POST"; 15833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 15843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Create an empty UploadData. 15853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data = NULL; 15863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // When request.upload_data is NULL for post, content-length is 15883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // expected to be 0. 15893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost(0, NULL, 0)); 15903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Set the FIN bit since there will be no body. 15913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick req->set_flags(spdy::CONTROL_FLAG_FIN); 15923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 15933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req), 15943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 15953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0)); 15973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 15983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 15993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 16003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 16013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 16023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 16033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 16043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data( 16053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads, arraysize(reads), 16063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 16073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(request, 16093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 1610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 1611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 1612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 1613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 1615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that a simple POST works. 16183345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, EmptyPost) { 1619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Setup the request 1620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 1621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "POST"; 1622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 1623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create an empty UploadData. 1624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.upload_data = new UploadData(); 1625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 16263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Http POST Content-Length is using UploadDataStream::size(). 16273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // It is the same as request.upload_data->GetContentLength(). 16283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<UploadDataStream> stream(UploadDataStream::Create( 16293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data, NULL)); 16303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(request.upload_data->GetContentLength(), stream->size()); 16313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 16323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 16333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick req(ConstructSpdyPost(request.upload_data->GetContentLength(), NULL, 0)); 1634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the FIN bit since there will be no body. 1635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch req->set_flags(spdy::CONTROL_FLAG_FIN); 1636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 1637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 1638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0)); 1641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 1642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 1643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 1644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 1645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 1646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 1649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 1650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 1651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(request, 16533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 1654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 1655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 1656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 1657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 1659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// While we're doing a post, the server sends back a SYN_REPLY. 16623345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, PostWithEarlySynReply) { 1663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const char upload[] = { "hello!" }; 1664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Setup the request 1666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 1667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "POST"; 1668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 1669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.upload_data = new UploadData(); 1670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.upload_data->AppendBytes(upload, sizeof(upload)); 1671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 16723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Http POST Content-Length is using UploadDataStream::size(). 16733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // It is the same as request.upload_data->GetContentLength(). 16743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<UploadDataStream> stream(UploadDataStream::Create( 16753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data, NULL)); 16763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(request.upload_data->GetContentLength(), stream->size()); 16773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> stream_reply(ConstructSpdyPostSynReply(NULL, 0)); 16783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> stream_body(ConstructSpdyBodyFrame(1, true)); 1679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 16803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream_reply, 2), 16813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream_body, 3), 1682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, 0, 0) // EOF 1683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 16863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(0, reads, arraysize(reads), NULL, 0)); 1687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(request, 16883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 1689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 16903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 1691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunDefaultTest(); 16923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 16933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 16953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv); 16963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 16973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 16983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The client upon cancellation tries to send a RST_STREAM frame. The mock 16993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// socket causes the TCP write to return zero. This test checks that the client 17003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// tries to queue up the RST_STREAM frame again. 17013345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) { 17023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 17033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> rst( 17043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyRstStream(1, spdy::CANCEL)); 17053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 17063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req.get(), 0, false), 17073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite(false, 0, 0, 2), 17083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*rst.get(), 3, false), 17093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 17103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 17113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 17123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 1713731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*resp.get(), 1, true), 1714731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead(true, 0, 0, 4) // EOF 17153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 17163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 17173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DeterministicSocketData> data( 17183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DeterministicSocketData(reads, arraysize(reads), 17193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 17203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 17213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 17223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.SetDeterministic(); 17233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 17243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddDeterministicData(data.get()); 17253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 17263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 17273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 17283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 17293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 17303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 17313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->SetStop(2); 17323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->Run(); 17333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.ResetTrans(); 17343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->SetStop(20); 17353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->Run(); 17363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 17373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 1738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that the transaction doesn't crash when we don't have a reply. 17413345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ResponseWithoutSynReply) { 1742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 1743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 1744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 1745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 1746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 1749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), NULL, 0)); 1750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 17513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 1752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 1753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 1754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv); 1755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that the transaction doesn't crash when we get two replies on the same 1758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// stream ID. See http://crbug.com/45639. 17593345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { 1760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 1761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 1762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 1764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 1765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 1766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 1767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 1768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 1769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 1770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 1773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 1774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 1775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 17773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 1778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 17793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 1780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 1782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 1784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 1785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 1786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 1787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 1788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 17903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response != NULL); 1791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 1792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 1793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 1794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = ReadTransaction(trans, &response_data); 1795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv); 1796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 1798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that sent data frames and received WINDOW_UPDATE frames change 18013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// the send_window_size_ correctly. 18023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 18033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// WINDOW_UPDATE is different than most other frames in that it can arrive 18043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// while the client is still sending the request body. In order to enforce 18053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// this scenario, we feed a couple of dummy frames and give a delay of 0 to 18063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// socket data provider, so that initial read that is done as soon as the 18073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// stream is created, succeeds and schedules another read. This way reads 18083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// and writes are interleaved; after doing a full frame write, SpdyStream 18093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// will break out of DoLoop and will read and process a WINDOW_UPDATE. 18103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Once our WINDOW_UPDATE is read, we cannot send SYN_REPLY right away 18113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// since request has not been completely written, therefore we feed 18123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// enough number of WINDOW_UPDATEs to finish the first read and cause a 18133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// write, leading to a complete write of request body; after that we send 18143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// a reply with a body, to cause a graceful shutdown. 18153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 18163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// TODO(agayev): develop a socket data provider where both, reads and 18173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// writes are ordered so that writing tests like these are easy and rewrite 18183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// all these tests using it. Right now we are working around the 18193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// limitations as described above and it's not deterministic, tests may 18203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// fail under specific circumstances. 18213345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) { 18223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(true); 18233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 18243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static int kFrameCount = 2; 18253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<std::string> content( 18263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new std::string(kMaxSpdyFrameChunkSize, 'a')); 18273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost( 18283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kMaxSpdyFrameChunkSize * kFrameCount, NULL, 0)); 18293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body( 18303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, content->c_str(), content->size(), false)); 18313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body_end( 18323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, content->c_str(), content->size(), true)); 1833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 1835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 1836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*body), 18373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*body_end), 1838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const int kDeltaWindowSize = 0xff; 18413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const int kDeltaCount = 4; 1842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> window_update( 1843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyWindowUpdate(1, kDeltaWindowSize)); 18443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> window_update_dummy( 18453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyWindowUpdate(2, kDeltaWindowSize)); 18463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0)); 1847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 18483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update_dummy), 18493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update_dummy), 18503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update_dummy), 18513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), // Four updates, therefore window 18523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), // size should increase by 18533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), // kDeltaWindowSize * 4 1854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*window_update), 18553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 18563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body_end), 1857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 1858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 18613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(0, reads, arraysize(reads), 1862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 1863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup the request 18653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 18663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "POST"; 18673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL(kDefaultURL); 18683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data = new UploadData(); 18693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < kFrameCount; ++i) 18703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data->AppendBytes(content->c_str(), content->size()); 1871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(request, BoundNetLog(), GetParam()); 18733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 18743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 1875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 18773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 18783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 18793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 1880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 1882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 1883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 1884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get()); 18863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(stream != NULL); 18873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(stream->stream() != NULL); 1888201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(static_cast<int>(spdy::kSpdyStreamInitialWindowSize) + 18893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kDeltaWindowSize * kDeltaCount - 18903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kMaxSpdyFrameChunkSize * kFrameCount, 18913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream->stream()->send_window_size()); 18923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 18933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(false); 1894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that received data frames and sent WINDOW_UPDATE frames change 18973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// the recv_window_size_ correctly. 18983345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) { 18993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(true); 1900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 19023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> window_update( 19033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyWindowUpdate(1, kUploadDataSize)); 1904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 19063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req), 19073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*window_update), 19083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 1909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp( 19113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyGetSynReply(NULL, 0, 1)); 19123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body_no_fin( 19133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, false)); 19143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body_fin( 19153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, NULL, 0, true)); 19163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 19173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 19183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body_no_fin), 19193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 0), // Force a pause 19203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body_fin), 19213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 0), // Force a pause 19223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 19233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 19243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data( 19263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads, arraysize(reads), 19273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 19283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 19303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 19313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 19323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 19333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 19343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 19363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 19373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 19393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 19403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 19413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyHttpStream* stream = 19433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static_cast<SpdyHttpStream*>(trans->stream_.get()); 19443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(stream != NULL); 19453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(stream->stream() != NULL); 19463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1947201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ( 1948201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static_cast<int>(spdy::kSpdyStreamInitialWindowSize) - kUploadDataSize, 1949201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream->stream()->recv_window_size()); 19503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 19523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response != NULL); 19533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response->headers != NULL); 19543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 19553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->was_fetched_via_spdy); 19563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Issue a read which will cause a WINDOW_UPDATE to be sent and window 19583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // size increased to default. 1959513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kUploadDataSize)); 19603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->Read(buf, kUploadDataSize, NULL); 19613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(kUploadDataSize, rv); 19623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string content(buf->data(), buf->data()+kUploadDataSize); 19633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_STREQ(kUploadData, content.c_str()); 19643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Schedule the reading of empty data frame with FIN 19663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 19673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Force write of WINDOW_UPDATE which was scheduled during the above 19693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // read. 19703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 19713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Read EOF. 19733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 19743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 19763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(false); 19773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 19783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that WINDOW_UPDATE frame causing overflow is handled correctly. We 19803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// use the same trick as in the above test to enforce our scenario. 19813345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) { 19823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(true); 19833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // number of full frames we hope to write (but will not, used to 19853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // set content-length header correctly) 19863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static int kFrameCount = 3; 19873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<std::string> content( 19893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new std::string(kMaxSpdyFrameChunkSize, 'a')); 19903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost( 19913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kMaxSpdyFrameChunkSize * kFrameCount, NULL, 0)); 19923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body( 19933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, content->c_str(), content->size(), false)); 1994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> rst( 1995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyRstStream(1, spdy::FLOW_CONTROL_ERROR)); 19963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We're not going to write a data frame with FIN, we'll receive a bad 19983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // WINDOW_UPDATE while sending a request and will send a RST_STREAM frame. 1999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 2000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 2001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*body), 2002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*rst), 2003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 2004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const int kDeltaWindowSize = 0x7fffffff; // cause an overflow 2006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> window_update( 2007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyWindowUpdate(1, kDeltaWindowSize)); 20083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> window_update2( 20093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyWindowUpdate(2, kDeltaWindowSize)); 2010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> reply(ConstructSpdyPostSynReply(NULL, 0)); 20113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 20133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update2), 20143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update2), 2015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*window_update), 20163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), 20173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), 20183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 0), // Wait for the RST to be written. 2019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 2020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 2021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 20233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(0, reads, arraysize(reads), 2024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 2025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup the request 20273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 20283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "POST"; 20293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 20303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data = new UploadData(); 20313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < kFrameCount; ++i) 20323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data->AppendBytes(content->c_str(), content->size()); 20333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(request, 20353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 20363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 20373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 2038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 2040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 20423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 2043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 2045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 2046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv); 2047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 2049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(helper.session() != NULL); 20513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(helper.session()->spdy_session_pool() != NULL); 20523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.session()->spdy_session_pool()->CloseAllSessions(); 20533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 20543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(false); 2056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that after hitting a send window size of 0, the write process 20593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// stalls and upon receiving WINDOW_UPDATE frame write resumes. 20603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// This test constructs a POST request followed by enough data frames 20623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// containing 'a' that would make the window size 0, followed by another 20633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// data frame containing default content (which is "hello!") and this frame 20643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// also contains a FIN flag. DelayedSocketData is used to enforce all 20653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// writes go through before a read could happen. However, the last frame 20663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// ("hello!") is not supposed to go through since by the time its turn 20673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// arrives, window size is 0. At this point MessageLoop::Run() called via 20683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// callback would block. Therefore we call MessageLoop::RunAllPending() 20693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// which returns after performing all possible writes. We use DCHECKS to 20703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// ensure that last data frame is still there and stream has stalled. 20713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// After that, next read is artifically enforced, which causes a 20723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// WINDOW_UPDATE to be read and I/O process resumes. 20733345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) { 20743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(true); 20753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Number of frames we need to send to zero out the window size: data 20773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // frames plus SYN_STREAM plus the last data frame; also we need another 20783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // data frame that we will send once the WINDOW_UPDATE is received, 20793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // therefore +3. 2080201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch size_t nwrites = 2081201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3; 20823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Calculate last frame's size; 0 size data frame is legal. 2084201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch size_t last_frame_size = 2085201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize; 20863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Construct content for a data frame of maximum size. 20883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<std::string> content( 20893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new std::string(kMaxSpdyFrameChunkSize, 'a')); 20903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost( 2092201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::kSpdyStreamInitialWindowSize + kUploadDataSize, NULL, 0)); 20933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Full frames. 20953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body1( 20963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, content->c_str(), content->size(), false)); 20973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Last frame to zero out the window size. 20993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body2( 21003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, content->c_str(), last_frame_size, false)); 21013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Data frame to be sent once WINDOW_UPDATE frame is received. 21033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(1, true)); 21043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Fill in mock writes. 21063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_array<MockWrite> writes(new MockWrite[nwrites]); 21073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t i = 0; 21083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes[i] = CreateMockWrite(*req); 21093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (i = 1; i < nwrites-2; i++) 21103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes[i] = CreateMockWrite(*body1); 21113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes[i++] = CreateMockWrite(*body2); 21123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes[i] = CreateMockWrite(*body3); 21133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Construct read frame, give enough space to upload the rest of the 21153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // data. 21163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> window_update( 21173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyWindowUpdate(1, kUploadDataSize)); 21183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> reply(ConstructSpdyPostSynReply(NULL, 0)); 21193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 21203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), 21213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), 21223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*reply), 21233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body2), 21243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body3), 21253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 21263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 21273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Force all writes to happen before any read, last write will not 21293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // actually queue a frame, due to window size being 0. 21303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data( 21313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(nwrites, reads, arraysize(reads), 21323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes.get(), nwrites)); 21333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 21353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "POST"; 21363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 21373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data = new UploadData(); 21383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<std::string> upload_data( 2139201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new std::string(spdy::kSpdyStreamInitialWindowSize, 'a')); 21403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick upload_data->append(kUploadData, kUploadDataSize); 21413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data->AppendBytes(upload_data->c_str(), upload_data->size()); 21423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(request, 21433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 21443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 21453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 21463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 21483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 21503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 21513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 21523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); // Write as much as we can. 21543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get()); 21563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(stream != NULL); 21573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(stream->stream() != NULL); 21583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, stream->stream()->send_window_size()); 21593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(stream->request_body_stream_->eof()); 21603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->ForceNextRead(); // Read in WINDOW_UPDATE frame. 21623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 21633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 21643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(false); 21663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 21673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21683345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, CancelledTransaction) { 2169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 2170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 2171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 2172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 2173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 2174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 2176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 2177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 2178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This following read isn't used by the test, except during the 2179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // RunAllPending() call at the end since the SpdySession survives the 2180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // HttpNetworkTransaction and still tries to continue Read()'ing. Any 2181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MockRead will do here. 2182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 2183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 2184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), 2186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes)); 2187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 21893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 2190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 21913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(&data); 2192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 2193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 2195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 2196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 2197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.ResetTrans(); // Cancel the transaction. 2198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 2200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MockClientSocketFactory) are still alive. 2201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 2202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataNotConsumed(); 2203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Verify that the client sends a Rst Frame upon cancelling the stream. 22063345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) { 22073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 22083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> rst( 22093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyRstStream(1, spdy::CANCEL)); 22103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 22113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 0, false), 22123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*rst, 2, false), 22133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 22143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 22163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 2217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*resp, 1, true), 2218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead(true, 0, 0, 3) // EOF 22193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 22203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DeterministicSocketData> data( 22223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DeterministicSocketData(reads, arraysize(reads), 22233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 22243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 22263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), 22273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GetParam()); 22283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.SetDeterministic(); 22293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 22303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddDeterministicData(data.get()); 22313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 22323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 22343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 22363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 22373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->SetStop(2); 22393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->Run(); 22403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.ResetTrans(); 22413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->SetStop(20); 22423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->Run(); 22433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 22453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 22463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyNetworkTransactionTest::StartTransactionCallback 2248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : public CallbackRunner< Tuple1<int> > { 2249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 2250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit StartTransactionCallback( 22513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const scoped_refptr<HttpNetworkSession>& session, 2252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper& helper) 2253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : session_(session), helper_(helper) {} 2254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We try to start another transaction, which should succeed. 2256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void RunWithParams(const Tuple1<int>& params) { 2257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpNetworkTransaction> trans( 2258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new HttpNetworkTransaction(session_)); 2259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 2260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 2261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 2262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 2263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 2264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 2265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 2266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 2267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 22703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const scoped_refptr<HttpNetworkSession>& session_; 2271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper& helper_; 2272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 2273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify that the client can correctly deal with the user callback attempting 2275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to start another transaction on a session that is closing down. See 2276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// http://crbug.com/47455 22773345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { 2278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 2279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 2280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes2[] = { CreateMockWrite(*req) }; 2281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The indicated length of this packet is longer than its actual length. When 2283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the session receives an empty packet after this one, it shuts down the 2284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // session, and calls the read callback with the incomplete data. 2285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const uint8 kGetBodyFrame2[] = { 2286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x00, 0x00, 0x00, 0x01, 2287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x01, 0x00, 0x00, 0x07, 2288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 'h', 'e', 'l', 'l', 'o', '!', 2289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 2290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 22923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 22933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 2), 22943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 3), // Force a pause 22953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kGetBodyFrame2), 22963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kGetBodyFrame2), 4), 22973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 5), // Force a pause 22983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 6), // EOF 22993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 23003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads2[] = { 23013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 2), 23023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 3), // EOF 23033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 23043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 23063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 23073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 23083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data2( 23093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads2, arraysize(reads2), 23103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes2, arraysize(writes2))); 23113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 23133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 23143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 23153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 23163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data2.get()); 23173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 23183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Start the transaction with basic parameters. 23203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 23213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 23223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 23233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 23243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StartTransactionCallback callback2(helper.session(), helper); 23263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const int kSize = 3000; 2327513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 23283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->Read(buf, kSize, &callback2); 23293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This forces an err_IO_pending, which sets the callback. 23303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 23313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This finishes the read. 23323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 23333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 23343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 23353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass SpdyNetworkTransactionTest::DeleteSessionCallback 23373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : public CallbackRunner< Tuple1<int> > { 23383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public: 23393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick explicit DeleteSessionCallback(NormalSpdyTransactionHelper& helper) : 23403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_(helper) {} 23413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We kill the transaction, which deletes the session and stream. 23433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void RunWithParams(const Tuple1<int>& params) { 23443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_.ResetTrans(); 23453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 23463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 23483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper& helper_; 23493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 23503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Verify that the client can correctly deal with the user callback deleting the 23523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// transaction. Failures will usually be valgrind errors. See 23533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// http://crbug.com/46925 23543345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { 23553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 23563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { CreateMockWrite(*req) }; 23573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 23593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 23603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 23613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp.get(), 2), 23623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 3), // Force a pause 23633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body.get(), 4), 23643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 5), // EOF 23653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 23663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 23683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 23693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 23703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 23723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 23733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 23743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 23753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 23763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Start the transaction with basic parameters. 23783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 23793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 23803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 23813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 23823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup a user callback which will delete the session, and clear out the 23843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // memory holding the stream object. Note that the callback deletes trans. 23853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DeleteSessionCallback callback2(helper); 23863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const int kSize = 3000; 2387513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 23883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->Read(buf, kSize, &callback2); 23893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, rv); 23903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 23913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Finish running rest of tasks. 23933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 23943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 23953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 23963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Send a spdy request to www.google.com that gets redirected to www.foo.com. 23983345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, RedirectGetRequest) { 239921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // These are headers which the net::URLRequest tacks on. 24003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kExtraHeaders[] = { 24013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "accept-charset", 24023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "", 24033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "accept-encoding", 24043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "gzip,deflate", 24053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "accept-language", 24063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "", 24073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynStartHeader = make_spdy_header(spdy::SYN_STREAM); 24093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kStandardGetHeaders[] = { 24103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", 24113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "www.google.com", 24123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "method", 24133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "GET", 24143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", 24153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "http", 24163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", 24173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "/", 24183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "user-agent", 24193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "", 24203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", 24213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1" 24223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kStandardGetHeaders2[] = { 24243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", 24253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "www.foo.com", 24263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "method", 24273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "GET", 24283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", 24293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "http", 24303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", 24313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "/index.php", 24323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "user-agent", 24333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "", 24343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", 24353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1" 24363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup writes/reads to www.google.com 24393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPacket( 2440201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kSynStartHeader, kExtraHeaders, arraysize(kExtraHeaders) / 2, 2441201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2)); 24423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyPacket( 2443201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kSynStartHeader, kExtraHeaders, arraysize(kExtraHeaders) / 2, 2444201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kStandardGetHeaders2, arraysize(kStandardGetHeaders2) / 2)); 24453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReplyRedirect(1)); 24463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 24473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 1), 24483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 24503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 2), 24513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 3) // EOF 24523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup writes/reads to www.foo.com 24553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1)); 24563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(1, true)); 24573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes2[] = { 24583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2, 1), 24593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads2[] = { 24613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 2), 24623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body2, 3), 24633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 4) // EOF 24643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 24663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 24673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 24683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data2( 24693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads2, arraysize(reads2), 24703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes2, arraysize(writes2))); 24713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(erikchen): Make test support SPDYSSL, SPDYNPN 24733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_over_ssl(false); 24743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_always(true); 24753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestDelegate d; 24763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { 247721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::URLRequest r(GURL("http://www.google.com/"), &d); 24783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyURLRequestContext* spdy_url_request_context = 24793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new SpdyURLRequestContext(); 24803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r.set_context(spdy_url_request_context); 24813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_url_request_context->socket_factory(). 24823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddSocketDataProvider(data.get()); 24833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_url_request_context->socket_factory(). 24843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddSocketDataProvider(data2.get()); 24853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick d.set_quit_on_redirect(true); 24873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r.Start(); 24883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->Run(); 24893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, d.received_redirect_count()); 24913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r.FollowDeferredRedirect(); 24933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->Run(); 24943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, d.response_started_count()); 24953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(d.received_data_before_response()); 249672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(net::URLRequestStatus::SUCCESS, r.status().status()); 24973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string contents("hello!"); 24983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(contents, d.data_received()); 24993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 25003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()); 25013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()); 25023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data2->at_read_eof()); 25033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data2->at_write_eof()); 25043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 25053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 25063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Send a spdy request to www.google.com. Get a pushed stream that redirects to 25073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// www.foo.com. 25083345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, RedirectServerPush) { 250921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // These are headers which the net::URLRequest tacks on. 25103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kExtraHeaders[] = { 25113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "accept-charset", 25123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "", 25133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "accept-encoding", 25143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "gzip,deflate", 25153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "accept-language", 25163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "", 25173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 25183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynStartHeader = make_spdy_header(spdy::SYN_STREAM); 25193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kStandardGetHeaders[] = { 25203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", 25213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "www.google.com", 25223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "method", 25233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "GET", 25243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", 25253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "http", 25263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", 25273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "/", 25283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "user-agent", 25293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "", 25303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", 25313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1" 25323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 25333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kStandardGetHeaders2[] = { 25343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", 25353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "www.foo.com", 25363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "method", 25373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "GET", 25383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", 25393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "http", 25403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", 25413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "/index.php", 25423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "user-agent", 25433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "", 25443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", 25453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1" 25463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 25473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 25483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup writes/reads to www.google.com 2549201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> req( 2550201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ConstructSpdyPacket(kSynStartHeader, 2551201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kExtraHeaders, 2552201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kExtraHeaders) / 2, 2553201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kStandardGetHeaders, 2554201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kStandardGetHeaders) / 2)); 2555201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> req2( 2556201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ConstructSpdyPacket(kSynStartHeader, 2557201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kExtraHeaders, 2558201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kExtraHeaders) / 2, 2559201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kStandardGetHeaders2, 2560201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kStandardGetHeaders2) / 2)); 25613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 2562201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> rep( 2563201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ConstructSpdyPush(NULL, 2564201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2565201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2566201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2567201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat", 2568201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "301 Moved Permanently", 2569201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.foo.com/index.php")); 25703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 25713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 25723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 1), 25733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 25743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 25753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 2), 25763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*rep, 3), 25773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body, 4), 25783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 5), // Force a pause 25793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 6) // EOF 25803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 25813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 25823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup writes/reads to www.foo.com 25833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1)); 25843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(1, true)); 25853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes2[] = { 25863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2, 1), 25873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 25883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads2[] = { 25893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 2), 25903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body2, 3), 25913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 5) // EOF 25923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 25933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 25943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 25953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 25963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data2( 25973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads2, arraysize(reads2), 25983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes2, arraysize(writes2))); 25993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(erikchen): Make test support SPDYSSL, SPDYNPN 26013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_over_ssl(false); 26023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_always(true); 26033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestDelegate d; 26043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestDelegate d2; 26053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<SpdyURLRequestContext> spdy_url_request_context( 26063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new SpdyURLRequestContext()); 26073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { 260821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::URLRequest r(GURL("http://www.google.com/"), &d); 26093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r.set_context(spdy_url_request_context); 26103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_url_request_context->socket_factory(). 26113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddSocketDataProvider(data.get()); 26123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r.Start(); 26143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->Run(); 26153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, d.received_redirect_count()); 26173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string contents("hello!"); 26183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(contents, d.data_received()); 26193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 262021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::URLRequest r2(GURL("http://www.google.com/foo.dat"), &d2); 26213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r2.set_context(spdy_url_request_context); 26223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_url_request_context->socket_factory(). 26233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddSocketDataProvider(data2.get()); 26243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick d2.set_quit_on_redirect(true); 26263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r2.Start(); 26273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->Run(); 26283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, d2.received_redirect_count()); 26293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r2.FollowDeferredRedirect(); 26313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->Run(); 26323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, d2.response_started_count()); 26333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(d2.received_data_before_response()); 263472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(net::URLRequestStatus::SUCCESS, r2.status().status()); 26353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string contents2("hello!"); 26363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(contents2, d2.data_received()); 26373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 26383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 26393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data2->CompleteRead(); 26403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()); 26413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()); 26423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data2->at_read_eof()); 26433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data2->at_write_eof()); 26443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 26453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26463345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) { 26473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const unsigned char kPushBodyFrame[] = { 26483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x00, 0x00, 0x00, 0x02, // header, ID 26493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x01, 0x00, 0x00, 0x06, // FIN, length 26503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 26513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 26523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 26533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 26543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 26553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 26563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 26573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 26583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 26593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 26613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 26623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2663201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 2664201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2665201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2666201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2667201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 26683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 26693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 26703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 26713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 4, false), 26723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 26733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame), 5), 26743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 6), // Force a pause 26753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 26763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response; 26783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response2; 26793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string expected_push_result("pushed"); 2680201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 2681201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 2682201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 2683201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 2684201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 2685201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RunServerPushTest(data.get(), 2686201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response, 2687201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response2, 2688201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch expected_push_result); 26893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 26913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 26923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 26933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the pushed stream. 26953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response2.headers != NULL); 26963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 26973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 26983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26993345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) { 27003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const unsigned char kPushBodyFrame[] = { 27013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x00, 0x00, 0x00, 0x02, // header, ID 27023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x01, 0x00, 0x00, 0x06, // FIN, length 27033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 27043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 27053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 27073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 27083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 27093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 27103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 27133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2714201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 2715201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2716201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2717201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2718201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 27193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 27213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 27223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 27233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 27243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 27253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame), 5), 27263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 4, false), 27273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 6), // Force a pause 27283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 27293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response; 27313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response2; 27323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string expected_push_result("pushed"); 2733201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 2734201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 2735201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 2736201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 2737201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 2738201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RunServerPushTest(data.get(), 2739201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response, 2740201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response2, 2741201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch expected_push_result); 27423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 27443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 27453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 27463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the pushed stream. 27483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response2.headers != NULL); 27493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 27503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 27513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27523345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushServerAborted) { 27533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 27553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 27573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 27583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 27593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 27603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 27633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2764201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 2765201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2766201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2767201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2768201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 27693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream2_rst(ConstructSpdyRstStream(2, spdy::PROTOCOL_ERROR)); 27713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 27723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 27733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 27743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_rst, 4), 27753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 5, false), 27763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 6), // Force a pause 27773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 27783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 27803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 27813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 27823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 27833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 27843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 27863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 27873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 27893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Start the transaction with basic parameters. 27913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 27923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 27933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 27943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 27953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 27963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we consumed all test data. 27983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()) << "Read count: " 27993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_count() 28003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Read index: " 28013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_index(); 28023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()) << "Write count: " 28033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_count() 28043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Write index: " 28053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_index(); 28063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 28083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response = *trans->GetResponseInfo(); 28093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 28103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 28113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 28123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28133345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushDuplicate) { 28143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we don't leak streams and that we properly send a reset 28153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // if the server pushes the same stream twice. 28163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const unsigned char kPushBodyFrame[] = { 28173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x00, 0x00, 0x00, 0x02, // header, ID 28183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x01, 0x00, 0x00, 0x06, // FIN, length 28193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 28203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 28213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 28233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 28243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 28253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 28263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 28273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream3_rst(ConstructSpdyRstStream(4, spdy::PROTOCOL_ERROR)); 28283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 28293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 28303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream3_rst, 5), 28313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 28323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 28343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 28353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2836201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 2837201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2838201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2839201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2840201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 28413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2842201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream3_syn(ConstructSpdyPush(NULL, 2843201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2844201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 4, 2845201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2846201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 28473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 28483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 28493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 28503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream3_syn, 4), 28513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 6, false), 28523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 28533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame), 7), 28543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 8), // Force a pause 28553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 28563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response; 28583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response2; 28593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string expected_push_result("pushed"); 2860201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 2861201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 2862201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 2863201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 2864201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 2865201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RunServerPushTest(data.get(), 2866201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response, 2867201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response2, 2868201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch expected_push_result); 28693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 28713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 28723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 28733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the pushed stream. 28753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response2.headers != NULL); 28763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 28773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 28783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28793345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) { 28803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const unsigned char kPushBodyFrame1[] = { 28813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x00, 0x00, 0x00, 0x02, // header, ID 28823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x01, 0x00, 0x00, 0x1F, // FIN, length 28833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 28843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 28853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kPushBodyFrame2[] = " my darling"; 28863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kPushBodyFrame3[] = " hello"; 28873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kPushBodyFrame4[] = " my baby"; 28883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 28903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 28913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 28923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 28933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 28943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 28953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 28963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 28983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 28993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2900201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 2901201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2902201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2903201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2904201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 29053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 29063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 29073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 29083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame1), 29093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame1), 4), 29103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame2), 29113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame2) - 1, 5), 29123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame3), 29133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame3) - 1, 6), 29143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame4), 29153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame4) - 1, 7), 29163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 8, false), 29173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 9), // Force a pause 29183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 29193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response; 29213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response2; 29223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string expected_push_result("pushed my darling hello my baby"); 2923201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 2924201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 2925201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 2926201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 2927201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 2928201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RunServerPushTest(data.get(), 2929201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response, 2930201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response2, 2931201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch expected_push_result); 29323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 29343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 29353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 29363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the pushed stream. 29383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response2.headers != NULL); 29393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 29403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 29413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29423345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) { 29433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const unsigned char kPushBodyFrame1[] = { 29443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x00, 0x00, 0x00, 0x02, // header, ID 29453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x01, 0x00, 0x00, 0x1F, // FIN, length 29463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 29473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 29483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kPushBodyFrame2[] = " my darling"; 29493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kPushBodyFrame3[] = " hello"; 29503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kPushBodyFrame4[] = " my baby"; 29513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 29533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 29543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 29553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 29563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 29573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 29583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 29593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 29613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 29623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2963201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 2964201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2965201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2966201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2967201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 29683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 29693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 29703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 29713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame1), 29723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame1), 4), 29733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame2), 29743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame2) - 1, 5), 29753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 6), // Force a pause 29763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame3), 29773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame3) - 1, 7), 29783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame4), 29793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame4) - 1, 8), 29803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body.get(), 9, false), 29813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 10) // Force a pause. 29823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 29833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response; 29853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response2; 29863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string expected_push_result("pushed my darling hello my baby"); 2987201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 2988201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 2989201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 2990201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 2991201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 2992201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RunServerPushTest(data.get(), 2993201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response, 2994201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response2, 2995201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch expected_push_result); 29963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 29983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 29993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 30003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the pushed stream. 30023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response2.headers != NULL); 30033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 30043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 30053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30063345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) { 30073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 30093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 30113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream2_rst(ConstructSpdyRstStream(2, spdy::INVALID_STREAM)); 30133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 30143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 30153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream2_rst, 4), 30163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 30173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 30203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 3021201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 3022201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 3023201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 3024201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 3025201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 30263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 30273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 30283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 30293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 4), 30303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 5) // Force a pause 30313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 30323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 30343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 30353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 30363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 30373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 30383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 30403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 30413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 30433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Start the transaction with basic parameters. 30453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 30463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 30473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 30483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 30493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 30503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we consumed all test data. 30523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()) << "Read count: " 30533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_count() 30543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Read index: " 30553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_index(); 30563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()) << "Write count: " 30573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_count() 30583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Write index: " 30593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_index(); 30603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 30623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response = *trans->GetResponseInfo(); 30633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 30643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 30653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 30663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30673345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) { 30683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 30703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 30723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream2_rst(ConstructSpdyRstStream(2, spdy::INVALID_ASSOCIATED_STREAM)); 30743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 30753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 30763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream2_rst, 4), 30773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 30783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 30813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 3082201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 3083201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 3084201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 3085201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 9, 3086201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 3087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 30883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 30893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 30903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 4), 3091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, ERR_IO_PENDING, 5), // Force a pause 3092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> data( 3095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData(reads, arraysize(reads), 3096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 30983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 30993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 31013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 31023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 3104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Start the transaction with basic parameters. 3106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 31073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 3108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 3109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 31103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 3111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we consumed all test data. 31133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()) << "Read count: " 31143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_count() 31153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Read index: " 31163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_index(); 31173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()) << "Write count: " 31183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_count() 31193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Write index: " 31203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_index(); 31213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 31223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 31233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response = *trans->GetResponseInfo(); 31243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 31253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 3126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31283345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) { 31293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 31303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 31313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 31323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 31333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 31343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream2_rst(ConstructSpdyRstStream(2, spdy::PROTOCOL_ERROR)); 31353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 31363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 31373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream2_rst, 4), 31383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 3139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 31413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 31423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 31433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream2_syn(ConstructSpdyPush(NULL, 0, 2, 1)); 3144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 31453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 31463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 31473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 4), 31483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 5) // Force a pause 3149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> data( 3152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData(reads, arraysize(reads), 3153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 31553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 31563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 31583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 31593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 3161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Start the transaction with basic parameters. 3163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 31643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 3165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 3166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 31673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 31683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we consumed all test data. 31693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()) << "Read count: " 31703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_count() 31713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Read index: " 31723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_index(); 31733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()) << "Write count: " 31743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_count() 31753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Write index: " 31763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_index(); 31773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 31783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 31793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response = *trans->GetResponseInfo(); 31803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 31813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 3182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify that various SynReply headers parse correctly through the 3185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HTTP layer. 31863345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) { 3187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SynReplyHeadersTests { 3188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int num_headers; 3189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* extra_headers[5]; 3190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* expected_headers; 3191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } test_cases[] = { 3192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This uses a multi-valued cookie header. 3193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 2, 3194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "cookie", "val1", 3195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "cookie", "val2", // will get appended separated by NULL 3196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "cookie: val1\n" 3199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "cookie: val2\n" 3200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "hello: bye\n" 3201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status: 200\n" 3202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version: HTTP/1.1\n" 3203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is the minimalist set of headers. 3205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 0, 3206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL }, 3207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "hello: bye\n" 3208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status: 200\n" 3209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version: HTTP/1.1\n" 3210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Headers with a comma separated list. 3212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 1, 3213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "cookie", "val1,val2", 3214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "cookie: val1,val2\n" 3217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "hello: bye\n" 3218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status: 200\n" 3219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version: HTTP/1.1\n" 3220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 3224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req( 3225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 3227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp( 3229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGetSynReply(test_cases[i].extra_headers, 3230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].num_headers, 3231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1)); 3232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 32433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 3248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 3250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers; 3252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(headers.get() != NULL); 3253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void* iter = NULL; 3254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string name, value, lines; 3255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (headers->EnumerateHeaderLines(&iter, &name, &value)) { 3256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append(name); 3257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append(": "); 3258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append(value); 3259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append("\n"); 3260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(std::string(test_cases[i].expected_headers), lines); 3262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify that various SynReply headers parse vary fields correctly 3266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// through the HTTP layer, and the response matches the request. 32673345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) { 3268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const SpdyHeaderInfo syn_reply_info = { 3269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SYN_REPLY, // Syn Reply 3270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, // Stream ID 3271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Associated Stream ID 32723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), 32733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Priority 3274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::CONTROL_FLAG_NONE, // Control Flags 3275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, // Compressed 3276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::INVALID, // Status 3277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // Data 3278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Data Length 3279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::DATA_FLAG_NONE // Data Flags 3280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Modify the following data to change/add test cases: 3282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SynReplyTests { 3283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const SpdyHeaderInfo* syn_reply; 3284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool vary_matches; 3285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int num_headers[2]; 3286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* extra_headers[2][16]; 3287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } test_cases[] = { 3288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test the case of a multi-valued cookie. When the value is delimited 3289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // with NUL characters, it needs to be unfolded into multiple headers. 3290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 3291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &syn_reply_info, 3292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 3293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 1, 4 }, 3294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { "cookie", "val1,val2", 3295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "vary", "cookie", 3298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", "200", 3299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", "/index.php", 3300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1", 3301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, { // Multiple vary fields. 3305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &syn_reply_info, 3306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 3307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 2, 5 }, 3308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { "friend", "barney", 3309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "enemy", "snaggletooth", 3310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "vary", "friend", 3313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "vary", "enemy", 3314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", "200", 3315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", "/index.php", 3316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1", 3317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, { // Test a '*' vary field. 3321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &syn_reply_info, 3322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 3323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 1, 4 }, 3324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { "cookie", "val1,val2", 3325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "vary", "*", 3328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", "200", 3329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", "/index.php", 3330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1", 3331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, { // Multiple comma-separated vary fields. 3335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &syn_reply_info, 3336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 3337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 2, 4 }, 3338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { "friend", "barney", 3339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "enemy", "snaggletooth", 3340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "vary", "friend,enemy", 3343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", "200", 3344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", "/index.php", 3345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1", 3346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 3353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 3354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> frame_req( 3355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(test_cases[i].extra_headers[0], 3356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].num_headers[0], 3357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 1, LOWEST)); 3358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 3360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*frame_req), 3361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the reply. 3364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> frame_reply( 3365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyPacket(*test_cases[i].syn_reply, 3366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].extra_headers[1], 3367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].num_headers[1], 3368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 3369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0)); 3370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*frame_reply), 3374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Attach the headers to the request. 3379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int header_count = test_cases[i].num_headers[0]; 3380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request = CreateGetRequest(); 3382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int ct = 0; ct < header_count; ct++) { 3383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* header_key = test_cases[i].extra_headers[0][ct * 2]; 3384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* header_value = test_cases[i].extra_headers[0][ct * 2 + 1]; 3385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.extra_headers.SetHeader(header_key, header_value); 3386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(request, 33923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv) << i; 3397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line) << i; 3398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data) << i; 3399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test the response information. 3401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(out.response_info.response_time > 3402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info.request_time) << i; 3403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::TimeDelta test_delay = out.response_info.response_time - 3404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info.request_time; 3405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::TimeDelta min_expected_delay; 3406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch min_expected_delay.FromMilliseconds(10); 3407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_GT(test_delay.InMillisecondsF(), 3408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch min_expected_delay.InMillisecondsF()) << i; 3409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.response_info.vary_data.is_valid(), 3410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].vary_matches) << i; 3411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check the headers. 3413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers; 3414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(headers.get() != NULL) << i; 3415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void* iter = NULL; 3416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string name, value, lines; 3417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (headers->EnumerateHeaderLines(&iter, &name, &value)) { 3418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append(name); 3419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append(": "); 3420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append(value); 3421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append("\n"); 3422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the expected header reply string. 3425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char reply_buffer[256] = ""; 3426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyReplyString(test_cases[i].extra_headers[1], 3427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].num_headers[1], 3428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reply_buffer, 3429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 256); 3430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(std::string(reply_buffer), lines) << i; 3432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify that we don't crash on invalid SynReply responses. 34363345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, InvalidSynReply) { 3437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const SpdyHeaderInfo kSynStartHeader = { 3438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SYN_REPLY, // Kind = SynReply 3439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, // Stream ID 3440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Associated stream ID 34413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), 34423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Priority 3443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::CONTROL_FLAG_NONE, // Control Flags 3444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, // Compressed 3445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::INVALID, // Status 3446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // Data 3447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Length 3448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::DATA_FLAG_NONE // Data Flags 3449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct InvalidSynReplyTests { 3452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int num_headers; 3453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* headers[10]; 3454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } test_cases[] = { 3455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // SYN_REPLY missing status header 3456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 4, 3457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "cookie", "val1", 3458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "cookie", "val2", 3459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", "/index.php", 3460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1", 3461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // SYN_REPLY missing version header 3465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 2, 3466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "status", "200", 3467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", "/index.php", 3468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // SYN_REPLY with no headers 3472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 0, { NULL }, }, 3473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 3476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req( 3477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 3479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 3480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp( 3483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyPacket(kSynStartHeader, 3484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 0, 3485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].headers, 3486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].num_headers)); 3487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 34983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3501201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_INCOMPLETE_SPDY_HEADERS, out.rv); 3502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify that we don't crash on some corrupt frames. 350672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_P(SpdyNetworkTransactionTest, CorruptFrameSessionError) { 350772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // This is the length field that's too short. 350872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<spdy::SpdyFrame> syn_reply_wrong_length( 3509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGetSynReply(NULL, 0, 1)); 351072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen syn_reply_wrong_length->set_length(syn_reply_wrong_length->length() - 4); 3511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SynReplyTests { 3513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdyFrame* syn_reply; 3514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } test_cases[] = { 351572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen { syn_reply_wrong_length.get(), }, 3516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 3519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req( 3520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 3522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 3523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite(true, 0, 0) // EOF 3524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*test_cases[i].syn_reply), 3529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 35373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 3541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that we shutdown correctly on write errors. 35453345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, WriteError) { 3546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 3548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We'll write 10 bytes successfully 3549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite(true, req->data(), 10), 3550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Followed by ERROR! 3551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite(true, ERR_FAILED), 3552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(2, NULL, 0, 3556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 35583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_FAILED, out.rv); 3562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->Reset(); 3563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that partial writes work. 35663345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, PartialWrite) { 3567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Chop the SYN_STREAM frame into 5 chunks. 3568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kChunks = 5; 3570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_array<MockWrite> writes(ChopWriteFrame(*req.get(), kChunks)); 3571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 3573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(kChunks, reads, arraysize(reads), 3582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes.get(), kChunks)); 3583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 35843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 3588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 3590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// In this test, we enable compression, but get a uncompressed SynReply from 3593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the server. Verify that teardown is all clean. 35943345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) { 3595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For this test, we turn on the normal compression. 3596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EnableCompression(true); 3597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> compressed( 3599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(NULL, 0, true, 1, LOWEST)); 36003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> rst( 36013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyRstStream(1, spdy::PROTOCOL_ERROR)); 3602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 3603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*compressed), 36043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*rst), 3605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 3608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 36123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) 3613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 36193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 36223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 3623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->Reset(); 3624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EnableCompression(false); 3626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that the NetLog contains good data for a simple GET request. 36293345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, NetLog) { 36304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch static const char* const kExtraHeaders[] = { 36314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch "user-agent", "Chrome", 36324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch }; 36334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(kExtraHeaders, 1, false, 1, 36344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch LOWEST)); 3635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 3636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 3638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded); 3646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 36504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch NormalSpdyTransactionHelper helper(CreateGetRequestWithUserAgent(), 36513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick log.bound(), GetParam()); 3652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 3655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 3657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check that the NetLog was filled reasonably. 3659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This test is intentionally non-specific about the exact ordering of the 3660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // log; instead we just check to make sure that certain events exist, and that 3661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // they are in the right order. 366221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 366321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 366421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 366521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_LT(0u, entries.size()); 3666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int pos = 0; 366721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pos = net::ExpectLogContainsSomewhere(entries, 0, 36683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, 3669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::NetLog::PHASE_BEGIN); 367021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 36713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, 3672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::NetLog::PHASE_END); 367321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 36743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, 3675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::NetLog::PHASE_BEGIN); 367621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 36773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, 3678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::NetLog::PHASE_END); 367921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 36803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, 3681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::NetLog::PHASE_BEGIN); 368221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 36833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, 3684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::NetLog::PHASE_END); 36854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 36864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Check that we logged all the headers correctly 36874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch pos = net::ExpectLogContainsSomewhere( 368821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 0, 36894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::NetLog::TYPE_SPDY_SESSION_SYN_STREAM, 36904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::NetLog::PHASE_NONE); 369121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CapturingNetLog::Entry entry = entries[pos]; 36924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch NetLogSpdySynParameter* request_params = 36934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch static_cast<NetLogSpdySynParameter*>(entry.extra_parameters.get()); 36944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch spdy::SpdyHeaderBlock* headers = 36954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch request_params->GetHeaders().get(); 36964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 36974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch spdy::SpdyHeaderBlock expected; 36984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch expected["host"] = "www.google.com"; 36994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch expected["url"] = "/"; 37004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch expected["scheme"] = "http"; 37014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch expected["version"] = "HTTP/1.1"; 37024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch expected["method"] = "GET"; 37034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch expected["user-agent"] = "Chrome"; 37044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(expected.size(), headers->size()); 37054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch spdy::SpdyHeaderBlock::const_iterator end = expected.end(); 37064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch for (spdy::SpdyHeaderBlock::const_iterator it = expected.begin(); 37074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch it != end; 37084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ++it) { 37094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(it->second, (*headers)[it->first]); 37104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 3711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Since we buffer the IO from the stream to the renderer, this test verifies 3714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// that when we read out the maximum amount of data (e.g. we received 50 bytes 3715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// on the network, but issued a Read for only 5 of those bytes) that the data 3716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// flow still works correctly. 37173345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, BufferFull) { 3718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 3719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 3722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 2 data frames in a single read. 3724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame_1( 3725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "goodby", 6, spdy::DATA_FLAG_NONE)); 3726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame_2( 3727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "e worl", 6, spdy::DATA_FLAG_NONE)); 3728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdyFrame* data_frames[2] = { 3729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame_1.get(), 3730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame_2.get(), 3731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char combined_data_frames[100]; 3733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int combined_data_frames_len = 3734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CombineFrames(data_frames, arraysize(data_frames), 3735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch combined_data_frames, arraysize(combined_data_frames)); 3736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> last_frame( 3737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "d", 1, spdy::DATA_FLAG_FIN)); 3738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 3740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, ERR_IO_PENDING), // Force a pause 3743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, combined_data_frames, combined_data_frames_len), 3744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, ERR_IO_PENDING), // Force a pause 3745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*last_frame), 3746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 3755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 37573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 37593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 3760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 3761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 3762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 3763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback.WaitForResult(); 3766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, OK); 3767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 3769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 3770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 3771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response->headers->GetStatusLine(); 3772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response; // Make a copy so we can verify. 3773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read Data 3775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback read_callback; 3776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string content; 3778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch do { 3779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read small chunks at a time. 3780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kSmallReadSize = 3; 3781513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize)); 3782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Read(buf, kSmallReadSize, &read_callback); 3783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == net::ERR_IO_PENDING) { 3784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->CompleteRead(); 3785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = read_callback.WaitForResult(); 3786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv > 0) { 3788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content.append(buf->data(), rv); 3789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (rv < 0) { 3790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 3791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (rv > 0); 3793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_data.swap(content); 3795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 3797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MockClientSocketFactory) are still alive. 3798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 3799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that we consumed all test data. 3801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 3802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 3804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("goodbye world", out.response_data); 3806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 38083345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ConnectFailureFallbackToHttp) { 3809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockConnect connects[] = { 3810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockConnect(true, ERR_NAME_NOT_RESOLVED), 3811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockConnect(false, ERR_NAME_NOT_RESOLVED), 3812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockConnect(true, ERR_INTERNET_DISCONNECTED), 3813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockConnect(false, ERR_INTERNET_DISCONNECTED) 3814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t index = 0; index < arraysize(connects); ++index) { 3817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req( 3818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 3820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 3821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite(true, 0, 0) // EOF 3822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 3825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(connects[index], 1, reads, arraysize(reads), 3834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 38363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 38383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 3839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set up http fallback data. 3841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead http_fallback_data[] = { 3842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("HTTP/1.1 200 OK\r\n\r\n"), 3843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead("hello world!!!"), 3844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, OK), 3845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<StaticSocketDataProvider> http_fallback( 3848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new StaticSocketDataProvider(http_fallback_data, 3849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(http_fallback_data), 3850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 0)); 3851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.AddDataNoSSL(http_fallback.get()); 3852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 3853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 3854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 3856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(rv, ERR_IO_PENDING); 3857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 3858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 38593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (GetParam() == SPDYNOSSL || GetParam() == SPDYSSL) { 38603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response == NULL); 38613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 38623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 38633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (GetParam() != SPDYNPN) 38643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 3865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 3866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 3867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 3868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 3869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = ReadTransaction(trans, &response_data); 3870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 3871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(!response->was_fetched_via_spdy); 3873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(!response->was_npn_negotiated); 3874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_alternate_protocol_available); 3875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(http_fallback->at_read_eof()); 3876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0u, data->read_index()); 3877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0u, data->write_index()); 3878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello world!!!", response_data); 3879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify that basic buffering works; when multiple data frames arrive 3883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// at the same time, ensure that we don't notify a read completion for 3884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// each data frame individually. 38853345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, Buffering) { 3886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 3887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 3890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 4 data frames in a single read. 3892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame( 3893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_NONE)); 3894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame_fin( 3895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_FIN)); 3896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdyFrame* data_frames[4] = { 3897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 3898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 3899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 3900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame_fin.get() 3901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char combined_data_frames[100]; 3903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int combined_data_frames_len = 3904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CombineFrames(data_frames, arraysize(data_frames), 3905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch combined_data_frames, arraysize(combined_data_frames)); 3906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 3908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, ERR_IO_PENDING), // Force a pause 3911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, combined_data_frames, combined_data_frames_len), 3912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 39203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 39223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 3923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 3924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 3926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 3927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 3928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback.WaitForResult(); 3931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, OK); 3932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 3934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 3935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 3936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response->headers->GetStatusLine(); 3937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response; // Make a copy so we can verify. 3938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read Data 3940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback read_callback; 3941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string content; 3943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int reads_completed = 0; 3944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch do { 3945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read small chunks at a time. 3946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kSmallReadSize = 14; 3947513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize)); 3948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Read(buf, kSmallReadSize, &read_callback); 3949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == net::ERR_IO_PENDING) { 3950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->CompleteRead(); 3951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = read_callback.WaitForResult(); 3952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv > 0) { 3954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSmallReadSize, rv); 3955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content.append(buf->data(), rv); 3956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (rv < 0) { 3957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FAIL() << "Unexpected read error: " << rv; 3958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reads_completed++; 3960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (rv > 0); 3961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(3, reads_completed); // Reads are: 14 bytes, 14 bytes, 0 bytes. 3963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_data.swap(content); 3965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 3967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MockClientSocketFactory) are still alive. 3968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 3969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that we consumed all test data. 3971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 3972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 3974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("messagemessagemessagemessage", out.response_data); 3976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify the case where we buffer data but read it after it has been buffered. 39793345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, BufferedAll) { 3980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 3981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 3984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 5 data frames in a single read. 3986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> syn_reply( 3987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGetSynReply(NULL, 0, 1)); 3988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch syn_reply->set_flags(spdy::CONTROL_FLAG_NONE); // turn off FIN bit 3989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame( 3990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_NONE)); 3991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame_fin( 3992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_FIN)); 3993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdyFrame* frames[5] = { 3994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch syn_reply.get(), 3995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 3996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 3997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 3998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame_fin.get() 3999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char combined_frames[200]; 4001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int combined_frames_len = 4002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CombineFrames(frames, arraysize(frames), 4003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch combined_frames, arraysize(combined_frames)); 4004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, combined_frames, combined_frames_len), 4007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 4008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 4012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 4013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 40153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 4016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 40173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 4018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 4019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 4021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 4022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 4023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 4025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback.WaitForResult(); 4026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, OK); 4027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 4029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 4030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 4031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response->headers->GetStatusLine(); 4032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response; // Make a copy so we can verify. 4033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read Data 4035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback read_callback; 4036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string content; 4038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int reads_completed = 0; 4039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch do { 4040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read small chunks at a time. 4041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kSmallReadSize = 14; 4042513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize)); 4043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Read(buf, kSmallReadSize, &read_callback); 4044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv > 0) { 4045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSmallReadSize, rv); 4046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content.append(buf->data(), rv); 4047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (rv < 0) { 4048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FAIL() << "Unexpected read error: " << rv; 4049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reads_completed++; 4051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (rv > 0); 4052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(3, reads_completed); 4054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_data.swap(content); 4056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 4058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MockClientSocketFactory) are still alive. 4059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 4060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that we consumed all test data. 4062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 4063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 4065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 4066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("messagemessagemessagemessage", out.response_data); 4067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify the case where we buffer data and close the connection. 40703345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, BufferedClosed) { 4071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 4072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 4075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // All data frames in a single read. 4077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NOTE: We don't FIN the stream. 4078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame( 4079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_NONE)); 4080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdyFrame* data_frames[4] = { 4081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 4082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 4083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 4084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get() 4085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char combined_data_frames[100]; 4087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int combined_data_frames_len = 4088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CombineFrames(data_frames, arraysize(data_frames), 4089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch combined_data_frames, arraysize(combined_data_frames)); 4090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 4091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 4093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, ERR_IO_PENDING), // Force a wait 4094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, combined_data_frames, combined_data_frames_len), 4095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 4096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 4100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 4101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 41033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 4104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 41053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 4106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 4107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 4109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 4111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 4112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 4114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback.WaitForResult(); 4115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, OK); 4116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 4118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 4119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 4120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response->headers->GetStatusLine(); 4121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response; // Make a copy so we can verify. 4122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read Data 4124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback read_callback; 4125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string content; 4127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int reads_completed = 0; 4128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch do { 4129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read small chunks at a time. 4130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kSmallReadSize = 14; 4131513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize)); 4132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Read(buf, kSmallReadSize, &read_callback); 4133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == net::ERR_IO_PENDING) { 4134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->CompleteRead(); 4135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = read_callback.WaitForResult(); 4136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv > 0) { 4138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content.append(buf->data(), rv); 4139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (rv < 0) { 4140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This test intentionally closes the connection, and will get an error. 4141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); 4142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 4143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reads_completed++; 4145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (rv > 0); 4146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0, reads_completed); 4148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_data.swap(content); 4150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 4152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MockClientSocketFactory) are still alive. 4153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 4154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that we consumed all test data. 4156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 4157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify the case where we buffer data and cancel the transaction. 41603345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, BufferedCancelled) { 4161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 4162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 4165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NOTE: We don't FIN the stream. 4167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame( 4168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_NONE)); 4169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 4171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 4173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, ERR_IO_PENDING), // Force a wait 4174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*data_frame), 4175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 4176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 4180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 4181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 41833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 4184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 41853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 4186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 4187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 4188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 4190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 4191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 4193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback.WaitForResult(); 4194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, OK); 4195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 4197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 4198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 4199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response->headers->GetStatusLine(); 4200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response; // Make a copy so we can verify. 4201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read Data 4203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback read_callback; 4204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch do { 4206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kReadSize = 256; 4207513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kReadSize)); 4208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Read(buf, kReadSize, &read_callback); 4209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == net::ERR_IO_PENDING) { 4210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Complete the read now, which causes buffering to start. 4211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->CompleteRead(); 4212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Destroy the transaction, causing the stream to get cancelled 4213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and orphaning the buffered IO task. 4214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.ResetTrans(); 4215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 4216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We shouldn't get here in this test. 4218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FAIL() << "Unexpected read: " << rv; 4219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (rv > 0); 4220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the MessageLoop; this will cause the buffered IO task 4222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to run for the final time. 4223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 4224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that we consumed all test data. 4226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 4227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that if the server requests persistence of settings, that we save 4230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the settings in the SpdySettingsStorage. 42313345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, SettingsSaved) { 4232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const SpdyHeaderInfo kSynReplyInfo = { 4233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SYN_REPLY, // Syn Reply 4234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, // Stream ID 4235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Associated Stream ID 42363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), 42373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Priority 4238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::CONTROL_FLAG_NONE, // Control Flags 4239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, // Compressed 4240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::INVALID, // Status 4241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // Data 4242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Data Length 4243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::DATA_FLAG_NONE // Data Flags 4244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const char* const kExtraHeaders[] = { 4246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", "200", 4247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1" 4248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 42513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 42523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 4253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that no settings exist initially. 42553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair host_port_pair("www.google.com", helper.port()); 4256dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); 4257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(spdy_session_pool->spdy_settings().Get(host_port_pair).empty()); 4258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 4260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 4262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the reply. 4264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> reply( 4265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyPacket(kSynReplyInfo, 4266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kExtraHeaders, 4267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(kExtraHeaders) / 2, 4268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 4269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0)); 4270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleId1 = 0x1; 4272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleValue1 = 0x0a0a0a0a; 4273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleId2 = 0x2; 4274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleValue2 = 0x0b0b0b0b; 4275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleId3 = 0xababab; 4276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleValue3 = 0x0c0c0c0c; 4277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> settings_frame; 4278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 4279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the SETTINGS frame. 4280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings settings; 4281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SettingsFlagsAndId setting(0); 4282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First add a persisted setting 4283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); 4284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_id(kSampleId1); 4285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(std::make_pair(setting, kSampleValue1)); 4286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Next add a non-persisted setting 4287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_flags(0); 4288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_id(kSampleId2); 4289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(std::make_pair(setting, kSampleValue2)); 4290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Next add another persisted setting 4291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); 4292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_id(kSampleId3); 4293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(std::make_pair(setting, kSampleValue3)); 4294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings_frame.reset(ConstructSpdySettings(settings)); 4295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 4298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*reply), 4300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 4301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*settings_frame), 4302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 4303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 4307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 43083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 43093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunDefaultTest(); 43103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 4311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 4312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 4313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 4314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 4315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 4317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify we had two persisted settings. 4318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings saved_settings = 4319dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session_pool->spdy_settings().Get(host_port_pair); 4320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(2u, saved_settings.size()); 4321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify the first persisted setting. 4323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySetting setting = saved_settings.front(); 4324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch saved_settings.pop_front(); 4325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, setting.first.flags()); 4326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleId1, setting.first.id()); 4327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleValue1, setting.second); 4328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify the second persisted setting. 4330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting = saved_settings.front(); 4331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch saved_settings.pop_front(); 4332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, setting.first.flags()); 4333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleId3, setting.first.id()); 4334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleValue3, setting.second); 4335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that when there are settings saved that they are sent back to the 4339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// server upon session establishment. 43403345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { 4341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const SpdyHeaderInfo kSynReplyInfo = { 4342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SYN_REPLY, // Syn Reply 4343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, // Stream ID 4344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Associated Stream ID 43453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), 43463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Priority 4347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::CONTROL_FLAG_NONE, // Control Flags 4348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, // Compressed 4349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::INVALID, // Status 4350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // Data 4351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Data Length 4352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::DATA_FLAG_NONE // Data Flags 4353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const char* kExtraHeaders[] = { 4355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", "200", 4356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1" 4357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 43603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 43613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 4362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that no settings exist initially. 43643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair host_port_pair("www.google.com", helper.port()); 4365dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); 4366dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(spdy_session_pool->spdy_settings().Get(host_port_pair).empty()); 4367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleId1 = 0x1; 4369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleValue1 = 0x0a0a0a0a; 4370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleId2 = 0xababab; 4371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleValue2 = 0x0c0c0c0c; 4372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Manually insert settings into the SpdySettingsStorage here. 4373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 4374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings settings; 4375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SettingsFlagsAndId setting(0); 4376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First add a persisted setting 4377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); 4378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_id(kSampleId1); 4379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(std::make_pair(setting, kSampleValue1)); 4380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Next add another persisted setting 4381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); 4382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_id(kSampleId2); 4383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(std::make_pair(setting, kSampleValue2)); 4384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4385dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session_pool->mutable_spdy_settings()->Set(host_port_pair, settings); 4386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4388dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(2u, spdy_session_pool->spdy_settings().Get(host_port_pair).size()); 4389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the SETTINGS frame. 4391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdySettings& settings = 4392dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session_pool->spdy_settings().Get(host_port_pair); 4393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); 4394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 4396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 4399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*settings_frame), 4400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 4401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the reply. 4404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> reply( 4405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyPacket(kSynReplyInfo, 4406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kExtraHeaders, 4407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(kExtraHeaders) / 2, 4408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 4409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0)); 4410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 4412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*reply), 4414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 4415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 4416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(2, reads, arraysize(reads), 4420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 44213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 44223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunDefaultTest(); 44233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 4424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 4425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 4426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 4427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 4428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 4430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify we had two persisted settings. 4431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings saved_settings = 4432dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session_pool->spdy_settings().Get(host_port_pair); 4433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(2u, saved_settings.size()); 4434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify the first persisted setting. 4436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySetting setting = saved_settings.front(); 4437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch saved_settings.pop_front(); 4438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, setting.first.flags()); 4439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleId1, setting.first.id()); 4440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleValue1, setting.second); 4441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify the second persisted setting. 4443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting = saved_settings.front(); 4444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch saved_settings.pop_front(); 4445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, setting.first.flags()); 4446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleId2, setting.first.id()); 4447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleValue2, setting.second); 4448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44513345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, GoAwayWithActiveStream) { 4452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 4454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> go_away(ConstructSpdyGoAway()); 4456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*go_away), 44583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0), // EOF 4459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 4463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 4464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 44653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 44663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data); 4467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 4468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 44693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_ABORTED, out.rv); 4470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44723345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) { 4473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 4475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 4477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 4479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, 0, 0) // EOF 4480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 4484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 4485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog log; 4486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 44873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick log, GetParam()); 4488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 44893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 4490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 4491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 4493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out; 4494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = trans->Start(&CreateGetRequest(), &callback, log); 4495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, ERR_IO_PENDING); 4497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback.WaitForResult(); 4498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, OK); 4499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 4501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 4502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 4503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = ReadTransaction(trans, &out.response_data); 4504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv); 4505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that we consumed all test data. 4507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 4508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 45103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test to make sure we can correctly connect through a proxy. 45113345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ProxyConnect) { 45123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 45133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 45143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.session_deps().reset(new SpdySessionDependencies( 45153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"))); 4516513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch helper.SetSession(make_scoped_refptr( 4517513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get()))); 45183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 45193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 45203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n" 45223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 45233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"}; 45243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n" 45253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 45263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"}; 45273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"}; 45283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 45293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 45303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 45313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes_SPDYNPN[] = { 45333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite(false, kConnect443, arraysize(kConnect443) - 1, 0), 45343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 2), 45353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 45363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads_SPDYNPN[] = { 45373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, kHTTP200, arraysize(kHTTP200) - 1, 1), 45383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 3), 45393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body.get(), 4), 45403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 5), 45413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 45423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes_SPDYSSL[] = { 45443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite(false, kConnect80, arraysize(kConnect80) - 1, 0), 45453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 2), 45463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 45473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads_SPDYSSL[] = { 45483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, kHTTP200, arraysize(kHTTP200) - 1, 1), 45493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 3), 45503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body.get(), 4), 45513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 5), 45523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 45533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes_SPDYNOSSL[] = { 45553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 0), 45563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 45573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads_SPDYNOSSL[] = { 45593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 1), 45603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body.get(), 2), 45613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 3), 45623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 45633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data; 45653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch(GetParam()) { 45663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNOSSL: 45673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data = new OrderedSocketData(reads_SPDYNOSSL, 45683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(reads_SPDYNOSSL), 45693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes_SPDYNOSSL, 45703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(writes_SPDYNOSSL)); 45713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 45723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYSSL: 45733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data = new OrderedSocketData(reads_SPDYSSL, arraysize(reads_SPDYSSL), 45743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes_SPDYSSL, arraysize(writes_SPDYSSL)); 45753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 45763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNPN: 45773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data = new OrderedSocketData(reads_SPDYNPN, arraysize(reads_SPDYNPN), 45783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes_SPDYNPN, arraysize(writes_SPDYNPN)); 45793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 45803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 45813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 45823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 45833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 45853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 45863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 45883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 45893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 45913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, rv); 45923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 45943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response = *trans->GetResponseInfo(); 45953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 45963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 45973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string response_data; 45993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, ReadTransaction(trans, &response_data)); 46003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", response_data); 46013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 46023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 46033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test to make sure we can correctly connect through a proxy to www.google.com, 46053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// if there already exists a direct spdy connection to www.google.com. See 46063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// http://crbug.com/49874 46073345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { 46083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // When setting up the first transaction, we store the SpdySessionPool so that 46093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // we can use the same pool in the second transaction. 46103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 46113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 46123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Use a proxy service which returns a proxy fallback list from DIRECT to 46143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // myproxy:70. For this test there will be no fallback, so it is equivalent 46153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // to simply DIRECT. The reason for appending the second proxy is to verify 46163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // that the session pool key used does is just "DIRECT". 46173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.session_deps().reset(new SpdySessionDependencies( 46183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyService::CreateFixedFromPacResult("DIRECT; PROXY myproxy:70"))); 4619513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch helper.SetSession(make_scoped_refptr( 4620513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get()))); 46213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4622731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); 46233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 46243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Construct and send a simple GET request. 46263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 46273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 46283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 1), 46293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 46303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 46323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 46333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 46343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 2), 46353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body, 3), 46363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 4), // Force a pause 46373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 5) // EOF 46383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 46393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 46403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 46413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 46423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 46433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 46443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 46463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TransactionHelperResult out; 46473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 46483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(out.rv, ERR_IO_PENDING); 46503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback.WaitForResult(); 46513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(out.rv, OK); 46523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 46543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->headers != NULL); 46553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->was_fetched_via_spdy); 46563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans, &out.response_data); 46573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 46583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response->headers->GetStatusLine(); 46593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 46603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", out.response_data); 46613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Check that the SpdySession is still in the SpdySessionPool. 46633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair host_port_pair("www.google.com", helper.port()); 46643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortProxyPair session_pool_key_direct( 46653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick host_port_pair, ProxyServer::Direct()); 46663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(spdy_session_pool->HasSession(session_pool_key_direct)); 46673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortProxyPair session_pool_key_proxy( 46683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick host_port_pair, 46693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyServer::FromURI("www.foo.com", ProxyServer::SCHEME_HTTP)); 46703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(spdy_session_pool->HasSession(session_pool_key_proxy)); 46713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Set up data for the proxy connection. 46733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n" 46743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 46753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"}; 46763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n" 46773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 46783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"}; 46793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"}; 46803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet( 46813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "http://www.google.com/foo.dat", false, 1, LOWEST)); 46823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1)); 46833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(1, true)); 46843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes_SPDYNPN[] = { 46863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite(false, kConnect443, arraysize(kConnect443) - 1, 0), 46873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2, 2), 46883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 46893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads_SPDYNPN[] = { 46903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, kHTTP200, arraysize(kHTTP200) - 1, 1), 46913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 3), 46923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body2, 4), 46933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 5) // EOF 46943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 46953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes_SPDYNOSSL[] = { 46973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2, 0), 46983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 46993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads_SPDYNOSSL[] = { 47003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 1), 47013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body2, 2), 47023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 3) // EOF 47033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 47043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes_SPDYSSL[] = { 47063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite(false, kConnect80, arraysize(kConnect80) - 1, 0), 47073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2, 2), 47083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 47093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads_SPDYSSL[] = { 47103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, kHTTP200, arraysize(kHTTP200) - 1, 1), 47113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 3), 47123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body2, 4), 47133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 5), 47143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 47153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_proxy; 47173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch(GetParam()) { 47183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNPN: 47193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_proxy = new OrderedSocketData(reads_SPDYNPN, 47203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(reads_SPDYNPN), 47213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes_SPDYNPN, 47223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(writes_SPDYNPN)); 47233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 47243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNOSSL: 47253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_proxy = new OrderedSocketData(reads_SPDYNOSSL, 47263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(reads_SPDYNOSSL), 47273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes_SPDYNOSSL, 47283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(writes_SPDYNOSSL)); 47293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 47303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYSSL: 47313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_proxy = new OrderedSocketData(reads_SPDYSSL, 47323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(reads_SPDYSSL), 47333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes_SPDYSSL, 47343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(writes_SPDYSSL)); 47353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 47363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 47373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 47383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 47393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Create another request to www.google.com, but this time through a proxy. 47413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request_proxy; 47423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request_proxy.method = "GET"; 47433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request_proxy.url = GURL("http://www.google.com/foo.dat"); 47443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request_proxy.load_flags = 0; 4745731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<SpdySessionDependencies> ssd_proxy(new SpdySessionDependencies()); 47463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Ensure that this transaction uses the same SpdySessionPool. 4747513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpNetworkSession> session_proxy( 4748513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SpdySessionDependencies::SpdyCreateSession(ssd_proxy.get())); 47493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper_proxy(request_proxy, 47503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 4751731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick HttpNetworkSessionPeer session_peer(session_proxy); 4752731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_peer.SetProxyService( 4753731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 47543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_proxy.session_deps().swap(ssd_proxy); 47553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_proxy.SetSession(session_proxy); 47563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_proxy.RunPreTestSetup(); 47573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_proxy.AddData(data_proxy.get()); 47583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans_proxy = helper_proxy.trans(); 47603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback_proxy; 47613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans_proxy->Start(&request_proxy, &callback_proxy, BoundNetLog()); 47623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 47633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback_proxy.WaitForResult(); 47643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, rv); 47653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response_proxy = *trans_proxy->GetResponseInfo(); 47673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response_proxy.headers != NULL); 47683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response_proxy.headers->GetStatusLine()); 47693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string response_data; 47713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, ReadTransaction(trans_proxy, &response_data)); 47723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", response_data); 47733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 47753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_proxy.VerifyDataConsumed(); 47763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 47773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// When we get a TCP-level RST, we need to retry a HttpNetworkTransaction 47793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// on a new connection, if the connection was previously known to be good. 47803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// This can happen when a server reboots without saying goodbye, or when 47813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// we're behind a NAT that masked the RST. 47823345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) { 47833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 47843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 47853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 47863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 47873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 47883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING), 47893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_CONNECTION_RESET), 47903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 47913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads2[] = { 47933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 47943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 47953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 47963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 47973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This test has a couple of variants. 47993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick enum { 48003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Induce the RST while waiting for our transaction to send. 48013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick VARIANT_RST_DURING_SEND_COMPLETION, 48023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Induce the RST while waiting for our transaction to read. 48033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // In this case, the send completed - everything copied into the SNDBUF. 48043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick VARIANT_RST_DURING_READ_COMPLETION 48053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 48063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int variant = VARIANT_RST_DURING_SEND_COMPLETION; 48083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick variant <= VARIANT_RST_DURING_READ_COMPLETION; 48093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ++variant) { 48103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data1( 48113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads, arraysize(reads), 48123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, 0)); 48133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data2( 48153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads2, arraysize(reads2), 48163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, 0)); 48173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 48193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 48203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data1.get()); 48213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data2.get()); 48223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 48233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < 2; ++i) { 48253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans( 48263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 48273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 48293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 48303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 48313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // On the second transaction, we trigger the RST. 48323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (i == 1) { 48333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (variant == VARIANT_RST_DURING_READ_COMPLETION) { 48343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Writes to the socket complete asynchronously on SPDY by running 48353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // through the message loop. Complete the write here. 48363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 48373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 48383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Now schedule the ERR_CONNECTION_RESET. 48403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(3u, data1->read_index()); 48413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data1->CompleteRead(); 48423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(4u, data1->read_index()); 48433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 48443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 48453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 48463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 48483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response != NULL); 48493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->headers != NULL); 48503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->was_fetched_via_spdy); 48513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string response_data; 48523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = ReadTransaction(trans.get(), &response_data); 48533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 48543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 48553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", response_data); 48563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 48573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 48593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 48603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4861731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4862731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Test that turning SPDY on and off works properly. 4863731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) { 4864731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick net::HttpStreamFactory::set_spdy_enabled(true); 4865731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4866731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 4867731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4868731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 4869731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 4870731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead spdy_reads[] = { 4871731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*resp), 4872731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*body), 4873731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead(true, 0, 0) // EOF 4874731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick }; 4875731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4876731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_refptr<DelayedSocketData> data( 4877513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new DelayedSocketData(1, 4878513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch spdy_reads, arraysize(spdy_reads), 4879731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_writes, arraysize(spdy_writes))); 4880731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 4881731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BoundNetLog(), GetParam()); 4882731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick helper.RunToCompletion(data.get()); 4883731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransactionHelperResult out = helper.output(); 4884731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(OK, out.rv); 4885731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 4886731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ("hello!", out.response_data); 4887731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4888731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick net::HttpStreamFactory::set_spdy_enabled(false); 4889731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead http_reads[] = { 4890731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead("HTTP/1.1 200 OK\r\n\r\n"), 4891731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead("hello from http"), 4892731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead(false, OK), 4893731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick }; 4894731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_refptr<DelayedSocketData> data2( 4895731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new DelayedSocketData(1, http_reads, arraysize(http_reads), 4896731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NULL, 0)); 4897731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NormalSpdyTransactionHelper helper2(CreateGetRequest(), 4898731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BoundNetLog(), GetParam()); 4899731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick helper2.SetSpdyDisabled(); 4900731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick helper2.RunToCompletion(data2.get()); 4901731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransactionHelperResult out2 = helper2.output(); 4902731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(OK, out2.rv); 4903731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out2.status_line); 4904731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ("hello from http", out2.response_data); 4905731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4906731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick net::HttpStreamFactory::set_spdy_enabled(true); 4907731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 4908513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4909513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Tests that Basic authentication works over SPDY 4910513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) { 4911513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::HttpStreamFactory::set_spdy_enabled(true); 4912513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4913513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // The first request will be a bare GET, the second request will be a 4914513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // GET with an Authorization header. 4915513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<spdy::SpdyFrame> req_get( 4916513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4917513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const char* const kExtraAuthorizationHeaders[] = { 4918513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "authorization", 4919513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Basic Zm9vOmJhcg==", 4920513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 4921513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<spdy::SpdyFrame> req_get_authorization( 4922513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ConstructSpdyGet( 4923201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kExtraAuthorizationHeaders, 4924201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kExtraAuthorizationHeaders) / 2, 4925513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch false, 3, LOWEST)); 4926513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockWrite spdy_writes[] = { 4927513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateMockWrite(*req_get, 1), 4928513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateMockWrite(*req_get_authorization, 4), 4929513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 4930513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4931513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // The first response is a 401 authentication challenge, and the second 4932513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // response will be a 200 response since the second request includes a valid 4933513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Authorization header. 4934513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const char* const kExtraAuthenticationHeaders[] = { 4935513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "WWW-Authenticate", 4936513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Basic realm=\"MyRealm\"" 4937513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 4938513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<spdy::SpdyFrame> resp_authentication( 4939513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ConstructSpdySynReplyError( 4940513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "401 Authentication Required", 4941201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kExtraAuthenticationHeaders, 4942201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kExtraAuthenticationHeaders) / 2, 4943513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1)); 4944513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<spdy::SpdyFrame> body_authentication( 4945513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ConstructSpdyBodyFrame(1, true)); 4946513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<spdy::SpdyFrame> resp_data(ConstructSpdyGetSynReply(NULL, 0, 3)); 4947513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<spdy::SpdyFrame> body_data(ConstructSpdyBodyFrame(3, true)); 4948513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead spdy_reads[] = { 4949513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateMockRead(*resp_authentication, 2), 4950513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateMockRead(*body_authentication, 3), 4951513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateMockRead(*resp_data, 5), 4952513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateMockRead(*body_data, 6), 4953513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead(true, 0, 7), 4954513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 4955513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4956513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<OrderedSocketData> data( 4957513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new OrderedSocketData(spdy_reads, arraysize(spdy_reads), 4958513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch spdy_writes, arraysize(spdy_writes))); 4959513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch HttpRequestInfo request(CreateGetRequest()); 4960513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch BoundNetLog net_log; 4961513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NormalSpdyTransactionHelper helper(request, net_log, GetParam()); 4962513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4963513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch helper.RunPreTestSetup(); 4964513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch helper.AddData(data.get()); 4965513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch HttpNetworkTransaction* trans = helper.trans(); 4966513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch TestCompletionCallback callback_start; 4967513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const int rv_start = trans->Start(&request, &callback_start, net_log); 4968513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv_start); 4969513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const int rv_start_complete = callback_start.WaitForResult(); 4970513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(OK, rv_start_complete); 4971513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4972513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Make sure the response has an auth challenge. 4973513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const HttpResponseInfo* const response_start = trans->GetResponseInfo(); 4974513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ASSERT_TRUE(response_start != NULL); 4975513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ASSERT_TRUE(response_start->headers != NULL); 4976513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(401, response_start->headers->response_code()); 4977513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_TRUE(response_start->was_fetched_via_spdy); 4978513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ASSERT_TRUE(response_start->auth_challenge.get() != NULL); 4979513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_FALSE(response_start->auth_challenge->is_proxy); 4980513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(L"basic", response_start->auth_challenge->scheme); 4981513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(L"MyRealm", response_start->auth_challenge->realm); 4982513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4983513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Restart with a username/password. 4984513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const string16 kFoo(ASCIIToUTF16("foo")); 4985513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const string16 kBar(ASCIIToUTF16("bar")); 4986513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch TestCompletionCallback callback_restart; 4987513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const int rv_restart = trans->RestartWithAuth(kFoo, kBar, &callback_restart); 4988513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv_restart); 4989513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const int rv_restart_complete = callback_restart.WaitForResult(); 4990513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(OK, rv_restart_complete); 4991513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // TODO(cbentzel): This is actually the same response object as before, but 4992513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // data has changed. 4993513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const HttpResponseInfo* const response_restart = trans->GetResponseInfo(); 4994513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ASSERT_TRUE(response_restart != NULL); 4995513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ASSERT_TRUE(response_restart->headers != NULL); 4996513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(200, response_restart->headers->response_code()); 4997513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_TRUE(response_restart->auth_challenge.get() == NULL); 4998513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 4999513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 5000201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) { 5001201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const unsigned char kPushBodyFrame[] = { 5002201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x00, 0x00, 0x00, 0x02, // header, ID 5003201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x01, 0x00, 0x00, 0x06, // FIN, length 5004201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 5005201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5006201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5007201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 5008201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5009201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_body(ConstructSpdyBodyFrame(1, true)); 5010201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { 5011201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockWrite(*stream1_syn, 1), 5012201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5013201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5014201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kInitialHeaders[] = { 5015201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "url", 5016201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat", 5017201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5018201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kLateHeaders[] = { 5019201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "hello", 5020201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "bye", 5021201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5022201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200", 5023201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 5024201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 5025201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5026201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5027201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyControlFrame(kInitialHeaders, 5028201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kInitialHeaders) / 2, 5029201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5030201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5031201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5032201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_STREAM, 5033201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5034201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5035201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5036201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1)); 5037201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5038201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_headers(ConstructSpdyControlFrame(kLateHeaders, 5039201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kLateHeaders) / 2, 5040201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5041201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5042201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5043201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5044201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5045201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5046201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5047201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5048201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5049201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5050201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 5051201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5052201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply, 2), 5053201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_syn, 3), 5054201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_headers, 4), 5055201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body, 5, false), 5056201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 5057201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kPushBodyFrame), 6), 5058201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, ERR_IO_PENDING, 7), // Force a pause 5059201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5060201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5061201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response; 5062201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response2; 5063201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string expected_push_result("pushed"); 5064201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 5065201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 5066201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 5067201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 5068201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 5069201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RunServerPushTest(data.get(), 5070201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response, 5071201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response2, 5072201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch expected_push_result); 5073201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5074201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5075201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response.headers != NULL); 5076201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 5077201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5078201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the pushed stream. 5079201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers != NULL); 5080201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 5081201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5082201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5083201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) { 5084201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // We push a stream and attempt to claim it before the headers come down. 5085201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const unsigned char kPushBodyFrame[] = { 5086201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x00, 0x00, 0x00, 0x02, // header, ID 5087201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x01, 0x00, 0x00, 0x06, // FIN, length 5088201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 5089201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5090201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5091201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 5092201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5093201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_body(ConstructSpdyBodyFrame(1, true)); 5094201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { 5095201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockWrite(*stream1_syn, 0, false), 5096201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5097201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5098201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kInitialHeaders[] = { 5099201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "url", 5100201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat", 5101201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5102201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kLateHeaders[] = { 5103201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "hello", 5104201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "bye", 5105201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200", 5107201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 5108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 5109201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5110201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyControlFrame(kInitialHeaders, 5112201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kInitialHeaders) / 2, 5113201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5114201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5115201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5116201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_STREAM, 5117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5119201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1)); 5121201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5122201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_headers(ConstructSpdyControlFrame(kLateHeaders, 5123201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kLateHeaders) / 2, 5124201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5125201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5126201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5127201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5128201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5129201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5130201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5131201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5134201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 5135201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5136201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply, 1), 5137201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_syn, 2), 5138201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body, 3), 5139201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_headers, 4), 5140201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 5141201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kPushBodyFrame), 5), 5142201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, 0, 5), // EOF 5143201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5144201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5145201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response; 5146201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response2; 5147201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string expected_push_result("pushed"); 5148201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<DeterministicSocketData> data(new DeterministicSocketData( 5149201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 5150201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 5151201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 5152201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 5153201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5154201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 5155201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BoundNetLog(), GetParam()); 5156201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.SetDeterministic(); 5157201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.AddDeterministicData(static_cast<DeterministicSocketData*>(data)); 5158201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.RunPreTestSetup(); 5159201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5160201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpNetworkTransaction* trans = helper.trans(); 5161201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5162201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM, 5163201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // and the body of the primary stream, but before we've received the HEADERS 5164201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // for the pushed stream. 5165201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->SetStop(3); 5166201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5167201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Start the transaction. 5168201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TestCompletionCallback callback; 5169201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 5170201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5171201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->Run(); 5172201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rv = callback.WaitForResult(); 5173201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(0, rv); 5174201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5175201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Request the pushed path. At this point, we've received the push, but the 5176201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // headers are not yet complete. 5177201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<HttpNetworkTransaction> trans2( 5178201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new HttpNetworkTransaction(helper.session())); 5179201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rv = trans2->Start(&CreateGetPushRequest(), &callback, BoundNetLog()); 5180201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5181201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->RunFor(3); 5182201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MessageLoop::current()->RunAllPending(); 5183201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5184201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Read the server push body. 5185201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string result2; 5186201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ReadResult(trans2.get(), data.get(), &result2); 5187201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Read the response body. 5188201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string result; 5189201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ReadResult(trans, data, &result); 5190201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5191201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify that we consumed all test data. 5192201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(data->at_read_eof()); 5193201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(data->at_write_eof()); 5194201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5195201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify that the received push data is same as the expected push data. 5196201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(result2.compare(expected_push_result), 0) 5197201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << "Received data: " 5198201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << result2 5199201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << "||||| Expected data: " 5200201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << expected_push_result; 5201201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5202201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5203201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Copy the response info, because trans goes away. 5204201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch response = *trans->GetResponseInfo(); 5205201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch response2 = *trans2->GetResponseInfo(); 5206201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5207201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch VerifyStreamsClosed(helper); 5208201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5209201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5210201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response.headers != NULL); 5211201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 5212201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5213201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the pushed stream. 5214201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers != NULL); 5215201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 5216201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5217201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5218201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) { 5219201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // We push a stream and attempt to claim it before the headers come down. 5220201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const unsigned char kPushBodyFrame[] = { 5221201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x00, 0x00, 0x00, 0x02, // header, ID 5222201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x01, 0x00, 0x00, 0x06, // FIN, length 5223201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 5224201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5225201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5226201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 5227201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5228201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_body(ConstructSpdyBodyFrame(1, true)); 5229201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { 5230201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockWrite(*stream1_syn, 0, false), 5231201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5232201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5233201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kInitialHeaders[] = { 5234201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "url", 5235201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat", 5236201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5237201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kMiddleHeaders[] = { 5238201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "hello", 5239201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "bye", 5240201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5241201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kLateHeaders[] = { 5242201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5243201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200", 5244201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 5245201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 5246201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5247201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5248201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyControlFrame(kInitialHeaders, 5249201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kInitialHeaders) / 2, 5250201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5251201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5252201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5253201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_STREAM, 5254201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5255201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5256201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5257201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1)); 5258201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5259201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_headers1(ConstructSpdyControlFrame(kMiddleHeaders, 5260201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kMiddleHeaders) / 2, 5261201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5262201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5263201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5264201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5265201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5266201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5267201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5268201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5269201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5270201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_headers2(ConstructSpdyControlFrame(kLateHeaders, 5271201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kLateHeaders) / 2, 5272201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5273201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5274201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5275201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5276201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5277201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5278201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5279201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5280201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5281201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5282201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 5283201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5284201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply, 1), 5285201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_syn, 2), 5286201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body, 3), 5287201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_headers1, 4), 5288201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_headers2, 5), 5289201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 5290201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kPushBodyFrame), 6), 5291201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, 0, 6), // EOF 5292201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5293201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5294201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response; 5295201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response2; 5296201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string expected_push_result("pushed"); 5297201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<DeterministicSocketData> data(new DeterministicSocketData( 5298201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 5299201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 5300201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 5301201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 5302201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5303201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 5304201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BoundNetLog(), GetParam()); 5305201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.SetDeterministic(); 5306201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.AddDeterministicData(static_cast<DeterministicSocketData*>(data)); 5307201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.RunPreTestSetup(); 5308201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5309201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpNetworkTransaction* trans = helper.trans(); 5310201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5311201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM, 5312201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // the first HEADERS frame, and the body of the primary stream, but before 5313201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // we've received the final HEADERS for the pushed stream. 5314201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->SetStop(4); 5315201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5316201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Start the transaction. 5317201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TestCompletionCallback callback; 5318201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 5319201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5320201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->Run(); 5321201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rv = callback.WaitForResult(); 5322201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(0, rv); 5323201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5324201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Request the pushed path. At this point, we've received the push, but the 5325201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // headers are not yet complete. 5326201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<HttpNetworkTransaction> trans2( 5327201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new HttpNetworkTransaction(helper.session())); 5328201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rv = trans2->Start(&CreateGetPushRequest(), &callback, BoundNetLog()); 5329201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5330201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->RunFor(3); 5331201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MessageLoop::current()->RunAllPending(); 5332201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5333201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Read the server push body. 5334201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string result2; 5335201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ReadResult(trans2.get(), data, &result2); 5336201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Read the response body. 5337201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string result; 5338201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ReadResult(trans, data, &result); 5339201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5340201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify that we consumed all test data. 5341201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(data->at_read_eof()); 5342201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(data->at_write_eof()); 5343201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5344201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify that the received push data is same as the expected push data. 5345201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(result2.compare(expected_push_result), 0) 5346201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << "Received data: " 5347201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << result2 5348201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << "||||| Expected data: " 5349201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << expected_push_result; 5350201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5351201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5352201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Copy the response info, because trans goes away. 5353201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch response = *trans->GetResponseInfo(); 5354201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch response2 = *trans2->GetResponseInfo(); 5355201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5356201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch VerifyStreamsClosed(helper); 5357201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5358201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5359201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response.headers != NULL); 5360201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 5361201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5362201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the pushed stream. 5363201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers != NULL); 5364201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 5365201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5366201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify we got all the headers 5367201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue( 5368201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "url", 5369201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 5370201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue("hello", "bye")); 5371201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue("status", "200")); 5372201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue("version", "HTTP/1.1")); 5373201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5374201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5375201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, SynReplyWithHeaders) { 5376201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 5377201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 5378201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5379201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kInitialHeaders[] = { 5380201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5381201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200 OK", 5382201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 5383201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 5384201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5385201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kLateHeaders[] = { 5386201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "hello", 5387201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "bye", 5388201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5389201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5390201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyControlFrame(kInitialHeaders, 5391201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kInitialHeaders) / 2, 5392201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5393201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5394201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5395201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_REPLY, 5396201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5397201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5398201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5399201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5400201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5401201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_headers(ConstructSpdyControlFrame(kLateHeaders, 5402201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kLateHeaders) / 2, 5403201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5404201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5405201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5406201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5407201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5408201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5409201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5410201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5411201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, true)); 5412201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5413201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply), 5414201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_headers), 5415201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body), 5416201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, 0, 0) // EOF 5417201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5418201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5419201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<DelayedSocketData> data( 5420201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new DelayedSocketData(1, reads, arraysize(reads), 5421201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, arraysize(writes))); 5422201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 5423201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BoundNetLog(), GetParam()); 5424201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.RunToCompletion(data.get()); 5425201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TransactionHelperResult out = helper.output(); 5426201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(OK, out.rv); 5427201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 5428201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("hello!", out.response_data); 5429201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5430201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5431201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, SynReplyWithLateHeaders) { 5432201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 5433201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 5434201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5435201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kInitialHeaders[] = { 5436201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5437201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200 OK", 5438201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 5439201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 5440201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5441201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kLateHeaders[] = { 5442201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "hello", 5443201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "bye", 5444201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5445201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5446201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyControlFrame(kInitialHeaders, 5447201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kInitialHeaders) / 2, 5448201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5449201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5450201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5451201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_REPLY, 5452201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5453201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5454201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5455201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5456201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5457201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_headers(ConstructSpdyControlFrame(kLateHeaders, 5458201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kLateHeaders) / 2, 5459201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5460201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5461201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5462201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5463201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5464201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5465201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5466201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5467201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, false)); 5468201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> stream1_body2(ConstructSpdyBodyFrame(1, true)); 5469201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5470201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply), 5471201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body), 5472201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_headers), 5473201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body2), 5474201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, 0, 0) // EOF 5475201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5476201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5477201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<DelayedSocketData> data( 5478201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new DelayedSocketData(1, reads, arraysize(reads), 5479201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, arraysize(writes))); 5480201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 5481201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BoundNetLog(), GetParam()); 5482201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.RunToCompletion(data.get()); 5483201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TransactionHelperResult out = helper.output(); 5484201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(OK, out.rv); 5485201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 5486201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("hello!hello!", out.response_data); 5487201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5488201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5489201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, SynReplyWithDuplicateLateHeaders) { 5490201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 5491201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 5492201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5493201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kInitialHeaders[] = { 5494201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5495201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200 OK", 5496201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 5497201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 5498201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5499201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kLateHeaders[] = { 5500201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5501201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "500 Server Error", 5502201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5503201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5504201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyControlFrame(kInitialHeaders, 5505201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kInitialHeaders) / 2, 5506201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5507201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5508201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5509201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_REPLY, 5510201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5511201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5512201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5513201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5514201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5515201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_headers(ConstructSpdyControlFrame(kLateHeaders, 5516201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kLateHeaders) / 2, 5517201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5518201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5519201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5520201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5521201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5522201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5523201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5524201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5525201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, false)); 5526201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> stream1_body2(ConstructSpdyBodyFrame(1, true)); 5527201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5528201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply), 5529201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body), 5530201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_headers), 5531201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body2), 5532201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, 0, 0) // EOF 5533201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5534201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5535201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<DelayedSocketData> data( 5536201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new DelayedSocketData(1, reads, arraysize(reads), 5537201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, arraysize(writes))); 5538201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 5539201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BoundNetLog(), GetParam()); 5540201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.RunToCompletion(data.get()); 5541201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TransactionHelperResult out = helper.output(); 5542201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 5543201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5544201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5545201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) { 5546201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // In this test we want to verify that we can't accidentally push content 5547201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // which can't be pushed by this content server. 5548201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // This test assumes that: 5549201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // - if we're requesting http://www.foo.com/barbaz 5550201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // - the browser has made a connection to "www.foo.com". 5551201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5552201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // A list of the URL to fetch, followed by the URL being pushed. 5553201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kTestCases[] = { 5554201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.html", 5555201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com:81/foo.js", // Bad port 5556201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5557201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.html", 5558201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "https://www.google.com/foo.js", // Bad protocol 5559201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5560201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.html", 5561201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "ftp://www.google.com/foo.js", // Invalid Protocol 5562201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5563201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.html", 5564201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://blat.www.google.com/foo.js", // Cross subdomain 5565201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5566201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.html", 5567201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.foo.com/foo.js", // Cross domain 5568201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5569201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5570201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5571201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const unsigned char kPushBodyFrame[] = { 5572201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x00, 0x00, 0x00, 0x02, // header, ID 5573201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x01, 0x00, 0x00, 0x06, // FIN, length 5574201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 5575201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5576201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5577201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (size_t index = 0; index < arraysize(kTestCases); index += 2) { 5578201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* url_to_fetch = kTestCases[index]; 5579201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* url_to_push = kTestCases[index + 1]; 5580201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5581201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5582201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_syn(ConstructSpdyGet(url_to_fetch, false, 1, LOWEST)); 5583201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5584201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_body(ConstructSpdyBodyFrame(1, true)); 5585201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> push_rst( 5586201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ConstructSpdyRstStream(2, spdy::REFUSED_STREAM)); 5587201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { 5588201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockWrite(*stream1_syn, 1), 5589201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockWrite(*push_rst, 4), 5590201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5591201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5592201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5593201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 5594201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5595201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 5596201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5597201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5598201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5599201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch url_to_push)); 5600201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> rst( 5601201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ConstructSpdyRstStream(2, spdy::CANCEL)); 5602201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5603201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5604201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply, 2), 5605201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_syn, 3), 5606201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body, 5, false), 5607201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 5608201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kPushBodyFrame), 6), 5609201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, ERR_IO_PENDING, 7), // Force a pause 5610201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5611201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5612201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response; 5613201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 5614201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 5615201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 5616201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 5617201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 5618201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5619201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpRequestInfo request; 5620201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch request.method = "GET"; 5621201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch request.url = GURL(url_to_fetch); 5622201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch request.load_flags = 0; 5623201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalSpdyTransactionHelper helper(request, 5624201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BoundNetLog(), GetParam()); 5625201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.RunPreTestSetup(); 5626201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.AddData(data); 5627201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5628201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpNetworkTransaction* trans = helper.trans(); 5629201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5630201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Start the transaction with basic parameters. 5631201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TestCompletionCallback callback; 5632201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5633201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5634201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5635201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rv = callback.WaitForResult(); 5636201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5637201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Read the response body. 5638201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string result; 5639201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ReadResult(trans, data, &result); 5640201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5641201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify that we consumed all test data. 5642201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(data->at_read_eof()); 5643201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(data->at_write_eof()); 5644201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5645201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5646201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Copy the response info, because trans goes away. 5647201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch response = *trans->GetResponseInfo(); 5648201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5649201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch VerifyStreamsClosed(helper); 5650201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5651201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5652201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response.headers != NULL); 5653201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 5654201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 5655201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5656201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace net 5658