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" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/socket/client_socket_pool_base.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_http_stream.h" 1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/spdy/spdy_http_utils.h" 173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/spdy/spdy_session.h" 183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/spdy/spdy_session_pool.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_test_util.h" 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/url_request/url_request_test_util.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/platform_test.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//----------------------------------------------------------------------------- 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net { 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// This is the expected list of advertised protocols from the browser's NPN 283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// list. 293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char kExpectedNPNString[] = "\x08http/1.1\x06spdy/2"; 303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickenum SpdyNetworkTransactionTestTypes { 323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SPDYNPN, 333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SPDYNOSSL, 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SPDYSSL, 353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass SpdyNetworkTransactionTest 373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : public ::testing::TestWithParam<SpdyNetworkTransactionTestTypes> { 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void SetUp() { 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // By default, all tests turn off compression. 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EnableCompression(false); 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch google_get_request_initialized_ = false; 443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_post_request_initialized_ = false; 45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_initialized_ = false; 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void TearDown() { 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Empty the current queue. 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct TransactionHelperResult { 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv; 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string status_line; 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpResponseInfo response_info; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void EnableCompression(bool enabled) { 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer::set_enable_compression_default(enabled); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class StartTransactionCallback; 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class DeleteSessionCallback; 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // A helper class that handles all the initial npn/ssl setup. 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class NormalSpdyTransactionHelper { 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper(const HttpRequestInfo& request, 713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const BoundNetLog& log, 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyNetworkTransactionTestTypes test_type) 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : request_(request), 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_(new SpdySessionDependencies()), 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_(SpdySessionDependencies::SpdyCreateSession( 763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_.get())), 773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick log_(log), 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick test_type_(test_type), 79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick deterministic_(false), 80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_enabled_(true) { 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch (test_type_) { 823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNOSSL: 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYSSL: 843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick port_ = 80; 853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNPN: 873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick port_ = 443; 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ~NormalSpdyTransactionHelper() { 953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Any test which doesn't close the socket by sending it an EOF will 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // have a valid session left open, which leaks the entire session pool. 973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This is just fine - in fact, some of our tests intentionally do this 983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // so that we can check consistency of the SpdySessionPool as the test 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // finishes. If we had put an EOF on the socket, the SpdySession would 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // have closed and we wouldn't be able to check the consistency. 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Forcefully close existing sessions here. 1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session()->spdy_session_pool()->CloseAllSessions(); 1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void SetDeterministic() { 1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic( 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_.get()); 1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick deterministic_ = true; 1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void SetSpdyDisabled() { 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_enabled_ = false; 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void RunPreTestSetup() { 1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!session_deps_.get()) 1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_.reset(new SpdySessionDependencies()); 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!session_.get()) 1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_ = SpdySessionDependencies::SpdyCreateSession( 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_.get()); 1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(false); 1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_over_ssl(false); 1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_always(false); 1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch (test_type_) { 1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNPN: 1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_->mutable_alternate_protocols()->SetAlternateProtocolFor( 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair("www.google.com", 80), 443, 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAlternateProtocols::NPN_SPDY_2); 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_use_alternate_protocols(true); 1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_next_protos(kExpectedNPNString); 1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNOSSL: 1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_over_ssl(false); 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_always(true); 1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYSSL: 1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_over_ssl(true); 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_always(true); 1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We're now ready to use SSL-npn SPDY. 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch trans_.reset(new HttpNetworkTransaction(session_)); 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Start the transaction, read some data, finish. 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RunDefaultTest() { 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_.rv = trans_->Start(&request_, &callback, log_); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We expect an IO Pending or some sort of error. 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_LT(output_.rv, 0); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (output_.rv != ERR_IO_PENDING) 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_.rv = callback.WaitForResult(); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (output_.rv != OK) { 1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_->spdy_session_pool()->CloseCurrentSessions(); 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify responses. 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans_->GetResponseInfo(); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response != NULL); 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(response->headers != NULL); 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(spdy_enabled_, response->was_fetched_via_spdy); 170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (test_type_ == SPDYNPN && spdy_enabled_) { 1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->was_npn_negotiated); 1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(!response->was_npn_negotiated); 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_); 240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (test_type_ == SPDYNPN || test_type_ == SPDYSSL) 2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_->socket_factory->AddSSLSocketDataProvider(ssl_.get()); 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_->socket_factory->AddSocketDataProvider(data); 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (test_type_ == SPDYNPN) { 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockConnect never_finishing_connect(false, ERR_IO_PENDING); 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen linked_ptr<StaticSocketDataProvider> 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hanging_non_alternate_protocol_socket( 247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new StaticSocketDataProvider(NULL, 0, NULL, 0)); 248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hanging_non_alternate_protocol_socket->set_connect_data( 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen never_finishing_connect); 250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps_->socket_factory->AddSocketDataProvider( 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hanging_non_alternate_protocol_socket.get()); 252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen alternate_vector_.push_back(hanging_non_alternate_protocol_socket); 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void AddDeterministicData(DeterministicSocketData* data) { 2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(deterministic_); 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_vector_.push_back(data); 2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick linked_ptr<SSLSocketDataProvider> ssl_( 2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new SSLSocketDataProvider(true, OK)); 2613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (test_type_ == SPDYNPN) { 2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_->next_proto_status = SSLClientSocket::kNextProtoNegotiated; 2633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_->next_proto = "spdy/2"; 2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_->was_npn_negotiated = true; 2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_vector_.push_back(ssl_); 267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (test_type_ == SPDYNPN || test_type_ == SPDYSSL) { 2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_->deterministic_socket_factory-> 2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddSSLSocketDataProvider(ssl_.get()); 270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_->deterministic_socket_factory->AddSocketDataProvider(data); 272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (test_type_ == SPDYNPN) { 273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockConnect never_finishing_connect(false, ERR_IO_PENDING); 274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<DeterministicSocketData> 275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hanging_non_alternate_protocol_socket( 276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new DeterministicSocketData(NULL, 0, NULL, 0)); 277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hanging_non_alternate_protocol_socket->set_connect_data( 278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen never_finishing_connect); 279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen session_deps_->deterministic_socket_factory->AddSocketDataProvider( 280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hanging_non_alternate_protocol_socket); 281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen alternate_deterministic_vector_.push_back( 282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hanging_non_alternate_protocol_socket); 283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This can only be called after RunPreTestSetup. It adds a Data Provider, 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // but not a corresponding SSL data provider 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void AddDataNoSSL(StaticSocketDataProvider* data) { 2893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!deterministic_); 2903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_->socket_factory->AddSocketDataProvider(data); 2913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void AddDataNoSSL(DeterministicSocketData* data) { 2933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(deterministic_); 2943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick session_deps_->deterministic_socket_factory->AddSocketDataProvider(data); 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void SetSession(const scoped_refptr<HttpNetworkSession>& session) { 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch session_ = session; 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans() { return trans_.get(); } 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ResetTrans() { trans_.reset(); } 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult& output() { return output_; } 3033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpRequestInfo& request() const { return request_; } 3043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const scoped_refptr<HttpNetworkSession>& session() const { 3053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return session_; 3063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<SpdySessionDependencies>& session_deps() { 3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return session_deps_; 3093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int port() const { return port_; } 3113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyNetworkTransactionTestTypes test_type() const { return test_type_; } 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::vector<StaticSocketDataProvider*> DataVector; 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::vector<linked_ptr<SSLSocketDataProvider> > SSLVector; 316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen typedef std::vector<linked_ptr<StaticSocketDataProvider> > AlternateVector; 317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen typedef std::vector<scoped_refptr<DeterministicSocketData> > 318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AlternateDeterministicVector; 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request_; 3203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<SpdySessionDependencies> session_deps_; 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpNetworkSession> session_; 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult output_; 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<StaticSocketDataProvider> first_transaction_; 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLVector ssl_vector_; 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpNetworkTransaction> trans_; 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpNetworkTransaction> trans_http_; 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DataVector data_vector_; 329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AlternateVector alternate_vector_; 330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AlternateDeterministicVector alternate_deterministic_vector_; 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& log_; 3323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyNetworkTransactionTestTypes test_type_; 3333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int port_; 3343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool deterministic_; 335731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool spdy_enabled_; 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ConnectStatusHelperWithExpectedStatus(const MockRead& status, 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int expected_status); 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ConnectStatusHelper(const MockRead& status); 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpRequestInfo& CreateGetPushRequest() { 3443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_get_push_request_.method = "GET"; 3453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_get_push_request_.url = GURL("http://www.google.com/foo.dat"); 3463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_get_push_request_.load_flags = 0; 3473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return google_get_push_request_; 3483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpRequestInfo& CreateGetRequest() { 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!google_get_request_initialized_) { 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch google_get_request_.method = "GET"; 3533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_get_request_.url = GURL(kDefaultURL); 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch google_get_request_.load_flags = 0; 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch google_get_request_initialized_ = true; 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return google_get_request_; 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const HttpRequestInfo& CreateGetRequestWithUserAgent() { 3614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!google_get_request_initialized_) { 3624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch google_get_request_.method = "GET"; 3634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch google_get_request_.url = GURL(kDefaultURL); 3644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch google_get_request_.load_flags = 0; 3654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch google_get_request_.extra_headers.SetHeader("User-Agent", "Chrome"); 3664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch google_get_request_initialized_ = true; 3674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 3684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return google_get_request_; 3694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 3704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 3713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpRequestInfo& CreatePostRequest() { 3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!google_post_request_initialized_) { 3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_post_request_.method = "POST"; 3743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_post_request_.url = GURL(kDefaultURL); 3753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_post_request_.upload_data = new UploadData(); 3763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_post_request_.upload_data->AppendBytes(kUploadData, 3773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kUploadDataSize); 3783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick google_post_request_initialized_ = true; 3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return google_post_request_; 3813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 383dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HttpRequestInfo& CreateChunkedPostRequest() { 384dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!google_chunked_post_request_initialized_) { 385dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_.method = "POST"; 386dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_.url = GURL(kDefaultURL); 387dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_.upload_data = new UploadData(); 388dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_.upload_data->set_is_chunked(true); 389dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_.upload_data->AppendChunk( 390dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kUploadData, kUploadDataSize, false); 391dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_.upload_data->AppendChunk( 392dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kUploadData, kUploadDataSize, true); 393dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen google_chunked_post_request_initialized_ = true; 394dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 395dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return google_chunked_post_request_; 396dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 397dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Read the result of a particular transaction, knowing that we've got 3993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // multiple transactions in the read pipeline; so as we read, we may have 4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // to skip over data destined for other transactions while we consume 4013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // the data for |trans|. 4023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int ReadResult(HttpNetworkTransaction* trans, 403201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch StaticSocketDataProvider* data, 4043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string* result) { 4053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const int kSize = 3000; 4063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int bytes_read = 0; 408513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(kSize)); 4093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 4103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick while (true) { 4113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Read(buf, kSize, &callback); 4123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (rv == ERR_IO_PENDING) { 4133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Multiple transactions may be in the data set. Keep pulling off 4143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // reads until we complete our callback. 4153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick while (!callback.have_result()) { 4163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 4183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 4203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (rv <= 0) { 4213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 4223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 4233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick result->append(buf->data(), rv); 4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bytes_read += rv; 4253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 4263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return bytes_read; 4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 4283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void VerifyStreamsClosed(const NormalSpdyTransactionHelper& helper) { 4303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This lengthy block is reaching into the pool to dig out the active 4313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // session. Once we have the session, we verify that the streams are 4323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // all closed and not leaked at this point. 4333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const GURL& url = helper.request().url; 4343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int port = helper.test_type() == SPDYNPN ? 443 : 80; 4353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair host_port_pair(url.host(), port); 4363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortProxyPair pair(host_port_pair, ProxyServer::Direct()); 4373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog log; 4383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const scoped_refptr<HttpNetworkSession>& session = helper.session(); 439731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SpdySessionPool* pool(session->spdy_session_pool()); 4403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(pool->HasSession(pair)); 441dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<SpdySession> spdy_session(pool->Get(pair, log)); 4423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(spdy_session.get() != NULL); 4433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0u, spdy_session->num_active_streams()); 4443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams()); 4453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 4463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 447201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void RunServerPushTest(OrderedSocketData* data, 4483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo* response, 449201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo* push_response, 4503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string& expected) { 4513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 4523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 4533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 454201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.AddData(data); 4553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 4573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Start the transaction with basic parameters. 4593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 4613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 4623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Request the pushed path. 4653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans2( 4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans2->Start(&CreateGetPushRequest(), &callback, BoundNetLog()); 4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 4703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The data for the pushed path may be coming in more than 1 packet. Compile 4723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // the results into a single string. 4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Read the server push body. 4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string result2; 4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ReadResult(trans2.get(), data, &result2); 4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Read the response body. 4783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string result; 4793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ReadResult(trans, data, &result); 4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we consumed all test data. 4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()); 4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()); 4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that the received push data is same as the expected push data. 4863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(result2.compare(expected), 0) << "Received data: " 4873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << result2 4883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << "||||| Expected data: " 4893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << expected; 4903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 4923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Copy the response info, because trans goes away. 4933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *response = *trans->GetResponseInfo(); 494201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch *push_response = *trans2->GetResponseInfo(); 4953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick VerifyStreamsClosed(helper); 4973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 4983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool google_get_request_initialized_; 5013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool google_post_request_initialized_; 502dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool google_chunked_post_request_initialized_; 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo google_get_request_; 5043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo google_post_request_; 505dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpRequestInfo google_chunked_post_request_; 5063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo google_get_push_request_; 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//----------------------------------------------------------------------------- 5103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// All tests are run with three different connection types: SPDY after NPN 5113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// negotiation, SPDY without SSL, and SPDY with SSL. 5123345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickINSTANTIATE_TEST_CASE_P(Spdy, 5133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyNetworkTransactionTest, 5143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ::testing::Values(SPDYNOSSL, SPDYSSL, SPDYNPN)); 5153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify HttpNetworkTransaction constructor. 5183345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, Constructor) { 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdySessionDependencies session_deps; 520513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpNetworkSession> session( 521513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SpdySessionDependencies::SpdyCreateSession(&session_deps)); 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5253345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, Get) { 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 5423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5503345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) { 5513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (RequestPriority p = HIGHEST; p < NUM_PRIORITIES; 5523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick p = RequestPriority(p+1)) { 5533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Construct the request. 5543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, p)); 5553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { CreateMockWrite(*req) }; 5563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const int spdy_prio = reinterpret_cast<spdy::SpdySynStreamControlFrame*>( 5583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick req.get())->priority(); 5593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // this repeats the RequestPriority-->SpdyPriority mapping from 5603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // SpdyFramer::ConvertRequestPriorityToSpdyPriority to make 5613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // sure it's being done right. 5623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch(p) { 5633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case HIGHEST: 5643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, spdy_prio); 5653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case MEDIUM: 5673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, spdy_prio); 5683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 5693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case LOW: 5703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case LOWEST: 5713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(2, spdy_prio); 5723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 5733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case IDLE: 5743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(3, spdy_prio); 5753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 5763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 5773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FAIL(); 5783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 5793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 5813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 5823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 5833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 5843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 5853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 5863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 5873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data( 5893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads, arraysize(reads), 5903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 5913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo http_req = CreateGetRequest(); 5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick http_req.priority = p; 5933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(http_req, BoundNetLog(), GetParam()); 5953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunToCompletion(data.get()); 5963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TransactionHelperResult out = helper.output(); 5973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 5983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 5993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", out.response_data); 6003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 6013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Start three gets simultaniously; making sure that multiplexed 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// streams work properly. 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This can't use the TransactionHelper method, since it only 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// handles a single transaction, and finishes them as soon 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// as it launches them. 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(gavinp): create a working generalized TransactionHelper that 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// can allow multiple streams in flight. 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6133345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ThreeGets) { 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, LOWEST)); 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5)); 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(5, false)); 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody3(ConstructSpdyBodyFrame(5, true)); 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 629dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockWrite writes[] = { 630dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req), 631dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req2), 632dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req3), 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp, 1), 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp2, 4), 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body2), 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp3, 7), 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body3), 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody), 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody2), 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody3), 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0), // EOF 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> data( 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData(reads, arraysize(reads), 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 6513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_placeholder( 6523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(NULL, 0, NULL, 0)); 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog log; 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out; 6563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 6573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 6583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 6593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 6603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We require placeholder data because three get requests are sent out, so 6613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // there needs to be three sets of SSL connection data. 6623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 6633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 6643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans1( 6653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 6663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans2( 6673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 6683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans3( 6693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 6703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 6723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback2; 6733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback3; 6743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq1 = CreateGetRequest(); 6763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq2 = CreateGetRequest(); 6773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq3 = CreateGetRequest(); 6783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans1->Start(&httpreq1, &callback1, log); 6803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 6813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans2->Start(&httpreq2, &callback2, log); 6823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 6833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans3->Start(&httpreq3, &callback3, log); 6843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 6853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback1.WaitForResult(); 6873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 6883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback3.WaitForResult(); 6893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 6903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 6923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->headers != NULL); 6933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->was_fetched_via_spdy); 6943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response1->headers->GetStatusLine(); 6953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response1; 6963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick trans2->GetResponseInfo(); 6983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans1.get(), &out.response_data); 7003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!hello!", out.response_data); 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 708dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) { 709dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 710dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 711dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 712dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); 713dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 714dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 715dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 716dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); 717dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); 718dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 719dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockWrite writes[] = { 720dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req), 721dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req2), 722dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 723dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockRead reads[] = { 724dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*resp, 1), 725dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*body), 726dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*resp2, 4), 727dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*body2), 728dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*fbody), 729dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*fbody2), 730dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockRead(true, 0, 0), // EOF 731dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 732dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<OrderedSocketData> data( 733dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new OrderedSocketData(reads, arraysize(reads), 734dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen writes, arraysize(writes))); 735dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 736ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockConnect never_finishing_connect(false, ERR_IO_PENDING); 737dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 738dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<OrderedSocketData> data_placeholder( 739dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new OrderedSocketData(NULL, 0, NULL, 0)); 740dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen data_placeholder->set_connect_data(never_finishing_connect); 741dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 742dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BoundNetLog log; 743dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TransactionHelperResult out; 744dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NormalSpdyTransactionHelper helper(CreateGetRequest(), 745dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BoundNetLog(), GetParam()); 746dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.RunPreTestSetup(); 747dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.AddData(data.get()); 748dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // We require placeholder data because two get requests are sent out, so 749dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // there needs to be two sets of SSL connection data. 750dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.AddData(data_placeholder.get()); 751dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<HttpNetworkTransaction> trans1( 752dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new HttpNetworkTransaction(helper.session())); 753dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<HttpNetworkTransaction> trans2( 754dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new HttpNetworkTransaction(helper.session())); 755dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 756dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TestCompletionCallback callback1; 757dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TestCompletionCallback callback2; 758dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 759dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpRequestInfo httpreq1 = CreateGetRequest(); 760dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpRequestInfo httpreq2 = CreateGetRequest(); 761dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 762dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = trans1->Start(&httpreq1, &callback1, log); 763dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(ERR_IO_PENDING, out.rv); 764dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = trans2->Start(&httpreq2, &callback2, log); 765dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(ERR_IO_PENDING, out.rv); 766dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 767dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = callback1.WaitForResult(); 768dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(OK, out.rv); 769dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = callback2.WaitForResult(); 770dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(OK, out.rv); 771dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 772dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 773dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response1->headers != NULL); 774dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response1->was_fetched_via_spdy); 775dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.status_line = response1->headers->GetStatusLine(); 776dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.response_info = *response1; 777dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = ReadTransaction(trans1.get(), &out.response_data); 778dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(OK, out.rv); 779dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 780dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("hello!hello!", out.response_data); 781dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 782dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 783dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response2->headers != NULL); 784dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response2->was_fetched_via_spdy); 785dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.status_line = response2->headers->GetStatusLine(); 786dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.response_info = *response2; 787dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = ReadTransaction(trans2.get(), &out.response_data); 788dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(OK, out.rv); 789dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 790dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("hello!hello!", out.response_data); 791dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 792dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.VerifyDataConsumed(); 793dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 794dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 795dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) { 796dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 797dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 798dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 799dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); 800dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 801dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 802dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 803dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); 804dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); 805dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 806dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockWrite writes[] = { 807dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req), 808dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req2), 809dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 810dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockRead reads[] = { 811dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*resp, 1), 812dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*body), 813dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*resp2, 4), 814dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*body2), 815dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*fbody), 816dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*fbody2), 817dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockRead(true, 0, 0), // EOF 818dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 819dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<OrderedSocketData> preconnect_data( 820dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new OrderedSocketData(reads, arraysize(reads), 821dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen writes, arraysize(writes))); 822dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 823dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockConnect never_finishing_connect(true, ERR_IO_PENDING); 824dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 825dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<OrderedSocketData> data_placeholder( 826dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new OrderedSocketData(NULL, 0, NULL, 0)); 827dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen data_placeholder->set_connect_data(never_finishing_connect); 828dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 829dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BoundNetLog log; 830dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TransactionHelperResult out; 831dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NormalSpdyTransactionHelper helper(CreateGetRequest(), 832dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BoundNetLog(), GetParam()); 833dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.RunPreTestSetup(); 834dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.AddData(preconnect_data.get()); 835dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // We require placeholder data because 3 connections are attempted (first is 836dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // the preconnect, 2nd and 3rd are the never finished connections. 837dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.AddData(data_placeholder.get()); 838dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.AddData(data_placeholder.get()); 839dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 840dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<HttpNetworkTransaction> trans1( 841dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new HttpNetworkTransaction(helper.session())); 842dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<HttpNetworkTransaction> trans2( 843dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new HttpNetworkTransaction(helper.session())); 844dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 845dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TestCompletionCallback callback1; 846dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TestCompletionCallback callback2; 847dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 848dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpRequestInfo httpreq = CreateGetRequest(); 849dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 850dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Preconnect the first. 851dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSLConfig preconnect_ssl_config; 852dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config); 853dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpStreamFactory* http_stream_factory = 854dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.session()->http_stream_factory(); 855dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (http_stream_factory->next_protos()) { 856dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen preconnect_ssl_config.next_protos = *http_stream_factory->next_protos(); 857dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 858dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 859dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen http_stream_factory->PreconnectStreams( 860dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1, httpreq, preconnect_ssl_config, log); 861dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 862dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = trans1->Start(&httpreq, &callback1, log); 863dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(ERR_IO_PENDING, out.rv); 864dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = trans2->Start(&httpreq, &callback2, log); 865dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(ERR_IO_PENDING, out.rv); 866dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 867dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = callback1.WaitForResult(); 868dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(OK, out.rv); 869dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = callback2.WaitForResult(); 870dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(OK, out.rv); 871dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 872dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 873dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response1->headers != NULL); 874dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response1->was_fetched_via_spdy); 875dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.status_line = response1->headers->GetStatusLine(); 876dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.response_info = *response1; 877dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = ReadTransaction(trans1.get(), &out.response_data); 878dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(OK, out.rv); 879dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 880dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("hello!hello!", out.response_data); 881dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 882dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 883dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response2->headers != NULL); 884dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(response2->was_fetched_via_spdy); 885dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.status_line = response2->headers->GetStatusLine(); 886dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.response_info = *response2; 887dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.rv = ReadTransaction(trans2.get(), &out.response_data); 888dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(OK, out.rv); 889dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 890dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("hello!hello!", out.response_data); 891dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 892dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.VerifyDataConsumed(); 893dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 894dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Similar to ThreeGets above, however this test adds a SETTINGS 896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// frame. The SETTINGS frame is read during the IO loop waiting on 897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the first transaction completion, and sets a maximum concurrent 898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// stream limit of 1. This means that our IO loop exists after the 899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// second transaction completes, so we can assert on read_index(). 9003345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) { 901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); 906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); 910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); 911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 5, LOWEST)); 913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 5)); 914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(5, false)); 915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody3(ConstructSpdyBodyFrame(5, true)); 916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings settings; 918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SettingsFlagsAndId id(0); 919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); 920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t max_concurrent_streams = 1; 921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(spdy::SpdySetting(id, max_concurrent_streams)); 923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); 924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockWrite writes[] = { 926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CreateMockWrite(*req), 927ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CreateMockWrite(*req2), 928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CreateMockWrite(*req3), 929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 930ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 9323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*settings_frame, 1), 933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody), 9363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 7), 937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body2), 938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody2), 9393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp3, 12), 940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body3), 941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody3), 942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0), // EOF 944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> data( 947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData(reads, arraysize(reads), 948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 9493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_placeholder( 9503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(NULL, 0, NULL, 0)); 951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog log; 953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out; 954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 955ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NormalSpdyTransactionHelper helper(CreateGetRequest(), 956ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BoundNetLog(), GetParam()); 957ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen helper.RunPreTestSetup(); 958ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen helper.AddData(data.get()); 959ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We require placeholder data because three get requests are sent out, so 960ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // there needs to be three sets of SSL connection data. 961ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen helper.AddData(data_placeholder.get()); 962ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen helper.AddData(data_placeholder.get()); 9633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans1( 9643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 9653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans2( 9663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 9673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans3( 9683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback1; 971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback2; 972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback3; 973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo httpreq1 = CreateGetRequest(); 975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo httpreq2 = CreateGetRequest(); 976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo httpreq3 = CreateGetRequest(); 977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = trans1->Start(&httpreq1, &callback1, log); 979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(out.rv, ERR_IO_PENDING); 980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // run transaction 1 through quickly to force a read of our SETTINGS 981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // frame 982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback1.WaitForResult(); 9833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = trans2->Start(&httpreq2, &callback2, log); 986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(out.rv, ERR_IO_PENDING); 987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = trans3->Start(&httpreq3, &callback3, log); 988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(out.rv, ERR_IO_PENDING); 989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback2.WaitForResult(); 990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, out.rv); 991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(7U, data->read_index()); // i.e. the third trans was queued 992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback3.WaitForResult(); 994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(OK, out.rv); 995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 9973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response1 != NULL); 998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response1->headers != NULL); 999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response1->was_fetched_via_spdy); 1000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response1->headers->GetStatusLine(); 1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response1; 1002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = ReadTransaction(trans1.get(), &out.response_data); 1003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 1004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!hello!", out.response_data); 1006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response2->headers->GetStatusLine(); 1009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response2; 1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = ReadTransaction(trans2.get(), &out.response_data); 1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!hello!", out.response_data); 1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response3 = trans3->GetResponseInfo(); 1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response3->headers->GetStatusLine(); 1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response3; 1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = ReadTransaction(trans3.get(), &out.response_data); 1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!hello!", out.response_data); 10223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Similar to ThreeGetsWithMaxConcurrent above, however this test adds 1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a fourth transaction. The third and fourth transactions have 1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// different data ("hello!" vs "hello!hello!") and because of the 1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// user specified priority, we expect to see them inverted in 1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the response from the server. 10333345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) { 1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); 1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); 1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); 1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req4( 1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(NULL, 0, false, 5, HIGHEST)); 1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp4(ConstructSpdyGetSynReply(NULL, 0, 5)); 1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody4(ConstructSpdyBodyFrame(5, true)); 1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req3(ConstructSpdyGet(NULL, 0, false, 7, LOWEST)); 1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp3(ConstructSpdyGetSynReply(NULL, 0, 7)); 1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(7, false)); 1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody3(ConstructSpdyBodyFrame(7, true)); 1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings settings; 1057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SettingsFlagsAndId id(0); 1058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); 1059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t max_concurrent_streams = 1; 1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(spdy::SpdySetting(id, max_concurrent_streams)); 1062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); 1063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req), 10653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2), 10663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req4), 10673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req3), 1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 10703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*settings_frame, 1), 1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 1072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 1073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody), 10743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 7), 1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body2), 1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody2), 10773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp4, 13), 1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody4), 10793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp3, 16), 1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body3), 1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody3), 1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0), // EOF 1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> data( 1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData(reads, arraysize(reads), 10883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 10893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_placeholder( 10903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(NULL, 0, NULL, 0)); 1091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog log; 1093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out; 10943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 10953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 10963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 10973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 10983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We require placeholder data because four get requests are sent out, so 10993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // there needs to be four sets of SSL connection data. 11003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 11013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 11023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 11033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans1( 11043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 11053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans2( 11063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 11073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans3( 11083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 11093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans4( 11103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 11113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 11133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback2; 11143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback3; 11153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback4; 11163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq1 = CreateGetRequest(); 11183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq2 = CreateGetRequest(); 11193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq3 = CreateGetRequest(); 11203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq4 = CreateGetRequest(); 11213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick httpreq4.priority = HIGHEST; 11223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans1->Start(&httpreq1, &callback1, log); 11243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 11253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // run transaction 1 through quickly to force a read of our SETTINGS 11263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // frame 11273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback1.WaitForResult(); 11283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 11293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans2->Start(&httpreq2, &callback2, log); 11313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 11323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans3->Start(&httpreq3, &callback3, log); 11333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 11343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans4->Start(&httpreq4, &callback4, log); 11353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, out.rv); 11363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback2.WaitForResult(); 11383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 11393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(data->read_index(), 7U); // i.e. the third & fourth trans queued 11403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback3.WaitForResult(); 11423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 11433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 11453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->headers != NULL); 11463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->was_fetched_via_spdy); 11473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response1->headers->GetStatusLine(); 11483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response1; 11493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans1.get(), &out.response_data); 11503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 11513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 11523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!hello!", out.response_data); 1153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 11553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response2->headers->GetStatusLine(); 11563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response2; 11573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans2.get(), &out.response_data); 11583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 11593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 11603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!hello!", out.response_data); 1161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // notice: response3 gets two hellos, response4 gets one 11633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // hello, so we know dequeuing priority was respected. 11643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response3 = trans3->GetResponseInfo(); 11653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response3->headers->GetStatusLine(); 11663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response3; 11673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans3.get(), &out.response_data); 1168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 11693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 11703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!hello!", out.response_data); 1171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback4.WaitForResult(); 11733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 11743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response4 = trans4->GetResponseInfo(); 11753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response4->headers->GetStatusLine(); 11763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response4; 11773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans4.get(), &out.response_data); 11783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 11793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 11803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", out.response_data); 11813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 11823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 1183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Similar to ThreeGetsMaxConcurrrent above, however, this test 1186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// deletes a session in the middle of the transaction to insure 1187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// that we properly remove pendingcreatestream objects from 1188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the spdy_session 11893345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) { 1190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 1191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 1192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 1193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 1194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true)); 1195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 1197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 1198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false)); 1199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true)); 1200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings settings; 1202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SettingsFlagsAndId id(0); 1203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); 1204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t max_concurrent_streams = 1; 1205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(spdy::SpdySetting(id, max_concurrent_streams)); 1207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); 1208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req), 12103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2), 1211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 12133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*settings_frame, 1), 1214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 1215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 1216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody), 12173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 7), 1218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body2), 1219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*fbody2), 1220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0), // EOF 1221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> data( 1224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData(reads, arraysize(reads), 12253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 12263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_placeholder( 12273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(NULL, 0, NULL, 0)); 1228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog log; 1230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out; 12313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 12323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 12333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 12343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 12353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We require placeholder data because three get requests are sent out, so 12363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // there needs to be three sets of SSL connection data. 12373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 12383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 12393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans1( 12403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 12413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans2( 12423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 12433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans3( 12443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 12453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 12473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback2; 12483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback3; 12493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq1 = CreateGetRequest(); 12513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq2 = CreateGetRequest(); 12523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq3 = CreateGetRequest(); 12533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans1->Start(&httpreq1, &callback1, log); 12553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(out.rv, ERR_IO_PENDING); 12563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // run transaction 1 through quickly to force a read of our SETTINGS 12573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // frame 12583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback1.WaitForResult(); 12593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 12603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans2->Start(&httpreq2, &callback2, log); 12623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(out.rv, ERR_IO_PENDING); 12633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans3->Start(&httpreq3, &callback3, log); 12643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick delete trans3.release(); 12653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(out.rv, ERR_IO_PENDING); 12663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback2.WaitForResult(); 12673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 12683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(8U, data->read_index()); 12703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 12713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 12723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response1 != NULL); 12733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->headers != NULL); 12743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->was_fetched_via_spdy); 12753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response1->headers->GetStatusLine(); 12763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response1; 12773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans1.get(), &out.response_data); 12783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 12793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 12803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!hello!", out.response_data); 1281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 12833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response2 != NULL); 12843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response2->headers->GetStatusLine(); 12853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response2; 12863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans2.get(), &out.response_data); 12873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 12883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 12893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!hello!", out.response_data); 12903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 12913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 12923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The KillerCallback will delete the transaction on error as part of the 12953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// callback. 12963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass KillerCallback : public TestCompletionCallback { 12973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public: 12983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick explicit KillerCallback(HttpNetworkTransaction* transaction) 12993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : transaction_(transaction) {} 1300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void RunWithParams(const Tuple1<int>& params) { 13023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (params.a < 0) 13033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick delete transaction_; 13043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback::RunWithParams(params); 13053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 13083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* transaction_; 13093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 1310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Similar to ThreeGetsMaxConcurrrentDelete above, however, this test 13123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// closes the socket while we have a pending transaction waiting for 13133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// a pending stream creation. http://crbug.com/52901 13143345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) { 13153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Construct the request. 13163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 13173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 13183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); 13193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> fin_body(ConstructSpdyBodyFrame(1, true)); 1320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST)); 13223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3)); 13233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SpdySettings settings; 13253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SettingsFlagsAndId id(0); 13263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); 13273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const size_t max_concurrent_streams = 1; 13283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick settings.push_back(spdy::SpdySetting(id, max_concurrent_streams)); 13303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); 13313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { CreateMockWrite(*req), 13333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2), 13343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 13353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 13363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*settings_frame, 1), 13373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 13383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 13393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*fin_body), 13403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 7), 13413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_CONNECTION_RESET, 0), // Abort! 13423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 13433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 13453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 13463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 13473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_placeholder( 13483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(NULL, 0, NULL, 0)); 13493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog log; 13513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TransactionHelperResult out; 13523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 13533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 13543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 13553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 13563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We require placeholder data because three get requests are sent out, so 13573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // there needs to be three sets of SSL connection data. 13583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 13593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data_placeholder.get()); 13603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction trans1(helper.session()); 13613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction trans2(helper.session()); 13623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans3(new HttpNetworkTransaction(helper.session())); 13633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback1; 13653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback2; 13663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick KillerCallback callback3(trans3); 13673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq1 = CreateGetRequest(); 13693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq2 = CreateGetRequest(); 13703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo httpreq3 = CreateGetRequest(); 13713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans1.Start(&httpreq1, &callback1, log); 13733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(out.rv, ERR_IO_PENDING); 13743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // run transaction 1 through quickly to force a read of our SETTINGS 13753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // frame 13763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback1.WaitForResult(); 13773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, out.rv); 13783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans2.Start(&httpreq2, &callback2, log); 13803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(out.rv, ERR_IO_PENDING); 13813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans3->Start(&httpreq3, &callback3, log); 13823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(out.rv, ERR_IO_PENDING); 13833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback3.WaitForResult(); 13843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_ABORTED, out.rv); 13853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(6U, data->read_index()); 13873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 13883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response1 = trans1.GetResponseInfo(); 13893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response1 != NULL); 13903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->headers != NULL); 13913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response1->was_fetched_via_spdy); 13923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response1->headers->GetStatusLine(); 13933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response1; 13943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(&trans1, &out.response_data); 1395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 1396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response2 = trans2.GetResponseInfo(); 13983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response2 != NULL); 13993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response2->headers->GetStatusLine(); 14003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.response_info = *response2; 14013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(&trans2, &out.response_data); 14023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_CONNECTION_RESET, out.rv); 14033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 14043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 1405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 14073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that a simple PUT request works. 14083345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, Put) { 14093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup the request 14103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 14113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "PUT"; 14123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 14133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 14143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynStartHeader = { 14153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_STREAM, // Kind = Syn 14163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, // Stream ID 14173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Associated stream ID 14183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), // Priority 14193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_FIN, // Control Flags 14203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, // Compressed 14213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::INVALID, // Status 14223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, // Data 14233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Length 14243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::DATA_FLAG_NONE // Data Flags 14253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kPutHeaders[] = { 14273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "method", "PUT", 14283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", "/", 14293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", "www.google.com", 14303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", "http", 14313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", "HTTP/1.1", 14323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "content-length", "0" 14333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPacket(kSynStartHeader, NULL, 0, 1435201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kPutHeaders, arraysize(kPutHeaders) / 2)); 14363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 14373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req) 14383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 14403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 14413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynReplyHeader = { 14423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_REPLY, // Kind = SynReply 14433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, // Stream ID 14443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Associated stream ID 14453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), // Priority 14463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_NONE, // Control Flags 14473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, // Compressed 14483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::INVALID, // Status 14493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, // Data 14503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Length 14513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::DATA_FLAG_NONE // Data Flags 14523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char* const kStandardGetHeaders[] = { 14543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "status", "200", 14553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", "HTTP/1.1" 14563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "content-length", "1234" 14573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPacket(kSynReplyHeader, 1459201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 0, kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2)); 14603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 14613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 14623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 14633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 14643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 14663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data( 14673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads, arraysize(reads), 14683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 14693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(request, 14703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 14713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunToCompletion(data.get()); 14723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TransactionHelperResult out = helper.output(); 14733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 14743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 14753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 14763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 14783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that a simple HEAD request works. 14793345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, Head) { 1480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Setup the request 1481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 14823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "HEAD"; 1483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 1484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 14853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynStartHeader = { 14863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_STREAM, // Kind = Syn 14873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, // Stream ID 14883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Associated stream ID 14893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), // Priority 14903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_FIN, // Control Flags 14913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, // Compressed 14923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::INVALID, // Status 14933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, // Data 14943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Length 14953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::DATA_FLAG_NONE // Data Flags 14963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 14973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kHeadHeaders[] = { 14983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "method", "HEAD", 14993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", "/", 15003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", "www.google.com", 15013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", "http", 15023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", "HTTP/1.1", 15033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "content-length", "0" 15043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 15053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPacket(kSynStartHeader, NULL, 0, 1506201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kHeadHeaders, arraysize(kHeadHeaders) / 2)); 15073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 15083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req) 15093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 15103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 15123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynReplyHeader = { 15133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::SYN_REPLY, // Kind = SynReply 15143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1, // Stream ID 15153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Associated stream ID 15163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), // Priority 15173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::CONTROL_FLAG_NONE, // Control Flags 15183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick false, // Compressed 15193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::INVALID, // Status 15203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, // Data 15213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0, // Length 15223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy::DATA_FLAG_NONE // Data Flags 15233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 15243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char* const kStandardGetHeaders[] = { 15253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "status", "200", 15263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", "HTTP/1.1" 15273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "content-length", "1234" 15283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 15293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPacket(kSynReplyHeader, 1530201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 0, kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2)); 15313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 15323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 15333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 15343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 15353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 15363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data( 15383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads, arraysize(reads), 15393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 15403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(request, 15413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 15423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunToCompletion(data.get()); 15433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TransactionHelperResult out = helper.output(); 15443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 15463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 15473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 15483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that a simple POST works. 15503345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, Post) { 15513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost(kUploadDataSize, NULL, 0)); 1552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 1553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 1554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 1555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*body), // POST upload frame 1556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0)); 1559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 1560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 1561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 1562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 1563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 1566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(2, reads, arraysize(reads), 1567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 15683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreatePostRequest(), 15693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 15703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunToCompletion(data.get()); 15713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TransactionHelperResult out = helper.output(); 15723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 15733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 15743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", out.response_data); 15753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 15763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1577dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Test that a chunked POST works. 1578dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_P(SpdyNetworkTransactionTest, ChunkedPost) { 1579dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UploadDataStream::set_merge_chunks(false); 1580dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0)); 1581dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false)); 1582dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> chunk2(ConstructSpdyBodyFrame(1, true)); 1583dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockWrite writes[] = { 1584dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*req), 1585dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*chunk1), 1586dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockWrite(*chunk2), 1587dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 1588dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1589dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0)); 1590dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockRead reads[] = { 1591dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*resp), 1592dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*chunk1), 1593dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateMockRead(*chunk2), 1594dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MockRead(true, 0, 0) // EOF 1595dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 1596dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1597dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<DelayedSocketData> data( 1598dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new DelayedSocketData(2, reads, arraysize(reads), 1599dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen writes, arraysize(writes))); 1600dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NormalSpdyTransactionHelper helper(CreateChunkedPostRequest(), 1601dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BoundNetLog(), GetParam()); 1602dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen helper.RunToCompletion(data.get()); 1603dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TransactionHelperResult out = helper.output(); 1604dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(OK, out.rv); 1605dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1606dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ("hello!hello!", out.response_data); 1607dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 1608dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 16093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that a POST without any post data works. 16103345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, NullPost) { 16113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup the request 16123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 16133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "POST"; 16143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 16153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Create an empty UploadData. 16163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data = NULL; 16173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 16183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // When request.upload_data is NULL for post, content-length is 16193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // expected to be 0. 16203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost(0, NULL, 0)); 16213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Set the FIN bit since there will be no body. 16223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick req->set_flags(spdy::CONTROL_FLAG_FIN); 16233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 16243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req), 16253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 16263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 16273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0)); 16283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 16293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 16303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 16313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 16323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 16333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 16343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 16353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data( 16363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads, arraysize(reads), 16373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 16383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(request, 16403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 1641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 1642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 1643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 1644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 1646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that a simple POST works. 16493345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, EmptyPost) { 1650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Setup the request 1651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 1652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "POST"; 1653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 1654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create an empty UploadData. 1655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.upload_data = new UploadData(); 1656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 16573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Http POST Content-Length is using UploadDataStream::size(). 16583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // It is the same as request.upload_data->GetContentLength(). 16593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<UploadDataStream> stream(UploadDataStream::Create( 16603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data, NULL)); 16613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(request.upload_data->GetContentLength(), stream->size()); 16623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 16633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 16643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick req(ConstructSpdyPost(request.upload_data->GetContentLength(), NULL, 0)); 1665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the FIN bit since there will be no body. 1666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch req->set_flags(spdy::CONTROL_FLAG_FIN); 1667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 1668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 1669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0)); 1672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 1673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 1674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 1675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 1676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 1677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 1680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 1681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 1682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(request, 16843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 1685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 1686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 1687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 1688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 1690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// While we're doing a post, the server sends back a SYN_REPLY. 16933345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, PostWithEarlySynReply) { 1694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const char upload[] = { "hello!" }; 1695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Setup the request 1697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 1698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "POST"; 1699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 1700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.upload_data = new UploadData(); 1701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.upload_data->AppendBytes(upload, sizeof(upload)); 1702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Http POST Content-Length is using UploadDataStream::size(). 17043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // It is the same as request.upload_data->GetContentLength(). 17053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<UploadDataStream> stream(UploadDataStream::Create( 17063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data, NULL)); 17073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(request.upload_data->GetContentLength(), stream->size()); 17083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> stream_reply(ConstructSpdyPostSynReply(NULL, 0)); 17093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> stream_body(ConstructSpdyBodyFrame(1, true)); 1710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 17113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream_reply, 2), 17123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream_body, 3), 1713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, 0, 0) // EOF 1714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 17173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(0, reads, arraysize(reads), NULL, 0)); 1718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(request, 17193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 1720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 17213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 1722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunDefaultTest(); 17233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 17243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 17263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv); 17273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 17283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 17293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The client upon cancellation tries to send a RST_STREAM frame. The mock 17303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// socket causes the TCP write to return zero. This test checks that the client 17313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// tries to queue up the RST_STREAM frame again. 17323345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) { 17333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 17343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> rst( 17353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyRstStream(1, spdy::CANCEL)); 17363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 17373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req.get(), 0, false), 17383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite(false, 0, 0, 2), 17393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*rst.get(), 3, false), 17403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 17413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 17423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 17433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 1744731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*resp.get(), 1, true), 1745731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead(true, 0, 0, 4) // EOF 17463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 17473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 17483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DeterministicSocketData> data( 17493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DeterministicSocketData(reads, arraysize(reads), 1750ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen writes, arraysize(writes))); 17513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 17523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 17533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.SetDeterministic(); 17543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 17553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddDeterministicData(data.get()); 17563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 17573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 17583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 17593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 17603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 17613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 17623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->SetStop(2); 17633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->Run(); 17643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.ResetTrans(); 17653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->SetStop(20); 17663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->Run(); 17673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 17683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 1769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that the transaction doesn't crash when we don't have a reply. 17723345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ResponseWithoutSynReply) { 1773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 1774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 1775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 1776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 1777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 1780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), NULL, 0)); 1781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 17823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 1783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 1784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 1785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv); 1786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that the transaction doesn't crash when we get two replies on the same 1789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// stream ID. See http://crbug.com/45639. 17903345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { 1791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 1792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 1793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 1795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 1796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 1797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 1798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 1799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 1800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 1801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 1804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 1805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 1806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 18083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 1809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 18103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 1811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 1813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 1815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 1816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 1817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 1818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 1819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 18213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response != NULL); 1822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 1823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 1824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string response_data; 1825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = ReadTransaction(trans, &response_data); 1826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv); 1827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 1829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that sent data frames and received WINDOW_UPDATE frames change 18323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// the send_window_size_ correctly. 18333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 18343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// WINDOW_UPDATE is different than most other frames in that it can arrive 18353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// while the client is still sending the request body. In order to enforce 18363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// this scenario, we feed a couple of dummy frames and give a delay of 0 to 18373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// socket data provider, so that initial read that is done as soon as the 18383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// stream is created, succeeds and schedules another read. This way reads 18393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// and writes are interleaved; after doing a full frame write, SpdyStream 18403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// will break out of DoLoop and will read and process a WINDOW_UPDATE. 18413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Once our WINDOW_UPDATE is read, we cannot send SYN_REPLY right away 18423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// since request has not been completely written, therefore we feed 18433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// enough number of WINDOW_UPDATEs to finish the first read and cause a 18443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// write, leading to a complete write of request body; after that we send 18453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// a reply with a body, to cause a graceful shutdown. 18463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 18473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// TODO(agayev): develop a socket data provider where both, reads and 18483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// writes are ordered so that writing tests like these are easy and rewrite 18493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// all these tests using it. Right now we are working around the 18503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// limitations as described above and it's not deterministic, tests may 18513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// fail under specific circumstances. 18523345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) { 18533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(true); 18543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 18553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static int kFrameCount = 2; 18563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<std::string> content( 18573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new std::string(kMaxSpdyFrameChunkSize, 'a')); 18583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost( 18593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kMaxSpdyFrameChunkSize * kFrameCount, NULL, 0)); 18603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body( 18613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, content->c_str(), content->size(), false)); 18623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body_end( 18633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, content->c_str(), content->size(), true)); 1864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 1866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 1867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*body), 18683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*body_end), 1869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const int kDeltaWindowSize = 0xff; 18723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const int kDeltaCount = 4; 1873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> window_update( 1874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyWindowUpdate(1, kDeltaWindowSize)); 18753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> window_update_dummy( 18763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyWindowUpdate(2, kDeltaWindowSize)); 18773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0)); 1878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 18793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update_dummy), 18803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update_dummy), 18813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update_dummy), 18823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), // Four updates, therefore window 18833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), // size should increase by 18843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), // kDeltaWindowSize * 4 1885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*window_update), 18863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 18873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body_end), 1888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 1889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 1890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 18923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(0, reads, arraysize(reads), 1893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 1894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup the request 18963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 18973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "POST"; 18983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL(kDefaultURL); 18993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data = new UploadData(); 19003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < kFrameCount; ++i) 19013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data->AppendBytes(content->c_str(), content->size()); 1902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(request, BoundNetLog(), GetParam()); 19043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 19053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 1906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 19083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 19103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 1911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 1913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 1914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, rv); 1915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get()); 19173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(stream != NULL); 19183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(stream->stream() != NULL); 1919201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(static_cast<int>(spdy::kSpdyStreamInitialWindowSize) + 19203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kDeltaWindowSize * kDeltaCount - 19213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kMaxSpdyFrameChunkSize * kFrameCount, 19223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream->stream()->send_window_size()); 19233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 19243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(false); 1925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that received data frames and sent WINDOW_UPDATE frames change 19283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// the recv_window_size_ correctly. 19293345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) { 19303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(true); 1931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 19333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> window_update( 19343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyWindowUpdate(1, kUploadDataSize)); 1935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 19373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req), 19383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*window_update), 19393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 1940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp( 19423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyGetSynReply(NULL, 0, 1)); 19433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body_no_fin( 19443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, false)); 19453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body_fin( 19463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, NULL, 0, true)); 19473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 19483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 19493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body_no_fin), 19503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 0), // Force a pause 19513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body_fin), 19523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 0), // Force a pause 19533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 19543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 19553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data( 19573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads, arraysize(reads), 19583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 19593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 19613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 19623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 19633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 19643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 19653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 19673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 19683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 19703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 19713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 19723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyHttpStream* stream = 19743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static_cast<SpdyHttpStream*>(trans->stream_.get()); 19753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(stream != NULL); 19763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(stream->stream() != NULL); 19773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1978201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ( 1979201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static_cast<int>(spdy::kSpdyStreamInitialWindowSize) - kUploadDataSize, 1980201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream->stream()->recv_window_size()); 19813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 19833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response != NULL); 19843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response->headers != NULL); 19853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 19863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->was_fetched_via_spdy); 19873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Issue a read which will cause a WINDOW_UPDATE to be sent and window 19893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // size increased to default. 1990513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kUploadDataSize)); 19913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->Read(buf, kUploadDataSize, NULL); 19923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(kUploadDataSize, rv); 19933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string content(buf->data(), buf->data()+kUploadDataSize); 19943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_STREQ(kUploadData, content.c_str()); 19953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Schedule the reading of empty data frame with FIN 19973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 19983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Force write of WINDOW_UPDATE which was scheduled during the above 20003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // read. 20013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 20023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Read EOF. 20043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 20053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 20073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(false); 20083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 20093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that WINDOW_UPDATE frame causing overflow is handled correctly. We 20113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// use the same trick as in the above test to enforce our scenario. 20123345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) { 20133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(true); 20143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // number of full frames we hope to write (but will not, used to 20163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // set content-length header correctly) 20173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static int kFrameCount = 3; 20183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<std::string> content( 20203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new std::string(kMaxSpdyFrameChunkSize, 'a')); 20213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost( 20223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kMaxSpdyFrameChunkSize * kFrameCount, NULL, 0)); 20233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body( 20243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, content->c_str(), content->size(), false)); 2025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> rst( 2026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyRstStream(1, spdy::FLOW_CONTROL_ERROR)); 20273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We're not going to write a data frame with FIN, we'll receive a bad 20293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // WINDOW_UPDATE while sending a request and will send a RST_STREAM frame. 2030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 2031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 2032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*body), 2033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*rst), 2034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 2035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const int kDeltaWindowSize = 0x7fffffff; // cause an overflow 2037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> window_update( 2038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyWindowUpdate(1, kDeltaWindowSize)); 20393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> window_update2( 20403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyWindowUpdate(2, kDeltaWindowSize)); 2041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> reply(ConstructSpdyPostSynReply(NULL, 0)); 20423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 20443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update2), 20453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update2), 2046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*window_update), 20473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), 20483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), 20493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 0), // Wait for the RST to be written. 2050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 2051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 2052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 20543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(0, reads, arraysize(reads), 2055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 2056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup the request 20583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 20593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "POST"; 20603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 20613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data = new UploadData(); 20623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < kFrameCount; ++i) 20633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data->AppendBytes(content->c_str(), content->size()); 20643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(request, 20663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 20673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 20683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 2069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 2071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 20733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 2074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 2076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 2077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv); 2078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 2080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(helper.session() != NULL); 20823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(helper.session()->spdy_session_pool() != NULL); 20833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.session()->spdy_session_pool()->CloseAllSessions(); 20843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 20853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(false); 2087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that after hitting a send window size of 0, the write process 20903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// stalls and upon receiving WINDOW_UPDATE frame write resumes. 20913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// This test constructs a POST request followed by enough data frames 20933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// containing 'a' that would make the window size 0, followed by another 20943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// data frame containing default content (which is "hello!") and this frame 20953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// also contains a FIN flag. DelayedSocketData is used to enforce all 20963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// writes go through before a read could happen. However, the last frame 20973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// ("hello!") is not supposed to go through since by the time its turn 20983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// arrives, window size is 0. At this point MessageLoop::Run() called via 20993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// callback would block. Therefore we call MessageLoop::RunAllPending() 21003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// which returns after performing all possible writes. We use DCHECKS to 21013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// ensure that last data frame is still there and stream has stalled. 21023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// After that, next read is artifically enforced, which causes a 21033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// WINDOW_UPDATE to be read and I/O process resumes. 21043345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) { 21053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(true); 21063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Number of frames we need to send to zero out the window size: data 21083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // frames plus SYN_STREAM plus the last data frame; also we need another 21093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // data frame that we will send once the WINDOW_UPDATE is received, 21103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // therefore +3. 2111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch size_t nwrites = 2112201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3; 21133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Calculate last frame's size; 0 size data frame is legal. 2115201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch size_t last_frame_size = 2116201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize; 21173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Construct content for a data frame of maximum size. 21193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<std::string> content( 21203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new std::string(kMaxSpdyFrameChunkSize, 'a')); 21213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost( 2123201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::kSpdyStreamInitialWindowSize + kUploadDataSize, NULL, 0)); 21243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Full frames. 21263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body1( 21273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, content->c_str(), content->size(), false)); 21283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Last frame to zero out the window size. 21303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body2( 21313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyBodyFrame(1, content->c_str(), last_frame_size, false)); 21323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Data frame to be sent once WINDOW_UPDATE frame is received. 21343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(1, true)); 21353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Fill in mock writes. 21373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_array<MockWrite> writes(new MockWrite[nwrites]); 21383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t i = 0; 21393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes[i] = CreateMockWrite(*req); 21403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (i = 1; i < nwrites-2; i++) 21413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes[i] = CreateMockWrite(*body1); 21423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes[i++] = CreateMockWrite(*body2); 21433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes[i] = CreateMockWrite(*body3); 21443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Construct read frame, give enough space to upload the rest of the 21463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // data. 21473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> window_update( 21483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyWindowUpdate(1, kUploadDataSize)); 21493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> reply(ConstructSpdyPostSynReply(NULL, 0)); 21503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 21513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), 21523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*window_update), 21533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*reply), 21543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body2), 21553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body3), 21563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 21573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 21583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Force all writes to happen before any read, last write will not 21603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // actually queue a frame, due to window size being 0. 21613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data( 21623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(nwrites, reads, arraysize(reads), 21633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes.get(), nwrites)); 21643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request; 21663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.method = "POST"; 21673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.url = GURL("http://www.google.com/"); 21683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data = new UploadData(); 21693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<std::string> upload_data( 2170201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new std::string(spdy::kSpdyStreamInitialWindowSize, 'a')); 21713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick upload_data->append(kUploadData, kUploadDataSize); 21723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request.upload_data->AppendBytes(upload_data->c_str(), upload_data->size()); 21733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(request, 21743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 21753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 21763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 21773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 21793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 21813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 21823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 21833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); // Write as much as we can. 21853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get()); 21873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(stream != NULL); 21883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(stream->stream() != NULL); 21893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, stream->stream()->send_window_size()); 21903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(stream->request_body_stream_->eof()); 21913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->ForceNextRead(); // Read in WINDOW_UPDATE frame. 21933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 21943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 21953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession::set_flow_control(false); 21973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 21983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21993345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, CancelledTransaction) { 2200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 2201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 2202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 2203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 2204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 2205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 2207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 2208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 2209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This following read isn't used by the test, except during the 2210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // RunAllPending() call at the end since the SpdySession survives the 2211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // HttpNetworkTransaction and still tries to continue Read()'ing. Any 2212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MockRead will do here. 2213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 2214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 2215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), 2217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes)); 2218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 22203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 2221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 22223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(&data); 2223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 2224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 2226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 2227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 2228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.ResetTrans(); // Cancel the transaction. 2229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 2231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MockClientSocketFactory) are still alive. 2232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 2233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataNotConsumed(); 2234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Verify that the client sends a Rst Frame upon cancelling the stream. 22373345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) { 22383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 22393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> rst( 22403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyRstStream(1, spdy::CANCEL)); 22413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 22423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 0, false), 22433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*rst, 2, false), 22443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 22453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 22473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 2248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*resp, 1, true), 2249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead(true, 0, 0, 3) // EOF 22503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 22513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DeterministicSocketData> data( 22533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DeterministicSocketData(reads, arraysize(reads), 22543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 22553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 22573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), 22583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GetParam()); 22593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.SetDeterministic(); 22603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 22613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddDeterministicData(data.get()); 22623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 22633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 22653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 22673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 22683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->SetStop(2); 22703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->Run(); 22713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.ResetTrans(); 22723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->SetStop(20); 22733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->Run(); 22743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 22763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 22773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyNetworkTransactionTest::StartTransactionCallback 2279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : public CallbackRunner< Tuple1<int> > { 2280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 2281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit StartTransactionCallback( 22823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const scoped_refptr<HttpNetworkSession>& session, 2283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper& helper) 2284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : session_(session), helper_(helper) {} 2285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We try to start another transaction, which should succeed. 2287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void RunWithParams(const Tuple1<int>& params) { 2288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpNetworkTransaction> trans( 2289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new HttpNetworkTransaction(session_)); 2290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 2291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request; 2292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.method = "GET"; 2293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.url = GURL("http://www.google.com/"); 2294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.load_flags = 0; 2295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 2296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 2297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 2298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 23013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const scoped_refptr<HttpNetworkSession>& session_; 2302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper& helper_; 2303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 2304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify that the client can correctly deal with the user callback attempting 2306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to start another transaction on a session that is closing down. See 2307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// http://crbug.com/47455 23083345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { 2309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 2310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 2311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes2[] = { CreateMockWrite(*req) }; 2312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The indicated length of this packet is longer than its actual length. When 2314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the session receives an empty packet after this one, it shuts down the 2315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // session, and calls the read callback with the incomplete data. 2316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const uint8 kGetBodyFrame2[] = { 2317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x00, 0x00, 0x00, 0x01, 2318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x01, 0x00, 0x00, 0x07, 2319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 'h', 'e', 'l', 'l', 'o', '!', 2320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 2321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 23233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 23243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 2), 23253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 3), // Force a pause 23263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kGetBodyFrame2), 23273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kGetBodyFrame2), 4), 23283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 5), // Force a pause 23293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 6), // EOF 23303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 23313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads2[] = { 23323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 2), 23333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 3), // EOF 23343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 23353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 23373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 23383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 23393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data2( 23403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads2, arraysize(reads2), 23413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes2, arraysize(writes2))); 23423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 23443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 23453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 23463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 23473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data2.get()); 23483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 23493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Start the transaction with basic parameters. 23513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 23523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 23533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 23543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 23553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StartTransactionCallback callback2(helper.session(), helper); 23573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const int kSize = 3000; 2358513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 23593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->Read(buf, kSize, &callback2); 23603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This forces an err_IO_pending, which sets the callback. 23613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 23623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This finishes the read. 23633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 23643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 23653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 23663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass SpdyNetworkTransactionTest::DeleteSessionCallback 23683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : public CallbackRunner< Tuple1<int> > { 23693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public: 23703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick explicit DeleteSessionCallback(NormalSpdyTransactionHelper& helper) : 23713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_(helper) {} 23723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We kill the transaction, which deletes the session and stream. 23743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void RunWithParams(const Tuple1<int>& params) { 23753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_.ResetTrans(); 23763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 23773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 23793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper& helper_; 23803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 23813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Verify that the client can correctly deal with the user callback deleting the 23833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// transaction. Failures will usually be valgrind errors. See 23843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// http://crbug.com/46925 23853345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { 23863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 23873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { CreateMockWrite(*req) }; 23883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 23903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 23913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 23923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp.get(), 2), 23933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 3), // Force a pause 23943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body.get(), 4), 23953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 5), // EOF 23963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 23973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 23993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 24003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 24013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 24033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 24043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 24053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 24063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 24073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Start the transaction with basic parameters. 24093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 24103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 24113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 24123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 24133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup a user callback which will delete the session, and clear out the 24153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // memory holding the stream object. Note that the callback deletes trans. 24163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DeleteSessionCallback callback2(helper); 24173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const int kSize = 3000; 2418513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 24193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = trans->Read(buf, kSize, &callback2); 24203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ERR_IO_PENDING, rv); 24213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 24223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Finish running rest of tasks. 24243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 24253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 24263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 24273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Send a spdy request to www.google.com that gets redirected to www.foo.com. 24293345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, RedirectGetRequest) { 243021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // These are headers which the net::URLRequest tacks on. 24313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kExtraHeaders[] = { 24323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "accept-encoding", 24333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "gzip,deflate", 24343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynStartHeader = make_spdy_header(spdy::SYN_STREAM); 24363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kStandardGetHeaders[] = { 24373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", 24383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "www.google.com", 24393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "method", 24403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "GET", 24413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", 24423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "http", 24433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", 24443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "/", 24453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "user-agent", 24463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "", 24473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", 24483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1" 24493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kStandardGetHeaders2[] = { 24513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", 24523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "www.foo.com", 24533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "method", 24543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "GET", 24553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", 24563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "http", 24573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", 24583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "/index.php", 24593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "user-agent", 24603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "", 24613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", 24623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1" 24633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup writes/reads to www.google.com 24663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPacket( 2467201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kSynStartHeader, kExtraHeaders, arraysize(kExtraHeaders) / 2, 2468201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kStandardGetHeaders, arraysize(kStandardGetHeaders) / 2)); 24693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyPacket( 2470201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kSynStartHeader, kExtraHeaders, arraysize(kExtraHeaders) / 2, 2471201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kStandardGetHeaders2, arraysize(kStandardGetHeaders2) / 2)); 24723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReplyRedirect(1)); 24733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 24743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 1), 24753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 24773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 2), 24783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 3) // EOF 24793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup writes/reads to www.foo.com 24823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1)); 24833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(1, true)); 24843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes2[] = { 24853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2, 1), 24863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads2[] = { 24883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 2), 24893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body2, 3), 24903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 4) // EOF 24913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 24923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 24933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 24943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 24953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data2( 24963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads2, arraysize(reads2), 24973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes2, arraysize(writes2))); 24983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 24993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(erikchen): Make test support SPDYSSL, SPDYNPN 25003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_over_ssl(false); 25013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_always(true); 25023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestDelegate d; 25033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { 250421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::URLRequest r(GURL("http://www.google.com/"), &d); 25053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdyURLRequestContext* spdy_url_request_context = 25063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new SpdyURLRequestContext(); 25073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r.set_context(spdy_url_request_context); 25083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_url_request_context->socket_factory(). 25093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddSocketDataProvider(data.get()); 25103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_url_request_context->socket_factory(). 25113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddSocketDataProvider(data2.get()); 25123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 25133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick d.set_quit_on_redirect(true); 25143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r.Start(); 25153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->Run(); 25163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 25173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, d.received_redirect_count()); 25183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 25193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r.FollowDeferredRedirect(); 25203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->Run(); 25213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, d.response_started_count()); 25223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(d.received_data_before_response()); 252372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(net::URLRequestStatus::SUCCESS, r.status().status()); 25243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string contents("hello!"); 25253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(contents, d.data_received()); 25263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 25273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()); 25283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()); 25293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data2->at_read_eof()); 25303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data2->at_write_eof()); 25313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 25323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 25333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Send a spdy request to www.google.com. Get a pushed stream that redirects to 25343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// www.foo.com. 25353345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, RedirectServerPush) { 253621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // These are headers which the net::URLRequest tacks on. 25373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kExtraHeaders[] = { 25383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "accept-encoding", 25393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "gzip,deflate", 25403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 25413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SpdyHeaderInfo kSynStartHeader = make_spdy_header(spdy::SYN_STREAM); 25423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const kStandardGetHeaders[] = { 25433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "host", 25443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "www.google.com", 25453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "method", 25463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "GET", 25473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "scheme", 25483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "http", 25493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "url", 25503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "/", 25513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "user-agent", 25523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "", 25533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "version", 25543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "HTTP/1.1" 25553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 25563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 25573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup writes/reads to www.google.com 2558201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> req( 2559201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ConstructSpdyPacket(kSynStartHeader, 2560201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kExtraHeaders, 2561201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kExtraHeaders) / 2, 2562201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kStandardGetHeaders, 2563201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kStandardGetHeaders) / 2)); 25643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 2565201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> rep( 2566201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ConstructSpdyPush(NULL, 2567201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2568201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2569201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2570201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat", 2571201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "301 Moved Permanently", 2572201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.foo.com/index.php")); 25733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 2574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<spdy::SpdyFrame> rst(ConstructSpdyRstStream(2, spdy::CANCEL)); 25753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 25763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 1), 2577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CreateMockWrite(*rst, 6), 25783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 25793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 25803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 2), 25813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*rep, 3), 25823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body, 4), 25833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 5), // Force a pause 2584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MockRead(true, 0, 0, 7) // EOF 25853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 25863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 25873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Setup writes/reads to www.foo.com 2588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const char* const kStandardGetHeaders2[] = { 2589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "host", 2590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "www.foo.com", 2591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "method", 2592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "GET", 2593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "scheme", 2594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "http", 2595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "url", 2596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "/index.php", 2597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "user-agent", 2598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "", 2599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "version", 2600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "HTTP/1.1" 2601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 2602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<spdy::SpdyFrame> req2( 2603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ConstructSpdyPacket(kSynStartHeader, 2604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen kExtraHeaders, 2605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen arraysize(kExtraHeaders) / 2, 2606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen kStandardGetHeaders2, 2607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen arraysize(kStandardGetHeaders2) / 2)); 26083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1)); 26093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(1, true)); 26103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes2[] = { 26113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2, 1), 26123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 26133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads2[] = { 26143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 2), 26153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body2, 3), 26163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 5) // EOF 26173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 26183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 26193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 26203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 26213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data2( 26223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads2, arraysize(reads2), 26233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes2, arraysize(writes2))); 26243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(erikchen): Make test support SPDYSSL, SPDYNPN 26263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_over_ssl(false); 26273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpStreamFactory::set_force_spdy_always(true); 26283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestDelegate d; 26293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestDelegate d2; 26303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<SpdyURLRequestContext> spdy_url_request_context( 26313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new SpdyURLRequestContext()); 26323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { 263321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::URLRequest r(GURL("http://www.google.com/"), &d); 26343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r.set_context(spdy_url_request_context); 26353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_url_request_context->socket_factory(). 26363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddSocketDataProvider(data.get()); 26373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r.Start(); 26393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->Run(); 26403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, d.received_redirect_count()); 26423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string contents("hello!"); 26433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(contents, d.data_received()); 26443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 264521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::URLRequest r2(GURL("http://www.google.com/foo.dat"), &d2); 26463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r2.set_context(spdy_url_request_context); 26473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick spdy_url_request_context->socket_factory(). 26483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddSocketDataProvider(data2.get()); 26493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick d2.set_quit_on_redirect(true); 26513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r2.Start(); 26523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->Run(); 26533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, d2.received_redirect_count()); 26543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick r2.FollowDeferredRedirect(); 26563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->Run(); 26573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(1, d2.response_started_count()); 26583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(d2.received_data_before_response()); 265972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(net::URLRequestStatus::SUCCESS, r2.status().status()); 26603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string contents2("hello!"); 26613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(contents2, d2.data_received()); 26623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 26633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 26643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data2->CompleteRead(); 26653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()); 26663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()); 26673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data2->at_read_eof()); 26683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data2->at_write_eof()); 26693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 26703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26713345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) { 26723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const unsigned char kPushBodyFrame[] = { 26733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x00, 0x00, 0x00, 0x02, // header, ID 26743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x01, 0x00, 0x00, 0x06, // FIN, length 26753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 26763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 26773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 26783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 26793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 26803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 26813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 26823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 26833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 26843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 26853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 26863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 26873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2688201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 2689201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2690201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2691201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2692201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 26933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 26943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 26953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 26963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 4, false), 26973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 26983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame), 5), 26993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 6), // Force a pause 27003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 27013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response; 27033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response2; 27043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string expected_push_result("pushed"); 2705201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 2706201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 2707201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 2708201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 2709201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 2710201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RunServerPushTest(data.get(), 2711201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response, 2712201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response2, 2713201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch expected_push_result); 27143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 27163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 27173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 27183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the pushed stream. 27203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response2.headers != NULL); 27213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 27223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 27233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27243345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) { 27253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const unsigned char kPushBodyFrame[] = { 27263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x00, 0x00, 0x00, 0x02, // header, ID 27273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x01, 0x00, 0x00, 0x06, // FIN, length 27283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 27293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 27303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 27323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 27333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 27343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 27353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 27383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2739201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 2740201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2741201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2742201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2743201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 27443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 27463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 27473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 27483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 27493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 27503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame), 5), 27513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 4, false), 27523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 6), // Force a pause 27533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 27543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response; 27563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response2; 27573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string expected_push_result("pushed"); 2758201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 2759201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 2760201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 2761201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 2762201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 2763201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RunServerPushTest(data.get(), 2764201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response, 2765201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response2, 2766201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch expected_push_result); 27673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 27693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 27703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 27713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the pushed stream. 27733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response2.headers != NULL); 27743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 27753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 27763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27773345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushServerAborted) { 27783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 27803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 27823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 27833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 27843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 27853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 27883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2789201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 2790201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2791201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2792201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2793201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 27943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 27953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream2_rst(ConstructSpdyRstStream(2, spdy::PROTOCOL_ERROR)); 27963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 27973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 27983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 27993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_rst, 4), 28003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 5, false), 28013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 6), // Force a pause 28023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 28033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 28053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 28063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 28073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 28083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 28093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 28113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 28123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 28143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Start the transaction with basic parameters. 28163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 28173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 28183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 28193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 28203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 28213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we consumed all test data. 28233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()) << "Read count: " 28243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_count() 28253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Read index: " 28263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_index(); 28273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()) << "Write count: " 28283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_count() 28293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Write index: " 28303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_index(); 28313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 28333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response = *trans->GetResponseInfo(); 28343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 28353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 28363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 28373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28383345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushDuplicate) { 28393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we don't leak streams and that we properly send a reset 28403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // if the server pushes the same stream twice. 28413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const unsigned char kPushBodyFrame[] = { 28423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x00, 0x00, 0x00, 0x02, // header, ID 28433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x01, 0x00, 0x00, 0x06, // FIN, length 28443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 28453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 28463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 28483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 28493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 28503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 28513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 28523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream3_rst(ConstructSpdyRstStream(4, spdy::PROTOCOL_ERROR)); 28533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 28543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 28553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream3_rst, 5), 28563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 28573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 28593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 28603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2861201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 2862201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2863201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2864201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2865201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 28663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2867201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream3_syn(ConstructSpdyPush(NULL, 2868201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2869201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 4, 2870201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2871201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 28723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 28733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 28743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 28753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream3_syn, 4), 28763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 6, false), 28773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 28783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame), 7), 28793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 8), // Force a pause 28803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 28813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response; 28833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response2; 28843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string expected_push_result("pushed"); 2885201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 2886201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 2887201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 2888201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 2889201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 2890201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RunServerPushTest(data.get(), 2891201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response, 2892201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response2, 2893201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch expected_push_result); 28943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 28963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 28973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 28983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the pushed stream. 29003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response2.headers != NULL); 29013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 29023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 29033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29043345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) { 29053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const unsigned char kPushBodyFrame1[] = { 29063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x00, 0x00, 0x00, 0x02, // header, ID 29073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x01, 0x00, 0x00, 0x1F, // FIN, length 29083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 29093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 29103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kPushBodyFrame2[] = " my darling"; 29113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kPushBodyFrame3[] = " hello"; 29123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kPushBodyFrame4[] = " my baby"; 29133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 29153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 29163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 29173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 29183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 29193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 29203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 29213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 29233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 29243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2925201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 2926201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2927201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2928201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2929201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 29303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 29313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 29323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 29333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame1), 29343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame1), 4), 29353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame2), 29363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame2) - 1, 5), 29373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame3), 29383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame3) - 1, 6), 29393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame4), 29403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame4) - 1, 7), 29413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 8, false), 29423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 9), // Force a pause 29433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 29443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response; 29463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response2; 29473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string expected_push_result("pushed my darling hello my baby"); 2948201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 2949201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 2950201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 2951201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 2952201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 2953201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RunServerPushTest(data.get(), 2954201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response, 2955201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response2, 2956201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch expected_push_result); 29573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 29593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 29603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 29613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the pushed stream. 29633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response2.headers != NULL); 29643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 29653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 29663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29673345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) { 29683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const unsigned char kPushBodyFrame1[] = { 29693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x00, 0x00, 0x00, 0x02, // header, ID 29703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0x01, 0x00, 0x00, 0x1F, // FIN, length 29713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 29723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 29733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kPushBodyFrame2[] = " my darling"; 29743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kPushBodyFrame3[] = " hello"; 29753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kPushBodyFrame4[] = " my baby"; 29763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 29783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 29793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 29803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 29813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 29823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 29833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 29843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 29853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 29863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 29873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 2988201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 2989201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 2990201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 2991201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 2992201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 29933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 29943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 29953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 29963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame1), 29973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame1), 4), 29983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame2), 29993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame2) - 1, 5), 30003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 6), // Force a pause 30013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame3), 30023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame3) - 1, 7), 30033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame4), 30043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(kPushBodyFrame4) - 1, 8), 30053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body.get(), 9, false), 30063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 10) // Force a pause. 30073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 30083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response; 30103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response2; 30113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string expected_push_result("pushed my darling hello my baby"); 3012201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 3013201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 3014201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 3015201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 3016201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 3017201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RunServerPushTest(data.get(), 3018201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response, 3019201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response2, 3020201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch expected_push_result); 30213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 30233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 30243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 30253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the pushed stream. 30273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response2.headers != NULL); 30283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 30293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 30303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30313345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) { 30323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 30343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 30363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream2_rst(ConstructSpdyRstStream(2, spdy::INVALID_STREAM)); 30383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 30393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 30403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream2_rst, 4), 30413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 30423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 30453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 3046201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 3047201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 3048201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 3049201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 3050201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 30513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 30523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 30533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 30543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 4), 30553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 5) // Force a pause 30563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 30573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 30593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 30603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 30613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 30623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 30633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 30653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 30663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 30683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Start the transaction with basic parameters. 30703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 30713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 30723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 30733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 30743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 30753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we consumed all test data. 30773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()) << "Read count: " 30783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_count() 30793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Read index: " 30803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_index(); 30813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()) << "Write count: " 30823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_count() 30833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Write index: " 30843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_index(); 30853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 30873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response = *trans->GetResponseInfo(); 30883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 30893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 30903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 30913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30923345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) { 30933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 30953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 30973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 30983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream2_rst(ConstructSpdyRstStream(2, spdy::INVALID_ASSOCIATED_STREAM)); 30993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 31003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 31013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream2_rst, 4), 31023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 31033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 31043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 31053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 31063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 3107201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 3108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 3109201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 3110201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 9, 3111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 3112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 31133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 31143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 31153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 4), 3116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, ERR_IO_PENDING, 5), // Force a pause 3117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> data( 3120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData(reads, arraysize(reads), 3121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 31233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 31243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 31263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 31273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 3129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Start the transaction with basic parameters. 3131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 31323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 3133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 3134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 31353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 3136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we consumed all test data. 31383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()) << "Read count: " 31393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_count() 31403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Read index: " 31413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_index(); 31423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()) << "Write count: " 31433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_count() 31443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Write index: " 31453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_index(); 31463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 31473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 31483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response = *trans->GetResponseInfo(); 31493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 31503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 3151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31533345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) { 31543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 31553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 31563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 31573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_body(ConstructSpdyBodyFrame(1, true)); 31583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 31593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream2_rst(ConstructSpdyRstStream(2, spdy::PROTOCOL_ERROR)); 31603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 31613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream1_syn, 1), 31623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*stream2_rst, 4), 31633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 3164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 31663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 31673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> 31683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stream2_syn(ConstructSpdyPush(NULL, 0, 2, 1)); 3169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 31703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_reply, 2), 31713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream2_syn, 3), 31723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*stream1_body, 4), 31733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 5) // Force a pause 3174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<OrderedSocketData> data( 3177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new OrderedSocketData(reads, arraysize(reads), 3178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 31803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 31813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 31833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 31843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 3186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Start the transaction with basic parameters. 3188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 31893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 3190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 3191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 31923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 31933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify that we consumed all test data. 31943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_read_eof()) << "Read count: " 31953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_count() 31963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Read index: " 31973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->read_index(); 31983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(data->at_write_eof()) << "Write count: " 31993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_count() 32003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << " Write index: " 32013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << data->write_index(); 32023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 32033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 32043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response = *trans->GetResponseInfo(); 32053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 32063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 3207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify that various SynReply headers parse correctly through the 3210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HTTP layer. 32113345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) { 3212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SynReplyHeadersTests { 3213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int num_headers; 3214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* extra_headers[5]; 3215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* expected_headers; 3216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } test_cases[] = { 3217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This uses a multi-valued cookie header. 3218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 2, 3219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "cookie", "val1", 3220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "cookie", "val2", // will get appended separated by NULL 3221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "cookie: val1\n" 3224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "cookie: val2\n" 3225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "hello: bye\n" 3226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status: 200\n" 3227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version: HTTP/1.1\n" 3228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is the minimalist set of headers. 3230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 0, 3231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL }, 3232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "hello: bye\n" 3233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status: 200\n" 3234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version: HTTP/1.1\n" 3235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Headers with a comma separated list. 3237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 1, 3238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "cookie", "val1,val2", 3239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "cookie: val1,val2\n" 3242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "hello: bye\n" 3243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status: 200\n" 3244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version: HTTP/1.1\n" 3245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 3249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req( 3250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 3252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp( 3254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGetSynReply(test_cases[i].extra_headers, 3255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].num_headers, 3256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1)); 3257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 32683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 3273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 3275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers; 3277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(headers.get() != NULL); 3278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void* iter = NULL; 3279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string name, value, lines; 3280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (headers->EnumerateHeaderLines(&iter, &name, &value)) { 3281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append(name); 3282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append(": "); 3283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append(value); 3284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append("\n"); 3285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(std::string(test_cases[i].expected_headers), lines); 3287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify that various SynReply headers parse vary fields correctly 3291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// through the HTTP layer, and the response matches the request. 32923345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) { 3293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const SpdyHeaderInfo syn_reply_info = { 3294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SYN_REPLY, // Syn Reply 3295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, // Stream ID 3296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Associated Stream ID 32973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), 32983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Priority 3299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::CONTROL_FLAG_NONE, // Control Flags 3300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, // Compressed 3301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::INVALID, // Status 3302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // Data 3303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Data Length 3304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::DATA_FLAG_NONE // Data Flags 3305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Modify the following data to change/add test cases: 3307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SynReplyTests { 3308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const SpdyHeaderInfo* syn_reply; 3309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool vary_matches; 3310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int num_headers[2]; 3311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* extra_headers[2][16]; 3312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } test_cases[] = { 3313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test the case of a multi-valued cookie. When the value is delimited 3314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // with NUL characters, it needs to be unfolded into multiple headers. 3315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 3316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &syn_reply_info, 3317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 3318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 1, 4 }, 3319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { "cookie", "val1,val2", 3320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "vary", "cookie", 3323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", "200", 3324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", "/index.php", 3325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1", 3326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, { // Multiple vary fields. 3330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &syn_reply_info, 3331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 3332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 2, 5 }, 3333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { "friend", "barney", 3334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "enemy", "snaggletooth", 3335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "vary", "friend", 3338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "vary", "enemy", 3339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", "200", 3340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", "/index.php", 3341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1", 3342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, { // Test a '*' vary field. 3346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &syn_reply_info, 3347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 3348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 1, 4 }, 3349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { "cookie", "val1,val2", 3350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "vary", "*", 3353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", "200", 3354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", "/index.php", 3355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1", 3356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, { // Multiple comma-separated vary fields. 3360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &syn_reply_info, 3361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 3362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 2, 4 }, 3363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { "friend", "barney", 3364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "enemy", "snaggletooth", 3365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "vary", "friend,enemy", 3368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", "200", 3369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", "/index.php", 3370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1", 3371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 3378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 3379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> frame_req( 3380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(test_cases[i].extra_headers[0], 3381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].num_headers[0], 3382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 1, LOWEST)); 3383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 3385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*frame_req), 3386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the reply. 3389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> frame_reply( 3390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyPacket(*test_cases[i].syn_reply, 3391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].extra_headers[1], 3392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].num_headers[1], 3393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 3394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0)); 3395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*frame_reply), 3399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Attach the headers to the request. 3404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int header_count = test_cases[i].num_headers[0]; 3405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo request = CreateGetRequest(); 3407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int ct = 0; ct < header_count; ct++) { 3408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* header_key = test_cases[i].extra_headers[0][ct * 2]; 3409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* header_value = test_cases[i].extra_headers[0][ct * 2 + 1]; 3410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.extra_headers.SetHeader(header_key, header_value); 3411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(request, 34173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv) << i; 3422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line) << i; 3423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data) << i; 3424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test the response information. 3426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(out.response_info.response_time > 3427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info.request_time) << i; 3428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::TimeDelta test_delay = out.response_info.response_time - 3429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info.request_time; 3430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::TimeDelta min_expected_delay; 3431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch min_expected_delay.FromMilliseconds(10); 3432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_GT(test_delay.InMillisecondsF(), 3433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch min_expected_delay.InMillisecondsF()) << i; 3434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.response_info.vary_data.is_valid(), 3435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].vary_matches) << i; 3436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check the headers. 3438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers; 3439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(headers.get() != NULL) << i; 3440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void* iter = NULL; 3441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string name, value, lines; 3442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (headers->EnumerateHeaderLines(&iter, &name, &value)) { 3443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append(name); 3444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append(": "); 3445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append(value); 3446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines.append("\n"); 3447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the expected header reply string. 3450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char reply_buffer[256] = ""; 3451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyReplyString(test_cases[i].extra_headers[1], 3452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].num_headers[1], 3453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reply_buffer, 3454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 256); 3455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(std::string(reply_buffer), lines) << i; 3457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify that we don't crash on invalid SynReply responses. 34613345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, InvalidSynReply) { 3462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const SpdyHeaderInfo kSynStartHeader = { 3463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SYN_REPLY, // Kind = SynReply 3464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, // Stream ID 3465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Associated stream ID 34663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), 34673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Priority 3468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::CONTROL_FLAG_NONE, // Control Flags 3469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, // Compressed 3470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::INVALID, // Status 3471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // Data 3472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Length 3473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::DATA_FLAG_NONE // Data Flags 3474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct InvalidSynReplyTests { 3477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int num_headers; 3478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* headers[10]; 3479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } test_cases[] = { 3480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // SYN_REPLY missing status header 3481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 4, 3482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "cookie", "val1", 3483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "cookie", "val2", 3484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", "/index.php", 3485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1", 3486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // SYN_REPLY missing version header 3490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 2, 3491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "status", "200", 3492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url", "/index.php", 3493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 3494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 3496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // SYN_REPLY with no headers 3497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 0, { NULL }, }, 3498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 3501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req( 3502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 3504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 3505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp( 3508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyPacket(kSynStartHeader, 3509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 0, 3510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].headers, 3511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_cases[i].num_headers)); 3512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 35233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3526201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_INCOMPLETE_SPDY_HEADERS, out.rv); 3527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify that we don't crash on some corrupt frames. 353172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_P(SpdyNetworkTransactionTest, CorruptFrameSessionError) { 353272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // This is the length field that's too short. 353372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<spdy::SpdyFrame> syn_reply_wrong_length( 3534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGetSynReply(NULL, 0, 1)); 353572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen syn_reply_wrong_length->set_length(syn_reply_wrong_length->length() - 4); 3536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SynReplyTests { 3538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdyFrame* syn_reply; 3539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } test_cases[] = { 354072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen { syn_reply_wrong_length.get(), }, 3541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 3544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req( 3545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 3547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 3548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite(true, 0, 0) // EOF 3549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*test_cases[i].syn_reply), 3554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 35623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 3566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that we shutdown correctly on write errors. 35703345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, WriteError) { 3571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 3573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We'll write 10 bytes successfully 3574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite(true, req->data(), 10), 3575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Followed by ERROR! 3576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite(true, ERR_FAILED), 3577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(2, NULL, 0, 3581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 35833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_FAILED, out.rv); 3587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->Reset(); 3588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that partial writes work. 35913345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, PartialWrite) { 3592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Chop the SYN_STREAM frame into 5 chunks. 3593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kChunks = 5; 3595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_array<MockWrite> writes(ChopWriteFrame(*req.get(), kChunks)); 3596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 3598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(kChunks, reads, arraysize(reads), 3607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes.get(), kChunks)); 3608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 36093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 3613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 3615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// In this test, we enable compression, but get a uncompressed SynReply from 3618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the server. Verify that teardown is all clean. 36193345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) { 3620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For this test, we turn on the normal compression. 3621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EnableCompression(true); 3622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> compressed( 3624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGet(NULL, 0, true, 1, LOWEST)); 36253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> rst( 36263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ConstructSpdyRstStream(1, spdy::PROTOCOL_ERROR)); 3627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 3628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*compressed), 36293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*rst), 3630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 3633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 36373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) 3638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 36443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 36473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 3648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->Reset(); 3649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EnableCompression(false); 3651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that the NetLog contains good data for a simple GET request. 36543345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, NetLog) { 36554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch static const char* const kExtraHeaders[] = { 36564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch "user-agent", "Chrome", 36574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch }; 36584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(kExtraHeaders, 1, false, 1, 36594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch LOWEST)); 3660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 3661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 3663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 3664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 3667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded); 3671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 36754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch NormalSpdyTransactionHelper helper(CreateGetRequestWithUserAgent(), 36763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick log.bound(), GetParam()); 3677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 3678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 3680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 3682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check that the NetLog was filled reasonably. 3684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This test is intentionally non-specific about the exact ordering of the 3685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // log; instead we just check to make sure that certain events exist, and that 3686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // they are in the right order. 368721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 368821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 368921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 369021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_LT(0u, entries.size()); 3691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int pos = 0; 369221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pos = net::ExpectLogContainsSomewhere(entries, 0, 36933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, 3694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::NetLog::PHASE_BEGIN); 369521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 36963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, 3697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::NetLog::PHASE_END); 369821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 36993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, 3700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::NetLog::PHASE_BEGIN); 370121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 37023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, 3703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::NetLog::PHASE_END); 370421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 37053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, 3706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::NetLog::PHASE_BEGIN); 370721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 37083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, 3709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::NetLog::PHASE_END); 37104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 37114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Check that we logged all the headers correctly 37124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch pos = net::ExpectLogContainsSomewhere( 371321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 0, 37144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::NetLog::TYPE_SPDY_SESSION_SYN_STREAM, 37154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::NetLog::PHASE_NONE); 371621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CapturingNetLog::Entry entry = entries[pos]; 37174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch NetLogSpdySynParameter* request_params = 37184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch static_cast<NetLogSpdySynParameter*>(entry.extra_parameters.get()); 37194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch spdy::SpdyHeaderBlock* headers = 37204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch request_params->GetHeaders().get(); 37214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 37224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch spdy::SpdyHeaderBlock expected; 37234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch expected["host"] = "www.google.com"; 37244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch expected["url"] = "/"; 37254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch expected["scheme"] = "http"; 37264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch expected["version"] = "HTTP/1.1"; 37274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch expected["method"] = "GET"; 37284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch expected["user-agent"] = "Chrome"; 37294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(expected.size(), headers->size()); 37304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch spdy::SpdyHeaderBlock::const_iterator end = expected.end(); 37314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch for (spdy::SpdyHeaderBlock::const_iterator it = expected.begin(); 37324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch it != end; 37334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ++it) { 37344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(it->second, (*headers)[it->first]); 37354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 3736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Since we buffer the IO from the stream to the renderer, this test verifies 3739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// that when we read out the maximum amount of data (e.g. we received 50 bytes 3740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// on the network, but issued a Read for only 5 of those bytes) that the data 3741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// flow still works correctly. 37423345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, BufferFull) { 3743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 3744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 3747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 2 data frames in a single read. 3749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame_1( 3750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "goodby", 6, spdy::DATA_FLAG_NONE)); 3751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame_2( 3752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "e worl", 6, spdy::DATA_FLAG_NONE)); 3753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdyFrame* data_frames[2] = { 3754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame_1.get(), 3755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame_2.get(), 3756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char combined_data_frames[100]; 3758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int combined_data_frames_len = 3759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CombineFrames(data_frames, arraysize(data_frames), 3760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch combined_data_frames, arraysize(combined_data_frames)); 3761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> last_frame( 3762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "d", 1, spdy::DATA_FLAG_FIN)); 3763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 3765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, ERR_IO_PENDING), // Force a pause 3768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, combined_data_frames, combined_data_frames_len), 3769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, ERR_IO_PENDING), // Force a pause 3770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*last_frame), 3771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 3780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 37823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 37843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 3785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 3786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 3787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 3788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback.WaitForResult(); 3791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, OK); 3792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 3794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 3795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 3796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response->headers->GetStatusLine(); 3797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response; // Make a copy so we can verify. 3798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read Data 3800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback read_callback; 3801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string content; 3803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch do { 3804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read small chunks at a time. 3805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kSmallReadSize = 3; 3806513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize)); 3807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Read(buf, kSmallReadSize, &read_callback); 3808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == net::ERR_IO_PENDING) { 3809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->CompleteRead(); 3810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = read_callback.WaitForResult(); 3811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv > 0) { 3813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content.append(buf->data(), rv); 3814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (rv < 0) { 3815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 3816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (rv > 0); 3818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_data.swap(content); 3820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 3822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MockClientSocketFactory) are still alive. 3823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 3824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that we consumed all test data. 3826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 3827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 3829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("goodbye world", out.response_data); 3831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify that basic buffering works; when multiple data frames arrive 3834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// at the same time, ensure that we don't notify a read completion for 3835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// each data frame individually. 38363345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, Buffering) { 3837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 3838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 3841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 4 data frames in a single read. 3843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame( 3844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_NONE)); 3845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame_fin( 3846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_FIN)); 3847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdyFrame* data_frames[4] = { 3848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 3849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 3850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 3851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame_fin.get() 3852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char combined_data_frames[100]; 3854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int combined_data_frames_len = 3855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CombineFrames(data_frames, arraysize(data_frames), 3856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch combined_data_frames, arraysize(combined_data_frames)); 3857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 3859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 3861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, ERR_IO_PENDING), // Force a pause 3862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, combined_data_frames, combined_data_frames_len), 3863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 38713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 38733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 3874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 3875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 3877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 3878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 3879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback.WaitForResult(); 3882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, OK); 3883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 3885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 3886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 3887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response->headers->GetStatusLine(); 3888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response; // Make a copy so we can verify. 3889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read Data 3891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback read_callback; 3892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string content; 3894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int reads_completed = 0; 3895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch do { 3896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read small chunks at a time. 3897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kSmallReadSize = 14; 3898513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize)); 3899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Read(buf, kSmallReadSize, &read_callback); 3900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == net::ERR_IO_PENDING) { 3901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->CompleteRead(); 3902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = read_callback.WaitForResult(); 3903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv > 0) { 3905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSmallReadSize, rv); 3906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content.append(buf->data(), rv); 3907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (rv < 0) { 3908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FAIL() << "Unexpected read error: " << rv; 3909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reads_completed++; 3911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (rv > 0); 3912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(3, reads_completed); // Reads are: 14 bytes, 14 bytes, 0 bytes. 3914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_data.swap(content); 3916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 3918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MockClientSocketFactory) are still alive. 3919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 3920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that we consumed all test data. 3922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 3923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 3925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("messagemessagemessagemessage", out.response_data); 3927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 3928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify the case where we buffer data but read it after it has been buffered. 39303345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, BufferedAll) { 3931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 3932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 3934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 3935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 5 data frames in a single read. 3937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> syn_reply( 3938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyGetSynReply(NULL, 0, 1)); 3939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch syn_reply->set_flags(spdy::CONTROL_FLAG_NONE); // turn off FIN bit 3940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame( 3941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_NONE)); 3942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame_fin( 3943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_FIN)); 3944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdyFrame* frames[5] = { 3945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch syn_reply.get(), 3946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 3947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 3948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 3949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame_fin.get() 3950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char combined_frames[200]; 3952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int combined_frames_len = 3953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CombineFrames(frames, arraysize(frames), 3954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch combined_frames, arraysize(combined_frames)); 3955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 3957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, combined_frames, combined_frames_len), 3958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 3959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 3960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 3962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 3963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 3964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 39663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 3967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 39683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 3969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 3970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 3972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 3973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 3974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 3976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback.WaitForResult(); 3977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, OK); 3978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 3980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 3981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 3982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response->headers->GetStatusLine(); 3983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response; // Make a copy so we can verify. 3984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read Data 3986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback read_callback; 3987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string content; 3989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int reads_completed = 0; 3990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch do { 3991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read small chunks at a time. 3992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kSmallReadSize = 14; 3993513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize)); 3994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Read(buf, kSmallReadSize, &read_callback); 3995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv > 0) { 3996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSmallReadSize, rv); 3997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content.append(buf->data(), rv); 3998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (rv < 0) { 3999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FAIL() << "Unexpected read error: " << rv; 4000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reads_completed++; 4002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (rv > 0); 4003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(3, reads_completed); 4005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_data.swap(content); 4007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 4009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MockClientSocketFactory) are still alive. 4010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 4011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that we consumed all test data. 4013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 4014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 4016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 4017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("messagemessagemessagemessage", out.response_data); 4018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify the case where we buffer data and close the connection. 40213345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, BufferedClosed) { 4022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 4023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 4026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // All data frames in a single read. 4028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NOTE: We don't FIN the stream. 4029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame( 4030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_NONE)); 4031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdyFrame* data_frames[4] = { 4032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 4033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 4034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get(), 4035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_frame.get() 4036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char combined_data_frames[100]; 4038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int combined_data_frames_len = 4039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CombineFrames(data_frames, arraysize(data_frames), 4040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch combined_data_frames, arraysize(combined_data_frames)); 4041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 4042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 4044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, ERR_IO_PENDING), // Force a wait 4045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, combined_data_frames, combined_data_frames_len), 4046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 4047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 4051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 4052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 40543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 4055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 40563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 4057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 4058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 4060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 4062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 4063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 4065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback.WaitForResult(); 4066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, OK); 4067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 4069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 4070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 4071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response->headers->GetStatusLine(); 4072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response; // Make a copy so we can verify. 4073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read Data 4075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback read_callback; 4076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string content; 4078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int reads_completed = 0; 4079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch do { 4080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read small chunks at a time. 4081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kSmallReadSize = 14; 4082513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize)); 4083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Read(buf, kSmallReadSize, &read_callback); 4084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == net::ERR_IO_PENDING) { 4085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->CompleteRead(); 4086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = read_callback.WaitForResult(); 4087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv > 0) { 4089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content.append(buf->data(), rv); 4090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (rv < 0) { 4091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This test intentionally closes the connection, and will get an error. 4092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); 4093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 4094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reads_completed++; 4096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (rv > 0); 4097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0, reads_completed); 4099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_data.swap(content); 4101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 4103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MockClientSocketFactory) are still alive. 4104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 4105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that we consumed all test data. 4107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 4108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verify the case where we buffer data and cancel the transaction. 41113345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, BufferedCancelled) { 4112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer framer; 4113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 4116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NOTE: We don't FIN the stream. 4118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> data_frame( 4119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch framer.CreateDataFrame(1, "message", 7, spdy::DATA_FLAG_NONE)); 4120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 4122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 4124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, ERR_IO_PENDING), // Force a wait 4125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*data_frame), 4126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 4127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 4131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 4132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 41343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 4135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 41363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 4137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 4138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 4139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 4141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 4142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 4144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback.WaitForResult(); 4145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, OK); 4146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 4148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 4149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 4150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.status_line = response->headers->GetStatusLine(); 4151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.response_info = *response; // Make a copy so we can verify. 4152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read Data 4154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback read_callback; 4155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch do { 4157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kReadSize = 256; 4158513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kReadSize)); 4159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = trans->Read(buf, kReadSize, &read_callback); 4160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == net::ERR_IO_PENDING) { 4161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Complete the read now, which causes buffering to start. 4162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->CompleteRead(); 4163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Destroy the transaction, causing the stream to get cancelled 4164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and orphaning the buffered IO task. 4165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.ResetTrans(); 4166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 4167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We shouldn't get here in this test. 4169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FAIL() << "Unexpected read: " << rv; 4170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (rv > 0); 4171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flush the MessageLoop; this will cause the buffered IO task 4173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to run for the final time. 4174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 4175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that we consumed all test data. 4177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 4178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that if the server requests persistence of settings, that we save 4181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the settings in the SpdySettingsStorage. 41823345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, SettingsSaved) { 4183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const SpdyHeaderInfo kSynReplyInfo = { 4184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SYN_REPLY, // Syn Reply 4185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, // Stream ID 4186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Associated Stream ID 41873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), 41883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Priority 4189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::CONTROL_FLAG_NONE, // Control Flags 4190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, // Compressed 4191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::INVALID, // Status 4192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // Data 4193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Data Length 4194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::DATA_FLAG_NONE // Data Flags 4195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const char* const kExtraHeaders[] = { 4197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", "200", 4198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1" 4199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 42023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 42033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 4204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that no settings exist initially. 42063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair host_port_pair("www.google.com", helper.port()); 4207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); 4208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(spdy_session_pool->spdy_settings().Get(host_port_pair).empty()); 4209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 4211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 4213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the reply. 4215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> reply( 4216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyPacket(kSynReplyInfo, 4217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kExtraHeaders, 4218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(kExtraHeaders) / 2, 4219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 4220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0)); 4221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleId1 = 0x1; 4223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleValue1 = 0x0a0a0a0a; 4224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleId2 = 0x2; 4225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleValue2 = 0x0b0b0b0b; 4226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleId3 = 0xababab; 4227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleValue3 = 0x0c0c0c0c; 4228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> settings_frame; 4229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 4230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the SETTINGS frame. 4231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings settings; 4232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SettingsFlagsAndId setting(0); 4233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First add a persisted setting 4234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); 4235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_id(kSampleId1); 4236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(std::make_pair(setting, kSampleValue1)); 4237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Next add a non-persisted setting 4238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_flags(0); 4239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_id(kSampleId2); 4240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(std::make_pair(setting, kSampleValue2)); 4241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Next add another persisted setting 4242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); 4243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_id(kSampleId3); 4244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(std::make_pair(setting, kSampleValue3)); 4245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings_frame.reset(ConstructSpdySettings(settings)); 4246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 4249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*reply), 4251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 4252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*settings_frame), 4253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 4254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 4258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 42593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 42603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunDefaultTest(); 42613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 4262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 4263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 4264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 4265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 4266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 4268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify we had two persisted settings. 4269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings saved_settings = 4270dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session_pool->spdy_settings().Get(host_port_pair); 4271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(2u, saved_settings.size()); 4272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify the first persisted setting. 4274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySetting setting = saved_settings.front(); 4275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch saved_settings.pop_front(); 4276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, setting.first.flags()); 4277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleId1, setting.first.id()); 4278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleValue1, setting.second); 4279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify the second persisted setting. 4281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting = saved_settings.front(); 4282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch saved_settings.pop_front(); 4283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, setting.first.flags()); 4284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleId3, setting.first.id()); 4285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleValue3, setting.second); 4286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that when there are settings saved that they are sent back to the 4290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// server upon session establishment. 42913345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { 4292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const SpdyHeaderInfo kSynReplyInfo = { 4293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SYN_REPLY, // Syn Reply 4294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, // Stream ID 4295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Associated Stream ID 42963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ConvertRequestPriorityToSpdyPriority(LOWEST), 42973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Priority 4298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::CONTROL_FLAG_NONE, // Control Flags 4299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, // Compressed 4300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::INVALID, // Status 4301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // Data 4302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, // Data Length 4303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::DATA_FLAG_NONE // Data Flags 4304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const char* kExtraHeaders[] = { 4306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "status", "200", 4307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "version", "HTTP/1.1" 4308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 43113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 43123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 4313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that no settings exist initially. 43153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair host_port_pair("www.google.com", helper.port()); 4316dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); 4317dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(spdy_session_pool->spdy_settings().Get(host_port_pair).empty()); 4318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleId1 = 0x1; 4320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleValue1 = 0x0a0a0a0a; 4321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleId2 = 0xababab; 4322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int kSampleValue2 = 0x0c0c0c0c; 4323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Manually insert settings into the SpdySettingsStorage here. 4324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 4325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings settings; 4326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SettingsFlagsAndId setting(0); 4327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First add a persisted setting 4328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); 4329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_id(kSampleId1); 4330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(std::make_pair(setting, kSampleValue1)); 4331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Next add another persisted setting 4332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); 4333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting.set_id(kSampleId2); 4334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch settings.push_back(std::make_pair(setting, kSampleValue2)); 4335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4336dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session_pool->mutable_spdy_settings()->Set(host_port_pair, settings); 4337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4339dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(2u, spdy_session_pool->spdy_settings().Get(host_port_pair).size()); 4340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the SETTINGS frame. 4342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const spdy::SpdySettings& settings = 4343dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session_pool->spdy_settings().Get(host_port_pair); 4344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); 4345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the request. 4347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { 4350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*settings_frame), 4351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockWrite(*req), 4352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Construct the reply. 4355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> reply( 4356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConstructSpdyPacket(kSynReplyInfo, 4357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kExtraHeaders, 4358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(kExtraHeaders) / 2, 4359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 4360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0)); 4361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 4363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*reply), 4365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*body), 4366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(true, 0, 0) // EOF 4367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(2, reads, arraysize(reads), 4371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 43723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 43733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunDefaultTest(); 43743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 4375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 4376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(OK, out.rv); 4377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 4378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ("hello!", out.response_data); 4379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 4381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify we had two persisted settings. 4382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySettings saved_settings = 4383dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session_pool->spdy_settings().Get(host_port_pair); 4384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(2u, saved_settings.size()); 4385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify the first persisted setting. 4387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdySetting setting = saved_settings.front(); 4388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch saved_settings.pop_front(); 4389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, setting.first.flags()); 4390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleId1, setting.first.id()); 4391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleValue1, setting.second); 4392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify the second persisted setting. 4394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setting = saved_settings.front(); 4395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch saved_settings.pop_front(); 4396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, setting.first.flags()); 4397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleId2, setting.first.id()); 4398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kSampleValue2, setting.second); 4399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44023345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, GoAwayWithActiveStream) { 4403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 4405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> go_away(ConstructSpdyGoAway()); 4407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*go_away), 44093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0), // EOF 4410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 4414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 4415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 44163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 44173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data); 4418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunToCompletion(data.get()); 4419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out = helper.output(); 44203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_ABORTED, out.rv); 4421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44233345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) { 4424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 4426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 4428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead reads[] = { 4429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateMockRead(*resp), 4430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockRead(false, 0, 0) // EOF 4431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 4432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<DelayedSocketData> data( 4434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DelayedSocketData(1, reads, arraysize(reads), 4435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch writes, arraysize(writes))); 4436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog log; 4437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 44383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick log, GetParam()); 4439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.RunPreTestSetup(); 44403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 4441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 4442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 4444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TransactionHelperResult out; 4445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = trans->Start(&CreateGetRequest(), &callback, log); 4446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, ERR_IO_PENDING); 4448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = callback.WaitForResult(); 4449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out.rv, OK); 4450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 4452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->headers != NULL); 4453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 4454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.rv = ReadTransaction(trans, &out.response_data); 4455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv); 4456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that we consumed all test data. 4458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch helper.VerifyDataConsumed(); 4459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 4460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test to make sure we can correctly connect through a proxy. 44623345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, ProxyConnect) { 44633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 44643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 44653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.session_deps().reset(new SpdySessionDependencies( 44663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"))); 4467513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch helper.SetSession(make_scoped_refptr( 4468513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get()))); 44693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 44703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 44713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 44723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n" 44733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 44743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"}; 44753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n" 44763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 44773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"}; 44783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"}; 44793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 44803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 44813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 44823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 44833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes_SPDYNPN[] = { 44843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite(false, kConnect443, arraysize(kConnect443) - 1, 0), 44853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 2), 44863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 44873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads_SPDYNPN[] = { 44883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, kHTTP200, arraysize(kHTTP200) - 1, 1), 44893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 3), 44903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body.get(), 4), 44913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 5), 44923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 44933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 44943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes_SPDYSSL[] = { 44953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite(false, kConnect80, arraysize(kConnect80) - 1, 0), 44963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 2), 44973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 44983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads_SPDYSSL[] = { 44993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, kHTTP200, arraysize(kHTTP200) - 1, 1), 45003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 3), 45013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body.get(), 4), 45023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 5), 45033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 45043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes_SPDYNOSSL[] = { 45063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 0), 45073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 45083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads_SPDYNOSSL[] = { 45103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 1), 45113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body.get(), 2), 45123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 3), 45133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 45143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data; 45163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch(GetParam()) { 45173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNOSSL: 45183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data = new OrderedSocketData(reads_SPDYNOSSL, 45193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(reads_SPDYNOSSL), 45203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes_SPDYNOSSL, 45213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(writes_SPDYNOSSL)); 45223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 45233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYSSL: 45243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data = new OrderedSocketData(reads_SPDYSSL, arraysize(reads_SPDYSSL), 45253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes_SPDYSSL, arraysize(writes_SPDYSSL)); 45263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 45273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNPN: 45283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data = new OrderedSocketData(reads_SPDYNPN, arraysize(reads_SPDYNPN), 45293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes_SPDYNPN, arraysize(writes_SPDYNPN)); 45303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 45313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 45323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 45333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 45343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 45363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 45373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 45393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 45403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 45423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, rv); 45433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Verify the SYN_REPLY. 45453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response = *trans->GetResponseInfo(); 45463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response.headers != NULL); 45473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 45483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string response_data; 45503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, ReadTransaction(trans, &response_data)); 45513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", response_data); 45523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 45533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 45543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test to make sure we can correctly connect through a proxy to www.google.com, 45563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// if there already exists a direct spdy connection to www.google.com. See 45573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// http://crbug.com/49874 45583345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { 45593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // When setting up the first transaction, we store the SpdySessionPool so that 45603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // we can use the same pool in the second transaction. 45613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 45623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 45633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Use a proxy service which returns a proxy fallback list from DIRECT to 45653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // myproxy:70. For this test there will be no fallback, so it is equivalent 45663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // to simply DIRECT. The reason for appending the second proxy is to verify 45673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // that the session pool key used does is just "DIRECT". 45683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.session_deps().reset(new SpdySessionDependencies( 45693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyService::CreateFixedFromPacResult("DIRECT; PROXY myproxy:70"))); 4570513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch helper.SetSession(make_scoped_refptr( 4571513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get()))); 45723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4573731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); 45743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 45753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Construct and send a simple GET request. 45773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 45783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes[] = { 45793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req, 1), 45803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 45813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 45833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 45843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 45853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp, 2), 45863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body, 3), 45873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING, 4), // Force a pause 45883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 5) // EOF 45893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 45903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data( 45913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new OrderedSocketData(reads, arraysize(reads), 45923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes, arraysize(writes))); 45933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data.get()); 45943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans = helper.trans(); 45953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 45963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 45973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TransactionHelperResult out; 45983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 45993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(out.rv, ERR_IO_PENDING); 46013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = callback.WaitForResult(); 46023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(out.rv, OK); 46033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 46053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->headers != NULL); 46063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->was_fetched_via_spdy); 46073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.rv = ReadTransaction(trans, &out.response_data); 46083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, out.rv); 46093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.status_line = response->headers->GetStatusLine(); 46103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 46113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", out.response_data); 46123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Check that the SpdySession is still in the SpdySessionPool. 46143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortPair host_port_pair("www.google.com", helper.port()); 46153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortProxyPair session_pool_key_direct( 46163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick host_port_pair, ProxyServer::Direct()); 46173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(spdy_session_pool->HasSession(session_pool_key_direct)); 46183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostPortProxyPair session_pool_key_proxy( 46193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick host_port_pair, 46203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyServer::FromURI("www.foo.com", ProxyServer::SCHEME_HTTP)); 46213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(spdy_session_pool->HasSession(session_pool_key_proxy)); 46223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Set up data for the proxy connection. 46243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n" 46253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 46263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"}; 46273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n" 46283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Host: www.google.com\r\n" 46293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Proxy-Connection: keep-alive\r\n\r\n"}; 46303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"}; 46313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet( 46323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "http://www.google.com/foo.dat", false, 1, LOWEST)); 46333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1)); 46343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(1, true)); 46353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes_SPDYNPN[] = { 46373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite(false, kConnect443, arraysize(kConnect443) - 1, 0), 46383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2, 2), 46393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 46403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads_SPDYNPN[] = { 46413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, kHTTP200, arraysize(kHTTP200) - 1, 1), 46423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 3), 46433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body2, 4), 46443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 5) // EOF 46453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 46463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes_SPDYNOSSL[] = { 46483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2, 0), 46493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 46503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads_SPDYNOSSL[] = { 46513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 1), 46523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body2, 2), 46533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 3) // EOF 46543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 46553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite writes_SPDYSSL[] = { 46573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockWrite(false, kConnect80, arraysize(kConnect80) - 1, 0), 46583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockWrite(*req2, 2), 46593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 46603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads_SPDYSSL[] = { 46613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(false, kHTTP200, arraysize(kHTTP200) - 1, 1), 46623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp2, 3), 46633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body2, 4), 46643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0, 5), 46653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 46663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<OrderedSocketData> data_proxy; 46683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch(GetParam()) { 46693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNPN: 46703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_proxy = new OrderedSocketData(reads_SPDYNPN, 46713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(reads_SPDYNPN), 46723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes_SPDYNPN, 46733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(writes_SPDYNPN)); 46743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 46753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYNOSSL: 46763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_proxy = new OrderedSocketData(reads_SPDYNOSSL, 46773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(reads_SPDYNOSSL), 46783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes_SPDYNOSSL, 46793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(writes_SPDYNOSSL)); 46803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 46813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case SPDYSSL: 46823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_proxy = new OrderedSocketData(reads_SPDYSSL, 46833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(reads_SPDYSSL), 46843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick writes_SPDYSSL, 46853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick arraysize(writes_SPDYSSL)); 46863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 46873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 46883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 46893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 46903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 46913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Create another request to www.google.com, but this time through a proxy. 46923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpRequestInfo request_proxy; 46933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request_proxy.method = "GET"; 46943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request_proxy.url = GURL("http://www.google.com/foo.dat"); 46953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request_proxy.load_flags = 0; 4696731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<SpdySessionDependencies> ssd_proxy(new SpdySessionDependencies()); 46973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Ensure that this transaction uses the same SpdySessionPool. 4698513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<HttpNetworkSession> session_proxy( 4699513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SpdySessionDependencies::SpdyCreateSession(ssd_proxy.get())); 47003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper_proxy(request_proxy, 47013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 4702731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick HttpNetworkSessionPeer session_peer(session_proxy); 4703731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_peer.SetProxyService( 4704731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 47053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_proxy.session_deps().swap(ssd_proxy); 47063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_proxy.SetSession(session_proxy); 47073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_proxy.RunPreTestSetup(); 47083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_proxy.AddData(data_proxy.get()); 47093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpNetworkTransaction* trans_proxy = helper_proxy.trans(); 47113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback_proxy; 47123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans_proxy->Start(&request_proxy, &callback_proxy, BoundNetLog()); 47133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 47143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback_proxy.WaitForResult(); 47153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, rv); 47163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo response_proxy = *trans_proxy->GetResponseInfo(); 47183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response_proxy.headers != NULL); 47193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response_proxy.headers->GetStatusLine()); 47203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string response_data; 47223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(OK, ReadTransaction(trans_proxy, &response_data)); 47233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", response_data); 47243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->CompleteRead(); 47263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper_proxy.VerifyDataConsumed(); 47273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 47283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// When we get a TCP-level RST, we need to retry a HttpNetworkTransaction 47303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// on a new connection, if the connection was previously known to be good. 47313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// This can happen when a server reboots without saying goodbye, or when 47323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// we're behind a NAT that masked the RST. 47333345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) { 47343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 47353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 47363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads[] = { 47373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 47383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 47393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_IO_PENDING), 47403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, ERR_CONNECTION_RESET), 47413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 47423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead reads2[] = { 47443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*resp), 47453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CreateMockRead(*body), 47463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MockRead(true, 0, 0) // EOF 47473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 47483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This test has a couple of variants. 47503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick enum { 47513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Induce the RST while waiting for our transaction to send. 47523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick VARIANT_RST_DURING_SEND_COMPLETION, 47533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Induce the RST while waiting for our transaction to read. 47543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // In this case, the send completed - everything copied into the SNDBUF. 47553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick VARIANT_RST_DURING_READ_COMPLETION 47563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 47573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int variant = VARIANT_RST_DURING_SEND_COMPLETION; 47593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick variant <= VARIANT_RST_DURING_READ_COMPLETION; 47603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ++variant) { 47613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data1( 47623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads, arraysize(reads), 47633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, 0)); 47643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<DelayedSocketData> data2( 47663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new DelayedSocketData(1, reads2, arraysize(reads2), 47673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL, 0)); 47683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 47703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BoundNetLog(), GetParam()); 47713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data1.get()); 47723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.AddData(data2.get()); 47733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.RunPreTestSetup(); 47743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < 2; ++i) { 47763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<HttpNetworkTransaction> trans( 47773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new HttpNetworkTransaction(helper.session())); 47783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 47803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); 47813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ERR_IO_PENDING, rv); 47823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // On the second transaction, we trigger the RST. 47833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (i == 1) { 47843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (variant == VARIANT_RST_DURING_READ_COMPLETION) { 47853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Writes to the socket complete asynchronously on SPDY by running 47863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // through the message loop. Complete the write here. 47873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->RunAllPending(); 47883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 47893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Now schedule the ERR_CONNECTION_RESET. 47913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(3u, data1->read_index()); 47923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data1->CompleteRead(); 47933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(4u, data1->read_index()); 47943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 47953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 47963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 47973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 47983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseInfo* response = trans->GetResponseInfo(); 47993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(response != NULL); 48003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->headers != NULL); 48013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(response->was_fetched_via_spdy); 48023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string response_data; 48033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = ReadTransaction(trans.get(), &response_data); 48043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(OK, rv); 48053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 48063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("hello!", response_data); 48073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 48083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick helper.VerifyDataConsumed(); 48103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 48113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4812731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4813731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Test that turning SPDY on and off works properly. 4814731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) { 4815731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick net::HttpStreamFactory::set_spdy_enabled(true); 4816731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4817731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 4818731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4819731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); 4820731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); 4821731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead spdy_reads[] = { 4822731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*resp), 4823731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CreateMockRead(*body), 4824731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead(true, 0, 0) // EOF 4825731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick }; 4826731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4827731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_refptr<DelayedSocketData> data( 4828513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new DelayedSocketData(1, 4829513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch spdy_reads, arraysize(spdy_reads), 4830731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_writes, arraysize(spdy_writes))); 4831731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NormalSpdyTransactionHelper helper(CreateGetRequest(), 4832731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BoundNetLog(), GetParam()); 4833731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick helper.RunToCompletion(data.get()); 4834731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransactionHelperResult out = helper.output(); 4835731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(OK, out.rv); 4836731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 4837731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ("hello!", out.response_data); 4838731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4839731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick net::HttpStreamFactory::set_spdy_enabled(false); 4840731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead http_reads[] = { 4841731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead("HTTP/1.1 200 OK\r\n\r\n"), 4842731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead("hello from http"), 4843731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MockRead(false, OK), 4844731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick }; 4845731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_refptr<DelayedSocketData> data2( 4846731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new DelayedSocketData(1, http_reads, arraysize(http_reads), 4847731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NULL, 0)); 4848731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NormalSpdyTransactionHelper helper2(CreateGetRequest(), 4849731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BoundNetLog(), GetParam()); 4850731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick helper2.SetSpdyDisabled(); 4851731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick helper2.RunToCompletion(data2.get()); 4852731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransactionHelperResult out2 = helper2.output(); 4853731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(OK, out2.rv); 4854731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ("HTTP/1.1 200 OK", out2.status_line); 4855731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ("hello from http", out2.response_data); 4856731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4857731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick net::HttpStreamFactory::set_spdy_enabled(true); 4858731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 4859513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4860513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Tests that Basic authentication works over SPDY 4861513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) { 4862513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::HttpStreamFactory::set_spdy_enabled(true); 4863513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4864513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // The first request will be a bare GET, the second request will be a 4865513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // GET with an Authorization header. 4866513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<spdy::SpdyFrame> req_get( 4867513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4868513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const char* const kExtraAuthorizationHeaders[] = { 4869513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "authorization", 4870513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Basic Zm9vOmJhcg==", 4871513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 4872513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<spdy::SpdyFrame> req_get_authorization( 4873513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ConstructSpdyGet( 4874201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kExtraAuthorizationHeaders, 4875201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kExtraAuthorizationHeaders) / 2, 4876513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch false, 3, LOWEST)); 4877513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockWrite spdy_writes[] = { 4878513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateMockWrite(*req_get, 1), 4879513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateMockWrite(*req_get_authorization, 4), 4880513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 4881513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4882513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // The first response is a 401 authentication challenge, and the second 4883513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // response will be a 200 response since the second request includes a valid 4884513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Authorization header. 4885513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const char* const kExtraAuthenticationHeaders[] = { 4886513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "WWW-Authenticate", 4887513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Basic realm=\"MyRealm\"" 4888513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 4889513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<spdy::SpdyFrame> resp_authentication( 4890513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ConstructSpdySynReplyError( 4891513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "401 Authentication Required", 4892201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kExtraAuthenticationHeaders, 4893201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kExtraAuthenticationHeaders) / 2, 4894513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1)); 4895513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<spdy::SpdyFrame> body_authentication( 4896513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ConstructSpdyBodyFrame(1, true)); 4897513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<spdy::SpdyFrame> resp_data(ConstructSpdyGetSynReply(NULL, 0, 3)); 4898513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<spdy::SpdyFrame> body_data(ConstructSpdyBodyFrame(3, true)); 4899513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead spdy_reads[] = { 4900513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateMockRead(*resp_authentication, 2), 4901513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateMockRead(*body_authentication, 3), 4902513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateMockRead(*resp_data, 5), 4903513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateMockRead(*body_data, 6), 4904513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MockRead(true, 0, 7), 4905513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 4906513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4907513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<OrderedSocketData> data( 4908513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new OrderedSocketData(spdy_reads, arraysize(spdy_reads), 4909513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch spdy_writes, arraysize(spdy_writes))); 4910513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch HttpRequestInfo request(CreateGetRequest()); 4911513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch BoundNetLog net_log; 4912513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NormalSpdyTransactionHelper helper(request, net_log, GetParam()); 4913513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4914513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch helper.RunPreTestSetup(); 4915513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch helper.AddData(data.get()); 4916513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch HttpNetworkTransaction* trans = helper.trans(); 4917513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch TestCompletionCallback callback_start; 4918513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const int rv_start = trans->Start(&request, &callback_start, net_log); 4919513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv_start); 4920513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const int rv_start_complete = callback_start.WaitForResult(); 4921513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(OK, rv_start_complete); 4922513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4923513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Make sure the response has an auth challenge. 4924513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const HttpResponseInfo* const response_start = trans->GetResponseInfo(); 4925513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ASSERT_TRUE(response_start != NULL); 4926513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ASSERT_TRUE(response_start->headers != NULL); 4927513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(401, response_start->headers->response_code()); 4928513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_TRUE(response_start->was_fetched_via_spdy); 4929513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ASSERT_TRUE(response_start->auth_challenge.get() != NULL); 4930513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_FALSE(response_start->auth_challenge->is_proxy); 4931513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(L"basic", response_start->auth_challenge->scheme); 4932513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(L"MyRealm", response_start->auth_challenge->realm); 4933513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4934513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Restart with a username/password. 4935513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const string16 kFoo(ASCIIToUTF16("foo")); 4936513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const string16 kBar(ASCIIToUTF16("bar")); 4937513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch TestCompletionCallback callback_restart; 4938513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const int rv_restart = trans->RestartWithAuth(kFoo, kBar, &callback_restart); 4939513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv_restart); 4940513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const int rv_restart_complete = callback_restart.WaitForResult(); 4941513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(OK, rv_restart_complete); 4942513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // TODO(cbentzel): This is actually the same response object as before, but 4943513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // data has changed. 4944513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const HttpResponseInfo* const response_restart = trans->GetResponseInfo(); 4945513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ASSERT_TRUE(response_restart != NULL); 4946513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ASSERT_TRUE(response_restart->headers != NULL); 4947513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_EQ(200, response_restart->headers->response_code()); 4948513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch EXPECT_TRUE(response_restart->auth_challenge.get() == NULL); 4949513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 4950513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4951201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) { 4952201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const unsigned char kPushBodyFrame[] = { 4953201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x00, 0x00, 0x00, 0x02, // header, ID 4954201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x01, 0x00, 0x00, 0x06, // FIN, length 4955201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 4956201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 4957201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 4958201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 4959201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 4960201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_body(ConstructSpdyBodyFrame(1, true)); 4961201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { 4962201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockWrite(*stream1_syn, 1), 4963201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 4964201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 4965201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kInitialHeaders[] = { 4966201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "url", 4967201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat", 4968201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 4969201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kLateHeaders[] = { 4970201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "hello", 4971201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "bye", 4972201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 4973201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200", 4974201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 4975201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 4976201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 4977201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 4978201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyControlFrame(kInitialHeaders, 4979201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kInitialHeaders) / 2, 4980201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 4981201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 4982201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 4983201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_STREAM, 4984201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 4985201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 4986201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 4987201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1)); 4988201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 4989201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_headers(ConstructSpdyControlFrame(kLateHeaders, 4990201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kLateHeaders) / 2, 4991201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 4992201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 4993201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 4994201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 4995201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 4996201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 4997201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 4998201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 4999201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5000201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5001201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 5002201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5003201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply, 2), 5004201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_syn, 3), 5005201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_headers, 4), 5006201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body, 5, false), 5007201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 5008201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kPushBodyFrame), 6), 5009201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, ERR_IO_PENDING, 7), // Force a pause 5010201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5011201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5012201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response; 5013201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response2; 5014201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string expected_push_result("pushed"); 5015201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 5016201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 5017201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 5018201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 5019201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 5020201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RunServerPushTest(data.get(), 5021201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response, 5022201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &response2, 5023201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch expected_push_result); 5024201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5025201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5026201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response.headers != NULL); 5027201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 5028201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5029201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the pushed stream. 5030201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers != NULL); 5031201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 5032201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5033201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5034201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) { 5035201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // We push a stream and attempt to claim it before the headers come down. 5036201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const unsigned char kPushBodyFrame[] = { 5037201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x00, 0x00, 0x00, 0x02, // header, ID 5038201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x01, 0x00, 0x00, 0x06, // FIN, length 5039201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 5040201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5041201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5042201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 5043201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5044201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_body(ConstructSpdyBodyFrame(1, true)); 5045201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { 5046201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockWrite(*stream1_syn, 0, false), 5047201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5048201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5049201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kInitialHeaders[] = { 5050201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "url", 5051201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat", 5052201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5053201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kLateHeaders[] = { 5054201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "hello", 5055201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "bye", 5056201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5057201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200", 5058201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 5059201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 5060201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5061201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5062201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyControlFrame(kInitialHeaders, 5063201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kInitialHeaders) / 2, 5064201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5065201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5066201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5067201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_STREAM, 5068201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5069201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5070201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5071201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1)); 5072201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5073201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_headers(ConstructSpdyControlFrame(kLateHeaders, 5074201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kLateHeaders) / 2, 5075201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5076201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5077201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5078201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5079201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5080201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5081201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5082201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5083201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5084201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5085201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 5086201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5087201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply, 1), 5088201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_syn, 2), 5089201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body, 3), 5090201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_headers, 4), 5091201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 5092201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kPushBodyFrame), 5), 5093201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, 0, 5), // EOF 5094201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5095201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5096201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response; 5097201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response2; 5098201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string expected_push_result("pushed"); 5099201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<DeterministicSocketData> data(new DeterministicSocketData( 5100201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 5101201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 5102201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 5103201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 5104201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5105201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 5106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BoundNetLog(), GetParam()); 5107201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.SetDeterministic(); 5108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.AddDeterministicData(static_cast<DeterministicSocketData*>(data)); 5109201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.RunPreTestSetup(); 5110201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpNetworkTransaction* trans = helper.trans(); 5112201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5113201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM, 5114201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // and the body of the primary stream, but before we've received the HEADERS 5115201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // for the pushed stream. 5116201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->SetStop(3); 5117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Start the transaction. 5119201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TestCompletionCallback callback; 5120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 5121201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5122201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->Run(); 5123201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rv = callback.WaitForResult(); 5124201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(0, rv); 5125201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5126201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Request the pushed path. At this point, we've received the push, but the 5127201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // headers are not yet complete. 5128201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<HttpNetworkTransaction> trans2( 5129201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new HttpNetworkTransaction(helper.session())); 5130201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rv = trans2->Start(&CreateGetPushRequest(), &callback, BoundNetLog()); 5131201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->RunFor(3); 5133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MessageLoop::current()->RunAllPending(); 5134201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5135201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Read the server push body. 5136201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string result2; 5137201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ReadResult(trans2.get(), data.get(), &result2); 5138201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Read the response body. 5139201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string result; 5140201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ReadResult(trans, data, &result); 5141201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5142201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify that we consumed all test data. 5143201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(data->at_read_eof()); 5144201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(data->at_write_eof()); 5145201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5146201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify that the received push data is same as the expected push data. 5147201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(result2.compare(expected_push_result), 0) 5148201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << "Received data: " 5149201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << result2 5150201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << "||||| Expected data: " 5151201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << expected_push_result; 5152201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5153201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5154201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Copy the response info, because trans goes away. 5155201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch response = *trans->GetResponseInfo(); 5156201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch response2 = *trans2->GetResponseInfo(); 5157201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5158201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch VerifyStreamsClosed(helper); 5159201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5160201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5161201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response.headers != NULL); 5162201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 5163201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5164201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the pushed stream. 5165201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers != NULL); 5166201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 5167201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5168201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5169201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) { 5170201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // We push a stream and attempt to claim it before the headers come down. 5171201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const unsigned char kPushBodyFrame[] = { 5172201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x00, 0x00, 0x00, 0x02, // header, ID 5173201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x01, 0x00, 0x00, 0x06, // FIN, length 5174201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 5175201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5176201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5177201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 5178201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5179201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_body(ConstructSpdyBodyFrame(1, true)); 5180201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { 5181201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockWrite(*stream1_syn, 0, false), 5182201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5183201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5184201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kInitialHeaders[] = { 5185201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "url", 5186201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat", 5187201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5188201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kMiddleHeaders[] = { 5189201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "hello", 5190201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "bye", 5191201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5192201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kLateHeaders[] = { 5193201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5194201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200", 5195201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 5196201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 5197201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5198201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5199201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyControlFrame(kInitialHeaders, 5200201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kInitialHeaders) / 2, 5201201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5202201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5203201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5204201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_STREAM, 5205201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5206201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5207201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5208201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1)); 5209201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5210201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_headers1(ConstructSpdyControlFrame(kMiddleHeaders, 5211201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kMiddleHeaders) / 2, 5212201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5213201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5214201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5215201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5216201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5217201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5218201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5219201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5220201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5221201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_headers2(ConstructSpdyControlFrame(kLateHeaders, 5222201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kLateHeaders) / 2, 5223201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5224201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5225201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5226201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5227201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5228201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5229201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5230201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5231201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5232201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5233201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 5234201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5235201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply, 1), 5236201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_syn, 2), 5237201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body, 3), 5238201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_headers1, 4), 5239201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_headers2, 5), 5240201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 5241201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kPushBodyFrame), 6), 5242201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, 0, 6), // EOF 5243201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5244201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5245201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response; 5246201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response2; 5247201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string expected_push_result("pushed"); 5248201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<DeterministicSocketData> data(new DeterministicSocketData( 5249201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 5250201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 5251201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 5252201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 5253201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5254201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 5255201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BoundNetLog(), GetParam()); 5256201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.SetDeterministic(); 5257201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.AddDeterministicData(static_cast<DeterministicSocketData*>(data)); 5258201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.RunPreTestSetup(); 5259201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5260201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpNetworkTransaction* trans = helper.trans(); 5261201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5262201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM, 5263201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // the first HEADERS frame, and the body of the primary stream, but before 5264201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // we've received the final HEADERS for the pushed stream. 5265201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->SetStop(4); 5266201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5267201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Start the transaction. 5268201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TestCompletionCallback callback; 5269201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); 5270201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5271201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->Run(); 5272201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rv = callback.WaitForResult(); 5273201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(0, rv); 5274201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5275201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Request the pushed path. At this point, we've received the push, but the 5276201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // headers are not yet complete. 5277201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<HttpNetworkTransaction> trans2( 5278201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new HttpNetworkTransaction(helper.session())); 5279201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rv = trans2->Start(&CreateGetPushRequest(), &callback, BoundNetLog()); 5280201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5281201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->RunFor(3); 5282201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MessageLoop::current()->RunAllPending(); 5283201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5284201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Read the server push body. 5285201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string result2; 5286201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ReadResult(trans2.get(), data, &result2); 5287201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Read the response body. 5288201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string result; 5289201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ReadResult(trans, data, &result); 5290201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5291201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify that we consumed all test data. 5292201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(data->at_read_eof()); 5293201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(data->at_write_eof()); 5294201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5295201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify that the received push data is same as the expected push data. 5296201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(result2.compare(expected_push_result), 0) 5297201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << "Received data: " 5298201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << result2 5299201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << "||||| Expected data: " 5300201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << expected_push_result; 5301201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5302201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5303201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Copy the response info, because trans goes away. 5304201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch response = *trans->GetResponseInfo(); 5305201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch response2 = *trans2->GetResponseInfo(); 5306201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5307201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch VerifyStreamsClosed(helper); 5308201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5309201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5310201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response.headers != NULL); 5311201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 5312201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5313201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the pushed stream. 5314201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers != NULL); 5315201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 5316201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5317201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify we got all the headers 5318201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue( 5319201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "url", 5320201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.dat")); 5321201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue("hello", "bye")); 5322201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue("status", "200")); 5323201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue("version", "HTTP/1.1")); 5324201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5325201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5326201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, SynReplyWithHeaders) { 5327201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 5328201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 5329201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5330201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kInitialHeaders[] = { 5331201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5332201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200 OK", 5333201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 5334201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 5335201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5336201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kLateHeaders[] = { 5337201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "hello", 5338201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "bye", 5339201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5340201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5341201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyControlFrame(kInitialHeaders, 5342201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kInitialHeaders) / 2, 5343201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5344201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5345201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5346201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_REPLY, 5347201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5348201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5349201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5350201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5351201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5352201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_headers(ConstructSpdyControlFrame(kLateHeaders, 5353201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kLateHeaders) / 2, 5354201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5355201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5356201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5357201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5358201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5359201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5360201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5361201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5362201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, true)); 5363201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5364201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply), 5365201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_headers), 5366201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body), 5367201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, 0, 0) // EOF 5368201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5369201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5370201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<DelayedSocketData> data( 5371201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new DelayedSocketData(1, reads, arraysize(reads), 5372201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, arraysize(writes))); 5373201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 5374201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BoundNetLog(), GetParam()); 5375201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.RunToCompletion(data.get()); 5376201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TransactionHelperResult out = helper.output(); 5377201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(OK, out.rv); 5378201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 5379201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("hello!", out.response_data); 5380201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5381201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5382201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, SynReplyWithLateHeaders) { 5383201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 5384201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 5385201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5386201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kInitialHeaders[] = { 5387201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5388201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200 OK", 5389201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 5390201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 5391201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5392201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kLateHeaders[] = { 5393201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "hello", 5394201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "bye", 5395201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5396201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5397201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyControlFrame(kInitialHeaders, 5398201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kInitialHeaders) / 2, 5399201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5400201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5401201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5402201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_REPLY, 5403201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5404201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5405201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5406201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5407201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5408201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_headers(ConstructSpdyControlFrame(kLateHeaders, 5409201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kLateHeaders) / 2, 5410201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5411201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5412201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5413201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5414201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5415201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5416201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5417201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5418201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, false)); 5419201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> stream1_body2(ConstructSpdyBodyFrame(1, true)); 5420201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5421201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply), 5422201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body), 5423201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_headers), 5424201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body2), 5425201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, 0, 0) // EOF 5426201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5427201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5428201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<DelayedSocketData> data( 5429201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new DelayedSocketData(1, reads, arraysize(reads), 5430201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, arraysize(writes))); 5431201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 5432201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BoundNetLog(), GetParam()); 5433201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.RunToCompletion(data.get()); 5434201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TransactionHelperResult out = helper.output(); 5435201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(OK, out.rv); 5436201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 5437201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("hello!hello!", out.response_data); 5438201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5439201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5440201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, SynReplyWithDuplicateLateHeaders) { 5441201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); 5442201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 5443201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5444201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kInitialHeaders[] = { 5445201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5446201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "200 OK", 5447201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "version", 5448201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "HTTP/1.1" 5449201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5450201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kLateHeaders[] = { 5451201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "status", 5452201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "500 Server Error", 5453201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5454201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5455201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyControlFrame(kInitialHeaders, 5456201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kInitialHeaders) / 2, 5457201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5458201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5459201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5460201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SYN_REPLY, 5461201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5462201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5463201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5464201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5465201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5466201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_headers(ConstructSpdyControlFrame(kLateHeaders, 5467201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kLateHeaders) / 2, 5468201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch false, 5469201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5470201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOWEST, 5471201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::HEADERS, 5472201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::CONTROL_FLAG_NONE, 5473201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL, 5474201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5475201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0)); 5476201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> stream1_body(ConstructSpdyBodyFrame(1, false)); 5477201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> stream1_body2(ConstructSpdyBodyFrame(1, true)); 5478201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5479201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply), 5480201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body), 5481201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_headers), 5482201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body2), 5483201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, 0, 0) // EOF 5484201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5485201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5486201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<DelayedSocketData> data( 5487201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new DelayedSocketData(1, reads, arraysize(reads), 5488201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, arraysize(writes))); 5489201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), 5490201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BoundNetLog(), GetParam()); 5491201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.RunToCompletion(data.get()); 5492201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TransactionHelperResult out = helper.output(); 5493201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 5494201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5495201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5496201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) { 5497201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // In this test we want to verify that we can't accidentally push content 5498201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // which can't be pushed by this content server. 5499201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // This test assumes that: 5500201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // - if we're requesting http://www.foo.com/barbaz 5501201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // - the browser has made a connection to "www.foo.com". 5502201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5503201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // A list of the URL to fetch, followed by the URL being pushed. 5504201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const char* const kTestCases[] = { 5505201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.html", 5506201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com:81/foo.js", // Bad port 5507201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5508201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.html", 5509201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "https://www.google.com/foo.js", // Bad protocol 5510201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5511201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.html", 5512201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "ftp://www.google.com/foo.js", // Invalid Protocol 5513201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5514201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.html", 5515201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://blat.www.google.com/foo.js", // Cross subdomain 5516201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5517201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.google.com/foo.html", 5518201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://www.foo.com/foo.js", // Cross domain 5519201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5520201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5521201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5522201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const unsigned char kPushBodyFrame[] = { 5523201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x00, 0x00, 0x00, 0x02, // header, ID 5524201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0x01, 0x00, 0x00, 0x06, // FIN, length 5525201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 5526201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5527201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5528201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (size_t index = 0; index < arraysize(kTestCases); index += 2) { 5529201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* url_to_fetch = kTestCases[index]; 5530201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* url_to_push = kTestCases[index + 1]; 5531201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5532201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5533201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_syn(ConstructSpdyGet(url_to_fetch, false, 1, LOWEST)); 5534201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5535201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_body(ConstructSpdyBodyFrame(1, true)); 5536201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> push_rst( 5537201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ConstructSpdyRstStream(2, spdy::REFUSED_STREAM)); 5538201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockWrite writes[] = { 5539201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockWrite(*stream1_syn, 1), 5540201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockWrite(*push_rst, 4), 5541201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5542201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5543201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5544201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); 5545201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> 5546201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch stream2_syn(ConstructSpdyPush(NULL, 5547201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 0, 5548201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2, 5549201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1, 5550201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch url_to_push)); 5551201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<spdy::SpdyFrame> rst( 5552201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ConstructSpdyRstStream(2, spdy::CANCEL)); 5553201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5554201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead reads[] = { 5555201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_reply, 2), 5556201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream2_syn, 3), 5557201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateMockRead(*stream1_body, 5, false), 5558201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame), 5559201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(kPushBodyFrame), 6), 5560201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MockRead(true, ERR_IO_PENDING, 7), // Force a pause 5561201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 5562201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5563201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpResponseInfo response; 5564201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_refptr<OrderedSocketData> data(new OrderedSocketData( 5565201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reads, 5566201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(reads), 5567201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch writes, 5568201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch arraysize(writes))); 5569201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5570201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpRequestInfo request; 5571201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch request.method = "GET"; 5572201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch request.url = GURL(url_to_fetch); 5573201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch request.load_flags = 0; 5574201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalSpdyTransactionHelper helper(request, 5575201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BoundNetLog(), GetParam()); 5576201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.RunPreTestSetup(); 5577201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch helper.AddData(data); 5578201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5579201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HttpNetworkTransaction* trans = helper.trans(); 5580201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5581201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Start the transaction with basic parameters. 5582201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TestCompletionCallback callback; 5583201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5584201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int rv = trans->Start(&request, &callback, BoundNetLog()); 5585201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5586201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rv = callback.WaitForResult(); 5587201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5588201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Read the response body. 5589201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string result; 5590201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ReadResult(trans, data, &result); 5591201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5592201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify that we consumed all test data. 5593201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(data->at_read_eof()); 5594201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(data->at_write_eof()); 5595201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5596201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5597201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Copy the response info, because trans goes away. 5598201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch response = *trans->GetResponseInfo(); 5599201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5600201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch VerifyStreamsClosed(helper); 5601201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5602201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Verify the SYN_REPLY. 5603201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_TRUE(response.headers != NULL); 5604201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 5605201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 5606201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 5607201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace net 5609