spdy_network_transaction_unittest.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h" 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/run_loop.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/stl_util.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/auth.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log_unittest.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/request_priority.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_bytes_element_reader.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/upload_data_stream.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_file_element_reader.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session_peer.h" 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/http/http_network_transaction.h" 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/http/http_server_properties.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_transaction_unittest.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_pool_base.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/next_proto.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/buffered_spdy_framer.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_http_stream.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_http_utils.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session_pool.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_test_util_common.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_test_utils.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_test_util.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//----------------------------------------------------------------------------- 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kRequestUrl[] = "http://www.google.com/"; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)enum SpdyNetworkTransactionTestSSLType { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDYNPN, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDYNOSSL, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDYSSL, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)struct SpdyNetworkTransactionTestParams { 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams() 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : protocol(kProtoSPDY3), 537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ssl_type(SPDYNPN) {} 547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams( 567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NextProto protocol, 577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestSSLType ssl_type) 587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : protocol(protocol), 597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ssl_type(ssl_type) {} 607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NextProto protocol; 627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestSSLType ssl_type; 637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}; 647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SpdySessionDependencies* CreateSpdySessionDependencies( 667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams test_params) { 677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return new SpdySessionDependencies(test_params.protocol); 687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SpdySessionDependencies* CreateSpdySessionDependencies( 717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams test_params, 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProxyService* proxy_service) { 737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return new SpdySessionDependencies(test_params.protocol, proxy_service); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace 777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class SpdyNetworkTransactionTest 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : public ::testing::TestWithParam<SpdyNetworkTransactionTestParams> { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTest() : spdy_util_(GetParam().protocol) { 82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual ~SpdyNetworkTransactionTest() { 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // UploadDataStream posts deletion tasks back to the message loop on 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // destruction. 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) upload_data_stream_.reset(); 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_request_initialized_ = false; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_post_request_initialized_ = false; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_chunked_post_request_initialized_ = false; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct TransactionHelperResult { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string status_line; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_data; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponseInfo response_info; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A helper class that handles all the initial npn/ssl setup. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class NormalSpdyTransactionHelper { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NormalSpdyTransactionHelper(const HttpRequestInfo& request, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RequestPriority priority, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& log, 1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams test_params, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdySessionDependencies* session_deps) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : request_(request), 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_(priority), 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_deps_(session_deps == NULL ? 1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CreateSpdySessionDependencies(test_params) : 1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session_deps), 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_(SpdySessionDependencies::SpdyCreateSession( 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.get())), 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_(log), 1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_params_(test_params), 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deterministic_(false), 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_enabled_(true) { 1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) switch (test_params_.ssl_type) { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SPDYNOSSL: 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SPDYSSL: 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) port_ = 80; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SPDYNPN: 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) port_ = 443; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~NormalSpdyTransactionHelper() { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Any test which doesn't close the socket by sending it an EOF will 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have a valid session left open, which leaks the entire session pool. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is just fine - in fact, some of our tests intentionally do this 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so that we can check consistency of the SpdySessionPool as the test 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // finishes. If we had put an EOF on the socket, the SpdySession would 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have closed and we wouldn't be able to check the consistency. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Forcefully close existing sessions here. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session()->spdy_session_pool()->CloseAllSessions(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetDeterministic() { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic( 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_deps_.get()); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deterministic_ = true; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetSpdyDisabled() { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_enabled_ = false; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) port_ = 80; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunPreTestSetup() { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!session_deps_.get()) 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session_deps_.reset(CreateSpdySessionDependencies(test_params_)); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!session_.get()) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ = SpdySessionDependencies::SpdyCreateSession( 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_deps_.get()); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpStreamFactory::set_use_alternate_protocols(false); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpStreamFactory::set_force_spdy_over_ssl(false); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpStreamFactory::set_force_spdy_always(false); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 170ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::vector<NextProto> next_protos = SpdyNextProtos(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) switch (test_params_.ssl_type) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SPDYNPN: 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->http_server_properties()->SetAlternateProtocol( 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostPortPair("www.google.com", 80), 443, 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AlternateProtocolFromNextProto(test_params_.protocol)); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpStreamFactory::set_use_alternate_protocols(true); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpStreamFactory::SetNextProtos(next_protos); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SPDYNOSSL: 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpStreamFactory::set_force_spdy_over_ssl(false); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpStreamFactory::set_force_spdy_always(true); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SPDYSSL: 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpStreamFactory::set_force_spdy_over_ssl(true); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpStreamFactory::set_force_spdy_always(true); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're now ready to use SSL-npn SPDY. 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) trans_.reset(new HttpNetworkTransaction(priority_, session_.get())); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the transaction, read some data, finish. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunDefaultTest() { 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!StartDefaultTest()) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FinishDefaultTest(); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool StartDefaultTest() { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_.rv = trans_->Start(&request_, callback.callback(), log_); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We expect an IO Pending or some sort of error. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(output_.rv, 0); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return output_.rv == ERR_IO_PENDING; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void FinishDefaultTest() { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_.rv = callback.WaitForResult(); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (output_.rv != OK) { 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_->spdy_session_pool()->CloseCurrentSessions(net::ERR_ABORTED); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify responses. 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response = trans_->GetResponseInfo(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(response != NULL); 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_TRUE(response->headers.get() != NULL); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(spdy_enabled_, response->was_fetched_via_spdy); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (HttpStreamFactory::spdy_enabled()) { 225558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_EQ( 226558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch HttpResponseInfo::ConnectionInfoFromNextProto( 227558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch test_params_.protocol), 228558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch response->connection_info); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1, 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response->connection_info); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (test_params_.ssl_type == SPDYNPN && spdy_enabled_) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response->was_npn_negotiated); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(!response->was_npn_negotiated); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If SPDY is not enabled, a HTTP request should not be diverted 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // over a SSL session. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!spdy_enabled_) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(request_.url.SchemeIs("https"), 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->was_npn_negotiated); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ("127.0.0.1", response->socket_address.host()); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(port_, response->socket_address.port()); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_.status_line = response->headers->GetStatusLine(); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_.response_info = *response; // Make a copy so we can verify. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_.rv = ReadTransaction(trans_.get(), &output_.response_data); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Most tests will want to call this function. In particular, the MockReads 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should end with an empty read, and that read needs to be processed to 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ensure proper deletion of the spdy_session_pool. 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void VerifyDataConsumed() { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (DataVector::iterator it = data_vector_.begin(); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != data_vector_.end(); ++it) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE((*it)->at_read_eof()) << "Read count: " 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (*it)->read_count() 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " Read index: " 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (*it)->read_index(); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE((*it)->at_write_eof()) << "Write count: " 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (*it)->write_count() 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " Write index: " 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (*it)->write_index(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Occasionally a test will expect to error out before certain reads are 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // processed. In that case we want to explicitly ensure that the reads were 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not processed. 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void VerifyDataNotConsumed() { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (DataVector::iterator it = data_vector_.begin(); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != data_vector_.end(); ++it) { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(!(*it)->at_read_eof()) << "Read count: " 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (*it)->read_count() 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " Read index: " 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (*it)->read_index(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(!(*it)->at_write_eof()) << "Write count: " 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (*it)->write_count() 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " Write index: " 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (*it)->write_index(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunToCompletion(StaticSocketDataProvider* data) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunPreTestSetup(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddData(data); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunDefaultTest(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VerifyDataConsumed(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddData(StaticSocketDataProvider* data) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!deterministic_); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_vector_.push_back(data); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider* ssl_provider = 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SSLSocketDataProvider(ASYNC, OK); 2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (test_params_.ssl_type == SPDYNPN) 2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ssl_provider->SetNextProto(test_params_.protocol); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_vector_.push_back(ssl_provider); 3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (test_params_.ssl_type == SPDYNPN || test_params_.ssl_type == SPDYSSL) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_deps_->socket_factory->AddSSLSocketDataProvider(ssl_provider); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_deps_->socket_factory->AddSocketDataProvider(data); 3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (test_params_.ssl_type == SPDYNPN) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StaticSocketDataProvider* hanging_non_alternate_protocol_socket = 3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new StaticSocketDataProvider(NULL, 0, NULL, 0); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hanging_non_alternate_protocol_socket->set_connect_data( 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) never_finishing_connect); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_deps_->socket_factory->AddSocketDataProvider( 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hanging_non_alternate_protocol_socket); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alternate_vector_.push_back(hanging_non_alternate_protocol_socket); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddDeterministicData(DeterministicSocketData* data) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(deterministic_); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_vector_.push_back(data); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider* ssl_provider = 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SSLSocketDataProvider(ASYNC, OK); 3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (test_params_.ssl_type == SPDYNPN) 3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ssl_provider->SetNextProto(test_params_.protocol); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_vector_.push_back(ssl_provider); 3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (test_params_.ssl_type == SPDYNPN || 3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_params_.ssl_type == SPDYSSL) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_deps_->deterministic_socket_factory-> 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddSSLSocketDataProvider(ssl_provider); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_deps_->deterministic_socket_factory->AddSocketDataProvider(data); 3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (test_params_.ssl_type == SPDYNPN) { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeterministicSocketData* hanging_non_alternate_protocol_socket = 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new DeterministicSocketData(NULL, 0, NULL, 0); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hanging_non_alternate_protocol_socket->set_connect_data( 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) never_finishing_connect); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_deps_->deterministic_socket_factory->AddSocketDataProvider( 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hanging_non_alternate_protocol_socket); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alternate_deterministic_vector_.push_back( 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hanging_non_alternate_protocol_socket); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetSession(const scoped_refptr<HttpNetworkSession>& session) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ = session; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans() { return trans_.get(); } 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetTrans() { trans_.reset(); } 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult& output() { return output_; } 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestInfo& request() const { return request_; } 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<HttpNetworkSession>& session() const { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return session_; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdySessionDependencies>& session_deps() { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return session_deps_; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port() const { return port_; } 3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams test_params() const { 3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return test_params_; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<StaticSocketDataProvider*> DataVector; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef ScopedVector<SSLSocketDataProvider> SSLVector; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef ScopedVector<StaticSocketDataProvider> AlternateVector; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef ScopedVector<DeterministicSocketData> AlternateDeterministicVector; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo request_; 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RequestPriority priority_; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdySessionDependencies> session_deps_; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<HttpNetworkSession> session_; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult output_; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<StaticSocketDataProvider> first_transaction_; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLVector ssl_vector_; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans_; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans_http_; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataVector data_vector_; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AlternateVector alternate_vector_; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AlternateDeterministicVector alternate_deterministic_vector_; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& log_; 3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams test_params_; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port_; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool deterministic_; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool spdy_enabled_; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ConnectStatusHelperWithExpectedStatus(const MockRead& status, 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int expected_status); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ConnectStatusHelper(const MockRead& status); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestInfo& CreateGetPushRequest() { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_push_request_.method = "GET"; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_push_request_.url = GURL("http://www.google.com/foo.dat"); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_push_request_.load_flags = 0; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return google_get_push_request_; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestInfo& CreateGetRequest() { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!google_get_request_initialized_) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_request_.method = "GET"; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_request_.url = GURL(kDefaultURL); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_request_.load_flags = 0; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_request_initialized_ = true; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return google_get_request_; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestInfo& CreateGetRequestWithUserAgent() { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!google_get_request_initialized_) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_request_.method = "GET"; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_request_.url = GURL(kDefaultURL); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_request_.load_flags = 0; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_request_.extra_headers.SetHeader("User-Agent", "Chrome"); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_get_request_initialized_ = true; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return google_get_request_; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestInfo& CreatePostRequest() { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!google_post_request_initialized_) { 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedVector<UploadElementReader> element_readers; 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) element_readers.push_back( 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new UploadBytesElementReader(kUploadData, kUploadDataSize)); 42668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) upload_data_stream_.reset( 42768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) new UploadDataStream(element_readers.Pass(), 0)); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_post_request_.method = "POST"; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_post_request_.url = GURL(kDefaultURL); 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) google_post_request_.upload_data_stream = upload_data_stream_.get(); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_post_request_initialized_ = true; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return google_post_request_; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestInfo& CreateFilePostRequest() { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!google_post_request_initialized_) { 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file_path; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(file_util::CreateTemporaryFileInDir(temp_dir_.path(), &file_path)); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(static_cast<int>(kUploadDataSize), 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::WriteFile(file_path, kUploadData, kUploadDataSize)); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedVector<UploadElementReader> element_readers; 4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) element_readers.push_back( 4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new UploadFileElementReader(base::MessageLoopProxy::current().get(), 4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) file_path, 4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 0, 4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kUploadDataSize, 4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Time())); 45168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) upload_data_stream_.reset( 45268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) new UploadDataStream(element_readers.Pass(), 0)); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_post_request_.method = "POST"; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_post_request_.url = GURL(kDefaultURL); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) google_post_request_.upload_data_stream = upload_data_stream_.get(); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_post_request_initialized_ = true; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return google_post_request_; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestInfo& CreateComplexPostRequest() { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!google_post_request_initialized_) { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kFileRangeOffset = 1; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kFileRangeLength = 3; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_LT(kFileRangeOffset + kFileRangeLength, kUploadDataSize); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file_path; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(file_util::CreateTemporaryFileInDir(temp_dir_.path(), &file_path)); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(static_cast<int>(kUploadDataSize), 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::WriteFile(file_path, kUploadData, kUploadDataSize)); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedVector<UploadElementReader> element_readers; 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) element_readers.push_back( 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new UploadBytesElementReader(kUploadData, kFileRangeOffset)); 4767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) element_readers.push_back( 4777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new UploadFileElementReader(base::MessageLoopProxy::current().get(), 4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) file_path, 4797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kFileRangeOffset, 4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kFileRangeLength, 4817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Time())); 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) element_readers.push_back(new UploadBytesElementReader( 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kUploadData + kFileRangeOffset + kFileRangeLength, 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kUploadDataSize - (kFileRangeOffset + kFileRangeLength))); 48568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) upload_data_stream_.reset( 48668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) new UploadDataStream(element_readers.Pass(), 0)); 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_post_request_.method = "POST"; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_post_request_.url = GURL(kDefaultURL); 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) google_post_request_.upload_data_stream = upload_data_stream_.get(); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_post_request_initialized_ = true; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return google_post_request_; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestInfo& CreateChunkedPostRequest() { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!google_chunked_post_request_initialized_) { 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_data_stream_.reset( 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new UploadDataStream(UploadDataStream::CHUNKED, 0)); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_chunked_post_request_.method = "POST"; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_chunked_post_request_.url = GURL(kDefaultURL); 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) google_chunked_post_request_.upload_data_stream = 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_data_stream_.get(); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google_chunked_post_request_initialized_ = true; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return google_chunked_post_request_; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read the result of a particular transaction, knowing that we've got 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // multiple transactions in the read pipeline; so as we read, we may have 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to skip over data destined for other transactions while we consume 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the data for |trans|. 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ReadResult(HttpNetworkTransaction* trans, 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StaticSocketDataProvider* data, 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* result) { 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kSize = 3000; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read = 0; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(kSize)); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int rv = trans->Read(buf.get(), kSize, callback.callback()); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) { 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Multiple transactions may be in the data set. Keep pulling off 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reads until we complete our callback. 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!callback.have_result()) { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->CompleteRead(); 5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (rv <= 0) { 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->append(buf->data(), rv); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_read += rv; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes_read; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void VerifyStreamsClosed(const NormalSpdyTransactionHelper& helper) { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This lengthy block is reaching into the pool to dig out the active 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // session. Once we have the session, we verify that the streams are 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // all closed and not leaked at this point. 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url = helper.request().url; 5457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int port = helper.test_params().ssl_type == SPDYNPN ? 443 : 80; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostPortPair host_port_pair(url.host(), port); 54790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdySessionKey key(host_port_pair, ProxyServer::Direct(), 54890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kPrivacyModeDisabled); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog log; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<HttpNetworkSession>& session = helper.session(); 551ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> spdy_session = 5527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->spdy_session_pool()->FindAvailableSession(key, log); 5537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_TRUE(spdy_session != NULL); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, spdy_session->num_active_streams()); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams()); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunServerPushTest(OrderedSocketData* data, 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponseInfo* response, 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponseInfo* push_response, 561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& expected) { 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(data); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the transaction with basic parameters. 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start( 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateGetRequest(), callback.callback(), BoundNetLog()); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Request the pushed path. 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans2( 578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = trans2->Start( 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateGetPushRequest(), callback.callback(), BoundNetLog()); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 5823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // The data for the pushed path may be coming in more than 1 frame. Compile 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the results into a single string. 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read the server push body. 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string result2; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadResult(trans2.get(), data, &result2); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read the response body. 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string result; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadResult(trans, data, &result); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that we consumed all test data. 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(data->at_read_eof()); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(data->at_write_eof()); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that the received push data is same as the expected push data. 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(result2.compare(expected), 0) << "Received data: " 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << result2 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "||||| Expected data: " 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << expected; 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify the SYN_REPLY. 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy the response info, because trans goes away. 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *response = *trans->GetResponseInfo(); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *push_response = *trans2->GetResponseInfo(); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VerifyStreamsClosed(helper); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void DeleteSessionCallback(NormalSpdyTransactionHelper* helper, 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result) { 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper->ResetTrans(); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void StartTransactionCallback( 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<HttpNetworkSession>& session, 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result) { 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans( 621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo request; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.method = "GET"; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.url = GURL("http://www.google.com/"); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.load_flags = 0; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 632b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SpdyTestUtil spdy_util_; 633b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadDataStream> upload_data_stream_; 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool google_get_request_initialized_; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool google_post_request_initialized_; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool google_chunked_post_request_initialized_; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo google_get_request_; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo google_post_request_; 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo google_chunked_post_request_; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo google_get_push_request_; 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ScopedTempDir temp_dir_; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//----------------------------------------------------------------------------- 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All tests are run with three different connection types: SPDY after NPN 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// negotiation, SPDY without SSL, and SPDY with SSL. 6497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// 6507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// TODO(akalin): Use ::testing::Combine() when we are able to use 6517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// <tr1/tuple>. 6527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)INSTANTIATE_TEST_CASE_P( 6537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Spdy, 6547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTest, 6557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ::testing::Values( 6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2, SPDYNOSSL), 6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2, SPDYSSL), 6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2, SPDYNPN), 6597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYNOSSL), 6607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYSSL), 6617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYNPN), 6627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYNOSSL), 6637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYSSL), 6647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYNPN), 6657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams(kProtoSPDY4a2, SPDYNOSSL), 6667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyNetworkTransactionTestParams(kProtoSPDY4a2, SPDYSSL), 667558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SpdyNetworkTransactionTestParams(kProtoSPDY4a2, SPDYNPN), 668558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SpdyNetworkTransactionTestParams(kProtoHTTP2Draft04, SPDYNOSSL), 669558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SpdyNetworkTransactionTestParams(kProtoHTTP2Draft04, SPDYSSL), 670558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SpdyNetworkTransactionTestParams(kProtoHTTP2Draft04, SPDYNPN))); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify HttpNetworkTransaction constructor. 6737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, Constructor) { 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdySessionDependencies> session_deps( 6757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CreateSpdySessionDependencies(GetParam())); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<HttpNetworkSession> session( 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdySessionDependencies::SpdyCreateSession(session_deps.get())); 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<HttpTransaction> trans( 679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, Get) { 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the request. 68490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 68590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req) }; 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 6897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) { 7088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (RequestPriority p = MINIMUM_PRIORITY; p <= MAXIMUM_PRIORITY; 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = RequestPriority(p + 1)) { 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the request. 71190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 71290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, p, true)); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req) }; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdyPriority spdy_prio = 0; 7167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_TRUE(GetSpdyPriority(spdy_util_.spdy_version(), *req, &spdy_prio)); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this repeats the RequestPriority-->SpdyPriority mapping from 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SpdyFramer::ConvertRequestPriorityToSpdyPriority to make 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sure it's being done right. 7207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (spdy_util_.spdy_version() < SPDY3) { 7217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) switch(p) { 7227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case HIGHEST: 7237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(0, spdy_prio); 7247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 7257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case MEDIUM: 7267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(1, spdy_prio); 7277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 7287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case LOW: 7297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case LOWEST: 7307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(2, spdy_prio); 7317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 7327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case IDLE: 7337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(3, spdy_prio); 7347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 7357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) default: 7367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) FAIL(); 7377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 7387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } else { 7397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) switch(p) { 7407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case HIGHEST: 7417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(0, spdy_prio); 7427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 7437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case MEDIUM: 7447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(1, spdy_prio); 7457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 7467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case LOW: 7477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(2, spdy_prio); 7487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 7497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case LOWEST: 7507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(3, spdy_prio); 7517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 7527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case IDLE: 7537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(4, spdy_prio); 7547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 7557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) default: 7567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) FAIL(); 7577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 7617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo http_req = CreateGetRequest(); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(http_req, p, BoundNetLog(), 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetParam(), NULL); 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Start three gets simultaniously; making sure that multiplexed 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// streams work properly. 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This can't use the TransactionHelper method, since it only 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// handles a single transaction, and finishes them as soon 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as it launches them. 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(gavinp): create a working generalized TransactionHelper that 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can allow multiple streams in flight. 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, ThreeGets) { 79390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 79490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 7957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 7967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 7977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true)); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 80090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 8017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 8027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false)); 8037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req3( 80690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true)); 8077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5)); 8087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, false)); 8097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(5, true)); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req), 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req2), 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req3), 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp, 1), 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp2, 4), 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body2), 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp3, 7), 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body3), 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody), 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody2), 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody3), 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0), // EOF 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data_placeholder(NULL, 0, NULL, 0); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog log; 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out; 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We require placeholder data because three get requests are sent out, so 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there needs to be three sets of SSL connection data. 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans1( 845868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans2( 847868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans3( 849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback1; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback2; 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback3; 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq1 = CreateGetRequest(); 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq2 = CreateGetRequest(); 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq3 = CreateGetRequest(); 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans1->Start(&httpreq1, callback1.callback(), log); 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, out.rv); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans2->Start(&httpreq2, callback2.callback(), log); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, out.rv); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans3->Start(&httpreq3, callback3.callback(), log); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, out.rv); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback1.WaitForResult(); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback3.WaitForResult(); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 872868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response1->headers.get() != NULL); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response1->was_fetched_via_spdy); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response1->headers->GetStatusLine(); 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response1; 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans2->GetResponseInfo(); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans1.get(), &out.response_data); 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) { 88990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 89090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 8917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 8927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 8937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true)); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 89590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 89690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 8977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 8987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false)); 8997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req), 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req2), 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp, 1), 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp2, 4), 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body2), 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody), 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody2), 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0), // EOF 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data_placeholder(NULL, 0, NULL, 0); 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_placeholder.set_connect_data(never_finishing_connect); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog log; 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out; 9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We require placeholder data because two get requests are sent out, so 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there needs to be two sets of SSL connection data. 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans1( 932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans2( 934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback1; 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback2; 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq1 = CreateGetRequest(); 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq2 = CreateGetRequest(); 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans1->Start(&httpreq1, callback1.callback(), log); 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, out.rv); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans2->Start(&httpreq2, callback2.callback(), log); 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, out.rv); 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback1.WaitForResult(); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback2.WaitForResult(); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response1->headers.get() != NULL); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response1->was_fetched_via_spdy); 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response1->headers->GetStatusLine(); 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response1; 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans1.get(), &out.response_data); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 963868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response2->headers.get() != NULL); 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response2->was_fetched_via_spdy); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response2->headers->GetStatusLine(); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response2; 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans2.get(), &out.response_data); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) { 97690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 97790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 9787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 9797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 9807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true)); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 98290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 98390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 9847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 9857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false)); 9867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req), 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req2), 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp, 1), 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp2, 4), 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body2), 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody), 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody2), 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0), // EOF 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData preconnect_data(reads, arraysize(reads), 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect never_finishing_connect(ASYNC, ERR_IO_PENDING); 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data_placeholder(NULL, 0, NULL, 0); 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_placeholder.set_connect_data(never_finishing_connect); 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog log; 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out; 10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&preconnect_data); 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We require placeholder data because 3 connections are attempted (first is 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the preconnect, 2nd and 3rd are the never finished connections. 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans1( 1021868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans2( 1023868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback1; 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback2; 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq = CreateGetRequest(); 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Preconnect the first. 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLConfig preconnect_ssl_config; 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config); 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpStreamFactory* http_stream_factory = 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.session()->http_stream_factory(); 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (http_stream_factory->has_next_protos()) { 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preconnect_ssl_config.next_protos = http_stream_factory->next_protos(); 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_stream_factory->PreconnectStreams( 10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1, httpreq, DEFAULT_PRIORITY, 10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preconnect_ssl_config, preconnect_ssl_config); 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans1->Start(&httpreq, callback1.callback(), log); 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, out.rv); 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans2->Start(&httpreq, callback2.callback(), log); 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, out.rv); 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback1.WaitForResult(); 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback2.WaitForResult(); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 1054868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response1->headers.get() != NULL); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response1->was_fetched_via_spdy); 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response1->headers->GetStatusLine(); 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response1; 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans1.get(), &out.response_data); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 1064868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response2->headers.get() != NULL); 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response2->was_fetched_via_spdy); 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response2->headers->GetStatusLine(); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response2; 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans2.get(), &out.response_data); 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to ThreeGets above, however this test adds a SETTINGS 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// frame. The SETTINGS frame is read during the IO loop waiting on 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the first transaction completion, and sets a maximum concurrent 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stream limit of 1. This means that our IO loop exists after the 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// second transaction completes, so we can assert on read_index(). 10817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) { 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the request. 108390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 108490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 10857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 10867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 10877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true)); 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 108990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 109090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 10917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 10927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false)); 10937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 109590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req3( 109690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true)); 10977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5)); 10987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, false)); 10997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(5, true)); 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsMap settings; 11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const uint32 max_concurrent_streams = 1; 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings[SETTINGS_MAX_CONCURRENT_STREAMS] = 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); 110590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> settings_frame( 110690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdySettings(settings)); 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req), 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req2), 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req3), 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*settings_frame, 1), 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody), 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp2, 7), 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body2), 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody2), 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp3, 12), 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body3), 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody3), 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0), // EOF 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data_placeholder(NULL, 0, NULL, 0); 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog log; 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out; 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We require placeholder data because three get requests are sent out, so 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there needs to be three sets of SSL connection data. 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans1( 1145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans2( 1147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans3( 1149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback1; 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback2; 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback3; 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq1 = CreateGetRequest(); 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq2 = CreateGetRequest(); 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq3 = CreateGetRequest(); 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans1->Start(&httpreq1, callback1.callback(), log); 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(out.rv, ERR_IO_PENDING); 11617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Run transaction 1 through quickly to force a read of our SETTINGS 11627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // frame. 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback1.WaitForResult(); 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans2->Start(&httpreq2, callback2.callback(), log); 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(out.rv, ERR_IO_PENDING); 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans3->Start(&httpreq3, callback3.callback(), log); 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(out.rv, ERR_IO_PENDING); 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback2.WaitForResult(); 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(7U, data.read_index()); // i.e. the third trans was queued 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback3.WaitForResult(); 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(response1 != NULL); 1179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response1->headers.get() != NULL); 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response1->was_fetched_via_spdy); 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response1->headers->GetStatusLine(); 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response1; 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans1.get(), &out.response_data); 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response2->headers->GetStatusLine(); 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response2; 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans2.get(), &out.response_data); 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response3 = trans3->GetResponseInfo(); 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response3->headers->GetStatusLine(); 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response3; 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans3.get(), &out.response_data); 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to ThreeGetsWithMaxConcurrent above, however this test adds 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a fourth transaction. The third and fourth transactions have 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// different data ("hello!" vs "hello!hello!") and because of the 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// user specified priority, we expect to see them inverted in 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the response from the server. 12147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) { 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the request. 121690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 121790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 12187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 12197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 12207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true)); 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 122290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 122390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 12247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 12257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false)); 12267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> req4( 122990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, HIGHEST, true)); 12307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp4(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5)); 12317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody4(spdy_util_.ConstructSpdyBodyFrame(5, true)); 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 123390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req3( 123490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 7, LOWEST, true)); 12357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 7)); 12367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(7, false)); 12377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(7, true)); 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsMap settings; 12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const uint32 max_concurrent_streams = 1; 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings[SETTINGS_MAX_CONCURRENT_STREAMS] = 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); 124390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> settings_frame( 124490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdySettings(settings)); 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req), 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req2), 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req4), 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req3), 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*settings_frame, 1), 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody), 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp2, 7), 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body2), 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody2), 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp4, 13), 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody4), 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp3, 16), 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body3), 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody3), 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0), // EOF 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data_placeholder(NULL, 0, NULL, 0); 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog log; 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out; 12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BoundNetLog(), GetParam(), NULL); 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We require placeholder data because four get requests are sent out, so 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there needs to be four sets of SSL connection data. 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans1( 1284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans2( 1286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans3( 1288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans4( 1290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(HIGHEST, helper.session().get())); 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback1; 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback2; 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback3; 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback4; 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq1 = CreateGetRequest(); 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq2 = CreateGetRequest(); 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq3 = CreateGetRequest(); 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq4 = CreateGetRequest(); 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans1->Start(&httpreq1, callback1.callback(), log); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, out.rv); 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run transaction 1 through quickly to force a read of our SETTINGS frame. 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback1.WaitForResult(); 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans2->Start(&httpreq2, callback2.callback(), log); 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, out.rv); 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans3->Start(&httpreq3, callback3.callback(), log); 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, out.rv); 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans4->Start(&httpreq4, callback4.callback(), log); 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, out.rv); 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback2.WaitForResult(); 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(data.read_index(), 7U); // i.e. the third & fourth trans queued 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback3.WaitForResult(); 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 1323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response1->headers.get() != NULL); 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response1->was_fetched_via_spdy); 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response1->headers->GetStatusLine(); 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response1; 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans1.get(), &out.response_data); 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response2->headers->GetStatusLine(); 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response2; 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans2.get(), &out.response_data); 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notice: response3 gets two hellos, response4 gets one 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // hello, so we know dequeuing priority was respected. 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response3 = trans3->GetResponseInfo(); 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response3->headers->GetStatusLine(); 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response3; 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans3.get(), &out.response_data); 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback4.WaitForResult(); 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response4 = trans4->GetResponseInfo(); 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response4->headers->GetStatusLine(); 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response4; 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans4.get(), &out.response_data); 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data); 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to ThreeGetsMaxConcurrrent above, however, this test 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// deletes a session in the middle of the transaction to insure 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that we properly remove pendingcreatestream objects from 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the spdy_session 13677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) { 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the request. 136990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 137090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 13717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 13727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 13737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true)); 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 137590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 137690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 13777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 13787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false)); 13797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsMap settings; 13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const uint32 max_concurrent_streams = 1; 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings[SETTINGS_MAX_CONCURRENT_STREAMS] = 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); 138590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> settings_frame( 138690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdySettings(settings)); 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req), 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req2), 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*settings_frame, 1), 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody), 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp2, 7), 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body2), 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fbody2), 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0), // EOF 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data_placeholder(NULL, 0, NULL, 0); 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog log; 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out; 14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BoundNetLog(), GetParam(), NULL); 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We require placeholder data because three get requests are sent out, so 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there needs to be three sets of SSL connection data. 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans1( 1417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans2( 1419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans3( 1421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback1; 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback2; 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback3; 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq1 = CreateGetRequest(); 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq2 = CreateGetRequest(); 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq3 = CreateGetRequest(); 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans1->Start(&httpreq1, callback1.callback(), log); 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(out.rv, ERR_IO_PENDING); 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run transaction 1 through quickly to force a read of our SETTINGS frame. 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback1.WaitForResult(); 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans2->Start(&httpreq2, callback2.callback(), log); 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(out.rv, ERR_IO_PENDING); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans3->Start(&httpreq3, callback3.callback(), log); 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete trans3.release(); 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(out.rv, ERR_IO_PENDING); 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback2.WaitForResult(); 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(8U, data.read_index()); 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response1 = trans1->GetResponseInfo(); 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(response1 != NULL); 1449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response1->headers.get() != NULL); 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response1->was_fetched_via_spdy); 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response1->headers->GetStatusLine(); 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response1; 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans1.get(), &out.response_data); 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response2 = trans2->GetResponseInfo(); 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(response2 != NULL); 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response2->headers->GetStatusLine(); 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response2; 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(trans2.get(), &out.response_data); 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!hello!", out.response_data); 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The KillerCallback will delete the transaction on error as part of the 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// callback. 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class KillerCallback : public TestCompletionCallbackBase { 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit KillerCallback(HttpNetworkTransaction* transaction) 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : transaction_(transaction), 1478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback_(base::Bind(&KillerCallback::OnComplete, 1479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))) { 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~KillerCallback() {} 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback() const { return callback_; } 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnComplete(int result) { 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result < 0) 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete transaction_; 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetResult(result); 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* transaction_; 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback callback_; 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to ThreeGetsMaxConcurrrentDelete above, however, this test 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// closes the socket while we have a pending transaction waiting for 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a pending stream creation. http://crbug.com/52901 15037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) { 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the request. 150590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 150690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 15077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 15087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 15097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> fin_body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 151190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 151290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 15137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsMap settings; 15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const uint32 max_concurrent_streams = 1; 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings[SETTINGS_MAX_CONCURRENT_STREAMS] = 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); 151990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> settings_frame( 152090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdySettings(settings)); 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req), 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req2), 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*settings_frame, 1), 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*fin_body), 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp2, 7), 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, ERR_CONNECTION_RESET, 0), // Abort! 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data_placeholder(NULL, 0, NULL, 0); 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog log; 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out; 15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BoundNetLog(), GetParam(), NULL); 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We require placeholder data because three get requests are sent out, so 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there needs to be three sets of SSL connection data. 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data_placeholder); 1548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session().get()); 1549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session().get()); 15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HttpNetworkTransaction* trans3( 1551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback1; 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback2; 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KillerCallback callback3(trans3); 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq1 = CreateGetRequest(); 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq2 = CreateGetRequest(); 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo httpreq3 = CreateGetRequest(); 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans1.Start(&httpreq1, callback1.callback(), log); 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(out.rv, ERR_IO_PENDING); 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run transaction 1 through quickly to force a read of our SETTINGS frame. 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback1.WaitForResult(); 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(OK, out.rv); 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans2.Start(&httpreq2, callback2.callback(), log); 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(out.rv, ERR_IO_PENDING); 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = trans3->Start(&httpreq3, callback3.callback(), log); 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(out.rv, ERR_IO_PENDING); 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback3.WaitForResult(); 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_ABORTED, out.rv); 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(6U, data.read_index()); 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response1 = trans1.GetResponseInfo(); 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(response1 != NULL); 1578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response1->headers.get() != NULL); 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response1->was_fetched_via_spdy); 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response1->headers->GetStatusLine(); 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response1; 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(&trans1, &out.response_data); 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response2 = trans2.GetResponseInfo(); 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(response2 != NULL); 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response2->headers->GetStatusLine(); 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response2; 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = ReadTransaction(&trans2, &out.response_data); 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_RESET, out.rv); 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a simple PUT request works. 15967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, Put) { 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup the request 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo request; 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.method = "PUT"; 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.url = GURL("http://www.google.com/"); 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdyHeaderInfo kSynStartHeader = { 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYN_STREAM, // Kind = Syn 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Stream ID 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Associated stream ID 16067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ConvertRequestPriorityToSpdyPriority( 16077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) LOWEST, spdy_util_.spdy_version()), 16087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kSpdyCredentialSlotUnused, 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTROL_FLAG_FIN, // Control Flags 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, // Compressed 16112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RST_STREAM_INVALID, // Status 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // Data 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Length 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DATA_FLAG_NONE // Data Flags 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 16167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> put_headers( 16177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructPutHeaderBlock("http://www.google.com", 0)); 1618b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyFrame( 16197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kSynStartHeader, put_headers.Pass())); 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 162190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateMockWrite(*req), 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdyHeaderInfo kSynReplyHeader = { 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYN_REPLY, // Kind = SynReply 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Stream ID 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Associated stream ID 16297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ConvertRequestPriorityToSpdyPriority( 16307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) LOWEST, spdy_util_.spdy_version()), 16317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kSpdyCredentialSlotUnused, 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTROL_FLAG_NONE, // Control Flags 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, // Compressed 16342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RST_STREAM_INVALID, // Status 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // Data 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Length 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DATA_FLAG_NONE // Data Flags 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 16397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock()); 16407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (*reply_headers)[spdy_util_.GetStatusKey()] = "200"; 16417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; 16427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (*reply_headers)["content-length"] = "1234"; 1643b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyFrame( 16447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kSynReplyHeader, reply_headers.Pass())); 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a simple HEAD request works. 16637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, Head) { 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup the request 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo request; 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.method = "HEAD"; 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.url = GURL("http://www.google.com/"); 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdyHeaderInfo kSynStartHeader = { 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYN_STREAM, // Kind = Syn 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Stream ID 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Associated stream ID 16737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ConvertRequestPriorityToSpdyPriority( 16747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) LOWEST, spdy_util_.spdy_version()), 16757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kSpdyCredentialSlotUnused, 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTROL_FLAG_FIN, // Control Flags 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, // Compressed 16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RST_STREAM_INVALID, // Status 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // Data 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Length 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DATA_FLAG_NONE // Data Flags 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 16837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> head_headers( 16847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructHeadHeaderBlock("http://www.google.com", 0)); 1685b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyFrame( 16867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kSynStartHeader, head_headers.Pass())); 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 168890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateMockWrite(*req), 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdyHeaderInfo kSynReplyHeader = { 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYN_REPLY, // Kind = SynReply 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Stream ID 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Associated stream ID 16967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ConvertRequestPriorityToSpdyPriority( 16977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) LOWEST, spdy_util_.spdy_version()), 16987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kSpdyCredentialSlotUnused, 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTROL_FLAG_NONE, // Control Flags 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, // Compressed 17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RST_STREAM_INVALID, // Status 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // Data 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Length 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DATA_FLAG_NONE // Data Flags 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 17067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock()); 17077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (*reply_headers)[spdy_util_.GetStatusKey()] = "200"; 17087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; 17097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (*reply_headers)["content-length"] = "1234"; 1710b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyFrame( 1711b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) kSynReplyHeader, 17127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) reply_headers.Pass())); 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a simple POST works. 17317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, Post) { 17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 17337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 17347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0)); 17357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req), 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*body), // POST upload frame 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(2, reads, arraysize(reads), 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 17502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreatePostRequest(), DEFAULT_PRIORITY, 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data); 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a POST with a file works. 17607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, FilePost) { 17612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 17627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 17637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0)); 17647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req), 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*body), // POST upload frame 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(2, reads, arraysize(reads), 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 17792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateFilePostRequest(), DEFAULT_PRIORITY, 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data); 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a complex POST works. 17897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, ComplexPost) { 17902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 17917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 17927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0)); 17937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req), 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*body), // POST upload frame 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(2, reads, arraysize(reads), 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NormalSpdyTransactionHelper helper(CreateComplexPostRequest(), 18092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DEFAULT_PRIORITY, 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data); 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a chunked POST works. 18197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, ChunkedPost) { 18207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); 18217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockWrite(*req), 18242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockWrite(*body), 18252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 18262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*resp), 18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*body), 18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 18322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DelayedSocketData data(2, reads, arraysize(reads), 18352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 18362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateChunkedPostRequest(), 18372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DEFAULT_PRIORITY, 18382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BoundNetLog(), GetParam(), NULL); 18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These chunks get merged into a single frame when being sent. 18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kFirstChunkSize = kUploadDataSize/2; 18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) helper.request().upload_data_stream->AppendChunk( 18432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kUploadData, kFirstChunkSize, false); 18442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) helper.request().upload_data_stream->AppendChunk( 18452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kUploadData + kFirstChunkSize, kUploadDataSize - kFirstChunkSize, true); 18462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) helper.RunToCompletion(&data); 18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransactionHelperResult out = helper.output(); 18492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(OK, out.rv); 18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kUploadData, out.response_data); 18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 18532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that a chunked POST works with chunks appended after transaction starts. 18557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, DelayedChunkedPost) { 18567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); 18577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, false)); 18587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> chunk2(spdy_util_.ConstructSpdyBodyFrame(1, false)); 18597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> chunk3(spdy_util_.ConstructSpdyBodyFrame(1, true)); 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req), 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*chunk1), 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*chunk2), 18642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockWrite(*chunk3), 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*chunk1), 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*chunk2), 18722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*chunk3), 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DelayedSocketData data(4, reads, arraysize(reads), 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NormalSpdyTransactionHelper helper(CreateChunkedPostRequest(), 18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DEFAULT_PRIORITY, 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) helper.request().upload_data_stream->AppendChunk( 18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kUploadData, kUploadDataSize, false); 18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) helper.RunPreTestSetup(); 18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) helper.AddData(&data); 18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(helper.StartDefaultTest()); 18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) helper.request().upload_data_stream->AppendChunk( 18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kUploadData, kUploadDataSize, false); 18923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 18932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) helper.request().upload_data_stream->AppendChunk( 18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kUploadData, kUploadDataSize, true); 18952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) helper.FinishDefaultTest(); 18972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) helper.VerifyDataConsumed(); 18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string expected_response; 19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_response += kUploadData; 19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_response += kUploadData; 19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_response += kUploadData; 19032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_response, out.response_data); 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a POST without any post data works. 19117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, NullPost) { 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup the request 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo request; 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.method = "POST"; 19152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.url = GURL(kRequestUrl); 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create an empty UploadData. 19172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.upload_data_stream = NULL; 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When request.upload_data_stream is NULL for post, content-length is 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // expected to be 0. 19212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 19227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost(kRequestUrl, 1, 0, LOWEST, NULL, 0)); 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the FIN bit since there will be no body. 19247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test::SetFrameFlags(req.get(), CONTROL_FLAG_FIN, spdy_util_.spdy_version()); 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req), 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 19307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data); 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a simple POST works. 19507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, EmptyPost) { 19512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create an empty UploadDataStream. 19522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedVector<UploadElementReader> element_readers; 195368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UploadDataStream stream(element_readers.Pass(), 0); 19542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup the request 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo request; 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.method = "POST"; 19587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) request.url = GURL(kRequestUrl); 19592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.upload_data_stream = &stream; 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint64 kContentLength = 0; 19622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 19637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 19647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kRequestUrl, 1, kContentLength, LOWEST, NULL, 0)); 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the FIN bit since there will be no body. 19667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test::SetFrameFlags(req.get(), CONTROL_FLAG_FIN, spdy_util_.spdy_version()); 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req), 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 19727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), writes, arraysize(writes)); 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data); 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// While we're doing a post, the server sends back a SYN_REPLY. 19917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, PostWithEarlySynReply) { 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char upload[] = { "hello!" }; 19932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedVector<UploadElementReader> element_readers; 19942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) element_readers.push_back( 19952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new UploadBytesElementReader(upload, sizeof(upload))); 199668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UploadDataStream stream(element_readers.Pass(), 0); 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup the request 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo request; 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.method = "POST"; 20017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) request.url = GURL(kRequestUrl); 20022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.upload_data_stream = &stream; 20032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> stream_reply( 20057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*stream_reply, 1), 2008ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 4) // EOF 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 20127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 20137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0)); 20147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 2015ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> rst( 2016ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req, 0), 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*body, 2), 2020ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*rst, 3) 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 20252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreatePostRequest(), DEFAULT_PRIORITY, 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.SetDeterministic(); 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddDeterministicData(&data); 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start( 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreatePostRequest(), callback.callback(), BoundNetLog()); 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2037ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(4); 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv); 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.RunFor(1); 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The client upon cancellation tries to send a RST_STREAM frame. The mock 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// socket causes the TCP write to return zero. This test checks that the client 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tries to queue up the RST_STREAM frame again. 20467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) { 204790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 204890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> rst( 205090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req.get(), 0, SYNCHRONOUS), 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite(SYNCHRONOUS, 0, 0, 2), 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*rst.get(), 3, SYNCHRONOUS), 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp.get(), 1, ASYNC), 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0, 4) // EOF 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 20652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.SetDeterministic(); 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddDeterministicData(&data); 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start( 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateGetRequest(), callback.callback(), BoundNetLog()); 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.SetStop(2); 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.Run(); 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.ResetTrans(); 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.SetStop(20); 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.Run(); 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the transaction doesn't crash when we don't have a reply. 20877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, ResponseWithoutSynReply) { 20887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), NULL, 0); 20952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 2099eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the transaction doesn't crash when we get two replies on the same 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stream ID. See http://crbug.com/45639. 21047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { 210590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 210690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 2108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_STREAM_IN_USE)); 2109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 2110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req), 2111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*rst), 2112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 21157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog()); 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, rv); 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response = trans->GetResponseInfo(); 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(response != NULL); 2141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response->headers.get() != NULL); 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response->was_fetched_via_spdy); 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_data; 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ReadTransaction(trans, &response_data); 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv); 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) { 2151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct the request. 2152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 2153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 2155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 2157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req), 2158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*rst), 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char* const headers[] = { 2162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "transfer-encoding", "chunked" 2163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp( 2165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGetSynReply(headers, 1, 1)); 2166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body( 2167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 2169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp), 2170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body), 2171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0) // EOF 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data(1, reads, arraysize(reads), 2175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 2176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 21772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BoundNetLog(), GetParam(), NULL); 2178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunToCompletion(&data); 2179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransactionHelperResult out = helper.output(); 2180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 21812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.session()->spdy_session_pool()->CloseAllSessions(); 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) { 2187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct the request. 218890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 218990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 2191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req), 2194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*rst), 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char* const headers[] = { 2199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "transfer-encoding", "chunked" 2200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> push( 2202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyPush(headers, arraysize(headers) / 2, 2203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 1, "http://www.google.com/1")); 2204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 2207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*push), 2208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body), 22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 22142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 2216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunToCompletion(&data); 2217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransactionHelperResult out = helper.output(); 2218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, out.rv); 2219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 2220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("hello!", out.response_data); 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.session()->spdy_session_pool()->CloseAllSessions(); 2223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 2224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, CancelledTransaction) { 2227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct the request. 2228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 2229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 2231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req), 2232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 2236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp), 2237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This following read isn't used by the test, except during the 2238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // RunUntilIdle() call at the end since the SpdySession survives the 2239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // HttpNetworkTransaction and still tries to continue Read()'ing. Any 2240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // MockRead will do here. 2241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0) // EOF 2242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), 2245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 2248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 2249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 2250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 2251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 2254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start( 2255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetRequest(), callback.callback(), BoundNetLog()); 2256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 2257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.ResetTrans(); // Cancel the transaction. 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 2260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // MockClientSocketFactory) are still alive. 22613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 2262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataNotConsumed(); 22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Verify that the client sends a Rst Frame upon cancelling the stream. 2266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) { 2267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 2268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> rst( 2270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 2272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 0, SYNCHRONOUS), 2273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*rst, 2, SYNCHRONOUS), 22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 2278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 1, ASYNC), 2279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 3) // EOF 22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 2286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), 2287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetParam(), NULL); 22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.SetDeterministic(); 22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddDeterministicData(&data); 22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start( 2296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetRequest(), callback.callback(), BoundNetLog()); 2297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.SetStop(2); 2300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.Run(); 2301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.ResetTrans(); 2302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.SetStop(20); 2303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.Run(); 23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 2306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Verify that the client can correctly deal with the user callback attempting 2309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// to start another transaction on a session that is closing down. See 2310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// http://crbug.com/47455 2311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { 2312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 2313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 2315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes2[] = { CreateMockWrite(*req) }; 23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The indicated length of this frame is longer than its actual length. When 2318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // the session receives an empty frame after this one, it shuts down the 2319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // session, and calls the read callback with the incomplete data. 2320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint8 kGetBodyFrame2[] = { 2321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0x00, 0x00, 0x00, 0x01, 2322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0x01, 0x00, 0x00, 0x07, 2323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 'h', 'e', 'l', 'l', 'o', '!', 2324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 2328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 2), 2329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 3), // Force a pause 2330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, reinterpret_cast<const char*>(kGetBodyFrame2), 2331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(kGetBodyFrame2), 4), 2332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause 2333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 6), // EOF 2334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads2[] = { 2336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 2), 2337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 3), // EOF 23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(reads, arraysize(reads), 2341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 2342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data2(1, reads2, arraysize(reads2), 2343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes2, arraysize(writes2)); 23442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 23462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BoundNetLog(), GetParam(), NULL); 23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 2348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 2349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data2); 23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Start the transaction with basic parameters. 23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog()); 23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int kSize = 3000; 2359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 2360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = trans->Read( 2361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch buf.get(), 2362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSize, 2363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&SpdyNetworkTransactionTest::StartTransactionCallback, 2364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.session())); 2365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This forces an err_IO_pending, which sets the callback. 2366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.CompleteRead(); 2367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This finishes the read. 2368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.CompleteRead(); 2369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 2370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Verify that the client can correctly deal with the user callback deleting the 2373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// transaction. Failures will usually be valgrind errors. See 2374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// http://crbug.com/46925 2375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { 2376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 2377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 2383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp.get(), 2), 2384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 3), // Force a pause 2385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body.get(), 4), 2386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 5), // EOF 23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(reads, arraysize(reads), 2390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 23912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 23932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BoundNetLog(), GetParam(), NULL); 23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 2395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Start the transaction with basic parameters. 23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog()); 24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 2402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Setup a user callback which will delete the session, and clear out the 2405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // memory holding the stream object. Note that the callback deletes trans. 2406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int kSize = 3000; 2407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 2408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = trans->Read( 2409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch buf.get(), 2410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSize, 2411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&SpdyNetworkTransactionTest::DeleteSessionCallback, 2412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Unretained(&helper))); 2413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(ERR_IO_PENDING, rv); 2414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.CompleteRead(); 24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Finish running rest of tasks. 24173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Send a spdy request to www.google.com that gets redirected to www.foo.com. 2422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, RedirectGetRequest) { 2423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SpdyHeaderInfo kSynStartHeader = spdy_util_.MakeSpdyHeader(SYN_STREAM); 2424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers( 2425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock("http://www.google.com/")); 2426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*headers)["user-agent"] = ""; 2427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*headers)["accept-encoding"] = "gzip,deflate"; 2428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers2( 2429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock("http://www.foo.com/index.php")); 2430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*headers2)["user-agent"] = ""; 2431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*headers2)["accept-encoding"] = "gzip,deflate"; 24327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Setup writes/reads to www.google.com 2434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyFrame( 2435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSynStartHeader, headers.Pass())); 2436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyFrame( 2437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSynStartHeader, headers2.Pass())); 2438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReplyRedirect(1)); 2439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 2440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 1), 2441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 2443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 2), 2444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 3) // EOF 2445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Setup writes/reads to www.foo.com 2448eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); 2450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes2[] = { 2451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 1), 2452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads2[] = { 2454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp2, 2), 2455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body2, 3), 2456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 4) // EOF 2457eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(reads, arraysize(reads), 2459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 2460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data2(reads2, arraysize(reads2), 2461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes2, arraysize(writes2)); 24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(erikchen): Make test support SPDYSSL, SPDYNPN 2464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpStreamFactory::set_force_spdy_over_ssl(false); 2465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpStreamFactory::set_force_spdy_always(true); 2466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestDelegate d; 2467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 2468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyURLRequestContext spdy_url_request_context(GetParam().protocol); 2469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::URLRequest r( 2470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL("http://www.google.com/"), &d, &spdy_url_request_context); 2471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_url_request_context.socket_factory(). 2472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddSocketDataProvider(&data); 2473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_url_request_context.socket_factory(). 2474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddSocketDataProvider(&data2); 24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch d.set_quit_on_redirect(true); 2477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch r.Start(); 24783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().Run(); 24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1, d.received_redirect_count()); 24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch r.FollowDeferredRedirect(); 24833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().Run(); 2484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1, d.response_started_count()); 2485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(d.received_data_before_response()); 2486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(net::URLRequestStatus::SUCCESS, r.status().status()); 2487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string contents("hello!"); 2488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(contents, d.data_received()); 2489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 2490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_read_eof()); 2491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()); 2492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data2.at_read_eof()); 2493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data2.at_write_eof()); 2494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Send a spdy request to www.google.com. Get a pushed stream that redirects to 2497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// www.foo.com. 2498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, RedirectServerPush) { 2499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SpdyHeaderInfo kSynStartHeader = spdy_util_.MakeSpdyHeader(SYN_STREAM); 25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers( 2502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock("http://www.google.com/")); 2503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*headers)["user-agent"] = ""; 2504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*headers)["accept-encoding"] = "gzip,deflate"; 25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Setup writes/reads to www.google.com 2507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 2508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyFrame(kSynStartHeader, headers.Pass())); 2509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rep( 2511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyPush(NULL, 2512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 2513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 2514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 2515eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat", 2516eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "301 Moved Permanently", 2517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.foo.com/index.php")); 2518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 2519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 2520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL)); 2521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 2522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 1), 2523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*rst, 6), 2524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2525eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 2526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 2), 2527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*rep, 3), 2528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body, 4), 2529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause 2530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 7) // EOF 25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Setup writes/reads to www.foo.com 2534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers2( 2535eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock("http://www.foo.com/index.php")); 2536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*headers2)["user-agent"] = ""; 2537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*headers2)["accept-encoding"] = "gzip,deflate"; 2538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2( 2539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyFrame(kSynStartHeader, headers2.Pass())); 2540eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); 2542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes2[] = { 2543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 1), 2544eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads2[] = { 2546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp2, 2), 2547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body2, 3), 2548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 5) // EOF 2549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(reads, arraysize(reads), 2551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 2552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data2(reads2, arraysize(reads2), 2553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes2, arraysize(writes2)); 25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(erikchen): Make test support SPDYSSL, SPDYNPN 2556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpStreamFactory::set_force_spdy_over_ssl(false); 2557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpStreamFactory::set_force_spdy_always(true); 2558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestDelegate d; 2559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestDelegate d2; 2560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyURLRequestContext spdy_url_request_context(GetParam().protocol); 2561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 2562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::URLRequest r( 2563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL("http://www.google.com/"), &d, &spdy_url_request_context); 2564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_url_request_context.socket_factory(). 2565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddSocketDataProvider(&data); 25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch r.Start(); 25683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().Run(); 25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, d.received_redirect_count()); 2571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string contents("hello!"); 2572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(contents, d.data_received()); 25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::URLRequest r2( 2575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL("http://www.google.com/foo.dat"), &d2, &spdy_url_request_context); 2576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_url_request_context.socket_factory(). 2577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddSocketDataProvider(&data2); 25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch d2.set_quit_on_redirect(true); 2580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch r2.Start(); 25813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().Run(); 2582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1, d2.received_redirect_count()); 25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch r2.FollowDeferredRedirect(); 25853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().Run(); 2586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1, d2.response_started_count()); 2587eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(d2.received_data_before_response()); 2588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(net::URLRequestStatus::SUCCESS, r2.status().status()); 2589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string contents2("hello!"); 2590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(contents2, d2.data_received()); 2591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 2592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.CompleteRead(); 2593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data2.CompleteRead(); 2594eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_read_eof()); 2595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()); 2596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data2.at_read_eof()); 2597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data2.at_write_eof()); 25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2600eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) { 2601eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 260290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 2604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 2606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 1), 26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 2613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 2614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 2615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 2616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat")); 2617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kPushedData[] = "pushed"; 2618eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body( 2619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 2620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, kPushedData, strlen(kPushedData), true)); 26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 2622eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 2), 2623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 3), 2624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 4, SYNCHRONOUS), 2625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body, 5), 2626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause 26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response; 2630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response2; 2631eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string expected_push_result("pushed"); 2632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(reads, arraysize(reads), 26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 2634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RunServerPushTest(&data, 2635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &response, 2636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &response2, 2637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected_push_result); 26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2639eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 2640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 2641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the pushed stream. 2644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers.get() != NULL); 2645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 2646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 26477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushBeforeSynReply) { 2649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 265090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 2652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 2654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 1), 26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 2661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 2662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 2663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 2664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat")); 2665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kPushedData[] = "pushed"; 2666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body( 2667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 2668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, kPushedData, strlen(kPushedData), true)); 26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 2670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 2), 2671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 3), 2672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 4, SYNCHRONOUS), 2673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body, 5), 2674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause 26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response; 2678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response2; 2679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string expected_push_result("pushed"); 2680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(reads, arraysize(reads), 26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 2682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RunServerPushTest(&data, 2683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &response, 2684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &response2, 2685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected_push_result); 26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 2688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 2689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the pushed stream. 2692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers.get() != NULL); 2693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 2694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 26957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) { 2697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 269890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { CreateMockWrite(*stream1_syn, 1), }; 27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 2705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 2706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 2707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 2708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat")); 2709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kPushedData[] = "pushed"; 2710eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body( 2711eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 2712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, kPushedData, strlen(kPushedData), true)); 2713eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2714eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 2716eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 2), 2717eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 3), 2718eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body, 4), 2719eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 5, SYNCHRONOUS), 2720eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause 27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2723eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response; 2724eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response2; 2725eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string expected_push_result("pushed"); 2726eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(reads, arraysize(reads), 2727eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 2728eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RunServerPushTest(&data, 2729eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &response, 2730eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &response2, 2731eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected_push_result); 27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 2734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 2735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the pushed stream. 2738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers.get() != NULL); 2739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushServerAborted) { 2743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 274490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 2746eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 2748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 1), 27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2752eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 2755eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 2756eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 2757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 2758eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat")); 2759eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_rst( 2760eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); 27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 2762eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 2), 2763eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 3), 2764eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_rst, 4), 2765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 5, SYNCHRONOUS), 2766eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause 27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2769eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(reads, arraysize(reads), 2770eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 27712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 2772eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 2773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 2775eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 2776eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2779eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Start the transaction with basic parameters. 27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start( 27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateGetRequest(), callback.callback(), BoundNetLog()); 27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 2784eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 2785eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, rv); 27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2787eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that we consumed all test data. 2788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_read_eof()) << "Read count: " 2789eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.read_count() 2790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " Read index: " 2791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.read_index(); 2792eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()) << "Write count: " 2793eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.write_count() 2794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " Write index: " 2795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.write_index(); 27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2797eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 2798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response = *trans->GetResponseInfo(); 2799eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 2800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Verify that we don't leak streams and that we properly send a reset 2804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// if the server pushes the same stream twice. 2805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushDuplicate) { 2806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 280790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 2809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 2810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream3_rst( 2811eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_PROTOCOL_ERROR)); 2812eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 2813eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 1), 2814eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream3_rst, 5), 28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2817eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2818eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2819eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 2821eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 2822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 2823eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 2824eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat")); 2825eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kPushedData[] = "pushed"; 2826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body( 2827eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 2828eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, kPushedData, strlen(kPushedData), true)); 2829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2830eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream3_syn(spdy_util_.ConstructSpdyPush(NULL, 2831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 2832eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4, 2833eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 2834eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat")); 28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 2836eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 2), 2837eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 3), 2838eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream3_syn, 4), 2839eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 6, SYNCHRONOUS), 2840eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body, 7), 2841eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 8), // Force a pause 28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2844eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response; 2845eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response2; 2846eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string expected_push_result("pushed"); 28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 2849eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RunServerPushTest(&data, 2850eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &response, 2851eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &response2, 2852eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected_push_result); 28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2854eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 2855eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 2856eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2858eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the pushed stream. 2859eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers.get() != NULL); 2860eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2863eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) { 2864eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 286590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2866eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 2867eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 2868eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 2869eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 1), 2870eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2872eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2873eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2874eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2875eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 2876eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 2877eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 2878eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 2879eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat")); 2880eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char kPushedData[] = "pushed my darling hello my baby"; 2881eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body_base( 2882eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 2883eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, kPushedData, strlen(kPushedData), true)); 2884eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const size_t kChunkSize = strlen(kPushedData) / 4; 2885eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body1( 2886eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new SpdyFrame(stream2_body_base->data(), kChunkSize, false)); 2887eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body2( 2888eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new SpdyFrame(stream2_body_base->data() + kChunkSize, kChunkSize, false)); 2889eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body3( 2890eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new SpdyFrame(stream2_body_base->data() + 2 * kChunkSize, 2891eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kChunkSize, false)); 2892eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body4( 2893eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new SpdyFrame(stream2_body_base->data() + 3 * kChunkSize, 2894eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2_body_base->size() - 3 * kChunkSize, false)); 28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 2896eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 2), 2897eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 3), 2898eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body1, 4), 2899eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body2, 5), 2900eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body3, 6), 2901eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body4, 7), 2902eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 8, SYNCHRONOUS), 2903eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 9), // Force a pause 29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2906eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response; 2907eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response2; 2908eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string expected_push_result("pushed my darling hello my baby"); 29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 2911eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RunServerPushTest(&data, &response, &response2, kPushedData); 29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2913eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 2914eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 2915eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2917eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the pushed stream. 2918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers.get() != NULL); 2919eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2922eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) { 2923eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 2924eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2925eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 2926eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 2928eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 1), 29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2930eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2931eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2932eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2933eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2934eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 2935eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 2936eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 2937eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 2938eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat")); 2939eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char kPushedData[] = "pushed my darling hello my baby"; 2940eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body_base( 2941eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 2942eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, kPushedData, strlen(kPushedData), true)); 2943eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const size_t kChunkSize = strlen(kPushedData) / 4; 2944eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body1( 2945eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new SpdyFrame(stream2_body_base->data(), kChunkSize, false)); 2946eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body2( 2947eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new SpdyFrame(stream2_body_base->data() + kChunkSize, kChunkSize, false)); 2948eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body3( 2949eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new SpdyFrame(stream2_body_base->data() + 2 * kChunkSize, 2950eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kChunkSize, false)); 2951eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body4( 2952eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new SpdyFrame(stream2_body_base->data() + 3 * kChunkSize, 2953eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2_body_base->size() - 3 * kChunkSize, false)); 29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 2955eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 2), 2956eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 3), 2957eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body1, 4), 2958eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body2, 5), 2959eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause 2960eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body3, 7), 2961eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body4, 8), 2962eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body.get(), 9, SYNCHRONOUS), 2963eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 10) // Force a pause. 29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2966eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response; 2967eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response2; 29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 2970eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RunServerPushTest(&data, &response, &response2, kPushedData); 29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2972eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 2973eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 2974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2976eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the pushed stream. 2977eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers.get() != NULL); 2978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) { 2982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 298390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 2985eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 2986eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_rst( 2987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); 29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 2989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 1), 2990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream2_rst, 4), 29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> 2994eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2995eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 2996eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 2997eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 2998eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 2999eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 3000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat")); 30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 3002eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 2), 3003eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 3), 3004eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 4), 3005eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 5) // Force a pause 30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 30102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 3014eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 30157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Start the transaction with basic parameters. 3019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 3020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start( 3021eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetRequest(), callback.callback(), BoundNetLog()); 3022eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 3023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 3024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, rv); 30257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3026eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that we consumed all test data. 3027eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_read_eof()) << "Read count: " 3028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.read_count() 3029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " Read index: " 3030eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.read_index(); 3031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()) << "Write count: " 3032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.write_count() 3033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " Write index: " 3034eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.write_index(); 30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3036eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 3037eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response = *trans->GetResponseInfo(); 3038eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 3039eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 30415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3042eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) { 3043eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 304490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 3045eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 3046eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 3047eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_rst( 3048eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_INVALID_STREAM)); 30495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 3050eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 1), 3051eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream2_rst, 4), 30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> 3055eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> 3057eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 3058eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 3059eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 3060eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 9, 3061eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat")); 30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 3063eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 2), 3064eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 3), 3065eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 4), 3066eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause 30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 30705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 30712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 30737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3074eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 3075eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3077eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3079eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Start the transaction with basic parameters. 3080eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 3081eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start( 3082eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetRequest(), callback.callback(), BoundNetLog()); 3083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 3084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 3085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, rv); 30865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that we consumed all test data. 3088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_read_eof()) << "Read count: " 3089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.read_count() 3090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " Read index: " 3091eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.read_index(); 3092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()) << "Write count: " 3093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.write_count() 3094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " Write index: " 3095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.write_index(); 30965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 3098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response = *trans->GetResponseInfo(); 3099eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 3100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 31025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) { 310490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> stream1_syn( 310590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 31067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> stream1_body( 31077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, true)); 3108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_rst( 3109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); 31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*stream1_syn, 1), 3112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream2_rst, 4), 31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> 31167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> incomplete_headers(new SpdyHeaderBlock()); 3118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*incomplete_headers)["hello"] = "bye"; 3119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*incomplete_headers)[spdy_util_.GetStatusKey()] = "200 OK"; 3120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*incomplete_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; 3121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_syn( 3122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(incomplete_headers.Pass(), 3123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 3124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, // Stream ID 3125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, 3126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SYN_STREAM, 3127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, 3128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Associated stream ID 3129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1)); 31305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 31315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*stream1_reply, 2), 31325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*stream2_syn, 3), 3133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 4), 3134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 5) // Force a pause 31355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 31365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 31385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 3139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 3140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 31417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 3143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 31445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 31465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Start the transaction with basic parameters. 3148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 3149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start( 3150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetRequest(), callback.callback(), BoundNetLog()); 3151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 3152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 3153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, rv); 3154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that we consumed all test data. 3155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_read_eof()) << "Read count: " 3156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.read_count() 3157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " Read index: " 3158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.read_index(); 3159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()) << "Write count: " 3160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.write_count() 3161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " Write index: " 3162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.write_index(); 31635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify the SYN_REPLY. 3165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response = *trans->GetResponseInfo(); 3166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response.headers.get() != NULL); 31675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Verify that various SynReply headers parse correctly through the 3171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// HTTP layer. 3172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) { 3173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch struct SynReplyHeadersTests { 3174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int num_headers; 3175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char* extra_headers[5]; 3176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyHeaderBlock expected_headers; 3177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } test_cases[] = { 3178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This uses a multi-valued cookie header. 3179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 2, 3180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { "cookie", "val1", 3181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "cookie", "val2", // will get appended separated by NULL 3182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NULL 3183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }, 3184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }, 3185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This is the minimalist set of headers. 3186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 0, 3187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { NULL }, 3188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }, 3189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Headers with a comma separated list. 3190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 1, 3191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { "cookie", "val1,val2", 3192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NULL 3193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }, 3194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[0].expected_headers["cookie"] = "val1"; 31987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[0].expected_headers["cookie"] += '\0'; 31997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[0].expected_headers["cookie"] += "val2"; 32007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[0].expected_headers["hello"] = "bye"; 32017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[0].expected_headers["status"] = "200"; 32027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[0].expected_headers["version"] = "HTTP/1.1"; 32037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 32047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[1].expected_headers["hello"] = "bye"; 32057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[1].expected_headers["status"] = "200"; 32067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[1].expected_headers["version"] = "HTTP/1.1"; 32077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 32087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[2].expected_headers["cookie"] = "val1,val2"; 32097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[2].expected_headers["hello"] = "bye"; 32107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[2].expected_headers["status"] = "200"; 32117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[2].expected_headers["version"] = "HTTP/1.1"; 32127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> req( 321590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req) }; 32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> resp( 32197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyGetSynReply(test_cases[i].extra_headers, 32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_cases[i].num_headers, 32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1)); 32227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 32312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data); 32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers; 32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(headers.get() != NULL); 32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* iter = NULL; 32437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string name, value; 32447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyHeaderBlock header_block; 32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (headers->EnumerateHeaderLines(&iter, &name, &value)) { 32467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (header_block[name].empty()) { 32477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) header_block[name] = value; 32487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } else { 32497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) header_block[name] += '\0'; 32507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) header_block[name] += value; 32517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(test_cases[i].expected_headers, header_block); 32545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that various SynReply headers parse vary fields correctly 32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// through the HTTP layer, and the response matches the request. 32597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) { 32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SpdyHeaderInfo syn_reply_info = { 32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYN_REPLY, // Syn Reply 32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Stream ID 32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Associated Stream ID 32647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ConvertRequestPriorityToSpdyPriority( 32657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) LOWEST, spdy_util_.spdy_version()), 32667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kSpdyCredentialSlotUnused, 32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTROL_FLAG_NONE, // Control Flags 32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, // Compressed 32692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RST_STREAM_INVALID, // Status 32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // Data 32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Data Length 32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DATA_FLAG_NONE // Data Flags 32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Modify the following data to change/add test cases: 32755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SynReplyTests { 32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdyHeaderInfo* syn_reply; 32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool vary_matches; 32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_headers[2]; 32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* extra_headers[2][16]; 32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } test_cases[] = { 32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test the case of a multi-valued cookie. When the value is delimited 32825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with NUL characters, it needs to be unfolded into multiple headers. 32835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &syn_reply_info, 32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, 32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1, 4 }, 32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { { "cookie", "val1,val2", 32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 32907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { "vary", "cookie", 32917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetStatusKey(), "200", 32927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetPathKey(), "/index.php", 32937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetVersionKey(), "HTTP/1.1", 32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, { // Multiple vary fields. 32985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &syn_reply_info, 32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, 33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2, 5 }, 33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { { "friend", "barney", 33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "enemy", "snaggletooth", 33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 33057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { "vary", "friend", 33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "vary", "enemy", 33077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetStatusKey(), "200", 33087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetPathKey(), "/index.php", 33097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetVersionKey(), "HTTP/1.1", 33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, { // Test a '*' vary field. 33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &syn_reply_info, 33155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, 33165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1, 4 }, 33175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { { "cookie", "val1,val2", 33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 33207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { "vary", "*", 33217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetStatusKey(), "200", 33227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetPathKey(), "/index.php", 33237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetVersionKey(), "HTTP/1.1", 33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, { // Multiple comma-separated vary fields. 33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &syn_reply_info, 33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, 33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2, 4 }, 33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { { "friend", "barney", 33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "enemy", "snaggletooth", 33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 33357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { "vary", "friend,enemy", 33367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetStatusKey(), "200", 33377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetPathKey(), "/index.php", 33387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetVersionKey(), "HTTP/1.1", 33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the request. 33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> frame_req( 334890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(test_cases[i].extra_headers[0], 334990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test_cases[i].num_headers[0], 335090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) false, 1, LOWEST, true)); 33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 33535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*frame_req), 33545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 33555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the reply. 33575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> frame_reply( 33587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyFrame(*test_cases[i].syn_reply, 33597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[i].extra_headers[1], 33607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[i].num_headers[1], 33617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NULL, 33627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 0)); 33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 33665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*frame_reply), 33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 33685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attach the headers to the request. 33725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int header_count = test_cases[i].num_headers[0]; 33735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo request = CreateGetRequest(); 33755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int ct = 0; ct < header_count; ct++) { 33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* header_key = test_cases[i].extra_headers[0][ct * 2]; 33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* header_value = test_cases[i].extra_headers[0][ct * 2 + 1]; 33785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.extra_headers.SetHeader(header_key, header_value); 33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 33832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv) << i; 33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line) << i; 33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data) << i; 33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test the response information. 33935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(out.response_info.response_time > 33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info.request_time) << i; 33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta test_delay = out.response_info.response_time - 33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info.request_time; 33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta min_expected_delay; 33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_expected_delay.FromMilliseconds(10); 33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(test_delay.InMillisecondsF(), 34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_expected_delay.InMillisecondsF()) << i; 34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(out.response_info.vary_data.is_valid(), 34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_cases[i].vary_matches) << i; 34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the headers. 34055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers; 34065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(headers.get() != NULL) << i; 34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* iter = NULL; 34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name, value, lines; 34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (headers->EnumerateHeaderLines(&iter, &name, &value)) { 34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lines.append(name); 34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lines.append(": "); 34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lines.append(value); 34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lines.append("\n"); 34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the expected header reply string. 3417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SpdyHeaderBlock reply_headers; 3418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AppendToHeaderBlock(test_cases[i].extra_headers[1], 3419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) test_cases[i].num_headers[1], 3420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &reply_headers); 3421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string expected_reply = 3422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyReplyString(reply_headers); 3423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(expected_reply, lines) << i; 34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that we don't crash on invalid SynReply responses. 34287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, InvalidSynReply) { 34295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdyHeaderInfo kSynStartHeader = { 34305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYN_REPLY, // Kind = SynReply 34315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Stream ID 34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Associated stream ID 34337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ConvertRequestPriorityToSpdyPriority( 34347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) LOWEST, spdy_util_.spdy_version()), 34357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kSpdyCredentialSlotUnused, 34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTROL_FLAG_NONE, // Control Flags 34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, // Compressed 34382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RST_STREAM_INVALID, // Status 34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // Data 34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Length 34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DATA_FLAG_NONE // Data Flags 34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct InvalidSynReplyTests { 34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_headers; 34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* headers[10]; 34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } test_cases[] = { 34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SYN_REPLY missing status header 34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4, 34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "cookie", "val1", 34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "cookie", "val2", 34527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetPathKey(), "/index.php", 34537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetVersionKey(), "HTTP/1.1", 34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SYN_REPLY missing version header 34585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2, 34597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { "status", "200", 34607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.GetPathKey(), "/index.php", 34615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 34635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SYN_REPLY with no headers 34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 0, { NULL }, }, 34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> req( 347090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 3471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 3472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); 34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*req), 3475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*rst), 34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> resp( 34797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyFrame(kSynStartHeader, 34807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NULL, 0, 34817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[i].headers, 34827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test_cases[i].num_headers)); 34837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 34855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 34865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 34912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 34925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 34935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 34945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 3495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 34965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 34985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that we don't crash on some corrupt frames. 35007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, CorruptFrameSessionError) { 35015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the length field that's too short. 35025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> syn_reply_wrong_length( 35037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 35047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 3505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t right_size = 3506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (spdy_util_.spdy_version() < SPDY4) ? 3507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syn_reply_wrong_length->size() - framer.GetControlFrameHeaderSize() : 3508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syn_reply_wrong_length->size(); 3509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t wrong_size = right_size - 4; 35102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test::SetFrameLength(syn_reply_wrong_length.get(), 3511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch wrong_size, 35127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.spdy_version()); 35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SynReplyTests { 35155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdyFrame* syn_reply; 35165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } test_cases[] = { 35175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { syn_reply_wrong_length.get(), }, 35185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 35195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 35215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> req( 352290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 3523ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> rst( 3524ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); 3525ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockWrite writes[] = { 3526ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req), 3527ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*rst), 35285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 35295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 35315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 35322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead(ASYNC, test_cases[i].syn_reply->data(), wrong_size), 35335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 35345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 35355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 35365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 35385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 35392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 35405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 35415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 35425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 35435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 35445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 35465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we shutdown correctly on write errors. 35487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, WriteError) { 354990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 355090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 35515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 35525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We'll write 10 bytes successfully 35538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MockWrite(ASYNC, req->data(), 10, 0), 35545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Followed by ERROR! 35558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MockWrite(ASYNC, ERR_FAILED, 1), 35565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 35575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MockRead reads[] = { 35598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MockRead(ASYNC, 0, 2) // EOF 35608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) }; 35618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 35628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 35638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) writes, arraysize(writes)); 35648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 35652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 35678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) helper.SetDeterministic(); 35688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) helper.RunPreTestSetup(); 35698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) helper.AddDeterministicData(&data); 35708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) EXPECT_TRUE(helper.StartDefaultTest()); 35718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) data.RunFor(2); 35728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) helper.FinishDefaultTest(); 35738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 35748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) EXPECT_TRUE(!data.at_read_eof()); 35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 35765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_FAILED, out.rv); 35775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that partial writes work. 35807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, PartialWrite) { 35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Chop the SYN_STREAM frame into 5 chunks. 358290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 358390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kChunks = 5; 3585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<MockWrite[]> writes(ChopWriteFrame(*req.get(), kChunks)); 35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 35887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 35905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 35915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(kChunks, reads, arraysize(reads), 35965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes.get(), kChunks); 35972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 36025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data); 36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In this test, we enable compression, but get a uncompressed SynReply from 36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the server. Verify that teardown is all clean. 36087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) { 36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> compressed( 361090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, true, 1, LOWEST, true)); 36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> rst( 361290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); 36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*compressed), 36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 36187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 36225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 36245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 36257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdySessionDependencies* session_deps = 36267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CreateSpdySessionDependencies(GetParam()); 36272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps->enable_compression = true; 36282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 36292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BoundNetLog(), GetParam(), session_deps); 36305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.Reset(); 36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the NetLog contains good data for a simple GET request. 36377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, NetLog) { 36385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* const kExtraHeaders[] = { 36395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "user-agent", "Chrome", 36405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 364190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 364290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(kExtraHeaders, 1, false, 1, LOWEST, true)); 36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req) }; 36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 36467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CapturingBoundNetLog log; 36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequestWithUserAgent(), 36582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DEFAULT_PRIORITY, 36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log.bound(), GetParam(), NULL); 36605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunToCompletion(&data); 36615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 36625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 36645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data); 36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that the NetLog was filled reasonably. 36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This test is intentionally non-specific about the exact ordering of the 36685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // log; instead we just check to make sure that certain events exist, and that 36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // they are in the right order. 36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CapturingNetLog::CapturedEntryList entries; 36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log.GetEntries(&entries); 36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(0u, entries.size()); 36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pos = 0; 36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = net::ExpectLogContainsSomewhere(entries, 0, 36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, 36775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::PHASE_BEGIN); 36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, 36805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::PHASE_END); 36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 36825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, 36835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::PHASE_BEGIN); 36845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 36855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, 36865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::PHASE_END); 36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, 36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::PHASE_BEGIN); 36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = net::ExpectLogContainsSomewhere(entries, pos + 1, 36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, 36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::PHASE_END); 36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that we logged all the headers correctly 36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = net::ExpectLogContainsSomewhere( 36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries, 0, 36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_SPDY_SESSION_SYN_STREAM, 36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::PHASE_NONE); 36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::ListValue* header_list; 37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(entries[pos].params.get()); 37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(entries[pos].params->GetList("headers", &header_list)); 37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> expected; 37057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) expected.push_back(std::string(spdy_util_.GetHostKey()) + ": www.google.com"); 37067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) expected.push_back(std::string(spdy_util_.GetPathKey()) + ": /"); 37077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) expected.push_back(std::string(spdy_util_.GetSchemeKey()) + ": http"); 37087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) expected.push_back(std::string(spdy_util_.GetVersionKey()) + ": HTTP/1.1"); 37097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) expected.push_back(std::string(spdy_util_.GetMethodKey()) + ": GET"); 37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back("user-agent: Chrome"); 37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(expected.size(), header_list->GetSize()); 37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<std::string>::const_iterator it = expected.begin(); 37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != expected.end(); 37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringValue header(*it); 37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(header_list->end(), header_list->Find(header)) << 37175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Header not found: " << *it; 37185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Since we buffer the IO from the stream to the renderer, this test verifies 37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that when we read out the maximum amount of data (e.g. we received 50 bytes 37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// on the network, but issued a Read for only 5 of those bytes) that the data 37245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// flow still works correctly. 37257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, BufferFull) { 37267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 372890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 372990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 37305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req) }; 37315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2 data frames in a single read. 37335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> data_frame_1( 37345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framer.CreateDataFrame(1, "goodby", 6, DATA_FLAG_NONE)); 37355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> data_frame_2( 37365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framer.CreateDataFrame(1, "e worl", 6, DATA_FLAG_NONE)); 37375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdyFrame* data_frames[2] = { 37385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame_1.get(), 37395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame_2.get(), 37405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 37415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char combined_data_frames[100]; 37425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int combined_data_frames_len = 37435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CombineFrames(data_frames, arraysize(data_frames), 37445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) combined_data_frames, arraysize(combined_data_frames)); 37455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> last_frame( 37465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framer.CreateDataFrame(1, "d", 1, DATA_FLAG_FIN)); 37475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 37495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 37505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 37515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, ERR_IO_PENDING), // Force a pause 37525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, combined_data_frames, combined_data_frames_len), 37535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, ERR_IO_PENDING), // Force a pause 37545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*last_frame), 37555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 37565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 37575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 37595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 37605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 37625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 37645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 37655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 37665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 37675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 37685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start( 37695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateGetRequest(), callback.callback(), BoundNetLog()); 37705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 37715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 37735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback.WaitForResult(); 37745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(out.rv, OK); 37755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response = trans->GetResponseInfo(); 3777868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response->headers.get() != NULL); 37785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response->was_fetched_via_spdy); 37795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response->headers->GetStatusLine(); 37805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response; // Make a copy so we can verify. 37815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read Data 37835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback read_callback; 37845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string content; 37865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 37875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read small chunks at a time. 37885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kSmallReadSize = 3; 37895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize)); 3790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback()); 37915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == net::ERR_IO_PENDING) { 37925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.CompleteRead(); 37935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = read_callback.WaitForResult(); 37945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv > 0) { 37965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content.append(buf->data(), rv); 37975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (rv < 0) { 37985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 37995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv > 0); 38015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_data.swap(content); 38035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 38055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MockClientSocketFactory) are still alive. 38063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 38075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that we consumed all test data. 38095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 38105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 38125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 38135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("goodbye world", out.response_data); 38145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 38155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that basic buffering works; when multiple data frames arrive 38175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// at the same time, ensure that we don't notify a read completion for 38185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// each data frame individually. 38197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, Buffering) { 38207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 38215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 382290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 382390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 38245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req) }; 38255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 4 data frames in a single read. 38275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> data_frame( 38285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE)); 38295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> data_frame_fin( 38305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN)); 38315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdyFrame* data_frames[4] = { 38325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame.get(), 38335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame.get(), 38345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame.get(), 38355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame_fin.get() 38365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 38375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char combined_data_frames[100]; 38385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int combined_data_frames_len = 38395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CombineFrames(data_frames, arraysize(data_frames), 38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) combined_data_frames, arraysize(combined_data_frames)); 38415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 38435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 38455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, ERR_IO_PENDING), // Force a pause 38465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, combined_data_frames, combined_data_frames_len), 38475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 38485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 38495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 38515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 38525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 38545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 38555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 38565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 38575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 38585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 38605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start( 38615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateGetRequest(), callback.callback(), BoundNetLog()); 38625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 38635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 38655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback.WaitForResult(); 38665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(out.rv, OK); 38675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response = trans->GetResponseInfo(); 3869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response->headers.get() != NULL); 38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response->was_fetched_via_spdy); 38715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response->headers->GetStatusLine(); 38725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response; // Make a copy so we can verify. 38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read Data 38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback read_callback; 38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string content; 38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int reads_completed = 0; 38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read small chunks at a time. 38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kSmallReadSize = 14; 38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize)); 3883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback()); 38845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == net::ERR_IO_PENDING) { 38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.CompleteRead(); 38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = read_callback.WaitForResult(); 38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv > 0) { 38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kSmallReadSize, rv); 38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content.append(buf->data(), rv); 38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (rv < 0) { 38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FAIL() << "Unexpected read error: " << rv; 38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reads_completed++; 38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv > 0); 38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3, reads_completed); // Reads are: 14 bytes, 14 bytes, 0 bytes. 38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_data.swap(content); 39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MockClientSocketFactory) are still alive. 39033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that we consumed all test data. 39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("messagemessagemessagemessage", out.response_data); 39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify the case where we buffer data but read it after it has been buffered. 39147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, BufferedAll) { 39157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 391790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 391890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req) }; 39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 5 data frames in a single read. 39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> syn_reply( 39237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 39242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // turn off FIN bit 39257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) test::SetFrameFlags( 39267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) syn_reply.get(), CONTROL_FLAG_NONE, spdy_util_.spdy_version()); 39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> data_frame( 39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE)); 39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> data_frame_fin( 39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN)); 39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdyFrame* frames[5] = { 39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syn_reply.get(), 39335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame.get(), 39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame.get(), 39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame.get(), 39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame_fin.get() 39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char combined_frames[200]; 39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int combined_frames_len = 39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CombineFrames(frames, arraysize(frames), 39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) combined_frames, arraysize(combined_frames)); 39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, combined_frames, combined_frames_len), 39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 39545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 39555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 39565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start( 39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateGetRequest(), callback.callback(), BoundNetLog()); 39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback.WaitForResult(); 39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(out.rv, OK); 39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response = trans->GetResponseInfo(); 3967868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response->headers.get() != NULL); 39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response->was_fetched_via_spdy); 39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response->headers->GetStatusLine(); 39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response; // Make a copy so we can verify. 39715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read Data 39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback read_callback; 39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string content; 39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int reads_completed = 0; 39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read small chunks at a time. 39795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kSmallReadSize = 14; 39805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize)); 3981868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback()); 39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv > 0) { 39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kSmallReadSize, rv); 39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content.append(buf->data(), rv); 39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (rv < 0) { 39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FAIL() << "Unexpected read error: " << rv; 39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reads_completed++; 39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv > 0); 39905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3, reads_completed); 39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_data.swap(content); 39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MockClientSocketFactory) are still alive. 39973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 39985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that we consumed all test data. 40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("messagemessagemessagemessage", out.response_data); 40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify the case where we buffer data and close the connection. 40087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, BufferedClosed) { 40097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 401190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 401290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req) }; 40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All data frames in a single read. 40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: We don't FIN the stream. 40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> data_frame( 40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE)); 40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdyFrame* data_frames[4] = { 40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame.get(), 40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame.get(), 40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame.get(), 40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_frame.get() 40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char combined_data_frames[100]; 40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int combined_data_frames_len = 40275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CombineFrames(data_frames, arraysize(data_frames), 40285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) combined_data_frames, arraysize(combined_data_frames)); 40297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 40325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, ERR_IO_PENDING), // Force a wait 40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, combined_data_frames, combined_data_frames_len), 40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 40355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 40395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 40415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 40435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 40475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start( 40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateGetRequest(), callback.callback(), BoundNetLog()); 40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback.WaitForResult(); 40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(out.rv, OK); 40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response = trans->GetResponseInfo(); 4057868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response->headers.get() != NULL); 40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response->was_fetched_via_spdy); 40595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response->headers->GetStatusLine(); 40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response; // Make a copy so we can verify. 40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read Data 40635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback read_callback; 40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string content; 40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int reads_completed = 0; 40675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read small chunks at a time. 40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kSmallReadSize = 14; 40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize)); 4071868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback()); 40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == net::ERR_IO_PENDING) { 40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.CompleteRead(); 40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = read_callback.WaitForResult(); 40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv > 0) { 40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content.append(buf->data(), rv); 40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (rv < 0) { 40795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This test intentionally closes the connection, and will get an error. 40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); 40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 40825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reads_completed++; 40845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv > 0); 40855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, reads_completed); 40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_data.swap(content); 40895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MockClientSocketFactory) are still alive. 40923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that we consumed all test data. 40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify the case where we buffer data and cancel the transaction. 40997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, BufferedCancelled) { 41007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 410290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 410390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req) }; 41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: We don't FIN the stream. 41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> data_frame( 41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE)); 41095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 41135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, ERR_IO_PENDING), // Force a wait 41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*data_frame), 41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 41265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start( 41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateGetRequest(), callback.callback(), BoundNetLog()); 41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.rv = callback.WaitForResult(); 41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(out.rv, OK); 41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response = trans->GetResponseInfo(); 4137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response->headers.get() != NULL); 41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(response->was_fetched_via_spdy); 41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.status_line = response->headers->GetStatusLine(); 41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.response_info = *response; // Make a copy so we can verify. 41415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read Data 41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback read_callback; 41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kReadSize = 256; 41475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kReadSize)); 4148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = trans->Read(buf.get(), kReadSize, read_callback.callback()); 41495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == net::ERR_IO_PENDING) { 41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Complete the read now, which causes buffering to start. 41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.CompleteRead(); 41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroy the transaction, causing the stream to get cancelled 41535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and orphaning the buffered IO task. 41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.ResetTrans(); 41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We shouldn't get here in this test. 41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FAIL() << "Unexpected read: " << rv; 41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv > 0); 41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flush the MessageLoop; this will cause the buffered IO task 41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to run for the final time. 41633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 41645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that we consumed all test data. 41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if the server requests persistence of settings, that we save 41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the settings in the HttpServerProperties. 41717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, SettingsSaved) { 41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SpdyHeaderInfo kSynReplyInfo = { 41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYN_REPLY, // Syn Reply 41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Stream ID 41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Associated Stream ID 41767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ConvertRequestPriorityToSpdyPriority( 41777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) LOWEST, spdy_util_.spdy_version()), 41787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kSpdyCredentialSlotUnused, 41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTROL_FLAG_NONE, // Control Flags 41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, // Compressed 41812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RST_STREAM_INVALID, // Status 41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // Data 41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Data Length 41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DATA_FLAG_NONE // Data Flags 41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog net_log; 41882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 41892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log, GetParam(), NULL); 41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that no settings exist initially. 41935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostPortPair host_port_pair("www.google.com", helper.port()); 41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); 41955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings( 41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_port_pair).empty()); 41975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the request. 419990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 420090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { CreateMockWrite(*req) }; 42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the reply. 42047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock()); 42057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (*reply_headers)[spdy_util_.GetStatusKey()] = "200"; 42067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; 42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> reply( 42087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyFrame(kSynReplyInfo, reply_headers.Pass())); 42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH; 42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int kSampleValue1 = 0x0a0a0a0a; 42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdySettingsIds kSampleId2 = SETTINGS_DOWNLOAD_BANDWIDTH; 42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int kSampleValue2 = 0x0b0b0b0b; 42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdySettingsIds kSampleId3 = SETTINGS_ROUND_TRIP_TIME; 42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int kSampleValue3 = 0x0c0c0c0c; 42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> settings_frame; 42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the SETTINGS frame. 42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsMap settings; 42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First add a persisted setting. 42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings[kSampleId1] = 42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_PLEASE_PERSIST, kSampleValue1); 42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next add a non-persisted setting. 42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings[kSampleId2] = 42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kSampleValue2); 42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next add another persisted setting. 42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings[kSampleId3] = 42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_PLEASE_PERSIST, kSampleValue3); 422990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) settings_frame.reset(spdy_util_.ConstructSpdySettings(settings)); 42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 42345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*reply), 42355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 4236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*settings_frame), 4237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0) // EOF 4238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data(1, reads, arraysize(reads), 4241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 4242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 4243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunDefaultTest(); 4244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 4245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransactionHelperResult out = helper.output(); 4246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, out.rv); 4247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 4248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("hello!", out.response_data); 4249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 4251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify we had two persisted settings. 4252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SettingsMap& settings_map = 4253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_session_pool->http_server_properties()->GetSpdySettings( 4254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch host_port_pair); 4255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(2u, settings_map.size()); 4256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the first persisted setting. 4258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsMap::const_iterator it1 = settings_map.find(kSampleId1); 4259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(it1 != settings_map.end()); 4260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsFlagsAndValue flags_and_value1 = it1->second; 4261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value1.first); 4262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSampleValue1, flags_and_value1.second); 4263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the second persisted setting. 4265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsMap::const_iterator it3 = settings_map.find(kSampleId3); 4266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(it3 != settings_map.end()); 4267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsFlagsAndValue flags_and_value3 = it3->second; 4268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value3.first); 4269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSampleValue3, flags_and_value3.second); 4270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 4271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 4272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test that when there are settings saved that they are sent back to the 4274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// server upon session establishment. 4275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { 4276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const SpdyHeaderInfo kSynReplyInfo = { 4277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SYN_REPLY, // Syn Reply 4278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, // Stream ID 4279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, // Associated Stream ID 4280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ConvertRequestPriorityToSpdyPriority( 4281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, spdy_util_.spdy_version()), 4282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSpdyCredentialSlotUnused, 4283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, // Control Flags 4284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, // Compressed 4285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RST_STREAM_INVALID, // Status 4286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NULL, // Data 4287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, // Data Length 4288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DATA_FLAG_NONE // Data Flags 4289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog net_log; 4292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 4293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net_log, GetParam(), NULL); 4294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 4295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); 4297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 4298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SpdySessionPoolPeer pool_peer(spdy_session_pool); 4299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pool_peer.SetEnableSendingInitialData(true); 4300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 4301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that no settings exist initially. 4302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostPortPair host_port_pair("www.google.com", helper.port()); 4303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings( 4304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch host_port_pair).empty()); 4305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH; 4307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned int kSampleValue1 = 0x0a0a0a0a; 4308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SpdySettingsIds kSampleId2 = SETTINGS_ROUND_TRIP_TIME; 4309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned int kSampleValue2 = 0x0c0c0c0c; 4310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // First add a persisted setting. 4312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_session_pool->http_server_properties()->SetSpdySetting( 4313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch host_port_pair, 4314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSampleId1, 4315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SETTINGS_FLAG_PLEASE_PERSIST, 4316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSampleValue1); 4317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Next add another persisted setting. 4319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_session_pool->http_server_properties()->SetSpdySetting( 4320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch host_port_pair, 4321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSampleId2, 4322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SETTINGS_FLAG_PLEASE_PERSIST, 4323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSampleValue2); 4324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(2u, spdy_session_pool->http_server_properties()->GetSpdySettings( 4326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch host_port_pair).size()); 4327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Construct the initial SETTINGS frame. 4329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SettingsMap initial_settings; 4330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) initial_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = 4331a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); 4332a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<SpdyFrame> initial_settings_frame( 4333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) spdy_util_.ConstructSpdySettings(initial_settings)); 4334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 4335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Construct the initial window update. 4336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<SpdyFrame> initial_window_update( 4337a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) spdy_util_.ConstructSpdyWindowUpdate( 4338a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) kSessionFlowControlStreamId, 4339a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize)); 4340a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 4341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Construct the persisted SETTINGS frame. 4342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SettingsMap& settings = 4343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_session_pool->http_server_properties()->GetSpdySettings( 4344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch host_port_pair); 4345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> settings_frame( 4346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdySettings(settings)); 4347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct the request. 4349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 4350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<MockWrite> writes; 4353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (GetParam().protocol == kProtoHTTP2Draft04) { 4354a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) writes.push_back( 4355a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockWrite(ASYNC, 4356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) kHttp2ConnectionHeaderPrefix, 4357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) kHttp2ConnectionHeaderPrefixSize)); 4358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 4359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) writes.push_back(CreateMockWrite(*initial_settings_frame)); 4360a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (GetParam().protocol >= kProtoSPDY31) { 4361a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) writes.push_back(CreateMockWrite(*initial_window_update)); 4362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) writes.push_back(CreateMockWrite(*settings_frame)); 4364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) writes.push_back(CreateMockWrite(*req)); 4365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct the reply. 4367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock()); 4368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*reply_headers)[spdy_util_.GetStatusKey()] = "200"; 4369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; 4370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> reply( 4371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyFrame(kSynReplyInfo, reply_headers.Pass())); 4372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 4374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 4375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*reply), 4376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body), 43775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data(2, reads, arraysize(reads), 4381a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) vector_as_array(&writes), writes.size()); 43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddData(&data); 43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunDefaultTest(); 43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransactionHelperResult out = helper.output(); 43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, out.rv); 43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("hello!", out.response_data); 43895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify we had two persisted settings. 43925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SettingsMap& settings_map = 43935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_session_pool->http_server_properties()->GetSpdySettings( 43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_port_pair); 43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2u, settings_map.size()); 43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify the first persisted setting. 43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsMap::const_iterator it1 = settings_map.find(kSampleId1); 43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(it1 != settings_map.end()); 44005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue flags_and_value1 = it1->second; 44015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value1.first); 44025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kSampleValue1, flags_and_value1.second); 44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify the second persisted setting. 4405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsMap::const_iterator it2 = settings_map.find(kSampleId2); 4406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(it2 != settings_map.end()); 4407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsFlagsAndValue flags_and_value2 = it2->second; 4408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value2.first); 4409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSampleValue2, flags_and_value2.second); 44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, GoAwayWithActiveStream) { 4414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 4415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 44177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> go_away(spdy_util_.ConstructSpdyGoAway()); 4419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 4420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*go_away), 44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data(1, reads, arraysize(reads), 4424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 44252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 4426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 4427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 4428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunToCompletion(&data); 4429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransactionHelperResult out = helper.output(); 4430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_ABORTED, out.rv); 4431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 4432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) { 4434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 4435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { CreateMockWrite(*req) }; 4437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 4439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 4440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp), 4441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, 0, 0) // EOF 4442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data(1, reads, arraysize(reads), 4445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 4446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog log; 4447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 4448eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log, GetParam(), NULL); 4449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 4450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 4451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 4452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 4454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransactionHelperResult out; 4455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch out.rv = trans->Start(&CreateGetRequest(), callback.callback(), log); 4456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4457eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(out.rv, ERR_IO_PENDING); 4458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch out.rv = callback.WaitForResult(); 4459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(out.rv, OK); 4460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 4462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response->headers.get() != NULL); 4463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 4464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch out.rv = ReadTransaction(trans, &out.response_data); 4465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv); 4466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that we consumed all test data. 4468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 4469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 4470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test to make sure we can correctly connect through a proxy. 4472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ProxyConnect) { 4473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 4474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 4475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.session_deps().reset(CreateSpdySessionDependencies( 4476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetParam(), 4477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"))); 4478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.SetSession(make_scoped_refptr( 4479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get()))); 4480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 4481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 4482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n" 4484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Host: www.google.com\r\n" 4485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Proxy-Connection: keep-alive\r\n\r\n"}; 4486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n" 4487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Host: www.google.com\r\n" 4488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Proxy-Connection: keep-alive\r\n\r\n"}; 4489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"}; 4490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 4491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 4493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 4494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes_SPDYNPN[] = { 4496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0), 4497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 2), 4498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads_SPDYNPN[] = { 4500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1), 4501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 3), 4502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body.get(), 4), 4503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 5), 4504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes_SPDYSSL[] = { 4507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite(SYNCHRONOUS, kConnect80, arraysize(kConnect80) - 1, 0), 4508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 2), 4509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads_SPDYSSL[] = { 4511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1), 4512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 3), 4513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body.get(), 4), 4514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 5), 4515eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4516eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes_SPDYNOSSL[] = { 4518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 0), 4519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads_SPDYNOSSL[] = { 4522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 1), 4523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body.get(), 2), 4524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 3), 4525eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<OrderedSocketData> data; 4528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch switch(GetParam().ssl_type) { 4529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case SPDYNOSSL: 4530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.reset(new OrderedSocketData(reads_SPDYNOSSL, 4531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(reads_SPDYNOSSL), 4532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes_SPDYNOSSL, 4533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(writes_SPDYNOSSL))); 4534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 4535eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case SPDYSSL: 4536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.reset(new OrderedSocketData(reads_SPDYSSL, 4537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(reads_SPDYSSL), 4538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes_SPDYSSL, 4539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(writes_SPDYSSL))); 4540eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 4541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case SPDYNPN: 4542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.reset(new OrderedSocketData(reads_SPDYNPN, 4543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(reads_SPDYNPN), 4544eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes_SPDYNPN, 4545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(writes_SPDYNPN))); 4546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 4547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch default: 4548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NOTREACHED(); 4549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 4550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(data.get()); 4552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 4553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start( 4555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetRequest(), callback.callback(), BoundNetLog()); 4556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 4557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 4559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, rv); 4560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 4562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response = *trans->GetResponseInfo(); 4563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 4564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 4565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string response_data; 4567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans, &response_data)); 4568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("hello!", response_data); 4569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 4570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 4571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test to make sure we can correctly connect through a proxy to www.google.com, 4573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// if there already exists a direct spdy connection to www.google.com. See 4574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// http://crbug.com/49874 4575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { 4576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // When setting up the first transaction, we store the SpdySessionPool so that 4577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // we can use the same pool in the second transaction. 4578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 4579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 4580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Use a proxy service which returns a proxy fallback list from DIRECT to 4582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // myproxy:70. For this test there will be no fallback, so it is equivalent 4583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // to simply DIRECT. The reason for appending the second proxy is to verify 4584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // that the session pool key used does is just "DIRECT". 4585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.session_deps().reset(CreateSpdySessionDependencies( 4586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetParam(), 4587eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ProxyService::CreateFixedFromPacResult("DIRECT; PROXY myproxy:70"))); 4588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.SetSession(make_scoped_refptr( 4589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get()))); 4590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); 45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 45935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4594eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct and send a simple GET request. 4595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 4596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 4598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 1), 4599eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4600eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4601eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 4602eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 4603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 4604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 2), 4605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body, 3), 4606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause 4607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 5) // EOF 4608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(reads, arraysize(reads), 4610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 4611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 4612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 4613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 4615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransactionHelperResult out; 4616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch out.rv = trans->Start( 4617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetRequest(), callback.callback(), BoundNetLog()); 4618eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(out.rv, ERR_IO_PENDING); 4620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch out.rv = callback.WaitForResult(); 4621eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(out.rv, OK); 4622eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 4624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response->headers.get() != NULL); 4625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 4626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch out.rv = ReadTransaction(trans, &out.response_data); 4627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, out.rv); 4628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch out.status_line = response->headers->GetStatusLine(); 4629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 4630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("hello!", out.response_data); 4631eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Check that the SpdySession is still in the SpdySessionPool. 4633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostPortPair host_port_pair("www.google.com", helper.port()); 4634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey session_pool_key_direct( 4635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch host_port_pair, ProxyServer::Direct(), kPrivacyModeDisabled); 46367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool, session_pool_key_direct)); 4637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey session_pool_key_proxy( 4638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch host_port_pair, 4639eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ProxyServer::FromURI("www.foo.com", ProxyServer::SCHEME_HTTP), 4640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kPrivacyModeDisabled); 46417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool, session_pool_key_proxy)); 4642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Set up data for the proxy connection. 4644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n" 4645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Host: www.google.com\r\n" 4646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Proxy-Connection: keep-alive\r\n\r\n"}; 4647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n" 4648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Host: www.google.com\r\n" 4649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Proxy-Connection: keep-alive\r\n\r\n"}; 4650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"}; 4651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyGet( 4652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat", false, 1, LOWEST)); 4653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 4654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); 46555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes_SPDYNPN[] = { 4657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0), 4658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 2), 4659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads_SPDYNPN[] = { 4661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1), 4662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp2, 3), 4663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body2, 4), 4664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 5) // EOF 4665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes_SPDYNOSSL[] = { 4668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 0), 4669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads_SPDYNOSSL[] = { 4671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp2, 1), 4672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body2, 2), 4673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 3) // EOF 4674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 46755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes_SPDYSSL[] = { 4677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite(SYNCHRONOUS, kConnect80, arraysize(kConnect80) - 1, 0), 4678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 2), 4679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads_SPDYSSL[] = { 4681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1), 4682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp2, 3), 4683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body2, 4), 4684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 5), 4685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 46865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<OrderedSocketData> data_proxy; 4688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch switch(GetParam().ssl_type) { 4689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case SPDYNPN: 4690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data_proxy.reset(new OrderedSocketData(reads_SPDYNPN, 4691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(reads_SPDYNPN), 4692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes_SPDYNPN, 4693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(writes_SPDYNPN))); 4694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 4695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case SPDYNOSSL: 4696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data_proxy.reset(new OrderedSocketData(reads_SPDYNOSSL, 4697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(reads_SPDYNOSSL), 4698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes_SPDYNOSSL, 4699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(writes_SPDYNOSSL))); 4700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 4701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case SPDYSSL: 4702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data_proxy.reset(new OrderedSocketData(reads_SPDYSSL, 4703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(reads_SPDYSSL), 4704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes_SPDYSSL, 4705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(writes_SPDYSSL))); 4706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 4707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch default: 4708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NOTREACHED(); 4709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4711eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create another request to www.google.com, but this time through a proxy. 4712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpRequestInfo request_proxy; 4713eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request_proxy.method = "GET"; 4714eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request_proxy.url = GURL("http://www.google.com/foo.dat"); 4715eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request_proxy.load_flags = 0; 4716eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdySessionDependencies> ssd_proxy( 4717eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateSpdySessionDependencies(GetParam())); 4718eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure that this transaction uses the same SpdySessionPool. 4719eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<HttpNetworkSession> session_proxy( 4720eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionDependencies::SpdyCreateSession(ssd_proxy.get())); 4721eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper_proxy(request_proxy, DEFAULT_PRIORITY, 4722eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 4723eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSessionPeer session_peer(session_proxy); 4724eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<net::ProxyService> proxy_service( 4725eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 4726eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_peer.SetProxyService(proxy_service.get()); 4727eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper_proxy.session_deps().swap(ssd_proxy); 4728eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper_proxy.SetSession(session_proxy); 4729eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper_proxy.RunPreTestSetup(); 4730eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper_proxy.AddData(data_proxy.get()); 47315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4732eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans_proxy = helper_proxy.trans(); 4733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback_proxy; 4734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans_proxy->Start( 4735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &request_proxy, callback_proxy.callback(), BoundNetLog()); 4736eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 4737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback_proxy.WaitForResult(); 4738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, rv); 47395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response_proxy = *trans_proxy->GetResponseInfo(); 4741eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response_proxy.headers.get() != NULL); 4742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response_proxy.headers->GetStatusLine()); 47435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string response_data; 4745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(OK, ReadTransaction(trans_proxy, &response_data)); 4746eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("hello!", response_data); 4747eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.CompleteRead(); 4749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper_proxy.VerifyDataConsumed(); 4750eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 47515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4752eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// When we get a TCP-level RST, we need to retry a HttpNetworkTransaction 4753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// on a new connection, if the connection was previously known to be good. 4754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// This can happen when a server reboots without saying goodbye, or when 4755eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// we're behind a NAT that masked the RST. 4756eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) { 4757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 47587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 47595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 4760eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp), 4761eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body), 4762eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING), 4763eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_CONNECTION_RESET), 4764eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4766eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads2[] = { 4767eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp), 47685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*body), 47695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 47705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 47715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4772eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This test has a couple of variants. 4773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch enum { 4774eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Induce the RST while waiting for our transaction to send. 4775eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VARIANT_RST_DURING_SEND_COMPLETION, 4776eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Induce the RST while waiting for our transaction to read. 4777eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // In this case, the send completed - everything copied into the SNDBUF. 4778eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VARIANT_RST_DURING_READ_COMPLETION 4779eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 47805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4781eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (int variant = VARIANT_RST_DURING_SEND_COMPLETION; 4782eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch variant <= VARIANT_RST_DURING_READ_COMPLETION; 4783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ++variant) { 4784eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data1(1, reads, arraysize(reads), NULL, 0); 47855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4786eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data2(1, reads2, arraysize(reads2), NULL, 0); 47875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 4789eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 4790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data1); 4791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data2); 4792eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 47935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (int i = 0; i < 2; ++i) { 4795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<HttpNetworkTransaction> trans( 4796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 47977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 4799eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start( 4800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &helper.request(), callback.callback(), BoundNetLog()); 4801eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 4802eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // On the second transaction, we trigger the RST. 4803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (i == 1) { 4804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (variant == VARIANT_RST_DURING_READ_COMPLETION) { 4805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Writes to the socket complete asynchronously on SPDY by running 4806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // through the message loop. Complete the write here. 48073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 4808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 48095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Now schedule the ERR_CONNECTION_RESET. 4811eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(3u, data1.read_index()); 4812eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data1.CompleteRead(); 4813eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(4u, data1.read_index()); 4814eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 4815eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 4816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, rv); 48175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4818eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 4819eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(response != NULL); 4820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response->headers.get() != NULL); 4821eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 4822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string response_data; 4823eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = ReadTransaction(trans.get(), &response_data); 4824eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, rv); 4825eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 4826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("hello!", response_data); 4827eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 48285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 4830eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 4831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 48327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4833eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test that turning SPDY on and off works properly. 4834eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) { 4835eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::HttpStreamFactory::set_spdy_enabled(true); 483690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 483790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4838eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 48395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 4841eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 4842eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead spdy_reads[] = { 48435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*resp), 4844eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body), 4845eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0) // EOF 48465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 48475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4848eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data(1, spdy_reads, arraysize(spdy_reads), 4849eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_writes, arraysize(spdy_writes)); 48502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 4851eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 4852eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunToCompletion(&data); 4853eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransactionHelperResult out = helper.output(); 4854eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, out.rv); 4855eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 4856eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("hello!", out.response_data); 48575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4858eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::HttpStreamFactory::set_spdy_enabled(false); 4859eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead http_reads[] = { 4860eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead("HTTP/1.1 200 OK\r\n\r\n"), 4861eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead("hello from http"), 4862eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, OK), 4863eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4864eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data2(1, http_reads, arraysize(http_reads), NULL, 0); 4865eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper2(CreateGetRequest(), DEFAULT_PRIORITY, 4866eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 4867eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper2.SetSpdyDisabled(); 4868eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper2.RunToCompletion(&data2); 4869eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransactionHelperResult out2 = helper2.output(); 4870eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, out2.rv); 4871eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", out2.status_line); 4872eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("hello from http", out2.response_data); 48735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4874eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::HttpStreamFactory::set_spdy_enabled(true); 48755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 48765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4877eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Tests that Basic authentication works over SPDY 4878eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) { 4879eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::HttpStreamFactory::set_spdy_enabled(true); 48805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4881eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The first request will be a bare GET, the second request will be a 4882eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // GET with an Authorization header. 4883eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req_get( 488490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4885eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char* const kExtraAuthorizationHeaders[] = { 4886eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "authorization", "Basic Zm9vOmJhcg==" 48875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4888eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req_get_authorization( 4889eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders, 4890eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(kExtraAuthorizationHeaders) / 2, 4891eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 3, LOWEST, true)); 4892eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite spdy_writes[] = { 4893eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req_get, 1), 4894eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req_get_authorization, 4), 48955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 48965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4897eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The first response is a 401 authentication challenge, and the second 4898eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // response will be a 200 response since the second request includes a valid 4899eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Authorization header. 4900eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char* const kExtraAuthenticationHeaders[] = { 4901eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "www-authenticate", 4902eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Basic realm=\"MyRealm\"" 49035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4904eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp_authentication( 4905eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdySynReplyError( 4906eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "401 Authentication Required", 4907eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kExtraAuthenticationHeaders, 4908eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch arraysize(kExtraAuthenticationHeaders) / 2, 4909eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1)); 4910eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body_authentication( 4911eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 4912eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp_data( 4913eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 4914eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true)); 4915eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead spdy_reads[] = { 4916eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp_authentication, 2), 4917eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body_authentication, 3), 4918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp_data, 5), 4919eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body_data, 6), 4920eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 7), 49215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 49225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4923eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(spdy_reads, arraysize(spdy_reads), 4924eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_writes, arraysize(spdy_writes)); 4925eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpRequestInfo request(CreateGetRequest()); 4926eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog net_log; 4927eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 4928eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net_log, GetParam(), NULL); 49295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4930eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 4931eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 4932eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 49335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 4934eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int rv_start = trans->Start(&request, callback.callback(), net_log); 4935eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv_start); 4936eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int rv_start_complete = callback.WaitForResult(); 4937eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, rv_start_complete); 49385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4939eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Make sure the response has an auth challenge. 4940eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const HttpResponseInfo* const response_start = trans->GetResponseInfo(); 4941eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(response_start != NULL); 4942eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(response_start->headers.get() != NULL); 4943eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(401, response_start->headers->response_code()); 4944eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response_start->was_fetched_via_spdy); 4945eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AuthChallengeInfo* auth_challenge = response_start->auth_challenge.get(); 4946eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(auth_challenge != NULL); 4947eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(auth_challenge->is_proxy); 4948eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("basic", auth_challenge->scheme); 4949eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("MyRealm", auth_challenge->realm); 49505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4951eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Restart with a username/password. 4952eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AuthCredentials credentials(ASCIIToUTF16("foo"), ASCIIToUTF16("bar")); 4953eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback_restart; 4954eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int rv_restart = trans->RestartWithAuth( 4955eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch credentials, callback_restart.callback()); 4956eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv_restart); 4957eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int rv_restart_complete = callback_restart.WaitForResult(); 4958eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, rv_restart_complete); 4959eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(cbentzel): This is actually the same response object as before, but 4960eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // data has changed. 4961eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const HttpResponseInfo* const response_restart = trans->GetResponseInfo(); 4962eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(response_restart != NULL); 4963eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(response_restart->headers.get() != NULL); 4964eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(200, response_restart->headers->response_code()); 4965eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response_restart->auth_challenge.get() == NULL); 49665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 49675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4968eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) { 4969eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 497090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4971eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 4972eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 49735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 4974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 1), 49755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 49765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4977eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); 4978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.AddUrlToHeaderBlock( 4979eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat", initial_headers.get()); 4980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_syn( 4981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(), 4982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 4983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 4984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, 4985eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SYN_STREAM, 4986eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, 4987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1)); 4988eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock()); 4990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*late_headers)["hello"] = "bye"; 4991eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*late_headers)[spdy_util_.GetStatusKey()] = "200"; 4992eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; 4993eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_headers( 4994eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(), 4995eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 4996eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 4997eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, 4998eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HEADERS, 4999eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, 5000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0)); 5001eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5002eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 5003eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 5004eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kPushedData[] = "pushed"; 5005eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body( 5006eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 5007eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, kPushedData, strlen(kPushedData), true)); 50085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 5009eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 2), 5010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 3), 5011eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_headers, 4), 5012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 5, SYNCHRONOUS), 5013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body, 5), 5014eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 7), // Force a pause 50155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5017eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response; 5018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response2; 5019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string expected_push_result("pushed"); 50205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrderedSocketData data(reads, arraysize(reads), 50215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 5022eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RunServerPushTest(&data, 5023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &response, 5024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &response2, 5025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected_push_result); 50265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5027eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 5028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 5029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 50305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the pushed stream. 5032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers.get() != NULL); 5033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 5034eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 50355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5036eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) { 5037eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // We push a stream and attempt to claim it before the headers come down. 5038eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 5039eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 5040eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 5041eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 5042eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 5043eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS), 50445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 50455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5046eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); 5047eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.AddUrlToHeaderBlock( 5048eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat", initial_headers.get()); 5049eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_syn( 5050eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(), 5051eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 5052eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 5053eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, 5054eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SYN_STREAM, 5055eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, 5056eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1)); 50575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5058eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock()); 5059eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*late_headers)["hello"] = "bye"; 5060eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*late_headers)[spdy_util_.GetStatusKey()] = "200"; 5061eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; 5062eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_headers( 5063eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(), 5064eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 5065eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 5066eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, 5067eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HEADERS, 5068eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, 5069eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0)); 50705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5071eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 5072eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 5073eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kPushedData[] = "pushed"; 5074eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body( 5075eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 5076eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, kPushedData, strlen(kPushedData), true)); 5077eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 5078eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 1), 5079eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 2), 5080eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 3), 5081eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_headers, 4), 5082eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body, 5), 5083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 6), // EOF 5084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 50855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5086eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response; 5087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response2; 5088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string expected_push_result("pushed"); 5089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 5090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 50915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 5093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 5094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.SetDeterministic(); 5095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddDeterministicData(&data); 5096eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 50977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 50995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM, 5101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // and the body of the primary stream, but before we've received the HEADERS 5102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // for the pushed stream. 5103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.SetStop(3); 51045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Start the transaction. 5106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 5107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start( 5108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetRequest(), callback.callback(), BoundNetLog()); 5109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.Run(); 5111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 5112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, rv); 51135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Request the pushed path. At this point, we've received the push, but the 5115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // headers are not yet complete. 5116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<HttpNetworkTransaction> trans2( 5117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 5118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = trans2->Start( 5119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetPushRequest(), callback.callback(), BoundNetLog()); 5120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(3); 51223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 51235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read the server push body. 5125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string result2; 5126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ReadResult(trans2.get(), &data, &result2); 5127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read the response body. 5128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string result; 5129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ReadResult(trans, &data, &result); 51305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that the received push data is same as the expected push data. 5132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(result2.compare(expected_push_result), 0) 5133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "Received data: " 5134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << result2 5135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "||||| Expected data: " 5136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << expected_push_result; 51375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 5139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Copy the response info, because trans goes away. 5140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch response = *trans->GetResponseInfo(); 5141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch response2 = *trans2->GetResponseInfo(); 51425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VerifyStreamsClosed(helper); 51445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 5146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 5147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 51485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the pushed stream. 5150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers.get() != NULL); 5151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 51525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read the final EOF (which will close the session) 5154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 51555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that we consumed all test data. 5157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_read_eof()); 5158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()); 5159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 51607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) { 5162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // We push a stream and attempt to claim it before the headers come down. 5163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 516490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 5165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 5166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 5167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 5168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS), 5169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 51705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); 5172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.AddUrlToHeaderBlock( 5173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat", initial_headers.get()); 5174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_syn( 5175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(), 5176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 5177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 5178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, 5179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SYN_STREAM, 5180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, 5181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1)); 5182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> middle_headers(new SpdyHeaderBlock()); 5184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*middle_headers)["hello"] = "bye"; 5185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_headers1( 5186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(middle_headers.Pass(), 5187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 5188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 5189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, 5190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HEADERS, 5191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, 5192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0)); 5193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock()); 5195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*late_headers)[spdy_util_.GetStatusKey()] = "200"; 5196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; 5197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_headers2( 5198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(), 5199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 5200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 5201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, 5202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HEADERS, 5203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, 5204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0)); 5205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 5207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 5208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kPushedData[] = "pushed"; 5209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body( 5210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 5211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, kPushedData, strlen(kPushedData), true)); 5212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 5213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 1), 5214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 2), 5215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 3), 5216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_headers1, 4), 5217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_headers2, 5), 5218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body, 6), 5219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 7), // EOF 52205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 52215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response; 5223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response2; 5224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string expected_push_result("pushed"); 5225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 5226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 5227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 52282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 52295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 5230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.SetDeterministic(); 5231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddDeterministicData(&data); 5232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 52335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 52355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM, 5237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // the first HEADERS frame, and the body of the primary stream, but before 5238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // we've received the final HEADERS for the pushed stream. 5239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.SetStop(4); 52405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Start the transaction. 5242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 5243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start( 5244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetRequest(), callback.callback(), BoundNetLog()); 5245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.Run(); 5247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 5248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, rv); 52497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Request the pushed path. At this point, we've received the push, but the 5251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // headers are not yet complete. 5252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<HttpNetworkTransaction> trans2( 5253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 5254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = trans2->Start( 5255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetPushRequest(), callback.callback(), BoundNetLog()); 5256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(3); 52583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 52595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read the server push body. 5261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string result2; 5262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ReadResult(trans2.get(), &data, &result2); 5263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read the response body. 5264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string result; 5265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ReadResult(trans, &data, &result); 5266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that the received push data is same as the expected push data. 5268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(expected_push_result, result2); 5269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 5271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Copy the response info, because trans goes away. 5272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch response = *trans->GetResponseInfo(); 5273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch response2 = *trans2->GetResponseInfo(); 52745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VerifyStreamsClosed(helper); 52765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 5278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 5279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 52805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the pushed stream. 5282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers.get() != NULL); 5283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 52845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify we got all the headers 5286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (spdy_util_.spdy_version() < SPDY3) { 5287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue( 5288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "url", 5289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.dat")); 5290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 5291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue( 5292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "scheme", "http")); 5293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue( 5294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "host", "www.google.com")); 5295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue( 5296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "path", "/foo.dat")); 5297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 5298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue("hello", "bye")); 5299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue("status", "200")); 5300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response2.headers->HasHeaderValue("version", "HTTP/1.1")); 53015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read the final EOF (which will close the session) 5303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 53045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that we consumed all test data. 5306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_read_eof()); 5307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()); 5308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 53097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushWithNoStatusHeaderFrames) { 5311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // We push a stream and attempt to claim it before the headers come down. 531290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> stream1_syn( 531390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 53147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> stream1_body( 53157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, true)); 53165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 5317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS), 53185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 53195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); 53217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.AddUrlToHeaderBlock( 53227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "http://www.google.com/foo.dat", initial_headers.get()); 5323a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) scoped_ptr<SpdyFrame> stream2_syn( 53247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(), 5325a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) false, 5326a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 2, 5327a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) LOWEST, 5328a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) SYN_STREAM, 5329a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) CONTROL_FLAG_NONE, 5330a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1)); 53317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> middle_headers(new SpdyHeaderBlock()); 5333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*middle_headers)["hello"] = "bye"; 5334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_headers1( 5335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(middle_headers.Pass(), 5336a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) false, 5337a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 2, 5338a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) LOWEST, 5339a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) HEADERS, 5340a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) CONTROL_FLAG_NONE, 5341a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 0)); 53425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> 53447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 5345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kPushedData[] = "pushed"; 5346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body( 5347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 5348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, kPushedData, strlen(kPushedData), true)); 53495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 5350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 1), 5351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 2), 5352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 3), 5353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_headers1, 4), 5354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body, 5), 5355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 6), // EOF 53565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 53575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 5359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 5360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 5362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 5363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.SetDeterministic(); 5364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddDeterministicData(&data); 5365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 5366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 5368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM, 5370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // the first HEADERS frame, and the body of the primary stream, but before 5371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // we've received the final HEADERS for the pushed stream. 5372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.SetStop(4); 5373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Start the transaction. 5375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 5376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start( 5377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetRequest(), callback.callback(), BoundNetLog()); 5378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.Run(); 5380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 5381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, rv); 5382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Request the pushed path. At this point, we've received the push, but the 5384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // headers are not yet complete. 5385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<HttpNetworkTransaction> trans2( 5386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get())); 5387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = trans2->Start( 5388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &CreateGetPushRequest(), callback.callback(), BoundNetLog()); 5389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(2); 53913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 5392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read the server push body. 5394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string result2; 5395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ReadResult(trans2.get(), &data, &result2); 5396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read the response body. 5397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string result; 5398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ReadResult(trans, &data, &result); 5399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("hello!", result); 5400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that we haven't received any push data. 5402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("", result2); 5403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 5405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Copy the response info, because trans goes away. 5406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response = *trans->GetResponseInfo(); 5407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(trans2->GetResponseInfo() == NULL); 5408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VerifyStreamsClosed(helper); 54105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify the SYN_REPLY. 5412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response.headers.get() != NULL); 54135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 54145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read the final EOF (which will close the session). 5416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 54175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that we consumed all test data. 5419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_read_eof()); 5420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()); 5421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 54227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, SynReplyWithHeaders) { 5424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 542590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 5426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 5427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); 5428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 5429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req), 5430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*rst), 5431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 5432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); 5434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*initial_headers)[spdy_util_.GetStatusKey()] = "200 OK"; 5435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*initial_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; 5436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_reply( 5437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(), 5438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 5439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 5440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, 5441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SYN_REPLY, 5442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, 5443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0)); 5444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock()); 5446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*late_headers)["hello"] = "bye"; 5447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_headers( 5448eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(), 5449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 5450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 5451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, 5452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HEADERS, 5453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, 5454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0)); 54557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> stream1_body( 54567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, true)); 5457eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 5458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply), 5459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_headers), 5460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body), 5461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0) // EOF 5462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 5463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data(1, reads, arraysize(reads), 5465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 5466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 5467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 5468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunToCompletion(&data); 5469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransactionHelperResult out = helper.output(); 5470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 5471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 5472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, SynReplyWithLateHeaders) { 5474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 5475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 5476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 5477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); 54785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 5479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req), 5480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*rst), 54815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 54825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); 5484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*initial_headers)[spdy_util_.GetStatusKey()] = "200 OK"; 5485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*initial_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; 5486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_reply( 54877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(), 5488a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) false, 5489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 5490a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) LOWEST, 5491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SYN_REPLY, 5492a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) CONTROL_FLAG_NONE, 5493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0)); 54947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 54957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock()); 54967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (*late_headers)["hello"] = "bye"; 5497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_headers( 54987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(), 5499a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) false, 5500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 5501a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) LOWEST, 5502a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) HEADERS, 5503a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) CONTROL_FLAG_NONE, 5504a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 0)); 5505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 5506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, false)); 5507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body2( 5508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 55095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 5510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply), 5511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body), 5512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_headers), 5513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body2), 5514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0) // EOF 55155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 55165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data(1, reads, arraysize(reads), 5518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 5519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 5520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 5521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunToCompletion(&data); 5522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransactionHelperResult out = helper.output(); 5523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 5524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 5525eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) { 5527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // In this test we want to verify that we can't accidentally push content 5528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // which can't be pushed by this content server. 5529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This test assumes that: 5530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // - if we're requesting http://www.foo.com/barbaz 5531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // - the browser has made a connection to "www.foo.com". 5532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // A list of the URL to fetch, followed by the URL being pushed. 5534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const char* const kTestCases[] = { 5535eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.html", 5536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com:81/foo.js", // Bad port 5537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.html", 5539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "https://www.google.com/foo.js", // Bad protocol 5540eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.html", 5542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "ftp://www.google.com/foo.js", // Invalid Protocol 5543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5544eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.html", 5545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://blat.www.google.com/foo.js", // Cross subdomain 5546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.google.com/foo.html", 5548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://www.foo.com/foo.js", // Cross domain 5549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 5550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t index = 0; index < arraysize(kTestCases); index += 2) { 5552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char* url_to_fetch = kTestCases[index]; 5553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char* url_to_push = kTestCases[index + 1]; 5554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_syn( 5556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(url_to_fetch, false, 1, LOWEST)); 5557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream1_body( 5558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 5559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> push_rst( 5560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); 5561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 5562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*stream1_syn, 1), 5563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*push_rst, 4), 5564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 5565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 5567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 5568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 5569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 5570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 5571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 5572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, 5573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch url_to_push)); 5574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kPushedData[] = "pushed"; 5575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> stream2_body( 5576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 5577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, kPushedData, strlen(kPushedData), true)); 5578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 5579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL)); 5580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 5582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_reply, 2), 5583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_syn, 3), 5584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream1_body, 5, SYNCHRONOUS), 5585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*stream2_body, 6), 5586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 7), // Force a pause 5587eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 5588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response; 5590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(reads, arraysize(reads), 5591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 5592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpRequestInfo request; 5594eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.method = "GET"; 5595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.url = GURL(url_to_fetch); 5596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.load_flags = 0; 5597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Enable cross-origin push. Since we are not using a proxy, this should 5599eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // not actually enable cross-origin SPDY push. 5600eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdySessionDependencies> session_deps( 5601eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateSpdySessionDependencies(GetParam())); 5602eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps->trusted_spdy_proxy = "123.45.67.89:8080"; 5603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 5604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), 5605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps.release()); 5606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 5607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 5608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 56105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Start the transaction with basic parameters. 5612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 5613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 5615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 5617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5618eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read the response body. 5619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string result; 5620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ReadResult(trans, &data, &result); 5621eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5622eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that we consumed all test data. 5623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_read_eof()); 5624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()); 5625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 5627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Copy the response info, because trans goes away. 5628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch response = *trans->GetResponseInfo(); 5629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VerifyStreamsClosed(helper); 5631eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the SYN_REPLY. 5633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response.headers.get() != NULL); 5634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 5635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 5636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 5637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, RetryAfterRefused) { 5639eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct the request. 5640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req( 5641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 5642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2( 5643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 5644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 5645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 1), 5646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 3), 5647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 5648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> refused( 5650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM)); 5651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 5652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(3, true)); 5653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 5654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*refused, 2), 5655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 4), 5656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body, 5), 5657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 6) // EOF 5658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 5659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(reads, arraysize(reads), 5661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 56622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 56635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 5664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 56655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 5666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 56675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 56695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Start the transaction with basic parameters. 56715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 56725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = trans->Start( 56735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateGetRequest(), callback.callback(), BoundNetLog()); 56745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 56755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 5676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, rv); 56775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify that we consumed all test data. 5679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_read_eof()) << "Read count: " 5680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.read_count() 5681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " Read index: " 5682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.read_index(); 5683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()) << "Write count: " 5684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.write_count() 5685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " Write index: " 5686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << data.write_index(); 56875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify the SYN_REPLY. 5689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpResponseInfo response = *trans->GetResponseInfo(); 5690868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(response.headers.get() != NULL); 56915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 56925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 56935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) { 5695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This first request will start to establish the SpdySession. 5696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Then we will start the second (MEDIUM priority) and then third 5697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // (HIGHEST priority) request in such a way that the third will actually 5698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // start before the second, causing the second to be numbered differently 5699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // than the order they were created. 5700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req1( 570190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 5702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2( 5703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, HIGHEST, true)); 5704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req3( 5705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, MEDIUM, true)); 57065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 5707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 5708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 3), 5709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req3, 4), 57105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 57115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 5713eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 5714eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 5715eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 5716eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5)); 5717eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true)); 57185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 5719eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp1, 1), 5720eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body1, 2), 5721eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp2, 5), 5722eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body2, 6), 5723eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp3, 7), 5724eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body3, 8), 5725eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 9) // EOF 57265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 57275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 57295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 5730eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(CreateGetRequest(), LOWEST, 57315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 57325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.SetDeterministic(); 57335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 5734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddDeterministicData(&data); 57355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5736eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Start the first transaction to set up the SpdySession 57375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 57385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 5739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpRequestInfo info1 = CreateGetRequest(); 5740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start(&info1, callback.callback(), BoundNetLog()); 57415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 57425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Run the message loop, but do not allow the write to complete. 5744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This leaves the SpdySession with a write pending, which prevents 5745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // SpdySession from attempting subsequent writes until this write completes. 57463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 5747eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Now, start both new transactions 5749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpRequestInfo info2 = CreateGetRequest(); 5750eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback2; 57515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans2( 5752eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new HttpNetworkTransaction(MEDIUM, helper.session().get())); 5753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = trans2->Start(&info2, callback2.callback(), BoundNetLog()); 57545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 57553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 57565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpRequestInfo info3 = CreateGetRequest(); 5758eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback3; 5759eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<HttpNetworkTransaction> trans3( 5760eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new HttpNetworkTransaction(HIGHEST, helper.session().get())); 5761eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = trans3->Start(&info3, callback3.callback(), BoundNetLog()); 5762eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 57633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 57645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // We now have two SYN_STREAM frames queued up which will be 5766eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // dequeued only once the first write completes, which we 5767eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // now allow to happen. 5768eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(2); 5769eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, callback.WaitForResult()); 57705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5771eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // And now we can allow everything else to run to completion. 5772eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.SetStop(10); 5773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.Run(); 5774eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, callback2.WaitForResult()); 5775eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, callback3.WaitForResult()); 57765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5777eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 5778eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 57795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5780eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The tests below are only for SPDY/3 and above. 57815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5782eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test that sent data frames and received WINDOW_UPDATE frames change 5783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// the send_window_size_ correctly. 57845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5785eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// WINDOW_UPDATE is different than most other frames in that it can arrive 5786eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// while the client is still sending the request body. In order to enforce 5787eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// this scenario, we feed a couple of dummy frames and give a delay of 0 to 5788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// socket data provider, so that initial read that is done as soon as the 5789eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// stream is created, succeeds and schedules another read. This way reads 5790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// and writes are interleaved; after doing a full frame write, SpdyStream 5791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// will break out of DoLoop and will read and process a WINDOW_UPDATE. 5792eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Once our WINDOW_UPDATE is read, we cannot send SYN_REPLY right away 5793eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// since request has not been completely written, therefore we feed 5794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// enough number of WINDOW_UPDATEs to finish the first read and cause a 5795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// write, leading to a complete write of request body; after that we send 5796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// a reply with a body, to cause a graceful shutdown. 57975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(agayev): develop a socket data provider where both, reads and 5799eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// writes are ordered so that writing tests like these are easy and rewrite 5800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// all these tests using it. Right now we are working around the 5801eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// limitations as described above and it's not deterministic, tests may 5802eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// fail under specific circumstances. 5803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) { 5804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam().protocol < kProtoSPDY3) 58057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 58067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5807eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static int kFrameCount = 2; 5808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<std::string> content( 5809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new std::string(kMaxSpdyFrameChunkSize, 'a')); 5810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost( 5811eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kRequestUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL, 0)); 5812eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body( 5813eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 5814eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, content->c_str(), content->size(), false)); 5815eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body_end( 5816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 5817eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, content->c_str(), content->size(), true)); 5818eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 58195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 5820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 0), 5821eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*body, 1), 5822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*body_end, 2), 58235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 58245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5825eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const int32 kDeltaWindowSize = 0xff; 5826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const int kDeltaCount = 4; 5827eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> window_update( 5828eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize)); 5829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> window_update_dummy( 5830eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate(2, kDeltaWindowSize)); 5831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 58325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 5833eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*window_update_dummy, 3), 5834eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*window_update_dummy, 4), 5835eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*window_update_dummy, 5), 5836eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*window_update, 6), // Four updates, therefore window 5837eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*window_update, 7), // size should increase by 5838eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*window_update, 8), // kDeltaWindowSize * 4 5839eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*window_update, 9), 5840eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 10), 5841eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body_end, 11), 5842eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 12) // EOF 58435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 58445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 58465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 58475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5848eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedVector<UploadElementReader> element_readers; 5849eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (int i = 0; i < kFrameCount; ++i) { 5850eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch element_readers.push_back( 5851eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new UploadBytesElementReader(content->c_str(), content->size())); 5852eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 585368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UploadDataStream upload_data_stream(element_readers.Pass(), 0); 5854eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5855eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Setup the request 5856eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpRequestInfo request; 5857eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.method = "POST"; 5858eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.url = GURL(kDefaultURL); 5859eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.upload_data_stream = &upload_data_stream; 5860eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5861eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 58625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 58635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.SetDeterministic(); 58645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddDeterministicData(&data); 58655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 58665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 58685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 5870eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog()); 58715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 58735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5874eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(11); 58755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5876eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get()); 5877eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream != NULL); 5878eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream->stream() != NULL); 5879eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(static_cast<int>(kSpdyStreamInitialWindowSize) + 5880eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kDeltaWindowSize * kDeltaCount - 5881eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kMaxSpdyFrameChunkSize * kFrameCount, 5882eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream->stream()->send_window_size()); 58835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.RunFor(1); 58855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5886eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 5887eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, rv); 5888eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5889eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 58905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 58915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5892eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test that received data frames and sent WINDOW_UPDATE frames change 5893eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// the recv_window_size_ correctly. 5894eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) { 5895eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam().protocol < kProtoSPDY3) 58967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 58977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5898eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Set the data in the body frame large enough to trigger sending a 5899eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // WINDOW_UPDATE by the stream. 5900eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string body_data(kSpdyStreamInitialWindowSize / 2 + 1, 'x'); 5901eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 590290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 590390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 5904eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> session_window_update( 5905eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate(0, body_data.size())); 5906eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> window_update( 5907eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate(1, body_data.size())); 59085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5909eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MockWrite> writes; 5910eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes.push_back(CreateMockWrite(*req)); 5911eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam().protocol >= kProtoSPDY31) 5912eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes.push_back(CreateMockWrite(*session_window_update)); 5913eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes.push_back(CreateMockWrite(*window_update)); 59147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5915eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp( 5916eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 5917eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body_no_fin( 5918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 5919eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, body_data.data(), body_data.size(), false)); 5920eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body_fin( 5921eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, NULL, 0, true)); 59225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 5923eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp), 5924eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body_no_fin), 5925eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 0), // Force a pause 5926eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body_fin), 5927eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, ERR_IO_PENDING, 0), // Force a pause 59285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 59295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 59305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayedSocketData data(1, reads, arraysize(reads), 5932eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch vector_as_array(&writes), writes.size()); 5933eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 59342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 59355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 5936eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 5937eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 5938eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 5939eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5940eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 5941eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog()); 5942eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5943eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 5944eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 5945eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, rv); 5946eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5947eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyHttpStream* stream = 5948eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static_cast<SpdyHttpStream*>(trans->stream_.get()); 5949eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream != NULL); 5950eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream->stream() != NULL); 5951eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5952eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ( 5953eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static_cast<int>(kSpdyStreamInitialWindowSize - body_data.size()), 5954eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream->stream()->recv_window_size()); 5955eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5956eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const HttpResponseInfo* response = trans->GetResponseInfo(); 5957eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(response != NULL); 5958eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(response->headers.get() != NULL); 5959eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 5960eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(response->was_fetched_via_spdy); 5961eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5962eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Issue a read which will cause a WINDOW_UPDATE to be sent and window 5963eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // size increased to default. 5964eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(body_data.size())); 5965eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = trans->Read(buf.get(), body_data.size(), CompletionCallback()); 5966eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(static_cast<int>(body_data.size()), rv); 5967eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content(buf->data(), buf->data() + body_data.size()); 5968eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(body_data, content); 5969eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5970eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Schedule the reading of empty data frame with FIN 5971eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.CompleteRead(); 5972eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5973eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Force write of WINDOW_UPDATE which was scheduled during the above 5974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // read. 59753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 5976eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5977eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read EOF. 5978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.CompleteRead(); 5979eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 59815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 59825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test that WINDOW_UPDATE frame causing overflow is handled correctly. 5984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) { 5985eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam().protocol < kProtoSPDY3) 59867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 59877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5988eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Number of full frames we hope to write (but will not, used to 5989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // set content-length header correctly) 5990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static int kFrameCount = 3; 59915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5992eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<std::string> content( 5993eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new std::string(kMaxSpdyFrameChunkSize, 'a')); 5994eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost( 5995eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kRequestUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL, 0)); 5996eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body( 5997eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 5998eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, content->c_str(), content->size(), false)); 5999eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 6000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR)); 60017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6002eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // We're not going to write a data frame with FIN, we'll receive a bad 6003eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // WINDOW_UPDATE while sending a request and will send a RST_STREAM frame. 6004eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 6005eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 0), 6006eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*body, 2), 6007eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*rst, 3), 6008eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 6009eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static const int32 kDeltaWindowSize = 0x7fffffff; // cause an overflow 6011eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> window_update( 6012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize)); 60135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 6014eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*window_update, 1), 6015eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 4) // EOF 60165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 60175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 6019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 6020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6021eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedVector<UploadElementReader> element_readers; 6022eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (int i = 0; i < kFrameCount; ++i) { 6023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch element_readers.push_back( 6024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new UploadBytesElementReader(content->c_str(), content->size())); 6025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 602668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UploadDataStream upload_data_stream(element_readers.Pass(), 0); 6027eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Setup the request 6029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpRequestInfo request; 6030eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.method = "POST"; 6031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.url = GURL("http://www.google.com/"); 6032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.upload_data_stream = &upload_data_stream; 6033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6034eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 60355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 6036eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.SetDeterministic(); 6037eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 6038eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddDeterministicData(&data); 6039eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 6040eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6041eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 6042eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog()); 6043eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(ERR_IO_PENDING, rv); 6044eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6045eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(5); 6046eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(callback.have_result()); 6047eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, callback.WaitForResult()); 6048eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 60495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 60505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6051eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test that after hitting a send window size of 0, the write process 6052eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// stalls and upon receiving WINDOW_UPDATE frame write resumes. 6053eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6054eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// This test constructs a POST request followed by enough data frames 6055eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// containing 'a' that would make the window size 0, followed by another 6056eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// data frame containing default content (which is "hello!") and this frame 6057eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// also contains a FIN flag. DelayedSocketData is used to enforce all 6058eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// writes go through before a read could happen. However, the last frame 6059eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// ("hello!") is not supposed to go through since by the time its turn 6060eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// arrives, window size is 0. At this point MessageLoop::Run() called via 6061eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// callback would block. Therefore we call MessageLoop::RunUntilIdle() 6062eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// which returns after performing all possible writes. We use DCHECKS to 6063eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// ensure that last data frame is still there and stream has stalled. 6064eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// After that, next read is artifically enforced, which causes a 6065eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// WINDOW_UPDATE to be read and I/O process resumes. 6066eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) { 6067eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam().protocol < kProtoSPDY3) 60687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 60697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6070eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Number of frames we need to send to zero out the window size: data 6071eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // frames plus SYN_STREAM plus the last data frame; also we need another 6072eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // data frame that we will send once the WINDOW_UPDATE is received, 6073eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // therefore +3. 6074eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3; 60755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6076eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Calculate last frame's size; 0 size data frame is legal. 6077eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t last_frame_size = 6078eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize; 60797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6080eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct content for a data frame of maximum size. 6081eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content(kMaxSpdyFrameChunkSize, 'a'); 60825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost( 6084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize, 6085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, NULL, 0)); 60865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Full frames. 6088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body1( 6089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 6090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, content.c_str(), content.size(), false)); 60917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Last frame to zero out the window size. 6093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body2( 6094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 6095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, content.c_str(), last_frame_size, false)); 60965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Data frame to be sent once WINDOW_UPDATE frame is received. 6098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true)); 60995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Fill in mock writes. 6101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<MockWrite[]> writes(new MockWrite[num_writes]); 6102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t i = 0; 6103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes[i] = CreateMockWrite(*req); 6104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (i = 1; i < num_writes - 2; i++) 6105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes[i] = CreateMockWrite(*body1); 6106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes[i++] = CreateMockWrite(*body2); 6107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes[i] = CreateMockWrite(*body3); 61085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct read frame, give enough space to upload the rest of the 6110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // data. 6111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> session_window_update( 6112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize)); 6113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> window_update( 6114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize)); 6115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 6116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 6117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*session_window_update), 6118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*session_window_update), 6119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*window_update), 6120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*window_update), 6121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*reply), 6122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body2), 6123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body3), 6124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0) // EOF 6125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 61265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Skip the session window updates unless we're using SPDY/3.1 and 6128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // above. 6129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t read_offset = (GetParam().protocol >= kProtoSPDY31) ? 0 : 2; 6130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t num_reads = arraysize(reads) - read_offset; 61315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Force all writes to happen before any read, last write will not 6133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // actually queue a frame, due to window size being 0. 6134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DelayedSocketData data(num_writes, reads + read_offset, num_reads, 6135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes.get(), num_writes); 61365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedVector<UploadElementReader> element_readers; 6138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a'); 6139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch upload_data_string.append(kUploadData, kUploadDataSize); 6140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch element_readers.push_back(new UploadBytesElementReader( 6141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch upload_data_string.c_str(), upload_data_string.size())); 614268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UploadDataStream upload_data_stream(element_readers.Pass(), 0); 61435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpRequestInfo request; 6145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.method = "POST"; 6146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.url = GURL("http://www.google.com/"); 6147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.upload_data_stream = &upload_data_stream; 6148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 6149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog(), GetParam(), NULL); 6150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddData(&data); 6151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.RunPreTestSetup(); 61525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkTransaction* trans = helper.trans(); 61545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 6156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog()); 6157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, rv); 61585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 61593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::RunLoop().RunUntilIdle(); // Write as much as we can. 61605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get()); 6162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream != NULL); 6163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream->stream() != NULL); 6164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, stream->stream()->send_window_size()); 6165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // All the body data should have been read. 6166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(satorux): This is because of the weirdness in reading the request 6167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // body in OnSendBodyComplete(). See crbug.com/113107. 6168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(upload_data_stream.IsEOF()); 6169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // But the body is not yet fully sent (kUploadData is not yet sent) 6170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // since we're send-stalled. 6171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control()); 61725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.ForceNextRead(); // Read in WINDOW_UPDATE frame. 6174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 6175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 6176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 61775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test we correctly handle the case where the SETTINGS frame results in 6179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// unstalling the send window. 6180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) { 6181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam().protocol < kProtoSPDY3) 6182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 61835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Number of frames we need to send to zero out the window size: data 6185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // frames plus SYN_STREAM plus the last data frame; also we need another 6186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // data frame that we will send once the SETTING is received, therefore +3. 6187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3; 61885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Calculate last frame's size; 0 size data frame is legal. 6190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t last_frame_size = 6191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize; 61925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct content for a data frame of maximum size. 6194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content(kMaxSpdyFrameChunkSize, 'a'); 6195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost( 6197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize, 6198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, NULL, 0)); 6199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Full frames. 6201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body1( 6202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 6203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, content.c_str(), content.size(), false)); 6204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Last frame to zero out the window size. 6206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body2( 6207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 6208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, content.c_str(), last_frame_size, false)); 62095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Data frame to be sent once SETTINGS frame is received. 6211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true)); 62125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Fill in mock reads/writes. 6214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MockRead> reads; 6215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MockWrite> writes; 6216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t i = 0; 6217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes.push_back(CreateMockWrite(*req, i++)); 6218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch while (i < num_writes - 2) 6219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes.push_back(CreateMockWrite(*body1, i++)); 6220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes.push_back(CreateMockWrite(*body2, i++)); 62215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct read frame for SETTINGS that gives enough space to upload the 6223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // rest of the data. 6224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsMap settings; 6225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings[SETTINGS_INITIAL_WINDOW_SIZE] = 6226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsFlagsAndValue( 6227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SETTINGS_FLAG_NONE, kSpdyStreamInitialWindowSize * 2); 6228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> settings_frame_large( 6229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdySettings(settings)); 62305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(CreateMockRead(*settings_frame_large, i++)); 62325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> session_window_update( 6234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize)); 6235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam().protocol >= kProtoSPDY31) 6236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(CreateMockRead(*session_window_update, i++)); 62375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes.push_back(CreateMockWrite(*body3, i++)); 62395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 6241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(CreateMockRead(*reply, i++)); 6242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(CreateMockRead(*body2, i++)); 6243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(CreateMockRead(*body3, i++)); 6244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(MockRead(ASYNC, 0, i++)); // EOF 62457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Force all writes to happen before any read, last write will not 6247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // actually queue a frame, due to window size being 0. 6248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(vector_as_array(&reads), reads.size(), 6249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch vector_as_array(&writes), writes.size()); 62505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedVector<UploadElementReader> element_readers; 6252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a'); 6253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch upload_data_string.append(kUploadData, kUploadDataSize); 6254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch element_readers.push_back(new UploadBytesElementReader( 6255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch upload_data_string.c_str(), upload_data_string.size())); 625668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UploadDataStream upload_data_stream(element_readers.Pass(), 0); 62575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpRequestInfo request; 6259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.method = "POST"; 6260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.url = GURL("http://www.google.com/"); 6261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.upload_data_stream = &upload_data_stream; 6262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 62635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 6264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.SetDeterministic(); 62655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 6266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.AddDeterministicData(&data); 62675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 62695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 6271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog()); 62725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 62735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(num_writes - 1); // Write as much as we can. 62755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get()); 6277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream != NULL); 6278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream->stream() != NULL); 6279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, stream->stream()->send_window_size()); 6280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // All the body data should have been read. 6282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(satorux): This is because of the weirdness in reading the request 6283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // body in OnSendBodyComplete(). See crbug.com/113107. 6284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(upload_data_stream.IsEOF()); 6285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // But the body is not yet fully sent (kUploadData is not yet sent) 6286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // since we're send-stalled. 6287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control()); 6288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(6); // Read in SETTINGS frame to unstall. 6290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 6291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch helper.VerifyDataConsumed(); 6292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If stream is NULL, that means it was unstalled and closed. 6293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(stream->stream() == NULL); 62945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 62955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test we correctly handle the case where the SETTINGS frame results in a 6297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// negative send window size. 6298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) { 6299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam().protocol < kProtoSPDY3) 63007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 63017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Number of frames we need to send to zero out the window size: data 6303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // frames plus SYN_STREAM plus the last data frame; also we need another 6304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // data frame that we will send once the SETTING is received, therefore +3. 6305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3; 63065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Calculate last frame's size; 0 size data frame is legal. 6308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t last_frame_size = 6309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize; 63105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct content for a data frame of maximum size. 6312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string content(kMaxSpdyFrameChunkSize, 'a'); 6313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost( 6315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize, 6316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, NULL, 0)); 6317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Full frames. 6319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body1( 6320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 6321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, content.c_str(), content.size(), false)); 6322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Last frame to zero out the window size. 6324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body2( 6325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame( 6326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1, content.c_str(), last_frame_size, false)); 6327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Data frame to be sent once SETTINGS frame is received. 6329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true)); 6330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Fill in mock reads/writes. 6332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MockRead> reads; 6333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<MockWrite> writes; 6334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t i = 0; 6335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes.push_back(CreateMockWrite(*req, i++)); 6336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch while (i < num_writes - 2) 6337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes.push_back(CreateMockWrite(*body1, i++)); 6338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes.push_back(CreateMockWrite(*body2, i++)); 6339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct read frame for SETTINGS that makes the send_window_size 6341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // negative. 6342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsMap new_settings; 6343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new_settings[SETTINGS_INITIAL_WINDOW_SIZE] = 6344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsFlagsAndValue( 6345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SETTINGS_FLAG_NONE, kSpdyStreamInitialWindowSize / 2); 6346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> settings_frame_small( 6347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdySettings(new_settings)); 6348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct read frames for WINDOW_UPDATE that makes the send_window_size 6349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // positive. 6350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> session_window_update_init_size( 6351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate(0, kSpdyStreamInitialWindowSize)); 6352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> window_update_init_size( 6353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate(1, kSpdyStreamInitialWindowSize)); 6354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(CreateMockRead(*settings_frame_small, i++)); 6356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam().protocol >= kProtoSPDY3) 6358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(CreateMockRead(*session_window_update_init_size, i++)); 6359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(CreateMockRead(*window_update_init_size, i++)); 6361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes.push_back(CreateMockWrite(*body3, i++)); 6363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 6365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(CreateMockRead(*reply, i++)); 6366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(CreateMockRead(*body2, i++)); 6367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(CreateMockRead(*body3, i++)); 6368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reads.push_back(MockRead(ASYNC, 0, i++)); // EOF 6369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Force all writes to happen before any read, last write will not 6371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // actually queue a frame, due to window size being 0. 6372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(vector_as_array(&reads), reads.size(), 6373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch vector_as_array(&writes), writes.size()); 6374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedVector<UploadElementReader> element_readers; 6376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a'); 6377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch upload_data_string.append(kUploadData, kUploadDataSize); 6378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch element_readers.push_back(new UploadBytesElementReader( 6379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch upload_data_string.c_str(), upload_data_string.size())); 638068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UploadDataStream upload_data_stream(element_readers.Pass(), 0); 6381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpRequestInfo request; 6383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.method = "POST"; 6384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.url = GURL("http://www.google.com/"); 6385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.upload_data_stream = &upload_data_stream; 6386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 63875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog(), GetParam(), NULL); 63885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.SetDeterministic(); 63895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.RunPreTestSetup(); 63905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.AddDeterministicData(&data); 63915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkTransaction* trans = helper.trans(); 63935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback; 6395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog()); 63965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 63975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(num_writes - 1); // Write as much as we can. 63995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get()); 6401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream != NULL); 6402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream->stream() != NULL); 6403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, stream->stream()->send_window_size()); 64045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // All the body data should have been read. 6406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(satorux): This is because of the weirdness in reading the request 6407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // body in OnSendBodyComplete(). See crbug.com/113107. 6408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(upload_data_stream.IsEOF()); 6409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // But the body is not yet fully sent (kUploadData is not yet sent) 6410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // since we're send-stalled. 6411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control()); 64125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read in WINDOW_UPDATE or SETTINGS frame. 6414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor((GetParam().protocol >= kProtoSPDY31) ? 8 : 7); 6415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = callback.WaitForResult(); 64165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper.VerifyDataConsumed(); 64175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 64185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 6420