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 "net/spdy/spdy_session.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/base64.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/callback.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 11a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/run_loop.h" 1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/test/histogram_tester.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/io_buffer.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/ip_endpoint.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log_unittest.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/request_priority.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_data_directory.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/test_data_stream.h" 19a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "net/socket/client_socket_pool_manager.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/next_proto.h" 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/socket/socket_test_util.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_http_utils.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session_pool.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_session_test_util.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_stream.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_stream_test_util.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_test_util_common.h" 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/spdy/spdy_test_utils.h" 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/test/cert_test_util.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kTestUrl[] = "http://www.example.org/"; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kTestHost[] = "www.example.org"; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kTestPort = 80; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kBodyData[] = "Body data"; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kBodyDataSize = arraysize(kBodyData); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::StringPiece kBodyDataStringPiece(kBodyData, kBodyDataSize); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstatic base::TimeDelta g_time_delta; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::TimeTicks TheNearFuture() { 46ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return base::TimeTicks::Now() + g_time_delta; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class SpdySessionTest : public PlatformTest, 527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public ::testing::WithParamInterface<NextProto> { 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Functions used with RunResumeAfterUnstallTest(). 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StallSessionOnly(SpdySession* session, SpdyStream* stream) { 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StallSessionSend(session); 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StallStreamOnly(SpdySession* session, SpdyStream* stream) { 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StallStreamSend(stream); 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StallSessionStream(SpdySession* session, SpdyStream* stream) { 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StallSessionSend(session); 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StallStreamSend(stream); 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StallStreamSession(SpdySession* session, SpdyStream* stream) { 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StallStreamSend(stream); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StallSessionSend(session); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void UnstallSessionOnly(SpdySession* session, 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyStream* stream, 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int32 delta_window_size) { 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UnstallSessionSend(session, delta_window_size); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void UnstallStreamOnly(SpdySession* session, 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyStream* stream, 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int32 delta_window_size) { 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UnstallStreamSend(stream, delta_window_size); 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void UnstallSessionStream(SpdySession* session, 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyStream* stream, 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int32 delta_window_size) { 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UnstallSessionSend(session, delta_window_size); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UnstallStreamSend(stream, delta_window_size); 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void UnstallStreamSession(SpdySession* session, 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyStream* stream, 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int32 delta_window_size) { 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UnstallStreamSend(stream, delta_window_size); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UnstallSessionSend(session, delta_window_size); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdySessionTest() 102a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) : old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group( 103a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) HttpNetworkSession::NORMAL_SOCKET_POOL)), 104a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool( 105a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) HttpNetworkSession::NORMAL_SOCKET_POOL)), 1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_(GetParam()), 1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session_deps_(GetParam()), 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) spdy_session_pool_(NULL), 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_url_(kTestUrl), 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_host_port_pair_(kTestHost, kTestPort), 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) key_(test_host_port_pair_, ProxyServer::Direct(), 112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch PRIVACY_MODE_DISABLED) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual ~SpdySessionTest() { 116a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Important to restore the per-pool limit first, since the pool limit must 117a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // always be greater than group limit, and the tests reduce both limits. 118a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ClientSocketPoolManager::set_max_sockets_per_pool( 119a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_); 120a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ClientSocketPoolManager::set_max_sockets_per_group( 121a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_); 122a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 123a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 124a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) virtual void SetUp() OVERRIDE { 125ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch g_time_delta = base::TimeDelta(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CreateDeterministicNetworkSession() { 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_session_ = 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_session_pool_ = http_session_->spdy_session_pool(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CreateNetworkSession() { 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_session_ = 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySessionDependencies::SpdyCreateSession(&session_deps_); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_session_pool_ = http_session_->spdy_session_pool(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void StallSessionSend(SpdySession* session) { 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Reduce the send window size to 0 to stall. 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (session->session_send_window_size_ > 0) { 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->DecreaseSendWindowSize( 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::min(kMaxSpdyFrameChunkSize, session->session_send_window_size_)); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void UnstallSessionSend(SpdySession* session, int32 delta_window_size) { 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->IncreaseSendWindowSize(delta_window_size); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StallStreamSend(SpdyStream* stream) { 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Reduce the send window size to 0 to stall. 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (stream->send_window_size() > 0) { 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->DecreaseSendWindowSize( 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::min(kMaxSpdyFrameChunkSize, stream->send_window_size())); 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void UnstallStreamSend(SpdyStream* stream, int32 delta_window_size) { 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->IncreaseSendWindowSize(delta_window_size); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void RunResumeAfterUnstallTest( 1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function, 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Callback<void(SpdySession*, SpdyStream*, int32)>& 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) unstall_function); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 169a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Original socket limits. Some tests set these. Safest to always restore 170a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // them once each test has been run. 171a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int old_max_group_sockets_; 172a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int old_max_pool_sockets_; 173a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 174b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SpdyTestUtil spdy_util_; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySessionDependencies session_deps_; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<HttpNetworkSession> http_session_; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySessionPool* spdy_session_pool_; 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL test_url_; 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HostPortPair test_host_port_pair_; 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdySessionKey key_; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)INSTANTIATE_TEST_CASE_P( 1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NextProto, 1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdySessionTest, 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) testing::Values(kProtoDeprecatedSPDY2, 187a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch kProtoSPDY3, kProtoSPDY31, kProtoSPDY4)); 1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 189ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Try to create a SPDY session that will fail during 190ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// initialization. Nothing should blow up. 191ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, InitialReadError) { 192ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 193ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::WeakPtr<SpdySession> session = TryCreateFakeSpdySessionExpectingFailure( 195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) spdy_session_pool_, key_, ERR_CONNECTION_CLOSED); 196effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_TRUE(session); 197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Flush the read. 198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::RunLoop().RunUntilIdle(); 199effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_FALSE(session); 200ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 201ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace { 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// A helper class that vends a callback that, when fired, destroys a 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// given SpdyStreamRequest. 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class StreamRequestDestroyingCallback : public TestCompletionCallbackBase { 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public: 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StreamRequestDestroyingCallback() {} 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual ~StreamRequestDestroyingCallback() {} 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void SetRequestToDestroy(scoped_ptr<SpdyStreamRequest> request) { 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_ = request.Pass(); 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CompletionCallback MakeCallback() { 2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return base::Bind(&StreamRequestDestroyingCallback::OnComplete, 2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Unretained(this)); 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private: 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void OnComplete(int result) { 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_.reset(); 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetResult(result); 2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<SpdyStreamRequest> request_; 2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace 2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Request kInitialMaxConcurrentStreams streams. Request two more 2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// streams, but have the callback for one destroy the second stream 2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// request. Close the session. Nothing should blow up. This is a 2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// regression test for http://crbug.com/250841 . 2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(SpdySessionTest, PendingStreamCancellingAnother) { 2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MockRead reads[] = {MockRead(ASYNC, 0, 0), }; 2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), NULL, 0); 2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) data.set_connect_data(connect_data); 2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CreateDeterministicNetworkSession(); 2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::WeakPtr<SpdySession> session = 2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Create the maximum number of concurrent streams. 2523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) { 2533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( 2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, BoundNetLog()); 2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ASSERT_TRUE(spdy_stream != NULL); 2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SpdyStreamRequest request1; 2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<SpdyStreamRequest> request2(new SpdyStreamRequest); 2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StreamRequestDestroyingCallback callback1; 2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, 2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request1.StartRequest(SPDY_BIDIRECTIONAL_STREAM, 2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) session, 2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) test_url_, 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MEDIUM, 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) BoundNetLog(), 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback1.MakeCallback())); 2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |callback2| is never called. 2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TestCompletionCallback callback2; 2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, 2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request2->StartRequest(SPDY_BIDIRECTIONAL_STREAM, 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) session, 2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) test_url_, 2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MEDIUM, 2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) BoundNetLog(), 2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback2.callback())); 2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback1.SetRequestToDestroy(request2.Pass()); 2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) session->CloseSessionOnError(ERR_ABORTED, "Aborting session"); 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(ERR_ABORTED, callback1.WaitForResult()); 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// A session receiving a GOAWAY frame with no active streams should close. 288ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) { 289ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 290ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 292ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 294ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway, 0), 295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 296ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), NULL, 0); 297ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 298ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 299ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 300ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 301ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 302ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 303ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 304ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 305ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 306ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 307ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 308ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 309ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the GOAWAY frame. 310ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 311ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 313ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 314ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 315ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 316ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// A session receiving a GOAWAY frame immediately with no active 317ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// streams should then close. 318ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) { 319ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 320ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 321ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 322ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 323ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 324ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway, 0, SYNCHRONOUS), 325ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 326ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), NULL, 0); 327ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 328ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 329ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 330ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 331ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 332ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.StopAfter(1); 333ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 334effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::WeakPtr<SpdySession> session = 335effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch TryCreateInsecureSpdySessionExpectingFailure( 336effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch http_session_, key_, ERR_CONNECTION_CLOSED, BoundNetLog()); 337effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::RunLoop().RunUntilIdle(); 338ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 339effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_FALSE(session); 340ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 341ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 342ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 343ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// A session receiving a GOAWAY frame with active streams should close 344ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// when the last active stream is closed. 345ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, GoAwayWithActiveStreams) { 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateMockRead(*goaway, 2), 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockRead(ASYNC, 0, 3) // EOF 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockWrite writes[] = { 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateMockWrite(*req1, 0), 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateMockWrite(*req2, 1), 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writes, arraysize(writes)); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateDeterministicNetworkSession(); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 369ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 3707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url(kDefaultURL); 375a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, MEDIUM, BoundNetLog()); 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateDoNothing delegate1(spdy_stream1); 37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 381a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream2 = 38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, MEDIUM, BoundNetLog()); 38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateDoNothing delegate2(spdy_stream2); 38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream2->SetDelegate(&delegate2); 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url.spec())); 3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 392ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 394ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.RunFor(2); 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(1u, spdy_stream1->stream_id()); 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(3u, spdy_stream2->stream_id()); 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Read and process the GOAWAY frame. 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.RunFor(1); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(session->IsStreamActive(3)); 409ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(NULL, spdy_stream2.get()); 410ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session->IsStreamActive(1)); 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(session->IsGoingAway()); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 414ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Should close the session. 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) spdy_stream1->Close(); 416a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 419ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 420ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 422ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Have a session receive two GOAWAY frames, with the last one causing 423ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// the last active stream to be closed. The session should then be 424ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// closed after the second GOAWAY frame. 425ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, GoAwayTwice) { 426ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 427ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 428ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 429ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway1(spdy_util_.ConstructSpdyGoAway(1)); 430ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway2(spdy_util_.ConstructSpdyGoAway(0)); 431ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 432ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway1, 2), 433ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway2, 3), 434ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 4) // EOF 435ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 436ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req1( 437ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 438ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req2( 439ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); 440ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockWrite writes[] = { 441ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req1, 0), 442ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req2, 1), 443ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 444ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 445ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch writes, arraysize(writes)); 446ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 447ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 448ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 449ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 450ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 451ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 452ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 453ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 454ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 455ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url(kDefaultURL); 457ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 458ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 459ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, MEDIUM, BoundNetLog()); 460ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate1(spdy_stream1); 461ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream1->SetDelegate(&delegate1); 462ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 463ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = 464ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 465ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, MEDIUM, BoundNetLog()); 466ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate2(spdy_stream2); 467ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream2->SetDelegate(&delegate2); 468ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 469ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 470ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 471ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); 472ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 473ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 474ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 475ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 476ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 477ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 478ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(2); 479ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 480ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(1u, spdy_stream1->stream_id()); 481ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(3u, spdy_stream2->stream_id()); 482ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 483ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 484ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 485ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the first GOAWAY frame. 486ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 487ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 488ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 489ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 490ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(session->IsStreamActive(3)); 491a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream2.get()); 492ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session->IsStreamActive(1)); 493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(session->IsGoingAway()); 494ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 495ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the second GOAWAY frame, which should close the 496ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // session. 497ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 499ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 500ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 501ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 502ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Have a session with active streams receive a GOAWAY frame and then 503ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// close it. It should handle the close properly (i.e., not try to 504ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// make itself unavailable in its pool twice). 505ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) { 506ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 507ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 508ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 509ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 510ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 511ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway, 2), 512ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 3) // EOF 513ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 514ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req1( 515ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 516ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req2( 517ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); 518ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockWrite writes[] = { 519ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req1, 0), 520ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req2, 1), 521ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 522ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 523ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch writes, arraysize(writes)); 524ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 525ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 526ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 527ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 528ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 529ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 530ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 531ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 532ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 533ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url(kDefaultURL); 535ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 536ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 537ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, MEDIUM, BoundNetLog()); 538ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate1(spdy_stream1); 539ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream1->SetDelegate(&delegate1); 540ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 541ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = 542ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 543ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, MEDIUM, BoundNetLog()); 544ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate2(spdy_stream2); 545ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream2->SetDelegate(&delegate2); 546ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 547ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 548ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 549ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); 550ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 551ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 552ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 553ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 554ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 555ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 556ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(2); 557ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 558ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(1u, spdy_stream1->stream_id()); 559ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(3u, spdy_stream2->stream_id()); 560ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 561ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 562ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 563ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the GOAWAY frame. 564ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 565ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 566ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 567ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 568ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(session->IsStreamActive(3)); 569ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(NULL, spdy_stream2.get()); 570ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session->IsStreamActive(1)); 571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(session->IsGoingAway()); 572ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 573ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, "Aborting session"); 574ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(NULL, spdy_stream1.get()); 575cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 576cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 577ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 578ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 579ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 58046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Process a joint read buffer which causes the session to begin draining, and 58146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// then processes a GOAWAY. The session should gracefully drain. Regression test 58246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// for crbug.com/379469 58346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_P(SpdySessionTest, GoAwayWhileDraining) { 58446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 58546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 58646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 58746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 58846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MockWrite writes[] = { 58946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CreateMockWrite(*req, 0), 59046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) }; 59146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 59246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 59346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 59446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 59546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size_t joint_size = goaway->size() * 2 + body->size(); 59646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 59746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Compose interleaved |goaway| and |body| frames into a single read. 59846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<char[]> buffer(new char[joint_size]); 59946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) { 60046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size_t out = 0; 60146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) memcpy(&buffer[out], goaway->data(), goaway->size()); 60246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) out += goaway->size(); 60346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) memcpy(&buffer[out], body->data(), body->size()); 60446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) out += body->size(); 60546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) memcpy(&buffer[out], goaway->data(), goaway->size()); 60646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) out += goaway->size(); 60746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ASSERT_EQ(out, joint_size); 60846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 60946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SpdyFrame joint_frames(buffer.get(), joint_size, false); 61046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 61146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MockRead reads[] = { 61246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CreateMockRead(*resp, 1), CreateMockRead(joint_frames, 2), 61346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MockRead(ASYNC, 0, 3) // EOF 61446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) }; 61546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 61646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 61746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DeterministicSocketData data( 61846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) reads, arraysize(reads), writes, arraysize(writes)); 61946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) data.set_connect_data(connect_data); 62046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 62146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 62246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CreateDeterministicNetworkSession(); 62346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::WeakPtr<SpdySession> session = 62446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 62546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 62646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GURL url(kDefaultURL); 62746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( 62846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); 62946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) test::StreamDelegateDoNothing delegate(spdy_stream); 63046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) spdy_stream->SetDelegate(&delegate); 63146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 63246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 63346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url.spec())); 63446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 63546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); 63646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 63746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) data.RunFor(3); 63846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 63946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 64046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Stream and session closed gracefully. 64146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(delegate.StreamIsClosed()); 64246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(OK, delegate.WaitForClose()); 64346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(kUploadData, delegate.TakeReceivedData()); 64446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(session == NULL); 64546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 64646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 647ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Try to create a stream after receiving a GOAWAY frame. It should 648ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// fail. 649ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, CreateStreamAfterGoAway) { 650ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 651ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 652ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 653ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 654ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 655ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway, 1), 656ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 2) // EOF 657ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 658ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req( 659ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 660ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockWrite writes[] = { 661ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req, 0), 662ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 663ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 664ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch writes, arraysize(writes)); 665ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 666ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 667ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 668ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 669ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 670ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 671ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 672ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 673ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 674ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url(kDefaultURL); 676ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream = 677ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 678ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, MEDIUM, BoundNetLog()); 679ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate(spdy_stream); 680ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream->SetDelegate(&delegate); 681ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 682ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 683ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 684ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 685ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); 686ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 687ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 688ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 689ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(1u, spdy_stream->stream_id()); 690ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 691ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 692ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 693ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the GOAWAY frame. 694ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 695ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 696ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 697ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session->IsStreamActive(1)); 698ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 699ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SpdyStreamRequest stream_request; 700ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int rv = stream_request.StartRequest( 701ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog(), 702ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CompletionCallback()); 703ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(ERR_FAILED, rv); 704ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 705ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process EOF. 706ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 707ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 708ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 709ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 710ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 711ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Receiving a SYN_STREAM frame after a GOAWAY frame should result in 712ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// the stream being refused. 713ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, SynStreamAfterGoAway) { 714ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 715ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 716ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 717ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 718ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> 7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kDefaultURL)); 720ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 721ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway, 1), 722ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*push, 2), 723ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 4) // EOF 724ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 725ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req( 726ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 727ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> rst( 728ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); 729ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockWrite writes[] = { 730ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req, 0), 731ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*rst, 3) 732ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 733ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 734ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch writes, arraysize(writes)); 735ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 736ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 737ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 738ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 739ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 740ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 741ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 742ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 743ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 744ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url(kDefaultURL); 746ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream = 747ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 748ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, MEDIUM, BoundNetLog()); 749ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate(spdy_stream); 750ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream->SetDelegate(&delegate); 751ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 752ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 753ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 754ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 755ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); 756ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 757ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 758ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 759ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(1u, spdy_stream->stream_id()); 760ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 761ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 762ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 763ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the GOAWAY frame. 764ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 765ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 766ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 767ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session->IsStreamActive(1)); 768ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 769ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the SYN_STREAM frame, the subsequent RST_STREAM, 770ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // and EOF. 771ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(3); 772cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 773ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A session observing a network change with active streams should close 7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// when the last active stream is closed. 7785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(SpdySessionTest, NetworkChangeWithActiveStreams) { 7795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 7805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MockRead reads[] = { 7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MockRead(ASYNC, 0, 1) // EOF 7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdyFrame> req1( 7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MockWrite writes[] = { 7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateMockWrite(*req1, 0), 7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 7905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) writes, arraysize(writes)); 7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data.set_connect_data(connect_data); 7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateDeterministicNetworkSession(); 7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::WeakPtr<SpdySession> session = 7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = 8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session, 8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL(kDefaultURL), MEDIUM, BoundNetLog()); 8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) test::StreamDelegateDoNothing delegate(spdy_stream); 8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_stream->SetDelegate(&delegate); 8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); 8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 8125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); 8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data.RunFor(1); 8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(1u, spdy_stream->stream_id()); 8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 8195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_session_pool_->OnIPAddressChanged(); 8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The SpdySessionPool behavior differs based on how the OSs reacts to 8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // network changes; see comment in SpdySessionPool::OnIPAddressChanged(). 8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS) 8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For OSs where the TCP connections will close upon relevant network 8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // changes, SpdySessionPool doesn't need to force them to close, so in these 8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // cases verify the session has become unavailable but remains open and the 8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // pre-existing stream is still active. 8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 831cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(session->IsGoingAway()); 8325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(session->IsStreamActive(1)); 8345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Should close the session. 8365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_stream->Close(); 8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 8385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(NULL, spdy_stream.get()); 8395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 8415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(session == NULL); 8425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 8435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ClientPing) { 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.enable_ping = true; 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 849a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1, true)); 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 851ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*read_ping, 1), 852ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 0, 2) // EOF 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 854a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false)); 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 856ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*write_ping, 0), 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 858ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data( 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reads, arraysize(reads), writes, arraysize(writes)); 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 861ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 863ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 8667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 868a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 86990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 87090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 87290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL); 8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks before_ping_time = base::TimeTicks::Now(); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->set_connection_at_risk_of_loss_time( 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromSeconds(-1)); 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->set_hung_interval(base::TimeDelta::FromMilliseconds(50)); 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->SendPrefacePingIfNoneInFlight(); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 883ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(2); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->CheckPingStatus(before_ping_time); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, session->pings_in_flight()); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1)); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(session->check_ping_status_pending()); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(session->last_activity_time(), before_ping_time); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 892ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 893ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 894ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 896ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 897ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ServerPing) { 9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 904a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(2, false)); 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*read_ping), 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(SYNCHRONOUS, 0, 0) // EOF 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 909a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(2, true)); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*write_ping), 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StaticSocketDataProvider data( 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reads, arraysize(reads), writes, arraysize(writes)); 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 920ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 9217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 923a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 92490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 92590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 92790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL); 9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 930ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Flush the read completion task. 93190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 936a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 939ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Cause a ping to be sent out while producing a write. The write loop 940ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// should handle this properly, i.e. another DoWriteLoop task should 941ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// not be posted. This is a regression test for 942ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// http://crbug.com/261043 . 943ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, PingAndWriteLoop) { 944ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.enable_ping = true; 945ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.time_func = TheNearFuture; 946ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 947ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 948a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false)); 949ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req( 950ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 951ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockWrite writes[] = { 952ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req, 0), 953ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*write_ping, 1), 954ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 955ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 956ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 957ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 2) // EOF 958ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 959ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 960ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 961ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 962ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 963ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch writes, arraysize(writes)); 964ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 965ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 966ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 967ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 968ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 969ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 970ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 971ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 9725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url(kDefaultURL); 973ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream = 974ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 975ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, LOWEST, BoundNetLog()); 976ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate(spdy_stream); 977ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream->SetDelegate(&delegate); 978ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 979ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 980ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 981ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 982ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 983ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Shift time so that a ping will be sent out. 984ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch g_time_delta = base::TimeDelta::FromSeconds(11); 985ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 986ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(2); 987ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 988ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, "Aborting"); 989ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 990ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 991cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(SpdySessionTest, StreamIdSpaceExhausted) { 992cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SpdyStreamId kLastStreamId = 0x7fffffff; 993cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 994cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 995cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Test setup: |stream_hi_water_mark_| and |max_concurrent_streams_| are 996cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // fixed to allow for two stream ID assignments, and three concurrent 997cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // streams. Four streams are started, and two are activated. Verify the 998cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // session goes away, and that the created (but not activated) and 999cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // stalled streams are aborted. Also verify the activated streams complete, 1000cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // at which point the session closes. 1001cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1002cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyGet( 1003cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NULL, 0, false, kLastStreamId - 2, MEDIUM, true)); 1004cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<SpdyFrame> req2( 1005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, kLastStreamId, MEDIUM, true)); 1006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1007cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockWrite writes[] = { 1008cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1), 1009cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 1010cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1011cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<SpdyFrame> resp1( 1012cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spdy_util_.ConstructSpdyGetSynReply(NULL, 0, kLastStreamId - 2)); 1013cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<SpdyFrame> resp2( 1014cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spdy_util_.ConstructSpdyGetSynReply(NULL, 0, kLastStreamId)); 1015cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1016cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<SpdyFrame> body1( 1017cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(kLastStreamId - 2, true)); 1018cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<SpdyFrame> body2( 1019cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(kLastStreamId, true)); 1020cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1021cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockRead reads[] = { 1022cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockRead(*resp1, 2), CreateMockRead(*resp2, 3), 1023cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockRead(*body1, 4), CreateMockRead(*body2, 5), 1024cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockRead(ASYNC, 0, 6) // EOF 1025cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 1026cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1027cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DeterministicSocketData data( 1028cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reads, arraysize(reads), writes, arraysize(writes)); 1029cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1030cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 1031cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data.set_connect_data(connect_data); 1032cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 1033cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1034cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateDeterministicNetworkSession(); 1035cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<SpdySession> session = 1036cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 1037cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1038cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Fix stream_hi_water_mark_ to allow for two stream activations. 1039cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session->stream_hi_water_mark_ = kLastStreamId - 2; 1040cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Fix max_concurrent_streams to allow for three stream creations. 1041cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session->max_concurrent_streams_ = 3; 1042cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1043cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Create three streams synchronously, and begin a fourth (which is stalled). 1044cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GURL url(kDefaultURL); 1045cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<SpdyStream> stream1 = CreateStreamSynchronously( 1046cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); 1047cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test::StreamDelegateDoNothing delegate1(stream1); 1048cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream1->SetDelegate(&delegate1); 1049cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1050cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<SpdyStream> stream2 = CreateStreamSynchronously( 1051cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); 1052cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test::StreamDelegateDoNothing delegate2(stream2); 1053cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream2->SetDelegate(&delegate2); 1054cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1055cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<SpdyStream> stream3 = CreateStreamSynchronously( 1056cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); 1057cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test::StreamDelegateDoNothing delegate3(stream3); 1058cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream3->SetDelegate(&delegate3); 1059cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1060cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SpdyStreamRequest request4; 1061cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TestCompletionCallback callback4; 1062cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 1063cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) request4.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, 1064cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session, 1065cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url, 1066cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MEDIUM, 1067cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BoundNetLog(), 1068cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback4.callback())); 1069cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1070cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Streams 1-3 were created. 4th is stalled. No streams are active yet. 1071cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 1072cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(3u, session->num_created_streams()); 1073cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM)); 1074cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1075cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Activate stream 1. One ID remains available. 1076cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream1->SendRequestHeaders( 1077cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock>( 1078cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url.spec())), 1079cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NO_MORE_DATA_TO_SEND); 1080cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data.RunFor(1); 1081cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1082cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(kLastStreamId - 2u, stream1->stream_id()); 1083cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1u, session->num_active_streams()); 1084cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(2u, session->num_created_streams()); 1085cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM)); 1086cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1087cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Activate stream 2. ID space is exhausted. 1088cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream2->SendRequestHeaders( 1089cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock>( 1090cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url.spec())), 1091cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NO_MORE_DATA_TO_SEND); 1092cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data.RunFor(1); 1093cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1094cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Active streams remain active. 1095cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(kLastStreamId, stream2->stream_id()); 1096cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(2u, session->num_active_streams()); 1097cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1098cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Session is going away. Created and stalled streams were aborted. 1099cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(SpdySession::STATE_GOING_AWAY, session->availability_state_); 1100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(ERR_ABORTED, delegate3.WaitForClose()); 1101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(ERR_ABORTED, callback4.WaitForResult()); 1102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(0u, session->num_created_streams()); 1103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); 1104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Read responses on remaining active streams. 1106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data.RunFor(4); 1107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(OK, delegate1.WaitForClose()); 1108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(kUploadData, delegate1.TakeReceivedData()); 1109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(OK, delegate2.WaitForClose()); 1110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(kUploadData, delegate2.TakeReceivedData()); 1111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Session was destroyed. 1113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(session.get()); 1115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 1116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Verifies that an unstalled pending stream creation racing with a new stream 1118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// creation doesn't violate the maximum stream concurrency. Regression test for 1119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// crbug.com/373858. 1120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(SpdySessionTest, UnstallRacesWithStreamCreation) { 1121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 1122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockRead reads[] = { 1124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 1125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 1126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 1128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 1130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data.set_connect_data(connect_data); 1131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 1132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateNetworkSession(); 1134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<SpdySession> session = 1135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 1136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Fix max_concurrent_streams to allow for one open stream. 1138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session->max_concurrent_streams_ = 1; 1139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Create two streams: one synchronously, and one which stalls. 1141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GURL url(kDefaultURL); 1142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<SpdyStream> stream1 = CreateStreamSynchronously( 1143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); 1144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SpdyStreamRequest request2; 1146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TestCompletionCallback callback2; 1147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 1148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, 1149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session, 1150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url, 1151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MEDIUM, 1152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BoundNetLog(), 1153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback2.callback())); 1154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1u, session->num_created_streams()); 1156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM)); 1157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Cancel the first stream. A callback to unstall the second stream was 1159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // posted. Don't run it yet. 1160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream1->Cancel(); 1161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(0u, session->num_created_streams()); 1163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); 1164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Create a third stream prior to the second stream's callback. 1166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<SpdyStream> stream3 = CreateStreamSynchronously( 1167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); 1168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1u, session->num_created_streams()); 1170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); 1171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // NOW run the message loop. The unstalled stream will re-stall itself. 1173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1u, session->num_created_streams()); 1175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM)); 1176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Cancel the third stream and run the message loop. Verify that the second 1178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // stream creation now completes. 1179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream3->Cancel(); 1180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1u, session->num_created_streams()); 1183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); 1184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(OK, callback2.WaitForResult()); 1185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 1186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 11877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, DeleteExpiredPushStreams) { 11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.time_func = TheNearFuture; 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdyFrame> req( 11925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 11935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdyFrame> rst( 11945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); 11955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 11965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush( 11975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 0, 2, 1, "http://www.google.com/a.dat")); 11985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdyFrame> push_a_body( 11995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(2, false)); 12005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush( 12015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 0, 4, 1, "http://www.google.com/b.dat")); 12025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4)}; 12035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MockRead reads[] = { 12045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateMockRead(*push_a, 1), CreateMockRead(*push_a_body, 2), 12055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateMockRead(*push_b, 3), MockRead(ASYNC, 0, 5), // EOF 12065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 12075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeterministicSocketData data( 12085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) reads, arraysize(reads), writes, arraysize(writes)); 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 12115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data.set_connect_data(connect_data); 12125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 12135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateDeterministicNetworkSession(); 1215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 12165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Process the principal request, and the first push stream request & body. 12195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url(kDefaultURL); 12205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( 12215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); 12225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) test::StreamDelegateDoNothing delegate(spdy_stream); 12235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_stream->SetDelegate(&delegate); 12245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 12265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url.spec())); 12275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 12285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data.RunFor(3); 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that there is one unclaimed push stream. 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, session->num_unclaimed_pushed_streams()); 123390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdySession::PushedStreamMap::iterator iter = 1234ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->unclaimed_pushed_streams_.find( 1235ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL("http://www.google.com/a.dat")); 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter); 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (session->flow_control_state_ == 12395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) { 12405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Unclaimed push body consumed bytes from the session window. 12415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize - kUploadDataSize, 12425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session->session_recv_window_size_); 12435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 12445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Shift time to expire the push stream. Read the second SYN_STREAM, 12475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // and verify a RST_STREAM was written. 12485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_time_delta = base::TimeDelta::FromSeconds(301); 12495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data.RunFor(2); 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that the second pushed stream evicted the first pushed stream. 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, session->num_unclaimed_pushed_streams()); 1253ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch iter = session->unclaimed_pushed_streams_.find( 1254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL("http://www.google.com/b.dat")); 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter); 12565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (session->flow_control_state_ == 12585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) { 12595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Verify that the session window reclaimed the evicted stream body. 12605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, 12615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session->session_recv_window_size_); 12625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_); 12635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Read and process EOF. 12665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data.RunFor(1); 1267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 12685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(session == NULL); 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, FailedPing) { 12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 1276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false)); 1279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SpdyFrame> goaway( 1280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Failed ping.")); 1281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MockWrite writes[] = {CreateMockWrite(*write_ping), CreateMockWrite(*goaway)}; 1282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StaticSocketDataProvider data( 1283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reads, arraysize(reads), writes, arraysize(writes)); 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 1285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateNetworkSession(); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1289ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 12907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1292a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 129390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 129490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 129690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL); 12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate); 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0)); 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->set_hung_interval(base::TimeDelta::FromSeconds(0)); 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send a PING frame. 1303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) session->WritePingFrame(1, false); 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(0, session->pings_in_flight()); 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1)); 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(session->check_ping_status_pending()); 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assert session is not closed. 1309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(session->IsAvailable()); 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(0u, session->num_active_streams() + session->num_created_streams()); 13117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We set last time we have received any data in 1 sec less than now. 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CheckPingStatus will trigger timeout because hung interval is zero. 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks now = base::TimeTicks::Now(); 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->last_activity_time_ = now - base::TimeDelta::FromSeconds(1); 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->CheckPingStatus(now); 1318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1320ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 13217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 1322a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Request kInitialMaxConcurrentStreams + 1 streams. Receive a 1326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// settings frame increasing the max concurrent streams by 1. Make 1327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// sure nothing blows up. This is a regression test for 1328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// http://crbug.com/57331 . 13297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, OnSettings) { 13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1332ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const SpdySettingsIds kSpdySettingsIds = SETTINGS_MAX_CONCURRENT_STREAMS; 1333ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsMap new_settings; 1335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1; 1336ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch new_settings[kSpdySettingsIds] = 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); 133890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> settings_frame( 133990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdySettings(new_settings)); 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 1341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateMockRead(*settings_frame, 0), 1342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockRead(ASYNC, 0, 1), 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck()); 1346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockWrite writes[] = { 1347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockWrite(*settings_ack, 2), 1348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 1349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 1351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) writes, arraysize(writes)); 1352ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 1354ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1356ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1358ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 13597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1361a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Create the maximum number of concurrent streams. 1362a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) { 1363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = 1364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 1365a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 1366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(spdy_stream != NULL); 1367a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1369a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) StreamReleaserCallback stream_releaser; 13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdyStreamRequest request; 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, 137290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request.StartRequest( 137390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, 137490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BoundNetLog(), 137590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream_releaser.MakeCallback(&request))); 1376ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) data.RunFor(1); 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13799ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch EXPECT_EQ(OK, stream_releaser.WaitForResult()); 1380ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1381ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 1382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (spdy_util_.spdy_version() >= SPDY4) { 1383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Allow the SETTINGS+ACK to write, so the session finishes draining. 1384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data.RunFor(1); 1385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1387ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1390a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Start with a persisted value for max concurrent streams. Receive a 1391a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// settings frame increasing the max concurrent streams by 1 and which 1392a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// also clears the persisted data. Verify that persisted data is 1393a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// correct. 13947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ClearSettings) { 1395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (spdy_util_.spdy_version() >= SPDY4) { 1396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // SPDY4 doesn't include settings persistence, or a CLEAR_SETTINGS flag. 1397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Flag 0x1, CLEAR_SETTINGS in SPDY3, is instead settings ACK in SPDY4. 1398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 1399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SettingsMap new_settings; 1403a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1; 1404a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = 1405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); 140690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> settings_frame( 140790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdySettings(new_settings)); 1408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint8 flags = SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; 1409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::SetFrameFlags(settings_frame.get(), flags, spdy_util_.spdy_version()); 1410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockRead reads[] = { 1411a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateMockRead(*settings_frame, 0), 1412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockRead(ASYNC, 0, 1), 1413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 1414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1415a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), NULL, 0); 1416ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 1417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.set_connect_data(connect_data); 1418ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 1419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1420ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 1421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1422a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Initialize the SpdySetting with the default. 1423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) spdy_session_pool_->http_server_properties()->SetSpdySetting( 1424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) test_host_port_pair_, 1425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SETTINGS_MAX_CONCURRENT_STREAMS, 1426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SETTINGS_FLAG_PLEASE_PERSIST, 1427a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) kInitialMaxConcurrentStreams); 1428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1429a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_FALSE( 1430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) spdy_session_pool_->http_server_properties()->GetSpdySettings( 1431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) test_host_port_pair_).empty()); 1432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1433ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 14347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 1435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Create the maximum number of concurrent streams. 1437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) { 1438a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = 1439a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 1440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 1441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(spdy_stream != NULL); 1442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1444a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) StreamReleaserCallback stream_releaser; 1445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyStreamRequest request; 1447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, 144890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request.StartRequest( 144990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, 145090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BoundNetLog(), 145190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream_releaser.MakeCallback(&request))); 1452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) data.RunFor(1); 1454ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 14559ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch EXPECT_EQ(OK, stream_releaser.WaitForResult()); 1456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure that persisted data is cleared. 1458a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE( 1459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) spdy_session_pool_->http_server_properties()->GetSpdySettings( 1460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) test_host_port_pair_).empty()); 1461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Make sure session's max_concurrent_streams is correct. 1463a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(kInitialMaxConcurrentStreams + 1, 1464a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session->max_concurrent_streams()); 14657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1466ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 1467ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 1468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1470a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Start with max concurrent streams set to 1. Request two streams. 1471a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// When the first completes, have the callback close its stream, which 1472a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// should trigger the second stream creation. Then cancel that one 1473a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// immediately. Don't crash. This is a regression test for 1474a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// http://crbug.com/63532 . 14757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, CancelPendingCreateStream) { 14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the SpdySetting with 1 max concurrent streams. 14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_session_pool_->http_server_properties()->SetSpdySetting( 14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_host_port_pair_, 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SETTINGS_MAX_CONCURRENT_STREAMS, 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SETTINGS_FLAG_PLEASE_PERSIST, 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1); 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1497ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 14987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1500a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Leave room for only one more stream to be created. 1501a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) { 1502a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = 1503a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 1504a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 1505a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(spdy_stream != NULL); 1506a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1507a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1508a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Create 2 more streams. First will succeed. Second will be pending. 1509a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 151090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 151190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use scoped_ptr to let us invalidate the memory when we want to, to trigger 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a valgrind error if the callback is invoked when it's not supposed to be. 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback); 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdyStreamRequest request; 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, 152090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request.StartRequest( 152190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, 152290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BoundNetLog(), 152390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback->callback())); 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Release the first one, this will allow the second to be created. 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_stream1->Cancel(); 1527a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.CancelRequest(); 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.reset(); 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should not crash when running the pending callback. 153390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1536a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_P(SpdySessionTest, SendInitialDataOnNewSession) { 15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsMap settings; 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS; 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdySettingsIds kSpdySettingsIds2 = SETTINGS_INITIAL_WINDOW_SIZE; 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32 kInitialRecvWindowSize = 10 * 1024 * 1024; 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings[kSpdySettingsIds1] = 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); 15497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (spdy_util_.spdy_version() >= SPDY3) { 15507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) settings[kSpdySettingsIds2] = 15517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kInitialRecvWindowSize); 15527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 155490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> settings_frame( 155590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdySettings(settings)); 1556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> initial_window_update( 1557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate( 1558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSessionFlowControlStreamId, 1559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize)); 1560a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<MockWrite> writes; 1561a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (GetParam() == kProtoSPDY4) { 1562a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) writes.push_back( 1563a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockWrite(ASYNC, 1564a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) kHttp2ConnectionHeaderPrefix, 1565a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) kHttp2ConnectionHeaderPrefixSize)); 1566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1567a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) writes.push_back(CreateMockWrite(*settings_frame)); 1568a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (GetParam() >= kProtoSPDY31) { 1569a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) writes.push_back(CreateMockWrite(*initial_window_update)); 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1572a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SettingsMap server_settings; 1573a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const uint32 initial_max_concurrent_streams = 1; 1574a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) server_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = 1575a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED, 1576a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) initial_max_concurrent_streams); 1577a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<SpdyFrame> server_settings_frame( 1578a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) spdy_util_.ConstructSpdySettings(server_settings)); 15791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (GetParam() <= kProtoSPDY31) { 15801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci writes.push_back(CreateMockWrite(*server_settings_frame)); 15811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1583a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session_deps_.stream_initial_recv_window_size = kInitialRecvWindowSize; 1584a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1585a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), 1586a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) vector_as_array(&writes), writes.size()); 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_session_pool_->http_server_properties()->SetSpdySetting( 15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_host_port_pair_, 1594a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SETTINGS_MAX_CONCURRENT_STREAMS, 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SETTINGS_FLAG_PLEASE_PERSIST, 1596a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) initial_max_concurrent_streams); 1597a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1598a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SpdySessionPoolPeer pool_peer(spdy_session_pool_); 1599a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pool_peer.SetEnableSendingInitialData(true); 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1601ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 16027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 160490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 16057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(data.at_write_eof()); 16062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ClearSettingsStorageOnIPAddressChanged) { 16092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1611ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<HttpServerProperties> test_http_server_properties = 16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_session_pool_->http_server_properties(); 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue flags_and_value1(SETTINGS_FLAG_PLEASE_PERSIST, 2); 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_http_server_properties->SetSpdySetting( 16152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_host_port_pair_, 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SETTINGS_MAX_CONCURRENT_STREAMS, 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SETTINGS_FLAG_PLEASE_PERSIST, 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2); 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(0u, test_http_server_properties->GetSpdySettings( 16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_host_port_pair_).size()); 16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_session_pool_->OnIPAddressChanged(); 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings( 16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_host_port_pair_).size()); 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, Initialize) { 1627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CapturingBoundNetLog log; 1628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.net_log = log.bound().net_log(); 1629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 1630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 1632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockRead reads[] = { 1633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 1634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 1635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 1637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.set_connect_data(connect_data); 1638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 1639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateNetworkSession(); 1641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1642ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 16437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, log.bound()); 16447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 1645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1646ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Flush the read completion task. 164790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::CapturingNetLog::CapturedEntryList entries; 1650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) log.GetEntries(&entries); 1651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_LT(0u, entries.size()); 1652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check that we logged TYPE_SPDY_SESSION_INITIALIZED correctly. 1654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int pos = net::ExpectLogContainsSomewhere( 1655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries, 0, 1656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::NetLog::TYPE_SPDY_SESSION_INITIALIZED, 1657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::NetLog::PHASE_NONE); 1658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_LT(0, pos); 1659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CapturingNetLog::CapturedEntry entry = entries[pos]; 1661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NetLog::Source socket_source; 1662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NetLog::Source::FromEventParameters(entry.params.get(), 1663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &socket_source)); 1664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(socket_source.IsValid()); 1665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_NE(log.bound().source().id, socket_source.id); 1666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1668cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(SpdySessionTest, NetLogOnSessionGoaway) { 16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 167290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway()); 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*goaway), 16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead(SYNCHRONOUS, 0, 0) // EOF 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 16772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CapturingBoundNetLog log; 1685ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 16867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, log.bound()); 16877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1689ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Flush the read completion task. 169090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 1693ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check that the NetLog was filled reasonably. 16962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::CapturingNetLog::CapturedEntryList entries; 16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) log.GetEntries(&entries); 16982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_LT(0u, entries.size()); 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check that we logged SPDY_SESSION_CLOSE correctly. 17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int pos = net::ExpectLogContainsSomewhere( 17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entries, 0, 17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::NetLog::TYPE_SPDY_SESSION_CLOSE, 17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::NetLog::PHASE_NONE); 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1706ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (pos < static_cast<int>(entries.size())) { 1707ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CapturingNetLog::CapturedEntry entry = entries[pos]; 1708ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int error_code = 0; 1709ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ASSERT_TRUE(entry.GetNetErrorCode(&error_code)); 1710cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(OK, error_code); 1711cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 1712cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ADD_FAILURE(); 1713cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1714cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 1715cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1716cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(SpdySessionTest, NetLogOnSessionEOF) { 1717cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 1718cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1719cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 1720cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockRead reads[] = { 1721cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockRead(SYNCHRONOUS, 0, 0) // EOF 1722cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 1723cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1724cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 1725cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data.set_connect_data(connect_data); 1726cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 1727cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1728cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateNetworkSession(); 1729cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1730cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CapturingBoundNetLog log; 1731cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<SpdySession> session = 1732cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateInsecureSpdySession(http_session_, key_, log.bound()); 1733cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 1734cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1735cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Flush the read completion task. 1736cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1737cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1738cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 1739cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(session == NULL); 1740cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1741cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Check that the NetLog was filled reasonably. 1742cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::CapturingNetLog::CapturedEntryList entries; 1743cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) log.GetEntries(&entries); 1744cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_LT(0u, entries.size()); 1745cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1746cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Check that we logged SPDY_SESSION_CLOSE correctly. 1747cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int pos = 1748cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::ExpectLogContainsSomewhere(entries, 1749cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 0, 1750cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::NetLog::TYPE_SPDY_SESSION_CLOSE, 1751cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::NetLog::PHASE_NONE); 1752cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1753cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (pos < static_cast<int>(entries.size())) { 1754cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CapturingNetLog::CapturedEntry entry = entries[pos]; 1755cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int error_code = 0; 1756cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_TRUE(entry.GetNetErrorCode(&error_code)); 1757ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, error_code); 1758ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else { 1759ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ADD_FAILURE(); 1760ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 17612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1763116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_P(SpdySessionTest, SynCompressionHistograms) { 1764116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch session_deps_.enable_compression = true; 1765116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1766116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> req( 1767116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, true, 1, MEDIUM, true)); 1768116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockWrite writes[] = { 1769116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateMockWrite(*req, 0), 1770116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 1771116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockRead reads[] = { 1772116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockRead(ASYNC, 0, 1) // EOF 1773116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 1774116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 1775116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch writes, arraysize(writes)); 1776116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 1777116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.set_connect_data(connect_data); 1778116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 1779116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1780116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateDeterministicNetworkSession(); 1781116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::WeakPtr<SpdySession> session = 1782116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 1783116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1784116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GURL url(kDefaultURL); 1785116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream = 1786116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 1787116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch session, url, MEDIUM, BoundNetLog()); 1788116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch test::StreamDelegateDoNothing delegate(spdy_stream); 1789116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_stream->SetDelegate(&delegate); 1790116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1791116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 1792116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 1793116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 1794116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); 1795116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1796116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Write request headers & capture resulting histogram update. 179703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::HistogramTester histogram_tester; 1798116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 179903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) data.RunFor(1); 1800116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Regression test of compression performance under the request fixture. 1801116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch switch (spdy_util_.spdy_version()) { 1802116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case SPDY2: 180303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) histogram_tester.ExpectBucketCount( 180403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "Net.SpdySynStreamCompressionPercentage", 0, 1); 1805116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 1806116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case SPDY3: 180703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) histogram_tester.ExpectBucketCount( 180803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "Net.SpdySynStreamCompressionPercentage", 30, 1); 1809116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 1810116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case SPDY4: 181103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) histogram_tester.ExpectBucketCount( 181203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "Net.SpdySynStreamCompressionPercentage", 82, 1); 1813116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 1814116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case SPDY5: 181503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) histogram_tester.ExpectBucketCount( 181603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "Net.SpdySynStreamCompressionPercentage", 82, 1); 1817116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 1818116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch default: 1819116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTREACHED(); 1820116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 1821116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1822116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Read and process EOF. 1823116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 1824116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::MessageLoop::current()->RunUntilIdle(); 1825116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(session == NULL); 1826116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 1827116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1828eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Queue up a low-priority SYN_STREAM followed by a high-priority 1829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// one. The high priority one should still send first and receive 1830eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// first. 18317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, OutOfOrderSynStreams) { 18322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Construct the request. 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 1834eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req_highest( 183590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, HIGHEST, true)); 1836eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req_lowest( 183790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 1839eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req_highest, 0), 1840eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req_lowest, 1), 18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1843eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp_highest( 1844eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 1845eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body_highest( 1846eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 1847eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp_lowest( 1848eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 1849eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body_lowest( 1850eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(3, true)); 18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 1852eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp_highest, 2), 1853eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body_highest, 3), 1854eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp_lowest, 4), 1855eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body_lowest, 5), 1856eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 6) // EOF 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 18582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 18602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1861eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 1862eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 1864eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1866eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1868ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 18697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url(kDefaultURL); 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1873eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream_lowest = 187490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 187590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, LOWEST, BoundNetLog()); 1876eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream_lowest); 1877eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream_lowest->stream_id()); 1878eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateDoNothing delegate_lowest(spdy_stream_lowest); 1879eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream_lowest->SetDelegate(&delegate_lowest); 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1881eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream_highest = 188290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 188390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, HIGHEST, BoundNetLog()); 1884eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream_highest); 1885eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream_highest->stream_id()); 1886eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateDoNothing delegate_highest(spdy_stream_highest); 1887eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream_highest->SetDelegate(&delegate_highest); 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1889eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Queue the lower priority one first. 1890eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1891eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers_lowest( 1892b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url.spec())); 1893eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream_lowest->SendRequestHeaders( 1894eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch headers_lowest.Pass(), NO_MORE_DATA_TO_SEND); 1895ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream_lowest->HasUrlFromHeaders()); 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1897eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers_highest( 1898b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url.spec())); 1899eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream_highest->SendRequestHeaders( 1900eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch headers_highest.Pass(), NO_MORE_DATA_TO_SEND); 1901ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream_highest->HasUrlFromHeaders()); 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1903eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(7); 19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1905eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(spdy_stream_lowest); 1906eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(spdy_stream_highest); 1907eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(3u, delegate_lowest.stream_id()); 1908eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, delegate_highest.stream_id()); 19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, CancelStream) { 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Request 1, at HIGHEST priority, will be cancelled before it writes data. 19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Request 2, at LOWEST priority, will be a full request and will be id 1. 191590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 191690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 19172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 19182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockWrite(*req2, 0), 19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 19202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 19227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 19242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*resp2, 1), 19252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*body2, 2), 19262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead(ASYNC, 0, 3) // EOF 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 19322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 19342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1938ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 19397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url1(kDefaultURL); 1942a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 194390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 194490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url1, HIGHEST, BoundNetLog()); 19452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 19462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 1947a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateDoNothing delegate1(spdy_stream1); 1948a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url2(kDefaultURL); 1951a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream2 = 195290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 195390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url2, LOWEST, BoundNetLog()); 19542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream2.get() != NULL); 19552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream2->stream_id()); 1956a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateDoNothing delegate2(spdy_stream2); 1957a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) spdy_stream2->SetDelegate(&delegate2); 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 1960b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 196190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 1962ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 196490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers2( 1965b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url2.spec())); 196690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 1967ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_stream1->Cancel(); 1972a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1974a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(0u, delegate1.stream_id()); 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.RunFor(1); 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1978a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(0u, delegate1.stream_id()); 1979a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(1u, delegate2.stream_id()); 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_stream2->Cancel(); 1982a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream2.get()); 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Create two streams that are set to re-close themselves on close, 1986eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// and then close the session. Nothing should blow up. Also a 1987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// regression test for http://crbug.com/139518 . 1988eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) { 19892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 19902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No actual data will be sent. 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite(ASYNC, 0, 1) // EOF 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 20042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2008ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 20097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url1(kDefaultURL); 2012a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 201390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 201490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url1, HIGHEST, BoundNetLog()); 20152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url2(kDefaultURL); 2019a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream2 = 202090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 202190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url2, LOWEST, BoundNetLog()); 20222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream2.get() != NULL); 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, spdy_stream2->stream_id()); 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate1(spdy_stream1); 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate2(spdy_stream2); 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_stream2->SetDelegate(&delegate2); 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 203190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 203290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 203390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 2034ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 203590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 203690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers2( 203790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url2.spec())); 203890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 2039ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the streams have not yet been activated and assigned an id. 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, spdy_stream2->stream_id()); 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure we don't crash while closing the session. 20467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, std::string()); 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2048a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 2049a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream2.get()); 2050a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 2051a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_TRUE(delegate1.StreamIsClosed()); 2052a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_TRUE(delegate2.StreamIsClosed()); 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2054cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2055ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2058eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Create two streams that are set to close each other on close, and 2059eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// then close the session. Nothing should blow up. 2060eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) { 20612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 20622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No actual data will be sent. 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite(ASYNC, 0, 1) // EOF 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 20762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2080ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 20817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url1(kDefaultURL); 2084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 2085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 2086eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url1, HIGHEST, BoundNetLog()); 2087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 2088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url2(kDefaultURL); 2091eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = 2092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 2093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url2, LOWEST, BoundNetLog()); 2094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream2.get() != NULL); 2095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream2->stream_id()); 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Make |spdy_stream1| close |spdy_stream2|. 2098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate1(spdy_stream2); 2099eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SetDelegate(&delegate1); 2100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Make |spdy_stream2| close |spdy_stream1|. 2102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate2(spdy_stream1); 2103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->SetDelegate(&delegate2); 2104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers( 2106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url1.spec())); 2107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 2108ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 2109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers2( 2111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url2.spec())); 2112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 2113ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 21147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure that the streams have not yet been activated and assigned an id. 2116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 2117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream2->stream_id()); 2118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure we don't crash while closing the session. 21207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, std::string()); 2121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream1.get()); 2123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream2.get()); 2124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate1.StreamIsClosed()); 2126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate2.StreamIsClosed()); 2127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 2130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Create two streams that are set to re-close themselves on close, 2133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// activate them, and then close the session. Nothing should blow up. 2134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) { 21352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 21362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req1( 2140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 2141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2( 2142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 2144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 2145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 1), 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 2149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 2) // EOF 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 21552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2159ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 21607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 21612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url1(kDefaultURL); 2163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 2164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 2165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url1, MEDIUM, BoundNetLog()); 2166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 2167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 21682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url2(kDefaultURL); 2170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = 2171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 2172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url2, MEDIUM, BoundNetLog()); 2173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream2.get() != NULL); 2174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream2->stream_id()); 21757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate1(spdy_stream1); 2177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SetDelegate(&delegate1); 21782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate2(spdy_stream2); 2180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->SetDelegate(&delegate2); 21812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers( 2183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url1.spec())); 2184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 2185ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 21862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers2( 2188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url2.spec())); 2189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 2190ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 21912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure that the streams have not yet been activated and assigned an id. 2193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 2194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream2->stream_id()); 21952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(2); 21972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, spdy_stream1->stream_id()); 2199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(3u, spdy_stream2->stream_id()); 2200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure we don't crash while closing the session. 22027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, std::string()); 2203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream1.get()); 2205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream2.get()); 2206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate1.StreamIsClosed()); 2208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate2.StreamIsClosed()); 2209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 2212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Create two streams that are set to close each other on close, 2215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// activate them, and then close the session. Nothing should blow up. 2216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) { 2217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 2218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 2220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req1( 2222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 2223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2( 2224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); 2225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 2226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 2227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 1), 2228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 22292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 2231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 2) // EOF 22322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 22332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 22352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 22362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 22372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 22382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 22402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 22427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 22432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url1(kDefaultURL); 2245a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 224690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 2247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url1, MEDIUM, BoundNetLog()); 22482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 22492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 22502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url2(kDefaultURL); 2252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = 2253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 2254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url2, MEDIUM, BoundNetLog()); 2255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream2.get() != NULL); 2256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream2->stream_id()); 22572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Make |spdy_stream1| close |spdy_stream2|. 2259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate1(spdy_stream2); 2260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SetDelegate(&delegate1); 22612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Make |spdy_stream2| close |spdy_stream1|. 2263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate2(spdy_stream1); 2264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->SetDelegate(&delegate2); 22652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 226690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 2267b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 226890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 2269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 22702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 227190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers2( 227290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url2.spec())); 2273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 2274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 22752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure that the streams have not yet been activated and assigned an id. 22772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 2278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream2->stream_id()); 22792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(2); 22812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, spdy_stream1->stream_id()); 2283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(3u, spdy_stream2->stream_id()); 22842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure we don't crash while closing the session. 22867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, std::string()); 22872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2288a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 2289a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream2.get()); 22902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate1.StreamIsClosed()); 2292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate2.StreamIsClosed()); 2293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 22962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 22972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2298bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Delegate that closes a given session when the stream is closed. 2299bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochclass SessionClosingDelegate : public test::StreamDelegateDoNothing { 2300bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch public: 2301bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch SessionClosingDelegate(const base::WeakPtr<SpdyStream>& stream, 2302bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const base::WeakPtr<SpdySession>& session_to_close) 2303bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch : StreamDelegateDoNothing(stream), 2304bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_to_close_(session_to_close) {} 2305bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2306bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch virtual ~SessionClosingDelegate() {} 2307bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2308bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch virtual void OnClose(int status) OVERRIDE { 2309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) session_to_close_->CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Error"); 2310bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 2311bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2312bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch private: 2313bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::WeakPtr<SpdySession> session_to_close_; 2314bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}; 2315bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2316bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Close an activated stream that closes its session. Nothing should 2317bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// blow up. This is a regression test for http://crbug.com/263691 . 2318bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) { 2319bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 2320bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2321bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 2322bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2323bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<SpdyFrame> req( 2324bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 2325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<SpdyFrame> rst( 2326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 2327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SpdyFrame> goaway( 2328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Error")); 2329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // The GOAWAY has higher-priority than the RST_STREAM, and is written first 2330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // despite being queued second. 2331bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockWrite writes[] = { 2332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 1), 2333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateMockWrite(*rst, 2), 2334bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch }; 2335bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2336bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockRead reads[] = { 2337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MockRead(ASYNC, 0, 3) // EOF 2338bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch }; 2339bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 2340bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch writes, arraysize(writes)); 2341bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch data.set_connect_data(connect_data); 2342bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 2343bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2344bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateDeterministicNetworkSession(); 2345bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2346bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::WeakPtr<SpdySession> session = 2347bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 2348bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 23495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url(kDefaultURL); 2350bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream = 2351bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 2352bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session, url, MEDIUM, BoundNetLog()); 2353bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ASSERT_TRUE(spdy_stream.get() != NULL); 2354bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(0u, spdy_stream->stream_id()); 2355bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2356bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch SessionClosingDelegate delegate(spdy_stream, session); 2357bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_stream->SetDelegate(&delegate); 2358bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2359bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 2360bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 2361bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 2362bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); 2363bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2364bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(0u, spdy_stream->stream_id()); 2365bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2366bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch data.RunFor(1); 2367bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2368bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(1u, spdy_stream->stream_id()); 2369bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2370bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Ensure we don't crash while closing the stream (which closes the 2371bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // session). 2372bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_stream->Cancel(); 2373bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2374bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(NULL, spdy_stream.get()); 2375bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE(delegate.StreamIsClosed()); 2376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2377f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) data.RunFor(2); // Write the RST_STREAM & GOAWAY. 2378f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2379bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE(session == NULL); 2380bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 2381bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 238203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_P(SpdySessionTest, VerifyDomainAuthentication) { 2383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 23847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 23852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 2386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // No actual data will be sent. 2388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 2389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite(ASYNC, 0, 1) // EOF 2390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 23922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 2393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0) // EOF 23942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 2395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 2396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 23972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 2398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 2399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Load a cert that is valid for: 2401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // www.example.org 2402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // mail.example.org 2403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // www.example.com 2404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::FilePath certs_dir = GetTestCertsDirectory(); 2405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<X509Certificate> test_cert( 2406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ImportCertFromFile(certs_dir, "spdy_pooling.pem")); 24071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); 24082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 2410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ssl.cert = test_cert; 2411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 24122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 24142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2415ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 24167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateSecureSpdySession(http_session_, key_, BoundNetLog()); 24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org")); 2419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org")); 2420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.com")); 2421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com")); 24222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 24232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_P(SpdySessionTest, ConnectionPooledWithTlsChannelId) { 2425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 24267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 24272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 2428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // No actual data will be sent. 24302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 2431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite(ASYNC, 0, 1) // EOF 24322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 2433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 2435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0) // EOF 2436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 2438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 24392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 2440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 2441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Load a cert that is valid for: 2443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // www.example.org 2444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // mail.example.org 2445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // www.example.com 2446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::FilePath certs_dir = GetTestCertsDirectory(); 2447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<X509Certificate> test_cert( 2448eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ImportCertFromFile(certs_dir, "spdy_pooling.pem")); 24491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); 24502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 24522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ssl.channel_id_sent = true; 2453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ssl.cert = test_cert; 2454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 24552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 24572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2458ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 24597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateSecureSpdySession(http_session_, key_, BoundNetLog()); 24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org")); 2462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org")); 2463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(session->VerifyDomainAuthentication("mail.example.com")); 2464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com")); 24652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 24662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseTwoStalledCreateStream) { 2468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(rtenneti): Define a helper class/methods and move the common code in 2469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // this file. 24702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 24717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsMap new_settings; 2473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS; 2474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint32 max_concurrent_streams = 1; 2475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new_settings[kSpdySettingsIds1] = 2476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); 24772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck()); 247990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 2480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2( 2482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 2483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req3( 2484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true)); 24852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 2486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockWrite(*settings_ack, 1), 2487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockWrite(*req1, 2), 2488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockWrite(*req2, 5), 2489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockWrite(*req3, 8), 24902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 24912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Set up the socket so we read a SETTINGS frame that sets max concurrent 2493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // streams to 1. 2494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> settings_frame( 2495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdySettings(new_settings)); 24962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 2499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 2501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 2502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5)); 2504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true)); 25052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 2507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*settings_frame), 2508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockRead(*resp1, 3), 2509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockRead(*body1, 4), 2510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockRead(*resp2, 6), 2511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockRead(*body2, 7), 2512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockRead(*resp3, 9), 2513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockRead(*body3, 10), 2514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockRead(ASYNC, 0, 11) // EOF 25152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 25162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 25182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 25192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 25202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 25212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 25232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2524ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 25257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 25262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read the settings frame. 2528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 2529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 25305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url1(kDefaultURL); 2531a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 253290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 2533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url1, LOWEST, BoundNetLog()); 25342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 25352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 2536a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateDoNothing delegate1(spdy_stream1); 2537a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 25382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback2; 25405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url2(kDefaultURL); 2541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamRequest request2; 2542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(ERR_IO_PENDING, 2543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request2.StartRequest( 2544eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SPDY_REQUEST_RESPONSE_STREAM, 2545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url2, LOWEST, BoundNetLog(), callback2.callback())); 2546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback3; 25485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url3(kDefaultURL); 2549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamRequest request3; 2550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(ERR_IO_PENDING, 2551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request3.StartRequest( 2552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SPDY_REQUEST_RESPONSE_STREAM, 2553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url3, LOWEST, BoundNetLog(), callback3.callback())); 2554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2555a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2556a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(1u, session->num_created_streams()); 25577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST)); 2558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers( 2560b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 2561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 2562ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 25632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2564a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Run until 1st stream is activated and then closed. 2565a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(0u, delegate1.stream_id()); 2566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data.RunFor(4); 2567a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 2568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, delegate1.stream_id()); 2569a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2570a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2571a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_created_streams()); 2572a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST)); 2573a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2574a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Pump loop for SpdySession::ProcessPendingStreamRequests() to 2575a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // create the 2nd stream. 2576a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2577a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2578a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2579a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(1u, session->num_created_streams()); 2580a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST)); 25812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream2 = request2.ReleaseStream(); 2583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateDoNothing delegate2(stream2); 2584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2->SetDelegate(&delegate2); 2585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers2( 2586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url2.spec())); 2587eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 2588ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream2->HasUrlFromHeaders()); 2589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2590a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Run until 2nd stream is activated and then closed. 2591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, delegate2.stream_id()); 2592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(3); 2593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, stream2.get()); 2594eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(3u, delegate2.stream_id()); 2595a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2596a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2597a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_created_streams()); 2598a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); 2599a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2600a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Pump loop for SpdySession::ProcessPendingStreamRequests() to 2601a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // create the 3rd stream. 2602a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2603a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2604a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2605a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(1u, session->num_created_streams()); 26067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); 2607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream3 = request3.ReleaseStream(); 2609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateDoNothing delegate3(stream3); 2610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream3->SetDelegate(&delegate3); 2611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers3( 2612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url3.spec())); 2613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream3->SendRequestHeaders(headers3.Pass(), NO_MORE_DATA_TO_SEND); 2614ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream3->HasUrlFromHeaders()); 2615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2616a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Run until 2nd stream is activated and then closed. 2617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, delegate3.stream_id()); 2618ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(3); 2619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, stream3.get()); 2620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(5u, delegate3.stream_id()); 2621a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2622a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2623a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_created_streams()); 26247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); 2625ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2626ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 2627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CancelTwoStalledCreateStream) { 2630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 2631eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 2633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 2634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 2637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 2638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2639eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 2640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 2641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateNetworkSession(); 2643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2644ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 26457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 2646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2647a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Leave room for only one more stream to be created. 2648a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) { 2649a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = 2650a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 2651a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 2652a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(spdy_stream != NULL); 2653a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 2654a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 26555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url1(kDefaultURL); 2656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 2657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 2658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url1, LOWEST, BoundNetLog()); 2659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 2660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 2661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback2; 26635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url2(kDefaultURL); 2664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamRequest request2; 2665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(ERR_IO_PENDING, 2666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request2.StartRequest( 2667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SPDY_BIDIRECTIONAL_STREAM, session, url2, LOWEST, BoundNetLog(), 2668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback2.callback())); 2669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback3; 26715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url3(kDefaultURL); 2672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamRequest request3; 2673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(ERR_IO_PENDING, 2674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request3.StartRequest( 2675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SPDY_BIDIRECTIONAL_STREAM, session, url3, LOWEST, BoundNetLog(), 2676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback3.callback())); 2677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2678a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2679a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams()); 26807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST)); 2681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2682a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Cancel the first stream; this will allow the second stream to be created. 2683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(spdy_stream1.get() != NULL); 2684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->Cancel(); 2685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream1.get()); 2686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2687a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(OK, callback2.WaitForResult()); 2688a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2689a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams()); 2690a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST)); 2691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2692a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Cancel the second stream; this will allow the third stream to be created. 2693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = request2.ReleaseStream(); 2694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->Cancel(); 2695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream2.get()); 2696a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2697a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(OK, callback3.WaitForResult()); 2698a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2699a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams()); 27007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); 2701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Cancel the third stream. 2703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream3 = request3.ReleaseStream(); 2704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream3->Cancel(); 2705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream3.get()); 2706a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2707a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(kInitialMaxConcurrentStreams - 1, session->num_created_streams()); 27087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); 2709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2710eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2711ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that SpdySession::DoReadLoop reads data from the socket 2712ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// without yielding. This test makes 32k - 1 bytes of data available 2713ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// on the socket for reading. It then verifies that it has read all 2714ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// the available data without yielding. 2715eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, ReadDataWithoutYielding) { 2716eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 2717eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 2718eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2719eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req1( 2720eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 2721eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 2722eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 2723eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2724eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2725ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Build buffer of size kMaxReadBytesWithoutYielding / 4 2726ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // (-spdy_data_frame_size). 2727ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding); 2728eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int kPayloadSize = 2729ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize(); 2730eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestDataStream test_stream; 2731eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize)); 2732eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch char* payload_data = payload->data(); 2733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test_stream.GetBytes(payload_data, kPayloadSize); 2734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> partial_data_frame( 2736eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); 2737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> finish_data_frame( 2738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch framer.CreateDataFrame(1, payload_data, kPayloadSize - 1, DATA_FLAG_FIN)); 2739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2741eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k 2743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // bytes. 2744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 2745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp1, 1), 2746eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*partial_data_frame, 2), 2747eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS), 2748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS), 2749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*finish_data_frame, 5, SYNCHRONOUS), 2750eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 6) // EOF 2751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2752eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create SpdySession and SpdyStream and send the request. 2754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 2755eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 2756eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 2757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 2758eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 2759eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2760eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 2761eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2762ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 27637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 2764eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 27655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url1(kDefaultURL); 2766eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 2767eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 2768eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url1, MEDIUM, BoundNetLog()); 2769eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 2770eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 2771eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateDoNothing delegate1(spdy_stream1); 2772eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SetDelegate(&delegate1); 2773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2774eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers1( 2775eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url1.spec())); 2776eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); 2777ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 2778eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2779ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Set up the TaskObserver to verify SpdySession::DoReadLoop doesn't 2780ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // post a task. 2781ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop"); 2782eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Run until 1st read. 2784eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, delegate1.stream_id()); 2785eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(2); 2786eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, delegate1.stream_id()); 2787eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, observer.executed_count()); 2788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2789ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read all the data and verify SpdySession::DoReadLoop has not 2790ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // posted a task. 2791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(4); 2792eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream1.get()); 2793eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify task observer's executed_count is zero, which indicates DoRead read 2795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // all the available data. 2796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, observer.executed_count()); 27972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 27982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 27992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 28002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2801ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that SpdySession::DoReadLoop yields while reading the 2802ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// data. This test makes 32k + 1 bytes of data available on the socket 2803ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// for reading. It then verifies that DoRead has yielded even though 2804ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// there is data available for it to read (i.e, socket()->Read didn't 2805ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// return ERR_IO_PENDING during socket reads). 28067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, TestYieldingDuringReadData) { 28072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 28087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 28092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 281090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 281190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 28122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 28132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockWrite(*req1, 0), 28142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 28152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2816ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Build buffer of size kMaxReadBytesWithoutYielding / 4 2817ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // (-spdy_data_frame_size). 2818ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding); 28192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kPayloadSize = 2820ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize(); 28212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestDataStream test_stream; 28222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize)); 28232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* payload_data = payload->data(); 28242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_stream.GetBytes(payload_data, kPayloadSize); 28252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> partial_data_frame( 28272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); 28282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> finish_data_frame( 28292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN)); 28302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 28322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Write 1 byte more than kMaxReadBytes to check that DoRead yields. 28342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 28352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*resp1, 1), 28362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*partial_data_frame, 2), 28372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS), 28382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS), 28392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*partial_data_frame, 5, SYNCHRONOUS), 28402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*finish_data_frame, 6, SYNCHRONOUS), 28412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead(ASYNC, 0, 7) // EOF 28422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 28432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create SpdySession and SpdyStream and send the request. 28452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 28462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 28472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 28482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 28492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 28502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 28522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2853ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 28547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 28552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url1(kDefaultURL); 2857a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 285890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 285990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url1, MEDIUM, BoundNetLog()); 28602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 28612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 2862a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateDoNothing delegate1(spdy_stream1); 2863a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 28642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 286590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers1( 2866b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 286790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); 2868ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 28692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2870ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Set up the TaskObserver to verify SpdySession::DoReadLoop posts a 2871ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // task. 2872ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop"); 28732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Run until 1st read. 2875a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(0u, delegate1.stream_id()); 28762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(2); 2877a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(1u, delegate1.stream_id()); 28782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, observer.executed_count()); 28792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2880ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read all the data and verify SpdySession::DoReadLoop has posted a 2881ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // task. 28822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(6); 2883a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 28842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify task observer's executed_count is 1, which indicates DoRead has 28862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // posted only one task and thus yielded though there is data available for it 28872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to read. 28882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1u, observer.executed_count()); 28892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 28902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 28912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 28922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2893ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that SpdySession::DoReadLoop() tests interactions of yielding 2894ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// + async, by doing the following MockReads. 28952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 28962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// MockRead of SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K 28972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ASYNC 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K. 28982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2899ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// The above reads 26K synchronously. Since that is less that 32K, we 2900ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// will attempt to read again. However, that DoRead() will return 2901ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// ERR_IO_PENDING (because of async read), so DoReadLoop() will 2902ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// yield. When we come back, DoRead() will read the results from the 2903ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// async read, and rest of the data synchronously. 29047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) { 29052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 29067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 29072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 290890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 290990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 29102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 29112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockWrite(*req1, 0), 29122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 29132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2914ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Build buffer of size kMaxReadBytesWithoutYielding / 4 2915ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // (-spdy_data_frame_size). 2916ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding); 29172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestDataStream test_stream; 29182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kEightKPayloadSize = 2919ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize(); 29202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<net::IOBuffer> eightk_payload( 29212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new net::IOBuffer(kEightKPayloadSize)); 29222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* eightk_payload_data = eightk_payload->data(); 29232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_stream.GetBytes(eightk_payload_data, kEightKPayloadSize); 29242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Build buffer of 2k size. 29262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestDataStream test_stream2; 29272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kTwoKPayloadSize = kEightKPayloadSize - 6 * 1024; 29282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<net::IOBuffer> twok_payload( 29292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new net::IOBuffer(kTwoKPayloadSize)); 29302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* twok_payload_data = twok_payload->data(); 29312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize); 29322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> eightk_data_frame(framer.CreateDataFrame( 29342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1, eightk_payload_data, kEightKPayloadSize, DATA_FLAG_NONE)); 29352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> twok_data_frame(framer.CreateDataFrame( 29362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1, twok_payload_data, kTwoKPayloadSize, DATA_FLAG_NONE)); 29372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame( 29382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1, "h", 1, DATA_FLAG_FIN)); 29392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 29412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 29432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*resp1, 1), 29442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 2), 29452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 3, SYNCHRONOUS), 29462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 4, SYNCHRONOUS), 29472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*twok_data_frame, 5, SYNCHRONOUS), 29482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 6, ASYNC), 29492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 7, SYNCHRONOUS), 29502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 8, SYNCHRONOUS), 29512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 9, SYNCHRONOUS), 29522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*twok_data_frame, 10, SYNCHRONOUS), 29532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*finish_data_frame, 11, SYNCHRONOUS), 29542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead(ASYNC, 0, 12) // EOF 29552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 29562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create SpdySession and SpdyStream and send the request. 29582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 29592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 29602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 29612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 29622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 29632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 29652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2966ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 29677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 29682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url1(kDefaultURL); 2970a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 297190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 297290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url1, MEDIUM, BoundNetLog()); 29732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 29742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 2975a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateDoNothing delegate1(spdy_stream1); 2976a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 29772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 297890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers1( 2979b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 298090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); 2981ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 29822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2983ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Set up the TaskObserver to monitor SpdySession::DoReadLoop 2984ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // posting of tasks. 2985ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop"); 29862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Run until 1st read. 2988a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(0u, delegate1.stream_id()); 29892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(2); 2990a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(1u, delegate1.stream_id()); 29912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, observer.executed_count()); 29922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2993ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read all the data and verify SpdySession::DoReadLoop has posted a 2994ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // task. 29952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(12); 2996a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 29972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify task observer's executed_count is 1, which indicates DoRead has 29992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // posted only one task and thus yielded though there is data available for 30002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // it to read. 30012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1u, observer.executed_count()); 30022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 30032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 30042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 30052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3006ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Send a GoAway frame when SpdySession is in DoReadLoop. Make sure 3007ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// nothing blows up. 3008ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, GoAwayWhileInDoReadLoop) { 30092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 30107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 30112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 301290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 301390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 30142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 30152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockWrite(*req1, 0), 30162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 30172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 30197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 302090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway()); 30212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 30232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*resp1, 1), 30242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*body1, 2), 30252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*goaway, 3), 30262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 30272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create SpdySession and SpdyStream and send the request. 30292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 30302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 30312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 30322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 30332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 30342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 30362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3037ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 30387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 30392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url1(kDefaultURL); 3041a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 304290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 304390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url1, MEDIUM, BoundNetLog()); 304490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateDoNothing delegate1(spdy_stream1); 304590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 30462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 30472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 30482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 304990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers1( 3050b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 305190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); 3052ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 30532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Run until 1st read. 30552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 30562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(1); 30572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1u, spdy_stream1->stream_id()); 30582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Run until GoAway. 3060ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(3); 3061a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 30622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 30632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 3064ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 30652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 30662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Within this framework, a SpdySession should be initialized with 30687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// flow control disabled for protocol version 2, with flow control 30697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// enabled only for streams for protocol version 3, and with flow 30707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// control enabled for streams and sessions for higher versions. 30717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ProtocolNegotiation) { 30722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 30732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 30752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 30762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead(SYNCHRONOUS, 0, 0) // EOF 30772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 30782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 30792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 30802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 30812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 3083ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 30847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateFakeSpdySession(spdy_session_pool_, key_); 30852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(spdy_util_.spdy_version(), 30877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session->buffered_spdy_framer_->protocol_version()); 30884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (GetParam() == kProtoDeprecatedSPDY2) { 30897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(SpdySession::FLOW_CONTROL_NONE, session->flow_control_state()); 30907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(0, session->session_send_window_size_); 30917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(0, session->session_recv_window_size_); 30927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } else if (GetParam() == kProtoSPDY3) { 30937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state()); 30947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(0, session->session_send_window_size_); 30957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(0, session->session_recv_window_size_); 30967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } else { 30977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 30987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session->flow_control_state()); 30997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, 31007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session->session_send_window_size_); 3101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, 31027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session->session_recv_window_size_); 31037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 31042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 31052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 31062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Tests the case of a non-SPDY request closing an idle SPDY session when no 3108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// pointers to the idle session are currently held. 3109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseOneIdleConnection) { 3110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ClientSocketPoolManager::set_max_sockets_per_group( 3111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 3112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ClientSocketPoolManager::set_max_sockets_per_pool( 3113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 31142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 31152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 31162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 3117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 31182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 3119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 31202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 3121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 3122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 31232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateNetworkSession(); 31252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransportClientSocketPool* pool = 3127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch http_session_->GetTransportSocketPool( 3128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL); 31292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create an idle SPDY session. 3131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(), 3132e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch PRIVACY_MODE_DISABLED); 3133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session1 = 31347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key1, BoundNetLog()); 3135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(pool->IsStalled()); 31362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Trying to create a new connection should cause the pool to be stalled, and 3138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // post a task asynchronously to try and close the session. 3139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback2; 3140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostPortPair host_port2("2.com", 80); 3141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<TransportSocketParams> params2( 31421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new TransportSocketParams( 31431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci host_port2, false, false, OnHostResolutionCallback(), 31441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); 3145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); 3146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 3147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY, 3148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback2.callback(), pool, BoundNetLog())); 3149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(pool->IsStalled()); 31502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The socket pool should close the connection asynchronously and establish a 3152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // new connection. 3153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, callback2.WaitForResult()); 3154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(pool->IsStalled()); 3155ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session1 == NULL); 31562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 31572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Tests the case of a non-SPDY request closing an idle SPDY session when no 3159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// pointers to the idle session are currently held, in the case the SPDY session 3160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// has an alias. 3161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) { 3162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ClientSocketPoolManager::set_max_sockets_per_group( 3163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 3164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ClientSocketPoolManager::set_max_sockets_per_pool( 3165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 31662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 31672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 31682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 3169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 31702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 31712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 31722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 31732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 3174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 3175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 3177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->rules()->AddIPLiteralRule( 3178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "1.com", "192.168.0.2", std::string()); 3179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->rules()->AddIPLiteralRule( 3180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "2.com", "192.168.0.2", std::string()); 3181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Not strictly needed. 3182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->rules()->AddIPLiteralRule( 3183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "3.com", "192.168.0.3", std::string()); 31842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 31852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 31862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransportClientSocketPool* pool = 3188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch http_session_->GetTransportSocketPool( 3189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL); 31902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create an idle SPDY session. 3192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(), 3193e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch PRIVACY_MODE_DISABLED); 3194ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session1 = 31957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key1, BoundNetLog()); 3196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(pool->IsStalled()); 31972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Set up an alias for the idle SPDY session, increasing its ref count to 2. 3199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key2(HostPortPair("2.com", 80), ProxyServer::Direct(), 3200e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch PRIVACY_MODE_DISABLED); 3201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostResolver::RequestInfo info(key2.host_port_pair()); 3202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddressList addresses; 3203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Pre-populate the DNS cache, since a synchronous resolution is required in 3204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // order to create the alias. 32053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) session_deps_.host_resolver->Resolve(info, 32063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DEFAULT_PRIORITY, 32073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &addresses, 32083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CompletionCallback(), 32093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NULL, 32103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) BoundNetLog()); 3211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Get a session for |key2|, which should return the session created earlier. 3212ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session2 = 32137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch spdy_session_pool_->FindAvailableSession(key2, BoundNetLog()); 3214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(session1.get(), session2.get()); 3215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(pool->IsStalled()); 32162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Trying to create a new connection should cause the pool to be stalled, and 3218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // post a task asynchronously to try and close the session. 3219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback3; 3220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostPortPair host_port3("3.com", 80); 3221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<TransportSocketParams> params3( 32221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new TransportSocketParams( 32231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci host_port3, false, false, OnHostResolutionCallback(), 32241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); 3225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle); 3226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 3227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY, 3228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback3.callback(), pool, BoundNetLog())); 3229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(pool->IsStalled()); 32307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The socket pool should close the connection asynchronously and establish a 3232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // new connection. 3233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, callback3.WaitForResult()); 3234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(pool->IsStalled()); 3235ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session1 == NULL); 3236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session2 == NULL); 3237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 32393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests that when a SPDY session becomes idle, it closes itself if there is 32403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// a lower layer pool stalled on the per-pool socket limit. 32413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) { 3242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ClientSocketPoolManager::set_max_sockets_per_group( 3243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 3244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ClientSocketPoolManager::set_max_sockets_per_pool( 3245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 3246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 3248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 3249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 3250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 3251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req1( 3252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 3253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> cancel1( 3254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 3255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 3256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 1), 3257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*cancel1, 1), 3258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 3259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), 32603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) writes, arraysize(writes)); 3261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 3262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 3263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 32643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MockRead http_reads[] = { 32653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 32663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }; 32673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 32683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NULL, 0); 32693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) http_data.set_connect_data(connect_data); 32703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&http_data); 32713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 32723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateNetworkSession(); 3274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransportClientSocketPool* pool = 3276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch http_session_->GetTransportSocketPool( 3277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL); 3278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create a SPDY session. 32805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url1(kDefaultURL); 3281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key1(HostPortPair(url1.host(), 80), 3282e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ProxyServer::Direct(), PRIVACY_MODE_DISABLED); 3283ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session1 = 32847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key1, BoundNetLog()); 3285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(pool->IsStalled()); 3286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create a stream using the session, and send a request. 3288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback1; 3290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 3291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 3292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session1, url1, DEFAULT_PRIORITY, 3293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog()); 3294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get()); 3295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateDoNothing delegate1(spdy_stream1); 3296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SetDelegate(&delegate1); 3297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers1( 3299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url1.spec())); 3300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 3301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SendRequestHeaders( 3302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch headers1.Pass(), NO_MORE_DATA_TO_SEND)); 3303ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 3304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->RunUntilIdle(); 3306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Trying to create a new connection should cause the pool to be stalled, and 3308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // post a task asynchronously to try and close the session. 3309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback2; 3310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostPortPair host_port2("2.com", 80); 3311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<TransportSocketParams> params2( 33121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new TransportSocketParams( 33131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci host_port2, false, false, OnHostResolutionCallback(), 33141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); 3315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); 3316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 3317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY, 3318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback2.callback(), pool, BoundNetLog())); 3319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(pool->IsStalled()); 3320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Running the message loop should cause the socket pool to ask the SPDY 3322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // session to close an idle socket, but since the socket is in use, nothing 3323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // happens. 3324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::RunLoop().RunUntilIdle(); 3325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(pool->IsStalled()); 3326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(callback2.have_result()); 3327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 33283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Cancelling the request should result in the session's socket being 33293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // closed, since the pool is stalled. 3330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get()); 3331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->Cancel(); 3332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::RunLoop().RunUntilIdle(); 33333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ASSERT_FALSE(pool->IsStalled()); 33343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(OK, callback2.WaitForResult()); 3335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Verify that SpdySessionKey and therefore SpdySession is different when 3338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// privacy mode is enabled or disabled. 3339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) { 3340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 3341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostPortPair host_port_pair("www.google.com", 443); 3343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(), 3344e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch PRIVACY_MODE_ENABLED); 3345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(), 3346e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch PRIVACY_MODE_DISABLED); 3347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 33487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); 33497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); 3350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add SpdySession with PrivacyMode Enabled to the pool. 3352ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session_privacy_enabled = 33537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateFakeSpdySession(spdy_session_pool_, key_privacy_enabled); 3354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 33557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); 33567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); 3357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add SpdySession with PrivacyMode Disabled to the pool. 3359ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session_privacy_disabled = 33607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateFakeSpdySession(spdy_session_pool_, key_privacy_disabled); 3361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 33627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); 33637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); 3364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 33657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session_privacy_enabled->CloseSessionOnError(ERR_ABORTED, std::string()); 33667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); 33677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); 3368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 33697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session_privacy_disabled->CloseSessionOnError(ERR_ABORTED, std::string()); 33707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); 33717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); 3372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3374bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Delegate that creates another stream when its stream is closed. 3375bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochclass StreamCreatingDelegate : public test::StreamDelegateDoNothing { 3376bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch public: 3377bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch StreamCreatingDelegate(const base::WeakPtr<SpdyStream>& stream, 3378bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const base::WeakPtr<SpdySession>& session) 3379bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch : StreamDelegateDoNothing(stream), 3380bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_(session) {} 3381bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3382bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch virtual ~StreamCreatingDelegate() {} 3383bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3384bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch virtual void OnClose(int status) OVERRIDE { 33855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url(kDefaultURL); 3386bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ignore_result( 3387bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 3388bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_, url, MEDIUM, BoundNetLog())); 3389bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 3390bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3391bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch private: 3392bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const base::WeakPtr<SpdySession> session_; 3393bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}; 3394bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3395bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Create another stream in response to a stream being reset. Nothing 3396bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// should blow up. This is a regression test for 3397bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// http://crbug.com/263690 . 3398bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_P(SpdySessionTest, CreateStreamOnStreamReset) { 3399bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 3400bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3401bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 3402bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3403bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<SpdyFrame> req( 3404bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 3405bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockWrite writes[] = { 3406bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateMockWrite(*req, 0), 3407bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch }; 3408bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3409bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<SpdyFrame> rst( 3410bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM)); 3411bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockRead reads[] = { 3412bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateMockRead(*rst, 1), 3413bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockRead(ASYNC, 0, 2) // EOF 3414bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch }; 3415bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 3416bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch writes, arraysize(writes)); 3417bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch data.set_connect_data(connect_data); 3418bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 3419bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3420bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateDeterministicNetworkSession(); 3421bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3422bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::WeakPtr<SpdySession> session = 3423bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 3424bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 34255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url(kDefaultURL); 3426bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream = 3427bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 3428bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session, url, MEDIUM, BoundNetLog()); 3429bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ASSERT_TRUE(spdy_stream.get() != NULL); 3430bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(0u, spdy_stream->stream_id()); 3431bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3432bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch StreamCreatingDelegate delegate(spdy_stream, session); 3433bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_stream->SetDelegate(&delegate); 3434bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3435bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 3436bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 3437bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 3438bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); 3439bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3440bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(0u, spdy_stream->stream_id()); 3441bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3442bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch data.RunFor(1); 3443bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3444bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(1u, spdy_stream->stream_id()); 3445bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3446bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Cause the stream to be reset, which should cause another stream 3447bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // to be created. 3448bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch data.RunFor(1); 3449bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3450bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(NULL, spdy_stream.get()); 3451bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE(delegate.StreamIsClosed()); 3452bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(0u, session->num_active_streams()); 3453bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(1u, session->num_created_streams()); 3454bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 3455bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The tests below are only for SPDY/3 and above. 3457eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) { 3459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam() < kProtoSPDY3) 3460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 3461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE 3463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // gets sent. 3464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsMap new_settings; 3465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int32 window_size = 1; 3466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new_settings[SETTINGS_INITIAL_WINDOW_SIZE] = 3467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size); 3468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Set up the socket so we read a SETTINGS frame that sets 3470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // INITIAL_WINDOW_SIZE. 3471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 3472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> settings_frame( 3473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdySettings(new_settings)); 3474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 3475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*settings_frame, 0), 3476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 1) // EOF 3477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 3478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck()); 3480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockWrite writes[] = { 3481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateMockWrite(*settings_ack, 2), 3482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 3483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 3484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 3485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 3487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) writes, arraysize(writes)); 3488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data.set_connect_data(connect_data); 3489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 3490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 3492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3493ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 34947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 3495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 3496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 3497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, test_url_, MEDIUM, BoundNetLog()); 3498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 3499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback1; 3500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_NE(spdy_stream1->send_window_size(), window_size); 3501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data.RunFor(1); // Process the SETTINGS frame, but not the EOF 3503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->RunUntilIdle(); 3504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(session->stream_initial_send_window_size(), window_size); 3505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(spdy_stream1->send_window_size(), window_size); 3506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Release the first one, this will allow the second to be created. 3508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->Cancel(); 3509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream1.get()); 3510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = 3512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 3513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, test_url_, MEDIUM, BoundNetLog()); 3514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream2.get() != NULL); 3515eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(spdy_stream2->send_window_size(), window_size); 3516eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->Cancel(); 3517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream2.get()); 3518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The tests below are only for SPDY/3.1 and above. 3521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// SpdySession::{Increase,Decrease}RecvWindowSize should properly 3523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// adjust the session receive window size for SPDY 3.1 and higher. In 3524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// addition, SpdySession::IncreaseRecvWindowSize should trigger 3525eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// sending a WINDOW_UPDATE frame for a large enough delta. 3526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, AdjustRecvWindowSize) { 3527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam() < kProtoSPDY31) 3528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 3529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 3531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int32 delta_window_size = 100; 3533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 3535eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 3536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 1) // EOF 3537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 3538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> window_update( 3539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate( 3540eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSessionFlowControlStreamId, 3541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSpdySessionInitialWindowSize + delta_window_size)); 3542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 3543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*window_update, 0), 3544eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 3545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 3546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 3547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 3548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 3549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 3551ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 35527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 3553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 3554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->flow_control_state()); 3555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 3558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->IncreaseRecvWindowSize(delta_window_size); 3560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size, 3561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->session_recv_window_size_); 3562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(delta_window_size, session->session_unacked_recv_window_bytes_); 3563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Should trigger sending a WINDOW_UPDATE frame. 3565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->IncreaseRecvWindowSize(kSpdySessionInitialWindowSize); 3566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size + 3567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSpdySessionInitialWindowSize, 3568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->session_recv_window_size_); 3569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 3570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 3572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3573ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // DecreaseRecvWindowSize() expects |in_io_loop_| to be true. 3574ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->in_io_loop_ = true; 3575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->DecreaseRecvWindowSize( 3576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSpdySessionInitialWindowSize + delta_window_size + 3577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSpdySessionInitialWindowSize); 3578ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->in_io_loop_ = false; 3579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, session->session_recv_window_size_); 3580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 3581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// SpdySession::{Increase,Decrease}SendWindowSize should properly 3584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// adjust the session send window size when the "enable_spdy_31" flag 3585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// is set. 3586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, AdjustSendWindowSize) { 3587eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam() < kProtoSPDY31) 3588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 3589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 3591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 3593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 3594eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, 0, 0) // EOF 3595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 3596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 3597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 3598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 3599eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3600eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateNetworkSession(); 3601ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 36027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateFakeSpdySession(spdy_session_pool_, key_); 3603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 3604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->flow_control_state()); 3605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int32 delta_window_size = 100; 3607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->IncreaseSendWindowSize(delta_window_size); 3611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size, 3612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->session_send_window_size_); 3613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->DecreaseSendWindowSize(delta_window_size); 3615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3618eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Incoming data for an inactive stream should not cause the session 3619c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch// receive window size to decrease, but it should cause the unacked 3620c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch// bytes to increase. 3621eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, SessionFlowControlInactiveStream) { 3622eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam() < kProtoSPDY31) 3623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 3624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 3626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 3628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyBodyFrame(1, false)); 3629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 3630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 0), 3631eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 1) // EOF 3632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 3633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), NULL, 0); 3634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 3635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 3636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 3638ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 36397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 3640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 3641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->flow_control_state()); 3642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 3645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3646ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 3647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3649c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_); 3650ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 3651ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 3652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// A delegate that drops any received data. 3655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate { 3656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 3657a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream, 3658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::StringPiece data) 365990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : StreamDelegateSendImmediate(stream, data) {} 3660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~DropReceivedDataDelegate() {} 3662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Drop any received data. 3664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE {} 3665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 3666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Send data back and forth but use a delegate that drops its received 3668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// data. The receive window should still increase to its original 3669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// value, i.e. we shouldn't "leak" receive window bytes. 36707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) { 36717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 36727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 3673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const char kStreamUrl[] = "http://www.google.com/"; 3675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int32 msg_data_size = 100; 3677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string msg_data(msg_data_size, 'a'); 3678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 3680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 36827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 36837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0)); 3684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyFrame> msg( 36857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame( 36867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1, msg_data.data(), msg_data_size, false)); 3687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockWrite writes[] = { 3688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 0), 3689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*msg, 2), 3690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 3691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyFrame> echo( 36947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame( 36957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1, msg_data.data(), msg_data_size, false)); 3696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyFrame> window_update( 369790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyWindowUpdate( 3698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kSessionFlowControlStreamId, msg_data_size)); 3699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockRead reads[] = { 3700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 1), 3701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*echo, 3), 3702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 4) // EOF 3703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 3704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create SpdySession and SpdyStream and send the request. 3706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 3707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writes, arraysize(writes)); 3708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.set_connect_data(connect_data); 3709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 3710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 3711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateDeterministicNetworkSession(); 3713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3714ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 37157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 3716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL url(kStreamUrl); 3718a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 371990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 372090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, MEDIUM, BoundNetLog()); 3721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 3722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(0u, stream->stream_id()); 3723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DropReceivedDataDelegate delegate(stream, msg_data); 3725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->SetDelegate(&delegate); 3726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 372790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 3728b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size)); 372990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 373090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 3731ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 3732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 3735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3736eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(4); 3737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 3739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 3740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3741eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); 3743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->Close(); 3745a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, stream.get()); 3746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(OK, delegate.WaitForClose()); 3748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); 3751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Send data back and forth but close the stream before its data frame 3754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// can be written to the socket. The send window should then increase 3755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// to its original value, i.e. we shouldn't "leak" send window bytes. 37567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) { 37577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 37587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 3759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 37607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const char kStreamUrl[] = "http://www.google.com/"; 3761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int32 msg_data_size = 100; 3763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string msg_data(msg_data_size, 'a'); 3764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 3766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 37687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 37697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0)); 3770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockWrite writes[] = { 3771eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 0), 3772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 3773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 37747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockRead reads[] = { 3776eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 1), 3777eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 2) // EOF 3778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 3779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create SpdySession and SpdyStream and send the request. 3781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 3782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writes, arraysize(writes)); 3783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.set_connect_data(connect_data); 3784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 3785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 3786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateDeterministicNetworkSession(); 3788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3789ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 37907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 3791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL url(kStreamUrl); 3793a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 379490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 379590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, MEDIUM, BoundNetLog()); 3796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 3797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(0u, stream->stream_id()); 3798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 379990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateSendImmediate delegate(stream, msg_data); 3800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->SetDelegate(&delegate); 3801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 380290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 3803b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size)); 380490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 380590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 3806ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 3807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 3811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.RunFor(1); 3815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 3817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 3818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size, 3820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session->session_send_window_size_); 3821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Closing the stream should increase the session's send window. 3823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->Close(); 3824a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, stream.get()); 3825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(OK, delegate.WaitForClose()); 3829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 38312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Send data back and forth; the send and receive windows should 38322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// change appropriately. 38337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) { 38347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 38357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 38362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const char kStreamUrl[] = "http://www.google.com/"; 38382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int32 msg_data_size = 100; 38402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string msg_data(msg_data_size, 'a'); 38412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 38432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 38457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 38467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0)); 38472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> msg( 38487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame( 38497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1, msg_data.data(), msg_data_size, false)); 38502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 3851eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 0), 3852eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*msg, 2), 38532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 38542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 38562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> echo( 38577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame( 38587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1, msg_data.data(), msg_data_size, false)); 38592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> window_update( 386090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyWindowUpdate( 38612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kSessionFlowControlStreamId, msg_data_size)); 38622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 3863eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 1), 3864eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*echo, 3), 3865eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*window_update, 4), 3866eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 5) // EOF 38672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 38682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create SpdySession and SpdyStream and send the request. 38702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 38712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 38722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 38732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 38742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 38752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 38772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3878ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 38797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 38802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 3882a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 388390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 388490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, MEDIUM, BoundNetLog()); 38852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 38862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, stream->stream_id()); 38872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 388890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateSendImmediate delegate(stream, msg_data); 38892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream->SetDelegate(&delegate); 38902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 389190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 3892b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size)); 389390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 389490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 3895ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 38962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3898eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 38992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 39002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3901eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 39022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3904eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 39052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 39062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(1); 39082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size, 39102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->session_send_window_size_); 3911eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 39122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 39132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(1); 39152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size, 39172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->session_send_window_size_); 3918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 39192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 39202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(1); 39222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size, 39242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->session_send_window_size_); 3925eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size, 39262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->session_recv_window_size_); 39272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 39282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(1); 39302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3932eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size, 39332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->session_recv_window_size_); 39342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 39352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 39372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 39382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(msg_data, delegate.TakeReceivedData()); 39402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Draining the delegate's read queue should increase the session's 3942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // receive window. 3943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3944eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 39452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); 39462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream->Close(); 3948a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, stream.get()); 39492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(OK, delegate.WaitForClose()); 3951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3953eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); 39552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 39562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Given a stall function and an unstall function, runs a test to make 3958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// sure that a stream resumes after unstall. 39597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void SpdySessionTest::RunResumeAfterUnstallTest( 39607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function, 396190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Callback<void(SpdySession*, SpdyStream*, int32)>& 396290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) unstall_function) { 39632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kStreamUrl[] = "http://www.google.com/"; 39642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 39652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 39672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 39697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 39707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); 397190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> body( 39727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true)); 39732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 3974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 0), 3975eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*body, 1), 39762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 39772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp( 39797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 39802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> echo( 39817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false)); 39822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 3983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 2), 3984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 3), // EOF 39852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 39862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 39882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 39892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 39902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 39912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 39932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 3995ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 39967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 39972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 39982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->flow_control_state()); 39992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4000a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 400190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 400290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, LOWEST, BoundNetLog()); 40032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 40042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4005a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateWithBody delegate(stream, kBodyDataStringPiece); 40062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream->SetDelegate(&delegate); 40072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4008ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream->HasUrlFromHeaders()); 400990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(stream->send_stalled_by_flow_control()); 40102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 401190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 4012b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 401390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 401490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 4015ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 4016ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 40172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 40187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch stall_function.Run(session.get(), stream.get()); 40192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 40212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 40222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream->send_stalled_by_flow_control()); 40232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4024868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unstall_function.Run(session.get(), stream.get(), kBodyDataSize); 40252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 40262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream->send_stalled_by_flow_control()); 40272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 40282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(3); 40292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 40302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 40312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 40322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(delegate.send_headers_completed()); 40332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status")); 403490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(std::string(), delegate.TakeReceivedData()); 403590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 40362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 40372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Run the resume-after-unstall test with all possible stall and 4039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// unstall sequences. 4040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ResumeAfterUnstallSession) { 40427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 40437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 40447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 40457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunResumeAfterUnstallTest( 40467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::StallSessionOnly, 4047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 40487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::UnstallSessionOnly, 4049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 4050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 4051c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4052c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Equivalent to 40537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// SpdyStreamTest.ResumeAfterSendWindowSizeIncrease. 40547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ResumeAfterUnstallStream) { 40557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 40567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 40577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 40587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunResumeAfterUnstallTest( 40597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::StallStreamOnly, 4060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 40617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::UnstallStreamOnly, 4062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 4063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 4064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, StallSessionStreamResumeAfterUnstallSessionStream) { 40667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 40677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 40687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 40697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunResumeAfterUnstallTest( 40707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::StallSessionStream, 4071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 40727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::UnstallSessionStream, 4073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 4074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 4075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, StallStreamSessionResumeAfterUnstallSessionStream) { 40777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 40787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 40797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 40807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunResumeAfterUnstallTest( 40817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::StallStreamSession, 4082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 40837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::UnstallSessionStream, 4084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 4085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 4086c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, StallStreamSessionResumeAfterUnstallStreamSession) { 40887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 40897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 40907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 40917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunResumeAfterUnstallTest( 40927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::StallStreamSession, 4093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 40947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::UnstallStreamSession, 4095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 4096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 4097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, StallSessionStreamResumeAfterUnstallStreamSession) { 40997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 41007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 41017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 41027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunResumeAfterUnstallTest( 41037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::StallSessionStream, 4104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 41057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::UnstallStreamSession, 4106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 4107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 4108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 41092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Cause a stall by reducing the flow control send window to 0. The 41102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// streams should resume in priority order when that window is then 41112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// increased. 41127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) { 41137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 41147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 41157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 41162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kStreamUrl[] = "http://www.google.com/"; 41172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 41182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 41192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 41202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 41212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 41227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 41237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); 41242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 41257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 41267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 3, kBodyDataSize, MEDIUM, NULL, 0)); 412790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> body1( 41287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true)); 412990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> body2( 41307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true)); 41312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 4132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 4133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 1), 4134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*body2, 2), 4135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*body1, 3), 41362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 41372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 41387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 41397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 41402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 4141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp1, 4), 4142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp2, 5), 4143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 6), // EOF 41442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 41452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 41462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 41472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 41482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 41492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 41502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 41512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 41522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 41532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 4154ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 41557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 41562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 41572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->flow_control_state()); 41582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4159a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream1 = 416090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 416190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, LOWEST, BoundNetLog()); 41622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream1.get() != NULL); 41632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4164a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); 41652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream1->SetDelegate(&delegate1); 41662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4167ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream1->HasUrlFromHeaders()); 41682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4169a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream2 = 417090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 417190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, MEDIUM, BoundNetLog()); 41722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream2.get() != NULL); 41732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4174a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece); 41752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream2->SetDelegate(&delegate2); 41762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4177ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream2->HasUrlFromHeaders()); 41782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 41792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream1->send_stalled_by_flow_control()); 41802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 41812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) StallSessionSend(session.get()); 41832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 418490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers1( 418590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 418690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 418790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); 4188ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream1->HasUrlFromHeaders()); 4189ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec()); 41902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 419290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(1u, stream1->stream_id()); 41932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream1->send_stalled_by_flow_control()); 419490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 419590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers2( 419690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 419790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 419890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); 4199ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream2->HasUrlFromHeaders()); 4200ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec()); 420190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 420290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data.RunFor(1); 420390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(3u, stream2->stream_id()); 42042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream2->send_stalled_by_flow_control()); 42052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This should unstall only stream2. 4207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UnstallSessionSend(session.get(), kBodyDataSize); 42082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream1->send_stalled_by_flow_control()); 42102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 42112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 421290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data.RunFor(1); 42132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream1->send_stalled_by_flow_control()); 42152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 42162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This should then unstall stream1. 4218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UnstallSessionSend(session.get(), kBodyDataSize); 42192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(stream1->send_stalled_by_flow_control()); 4221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 42222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(4); 42242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); 42262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); 42272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(delegate1.send_headers_completed()); 4229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status")); 4230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); 42312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(delegate2.send_headers_completed()); 42332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); 423490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); 42352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 423690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 423790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 42382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Delegate that closes a given stream after sending its body. 4240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass StreamClosingDelegate : public test::StreamDelegateWithBody { 4241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 4242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream, 4243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::StringPiece data) 4244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : StreamDelegateWithBody(stream, data) {} 4245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual ~StreamClosingDelegate() {} 4247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) { 4249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream_to_close_ = stream_to_close; 4250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 4251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void OnDataSent() OVERRIDE { 4253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateWithBody::OnDataSent(); 4254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (stream_to_close_.get()) { 4255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream_to_close_->Close(); 4256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, stream_to_close_.get()); 4257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 4258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 4259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 4261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream_to_close_; 4262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 4263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 42642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Cause a stall by reducing the flow control send window to 4265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 0. Unstalling the session should properly handle deleted streams. 4266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) { 42677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 42687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 42697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 42702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kStreamUrl[] = "http://www.google.com/"; 42712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 42722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 42742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 42767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 42777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); 42782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 42797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 42807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0)); 4281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req3( 4282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyPost( 4283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kStreamUrl, 5, kBodyDataSize, LOWEST, NULL, 0)); 4284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body2( 4285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true)); 42862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 4287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 4288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 1), 4289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req3, 2), 4290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*body2, 3), 42912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 42922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 42942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 4295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp2, 4), 4296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 5), // EOF 42972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 42982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 43002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 43012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 43022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 43032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 43042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 43052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 43062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 4307ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 43087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 43092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 43102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->flow_control_state()); 43112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4312a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream1 = 431390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 431490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, LOWEST, BoundNetLog()); 43152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream1.get() != NULL); 43162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 431790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); 43182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream1->SetDelegate(&delegate1); 43192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4320ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream1->HasUrlFromHeaders()); 43212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4322a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream2 = 432390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 432490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, LOWEST, BoundNetLog()); 43252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream2.get() != NULL); 43262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece); 43282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream2->SetDelegate(&delegate2); 43292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4330ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream2->HasUrlFromHeaders()); 43312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream3 = 4333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 4334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url, LOWEST, BoundNetLog()); 4335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream3.get() != NULL); 4336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece); 4338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream3->SetDelegate(&delegate3); 4339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4340ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream3->HasUrlFromHeaders()); 4341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 43422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream1->send_stalled_by_flow_control()); 43432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 4344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(stream3->send_stalled_by_flow_control()); 43452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) StallSessionSend(session.get()); 43472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 434890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers1( 434990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 435090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 435190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); 4352ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream1->HasUrlFromHeaders()); 4353ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec()); 43542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 435690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(1u, stream1->stream_id()); 43572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream1->send_stalled_by_flow_control()); 435890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 435990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers2( 436090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 436190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 436290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); 4363ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream2->HasUrlFromHeaders()); 4364ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec()); 436590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 436690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data.RunFor(1); 436790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(3u, stream2->stream_id()); 43682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream2->send_stalled_by_flow_control()); 43692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers3( 4371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 4372a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 4373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream3->SendRequestHeaders(headers3.Pass(), MORE_DATA_TO_SEND)); 4374ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream3->HasUrlFromHeaders()); 4375ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream3->GetUrlFromHeaders().spec()); 4376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 4378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(5u, stream3->stream_id()); 4379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(stream3->send_stalled_by_flow_control()); 4380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamId stream_id1 = stream1->stream_id(); 4382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamId stream_id2 = stream2->stream_id(); 4383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamId stream_id3 = stream3->stream_id(); 4384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Close stream1 preemptively. 4386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED); 4387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, stream1.get()); 4388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(session->IsStreamActive(stream_id1)); 4390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->IsStreamActive(stream_id2)); 4391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->IsStreamActive(stream_id3)); 43927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Unstall stream2, which should then close stream3. 4394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delegate2.set_stream_to_close(stream3); 4395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UnstallSessionSend(session.get(), kBodyDataSize); 4396a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 4398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, stream3.get()); 4399a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 4401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(session->IsStreamActive(stream_id1)); 4402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->IsStreamActive(stream_id2)); 4403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(session->IsStreamActive(stream_id3)); 4404a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(2); 4406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, stream2.get()); 4407a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); 4409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); 4410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, delegate3.WaitForClose()); 4411a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate1.send_headers_completed()); 4413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); 4414a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate2.send_headers_completed()); 4416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); 4417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); 4418a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate3.send_headers_completed()); 4420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(std::string(), delegate3.TakeReceivedData()); 4421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()); 4423a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 4424a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Cause a stall by reducing the flow control send window to 4426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 0. Unstalling the session should properly handle the session itself 4427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// being closed. 4428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) { 4429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam() < kProtoSPDY31) 44307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 44317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kStreamUrl[] = "http://www.google.com/"; 4433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url(kStreamUrl); 4434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 4436a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 443790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 4438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyPost( 4439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); 4440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2( 4441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyPost( 4442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0)); 4443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body1( 4444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false)); 4445a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) MockWrite writes[] = { 4446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 4447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 1), 4448a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) }; 4449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 4451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 2), // EOF 4452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 4455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 4456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 4457a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) data.set_connect_data(connect_data); 4458a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 4460a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 4462ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 44637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 4464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 4465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->flow_control_state()); 4466a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream1 = 4468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 4469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url, LOWEST, BoundNetLog()); 4470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream1.get() != NULL); 4471a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); 4473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1->SetDelegate(&delegate1); 4474a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4475ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream1->HasUrlFromHeaders()); 4476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream2 = 447890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 4479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url, LOWEST, BoundNetLog()); 4480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream2.get() != NULL); 4481a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece); 4483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2->SetDelegate(&delegate2); 4484a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4485ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream2->HasUrlFromHeaders()); 4486a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(stream1->send_stalled_by_flow_control()); 4488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 4489a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StallSessionSend(session.get()); 4491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers1( 4493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 4494a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 4495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); 4496ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream1->HasUrlFromHeaders()); 4497ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec()); 4498a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 4500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, stream1->stream_id()); 4501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(stream1->send_stalled_by_flow_control()); 4502a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers2( 4504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 4505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 4506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); 4507ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream2->HasUrlFromHeaders()); 4508ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec()); 4509a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 4511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(3u, stream2->stream_id()); 4512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(stream2->send_stalled_by_flow_control()); 451390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 45147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 451590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4516eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Unstall stream1. 4517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UnstallSessionSend(session.get(), kBodyDataSize); 451890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Close the session (since we can't do it from within the delegate 4520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // method, since it's in the stream's loop). 45217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session"); 4522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 4523ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 452490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 45257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 452690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); 4528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); 452990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate1.send_headers_completed()); 4531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); 453290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate2.send_headers_completed()); 4534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); 453590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()); 453790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 453890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4539f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_P(SpdySessionTest, GoAwayOnSessionFlowControlError) { 4540f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 4541f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 4542f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4543f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 4544f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4545f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SpdyFrame> req( 4546f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4547f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway( 4548f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 0, 4549f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GOAWAY_FLOW_CONTROL_ERROR, 4550f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "delta_window_size is 6 in DecreaseRecvWindowSize, which is larger than " 4551f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "the receive window size of 1")); 4552f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MockWrite writes[] = { 4553f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 3), 4554f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) }; 4555f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4556f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 4557f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 4558f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MockRead reads[] = { 4559f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateMockRead(*resp, 1), CreateMockRead(*body, 2), 4560f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) }; 4561f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4562f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DeterministicSocketData data( 4563f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) reads, arraysize(reads), writes, arraysize(writes)); 4564f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) data.set_connect_data(connect_data); 4565f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 4566f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4567f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateDeterministicNetworkSession(); 4568f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4569f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::WeakPtr<SpdySession> session = 4570f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 4571f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4572f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GURL url(kDefaultURL); 4573f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( 4574f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog()); 4575f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ASSERT_TRUE(spdy_stream.get() != NULL); 4576f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) test::StreamDelegateDoNothing delegate(spdy_stream); 4577f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) spdy_stream->SetDelegate(&delegate); 4578f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4579f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 4580f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url.spec())); 4581f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 4582f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4583f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) data.RunFor(1); // Write request. 4584f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4585f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Put session on the edge of overflowing it's recv window. 4586f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) session->session_recv_window_size_ = 1; 4587f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4588f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Read response headers & body. Body overflows the session window, and a 4589f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // goaway is written. 4590f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) data.RunFor(3); 4591f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 4592f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4593f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(ERR_SPDY_FLOW_CONTROL_ERROR, delegate.WaitForClose()); 4594f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(session == NULL); 4595f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 4596f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4597f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_P(SpdySessionTest, SplitHeaders) { 4598f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GURL kStreamUrl("http://www.google.com/foo.dat"); 4599f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SpdyHeaderBlock headers; 4600f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) spdy_util_.AddUrlToHeaderBlock(kStreamUrl.spec(), &headers); 4601f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) headers["alpha"] = "beta"; 4602f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4603f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SpdyHeaderBlock request_headers; 4604f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SpdyHeaderBlock response_headers; 4605f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4606f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SplitPushedHeadersToRequestAndResponse( 4607f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) headers, spdy_util_.spdy_version(), &request_headers, &response_headers); 4608f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4609f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SpdyHeaderBlock::const_iterator it = response_headers.find("alpha"); 4610f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string alpha_val = 4611f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) (it == response_headers.end()) ? std::string() : it->second; 4612f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ("beta", alpha_val); 4613f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4614f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GURL request_url = 4615f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GetUrlFromHeaderBlock(request_headers, spdy_util_.spdy_version(), true); 4616f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(kStreamUrl, request_url); 4617f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 4618f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4619116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Regression. Sorta. Push streams and client streams were sharing a single 4620116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// limit for a long time. 4621116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_P(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) { 4622116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SettingsMap new_settings; 4623116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = 4624116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 2); 4625116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> settings_frame( 4626116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructSpdySettings(new_settings)); 4627116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> pushed(spdy_util_.ConstructSpdyPush( 4628116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NULL, 0, 2, 1, "http://www.google.com/a.dat")); 4629116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockRead reads[] = { 4630116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateMockRead(*settings_frame), CreateMockRead(*pushed, 3), 4631116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockRead(ASYNC, 0, 4), 4632116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 4633116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4634116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck()); 4635116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> req( 4636116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4637116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockWrite writes[] = { 4638116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateMockWrite(*settings_ack, 1), CreateMockWrite(*req, 2), 4639116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 4640116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4641116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DeterministicSocketData data( 4642116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch reads, arraysize(reads), writes, arraysize(writes)); 4643116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 4644116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.set_connect_data(connect_data); 4645116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 4646116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4647116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateDeterministicNetworkSession(); 4648116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4649116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::WeakPtr<SpdySession> session = 4650116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 4651116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4652116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Read the settings frame. 4653116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4654116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4655116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GURL url1(kDefaultURL); 4656116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously( 4657116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); 4658116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 4659116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 4660116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch test::StreamDelegateDoNothing delegate1(spdy_stream1); 4661116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_stream1->SetDelegate(&delegate1); 4662116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4663116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_streams()); 4664116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_created_streams()); 4665116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_pushed_streams()); 4666116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_pushed_streams()); 4667116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4668116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 4669116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url1.spec())); 4670116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 4671116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 4672116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4673116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Run until 1st stream is activated. 4674116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, delegate1.stream_id()); 4675116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(2); 4676116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, delegate1.stream_id()); 4677116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_active_streams()); 4678116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_created_streams()); 4679116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_pushed_streams()); 4680116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_pushed_streams()); 4681116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4682116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Run until pushed stream is created. 4683116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4684116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(2u, session->num_active_streams()); 4685116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_created_streams()); 4686116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_pushed_streams()); 4687116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_active_pushed_streams()); 4688116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4689116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Second stream should not be stalled, although we have 2 active streams, but 4690116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // one of them is push stream and should not be taken into account when we 4691116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // create streams on the client. 4692116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = CreateStreamSynchronously( 4693116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); 4694116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(spdy_stream2.get() != NULL); 4695116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(2u, session->num_active_streams()); 4696116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_created_streams()); 4697116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_pushed_streams()); 4698116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_active_pushed_streams()); 4699116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4700116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Read EOF. 4701116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4702116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 4703116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4704116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) { 4705116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush( 4706116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NULL, 0, 2, 1, "http://www.google.com/a.dat")); 4707116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush( 4708116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NULL, 0, 4, 1, "http://www.google.com/b.dat")); 4709116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockRead reads[] = { 4710116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateMockRead(*push_a, 1), CreateMockRead(*push_b, 2), 4711116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockRead(ASYNC, 0, 4), 4712116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 4713116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4714116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> req( 4715116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4716116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> rst( 4717116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM)); 4718116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockWrite writes[] = { 4719116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateMockWrite(*req, 0), CreateMockWrite(*rst, 3), 4720116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 4721116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4722116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DeterministicSocketData data( 4723116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch reads, arraysize(reads), writes, arraysize(writes)); 4724116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 4725116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.set_connect_data(connect_data); 4726116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 4727116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4728116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateDeterministicNetworkSession(); 4729116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4730116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::WeakPtr<SpdySession> session = 4731116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 4732116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch session->set_max_concurrent_pushed_streams(1); 4733116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4734116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GURL url1(kDefaultURL); 4735116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously( 4736116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); 4737116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 4738116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 4739116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch test::StreamDelegateDoNothing delegate1(spdy_stream1); 4740116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_stream1->SetDelegate(&delegate1); 4741116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4742116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_streams()); 4743116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_created_streams()); 4744116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_pushed_streams()); 4745116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_pushed_streams()); 4746116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4747116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 4748116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url1.spec())); 4749116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 4750116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 4751116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4752116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Run until 1st stream is activated. 4753116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, delegate1.stream_id()); 4754116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4755116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, delegate1.stream_id()); 4756116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_active_streams()); 4757116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_created_streams()); 4758116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_pushed_streams()); 4759116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_pushed_streams()); 4760116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4761116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Run until pushed stream is created. 4762116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4763116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(2u, session->num_active_streams()); 4764116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_created_streams()); 4765116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_pushed_streams()); 4766116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_active_pushed_streams()); 4767116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4768116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Reset incoming pushed stream. 4769116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(2); 4770116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(2u, session->num_active_streams()); 4771116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_created_streams()); 4772116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_pushed_streams()); 4773116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_active_pushed_streams()); 4774116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4775116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Read EOF. 4776116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4777116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 4778116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4779116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) { 4780116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Streams in reserved remote state exist only in SPDY4. 4781116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (spdy_util_.spdy_version() < SPDY4) 4782116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 4783116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4784116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush( 4785116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NULL, 0, 2, 1, "http://www.google.com/a.dat")); 4786116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); 4787116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.AddUrlToHeaderBlock("http://www.google.com/b.dat", 4788116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch push_headers.get()); 4789116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> push_b( 4790116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 4, 1)); 4791116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> headers_b( 4792116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructSpdyPushHeaders(4, NULL, 0)); 4793116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockRead reads[] = { 4794116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateMockRead(*push_a, 1), CreateMockRead(*push_b, 2), 4795116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateMockRead(*headers_b, 3), MockRead(ASYNC, 0, 5), 4796116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 4797116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4798116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> req( 4799116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4800116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> rst( 4801116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM)); 4802116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockWrite writes[] = { 4803116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4), 4804116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 4805116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4806116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DeterministicSocketData data( 4807116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch reads, arraysize(reads), writes, arraysize(writes)); 4808116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 4809116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.set_connect_data(connect_data); 4810116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 4811116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4812116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateDeterministicNetworkSession(); 4813116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4814116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::WeakPtr<SpdySession> session = 4815116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 4816116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch session->set_max_concurrent_pushed_streams(1); 4817116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4818116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GURL url1(kDefaultURL); 4819116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously( 4820116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); 4821116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 4822116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 4823116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch test::StreamDelegateDoNothing delegate1(spdy_stream1); 4824116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_stream1->SetDelegate(&delegate1); 4825116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4826116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_streams()); 4827116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_created_streams()); 4828116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_pushed_streams()); 4829116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_pushed_streams()); 4830116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4831116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 4832116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url1.spec())); 4833116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 4834116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 4835116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4836116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Run until 1st stream is activated. 4837116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, delegate1.stream_id()); 4838116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4839116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, delegate1.stream_id()); 4840116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_active_streams()); 4841116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_created_streams()); 4842116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_pushed_streams()); 4843116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_pushed_streams()); 4844116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4845116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Run until pushed stream is created. 4846116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4847116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(2u, session->num_active_streams()); 4848116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_created_streams()); 4849116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_pushed_streams()); 4850116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_active_pushed_streams()); 4851116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4852116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Accept promised stream. It should not count towards pushed stream limit. 4853116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4854116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(3u, session->num_active_streams()); 4855116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_created_streams()); 4856116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(2u, session->num_pushed_streams()); 4857116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_active_pushed_streams()); 4858116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4859116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Reset last pushed stream upon headers reception as it is going to be 2nd, 4860116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // while we accept only one. 4861116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(2); 4862116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(2u, session->num_active_streams()); 4863116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_created_streams()); 4864116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_pushed_streams()); 4865116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_active_pushed_streams()); 4866116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4867116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Read EOF. 4868116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4869116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 4870116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4871116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_P(SpdySessionTest, CancelReservedStreamOnHeadersReceived) { 4872116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Streams in reserved remote state exist only in SPDY4. 4873116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (spdy_util_.spdy_version() < SPDY4) 4874116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 4875116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4876116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char kPushedUrl[] = "http://www.google.com/a.dat"; 4877116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); 4878116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.AddUrlToHeaderBlock(kPushedUrl, push_headers.get()); 4879116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> push_promise( 4880116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 2, 1)); 4881116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> headers_frame( 4882116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructSpdyPushHeaders(2, NULL, 0)); 4883116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockRead reads[] = { 4884116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateMockRead(*push_promise, 1), CreateMockRead(*headers_frame, 2), 4885116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockRead(ASYNC, 0, 4), 4886116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 4887116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4888116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> req( 4889116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4890116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyFrame> rst( 4891116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL)); 4892116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockWrite writes[] = { 4893116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateMockWrite(*req, 0), CreateMockWrite(*rst, 3), 4894116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 4895116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4896116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DeterministicSocketData data( 4897116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch reads, arraysize(reads), writes, arraysize(writes)); 4898116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 4899116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.set_connect_data(connect_data); 4900116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 4901116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4902116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateDeterministicNetworkSession(); 4903116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4904116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::WeakPtr<SpdySession> session = 4905116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 4906116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4907116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GURL url1(kDefaultURL); 4908116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously( 4909116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); 4910116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 4911116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 4912116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch test::StreamDelegateDoNothing delegate1(spdy_stream1); 4913116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_stream1->SetDelegate(&delegate1); 4914116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4915116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_streams()); 4916116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_created_streams()); 4917116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_pushed_streams()); 4918116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_pushed_streams()); 4919116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4920116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 4921116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url1.spec())); 4922116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 4923116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 4924116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4925116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Run until 1st stream is activated. 4926116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, delegate1.stream_id()); 4927116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4928116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, delegate1.stream_id()); 4929116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_active_streams()); 4930116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_created_streams()); 4931116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_pushed_streams()); 4932116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_pushed_streams()); 4933116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4934116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Run until pushed stream is created. 4935116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4936116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(2u, session->num_active_streams()); 4937116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_created_streams()); 4938116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_pushed_streams()); 4939116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_pushed_streams()); 4940116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4941116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::WeakPtr<SpdyStream> pushed_stream; 4942116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int rv = 4943116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch session->GetPushStream(GURL(kPushedUrl), &pushed_stream, BoundNetLog()); 4944116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_EQ(OK, rv); 4945116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_TRUE(pushed_stream.get() != NULL); 4946116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch test::StreamDelegateCloseOnHeaders delegate2(pushed_stream); 4947116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pushed_stream->SetDelegate(&delegate2); 4948116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4949116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Receive headers for pushed stream. Delegate will cancel the stream, ensure 4950116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // that all our counters are in consistent state. 4951116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(1); 4952116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(1u, session->num_active_streams()); 4953116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_created_streams()); 4954116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_pushed_streams()); 4955116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0u, session->num_active_pushed_streams()); 4956116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4957116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Read EOF. 4958116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.RunFor(2); 4959116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 4960116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 496103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_P(SpdySessionTest, RejectInvalidUnknownFrames) { 496203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 496303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 496403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) MockRead reads[] = { 496503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 496603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 496703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 496803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 496903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 497003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 497103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) data.set_connect_data(connect_data); 497203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 497303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 497403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) CreateNetworkSession(); 497503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::WeakPtr<SpdySession> session = 497603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 497703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 497803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) session->stream_hi_water_mark_ = 5; 497903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Low client (odd) ids are fine. 498003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(session->OnUnknownFrame(3, 0)); 498103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Client id exceeding watermark. 498203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(session->OnUnknownFrame(9, 0)); 49831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 49841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci session->last_accepted_push_stream_id_ = 6; 49851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Low server (even) ids are fine. 498603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(session->OnUnknownFrame(2, 0)); 49871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Server id exceeding last accepted id. 49881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(session->OnUnknownFrame(8, 0)); 498903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 499003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 49915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST(MapFramerErrorToProtocolError, MapsValues) { 4992f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ( 4993f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SPDY_ERROR_INVALID_CONTROL_FRAME, 4994f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapFramerErrorToProtocolError(SpdyFramer::SPDY_INVALID_CONTROL_FRAME)); 4995f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ( 4996f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SPDY_ERROR_INVALID_DATA_FRAME_FLAGS, 4997f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapFramerErrorToProtocolError(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS)); 4998f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ( 4999f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SPDY_ERROR_GOAWAY_FRAME_CORRUPT, 5000f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapFramerErrorToProtocolError(SpdyFramer::SPDY_GOAWAY_FRAME_CORRUPT)); 5001a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK_EQ(SPDY_ERROR_UNEXPECTED_FRAME, 5002f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapFramerErrorToProtocolError(SpdyFramer::SPDY_UNEXPECTED_FRAME)); 5003f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 5004f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 5005f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST(MapFramerErrorToNetError, MapsValue) { 5006f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ(ERR_SPDY_PROTOCOL_ERROR, 5007f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapFramerErrorToNetError(SpdyFramer::SPDY_INVALID_CONTROL_FRAME)); 5008f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ(ERR_SPDY_COMPRESSION_ERROR, 5009f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapFramerErrorToNetError(SpdyFramer::SPDY_COMPRESS_FAILURE)); 5010f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ(ERR_SPDY_COMPRESSION_ERROR, 5011f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapFramerErrorToNetError(SpdyFramer::SPDY_DECOMPRESS_FAILURE)); 5012f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ( 5013f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ERR_SPDY_FRAME_SIZE_ERROR, 5014f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapFramerErrorToNetError(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE)); 50155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 50165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 50175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST(MapRstStreamStatusToProtocolError, MapsValues) { 50185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CHECK_EQ(STATUS_CODE_PROTOCOL_ERROR, 5019f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapRstStreamStatusToProtocolError(RST_STREAM_PROTOCOL_ERROR)); 50205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CHECK_EQ(STATUS_CODE_FRAME_SIZE_ERROR, 5021f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapRstStreamStatusToProtocolError(RST_STREAM_FRAME_SIZE_ERROR)); 50225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CHECK_EQ(STATUS_CODE_ENHANCE_YOUR_CALM, 5023f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapRstStreamStatusToProtocolError(RST_STREAM_ENHANCE_YOUR_CALM)); 5024f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 5025f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 5026f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST(MapNetErrorToGoAwayStatus, MapsValue) { 5027f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ(GOAWAY_INADEQUATE_SECURITY, 5028f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapNetErrorToGoAwayStatus(ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY)); 5029f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ(GOAWAY_FLOW_CONTROL_ERROR, 5030f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapNetErrorToGoAwayStatus(ERR_SPDY_FLOW_CONTROL_ERROR)); 5031f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ(GOAWAY_PROTOCOL_ERROR, 5032f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapNetErrorToGoAwayStatus(ERR_SPDY_PROTOCOL_ERROR)); 5033f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ(GOAWAY_COMPRESSION_ERROR, 5034f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapNetErrorToGoAwayStatus(ERR_SPDY_COMPRESSION_ERROR)); 5035f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ(GOAWAY_FRAME_SIZE_ERROR, 5036f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MapNetErrorToGoAwayStatus(ERR_SPDY_FRAME_SIZE_ERROR)); 5037f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ(GOAWAY_PROTOCOL_ERROR, MapNetErrorToGoAwayStatus(ERR_UNEXPECTED)); 50385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 50395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 504003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST(CanPoolTest, CanPool) { 504103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Load a cert that is valid for: 504203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // www.example.org 504303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // mail.example.org 504403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // www.example.com 504503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 504603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TransportSecurityState tss; 504703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SSLInfo ssl_info; 504803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), 504903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "spdy_pooling.pem"); 505003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 505103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(SpdySession::CanPool( 505203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &tss, ssl_info, "www.example.org", "www.example.org")); 505303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(SpdySession::CanPool( 505403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &tss, ssl_info, "www.example.org", "mail.example.org")); 505503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(SpdySession::CanPool( 505603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &tss, ssl_info, "www.example.org", "mail.example.com")); 505703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(SpdySession::CanPool( 505803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &tss, ssl_info, "www.example.org", "mail.google.com")); 505903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 506003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 506103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST(CanPoolTest, CanNotPoolWithCertErrors) { 506203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Load a cert that is valid for: 506303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // www.example.org 506403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // mail.example.org 506503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // www.example.com 506603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 506703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TransportSecurityState tss; 506803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SSLInfo ssl_info; 506903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), 507003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "spdy_pooling.pem"); 507103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.cert_status = CERT_STATUS_REVOKED; 507203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 507303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(SpdySession::CanPool( 507403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &tss, ssl_info, "www.example.org", "mail.example.org")); 507503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 507603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 507703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST(CanPoolTest, CanNotPoolWithClientCerts) { 507803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Load a cert that is valid for: 507903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // www.example.org 508003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // mail.example.org 508103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // www.example.com 508203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 508303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TransportSecurityState tss; 508403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SSLInfo ssl_info; 508503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), 508603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "spdy_pooling.pem"); 508703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.client_cert_sent = true; 508803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 508903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(SpdySession::CanPool( 509003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &tss, ssl_info, "www.example.org", "mail.example.org")); 509103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 509203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 509303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST(CanPoolTest, CanNotPoolAcrossETLDsWithChannelID) { 509403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Load a cert that is valid for: 509503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // www.example.org 509603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // mail.example.org 509703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // www.example.com 509803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 509903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TransportSecurityState tss; 510003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SSLInfo ssl_info; 510103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), 510203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "spdy_pooling.pem"); 510303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.channel_id_sent = true; 510403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 510503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(SpdySession::CanPool( 510603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &tss, ssl_info, "www.example.org", "mail.example.org")); 510703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(SpdySession::CanPool( 510803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &tss, ssl_info, "www.example.org", "www.example.com")); 510903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 511003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 511103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST(CanPoolTest, CanNotPoolWithBadPins) { 511203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint8 primary_pin = 1; 511303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint8 backup_pin = 2; 511403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint8 bad_pin = 3; 511503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TransportSecurityState tss; 511603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) test::AddPin(&tss, "mail.example.org", primary_pin, backup_pin); 511703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 511803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SSLInfo ssl_info; 511903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), 512003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "spdy_pooling.pem"); 512103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.is_issued_by_known_root = true; 512203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.public_key_hashes.push_back(test::GetTestHashValue(bad_pin)); 512303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 512403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(SpdySession::CanPool( 512503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &tss, ssl_info, "www.example.org", "mail.example.org")); 512603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 512703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 512803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST(CanPoolTest, CanPoolWithAcceptablePins) { 512903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint8 primary_pin = 1; 513003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint8 backup_pin = 2; 513103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TransportSecurityState tss; 513203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) test::AddPin(&tss, "mail.example.org", primary_pin, backup_pin); 513303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 513403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SSLInfo ssl_info; 513503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), 513603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "spdy_pooling.pem"); 513703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.is_issued_by_known_root = true; 513803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.public_key_hashes.push_back(test::GetTestHashValue(primary_pin)); 513903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 514003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(SpdySession::CanPool( 514103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &tss, ssl_info, "www.example.org", "mail.example.org")); 514203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 514303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 51445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 5145