spdy_session_unittest.cc revision c2db58bd994c04d98e4ee2cd7565b71548655fe3
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) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/callback.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 10a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/run_loop.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/io_buffer.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/ip_endpoint.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log_unittest.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/request_priority.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_data_directory.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/test_data_stream.h" 17a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "net/socket/client_socket_pool_manager.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/next_proto.h" 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/socket/socket_test_util.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_http_utils.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session_pool.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_session_test_util.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_stream.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_stream_test_util.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_test_util_common.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/spdy/spdy_test_utils.h" 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/test/cert_test_util.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kTestUrl[] = "http://www.example.org/"; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kTestHost[] = "www.example.org"; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kTestPort = 80; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kBodyData[] = "Body data"; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kBodyDataSize = arraysize(kBodyData); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::StringPiece kBodyDataStringPiece(kBodyData, kBodyDataSize); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstatic base::TimeDelta g_time_delta; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::TimeTicks TheNearFuture() { 44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return base::TimeTicks::Now() + g_time_delta; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class SpdySessionTest : public PlatformTest, 507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public ::testing::WithParamInterface<NextProto> { 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Functions used with RunResumeAfterUnstallTest(). 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StallSessionOnly(SpdySession* session, SpdyStream* stream) { 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StallSessionSend(session); 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StallStreamOnly(SpdySession* session, SpdyStream* stream) { 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StallStreamSend(stream); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StallSessionStream(SpdySession* session, SpdyStream* stream) { 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StallSessionSend(session); 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StallStreamSend(stream); 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StallStreamSession(SpdySession* session, SpdyStream* stream) { 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StallStreamSend(stream); 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StallSessionSend(session); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void UnstallSessionOnly(SpdySession* session, 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyStream* stream, 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int32 delta_window_size) { 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UnstallSessionSend(session, delta_window_size); 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void UnstallStreamOnly(SpdySession* session, 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyStream* stream, 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int32 delta_window_size) { 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UnstallStreamSend(stream, delta_window_size); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void UnstallSessionStream(SpdySession* session, 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyStream* stream, 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int32 delta_window_size) { 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UnstallSessionSend(session, delta_window_size); 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UnstallStreamSend(stream, delta_window_size); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void UnstallStreamSession(SpdySession* session, 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyStream* stream, 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int32 delta_window_size) { 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UnstallStreamSend(stream, delta_window_size); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UnstallSessionSend(session, delta_window_size); 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdySessionTest() 100a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) : old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group( 101a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) HttpNetworkSession::NORMAL_SOCKET_POOL)), 102a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool( 103a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) HttpNetworkSession::NORMAL_SOCKET_POOL)), 1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_(GetParam()), 1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session_deps_(GetParam()), 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) spdy_session_pool_(NULL), 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_url_(kTestUrl), 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_host_port_pair_(kTestHost, kTestPort), 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) key_(test_host_port_pair_, ProxyServer::Direct(), 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kPrivacyModeDisabled) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual ~SpdySessionTest() { 114a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Important to restore the per-pool limit first, since the pool limit must 115a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // always be greater than group limit, and the tests reduce both limits. 116a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ClientSocketPoolManager::set_max_sockets_per_pool( 117a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_); 118a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ClientSocketPoolManager::set_max_sockets_per_group( 119a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_); 120a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 121a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 122a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) virtual void SetUp() OVERRIDE { 123ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch g_time_delta = base::TimeDelta(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CreateDeterministicNetworkSession() { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_session_ = 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_session_pool_ = http_session_->spdy_session_pool(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CreateNetworkSession() { 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_session_ = 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySessionDependencies::SpdyCreateSession(&session_deps_); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_session_pool_ = http_session_->spdy_session_pool(); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void StallSessionSend(SpdySession* session) { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Reduce the send window size to 0 to stall. 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (session->session_send_window_size_ > 0) { 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->DecreaseSendWindowSize( 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::min(kMaxSpdyFrameChunkSize, session->session_send_window_size_)); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void UnstallSessionSend(SpdySession* session, int32 delta_window_size) { 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->IncreaseSendWindowSize(delta_window_size); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StallStreamSend(SpdyStream* stream) { 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Reduce the send window size to 0 to stall. 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (stream->send_window_size() > 0) { 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->DecreaseSendWindowSize( 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::min(kMaxSpdyFrameChunkSize, stream->send_window_size())); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void UnstallStreamSend(SpdyStream* stream, int32 delta_window_size) { 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->IncreaseSendWindowSize(delta_window_size); 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void RunResumeAfterUnstallTest( 1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function, 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Callback<void(SpdySession*, SpdyStream*, int32)>& 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) unstall_function); 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 167a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Original socket limits. Some tests set these. Safest to always restore 168a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // them once each test has been run. 169a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int old_max_group_sockets_; 170a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int old_max_pool_sockets_; 171a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 172b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SpdyTestUtil spdy_util_; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySessionDependencies session_deps_; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<HttpNetworkSession> http_session_; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySessionPool* spdy_session_pool_; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL test_url_; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HostPortPair test_host_port_pair_; 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdySessionKey key_; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)INSTANTIATE_TEST_CASE_P( 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NextProto, 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdySessionTest, 184558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, 185558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch kProtoHTTP2Draft04)); 1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 187ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Try to create a SPDY session that will fail during 188ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// initialization. Nothing should blow up. 189ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, InitialReadError) { 190ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 191ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 192ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch TryCreateFakeSpdySessionExpectingFailure( 193ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_session_pool_, key_, ERR_FAILED); 194ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 195ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 196ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// A session receiving a GOAWAY frame with no active streams should 197ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// immediately close. 198ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) { 199ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 200ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 201ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 202ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 203ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 204ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway, 0), 205ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 206ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), NULL, 0); 207ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 209ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 210ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 212ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 213ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 214ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 216ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 217ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 219ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 220ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 221ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 222ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the GOAWAY frame. 223ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 225ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 227ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 228ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 229ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 230ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// A session receiving a GOAWAY frame immediately with no active 231ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// streams should then close. 232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) { 233ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 234ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 235ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway, 0, SYNCHRONOUS), 239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 240ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), NULL, 0); 241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 242ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 243ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 244ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 245ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 246ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 247ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.StopAfter(1); 250ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 251ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch TryCreateInsecureSpdySessionExpectingFailure( 252ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch http_session_, key_, ERR_CONNECTION_CLOSED, BoundNetLog()); 253ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 256ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 257ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// A session receiving a GOAWAY frame with active streams should close 258ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// when the last active stream is closed. 259ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, GoAwayWithActiveStreams) { 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateMockRead(*goaway, 2), 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockRead(ASYNC, 0, 3) // EOF 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockWrite writes[] = { 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateMockWrite(*req1, 0), 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateMockWrite(*req2, 1), 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writes, arraysize(writes)); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateDeterministicNetworkSession(); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL url("http://www.google.com"); 292a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, MEDIUM, BoundNetLog()); 29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateDoNothing delegate1(spdy_stream1); 29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 298a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream2 = 29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, MEDIUM, BoundNetLog()); 30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateDoNothing delegate2(spdy_stream2); 30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream2->SetDelegate(&delegate2); 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url.spec())); 3067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 309ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 311ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.RunFor(2); 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(1u, spdy_stream1->stream_id()); 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(3u, spdy_stream2->stream_id()); 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Read and process the GOAWAY frame. 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.RunFor(1); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(session->IsStreamActive(3)); 326ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(NULL, spdy_stream2.get()); 327ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session->IsStreamActive(1)); 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 329ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(session->IsClosed()); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 331ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Should close the session. 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) spdy_stream1->Close(); 333a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 335ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 336ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 338ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Have a session receive two GOAWAY frames, with the last one causing 339ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// the last active stream to be closed. The session should then be 340ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// closed after the second GOAWAY frame. 341ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, GoAwayTwice) { 342ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 343ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 344ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 345ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway1(spdy_util_.ConstructSpdyGoAway(1)); 346ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway2(spdy_util_.ConstructSpdyGoAway(0)); 347ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 348ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway1, 2), 349ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway2, 3), 350ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 4) // EOF 351ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 352ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req1( 353ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 354ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req2( 355ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); 356ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockWrite writes[] = { 357ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req1, 0), 358ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req2, 1), 359ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 360ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 361ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch writes, arraysize(writes)); 362ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 363ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 364ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 365ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 366ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 368ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 369ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 370ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 371ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 372ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 373ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 374ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 375ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL url("http://www.google.com"); 376ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 377ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 378ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, MEDIUM, BoundNetLog()); 379ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate1(spdy_stream1); 380ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream1->SetDelegate(&delegate1); 381ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 382ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = 383ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 384ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, MEDIUM, BoundNetLog()); 385ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate2(spdy_stream2); 386ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream2->SetDelegate(&delegate2); 387ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 388ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 389ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 390ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); 391ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 392ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 393ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 394ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 395ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 396ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 397ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(2); 398ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 399ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(1u, spdy_stream1->stream_id()); 400ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(3u, spdy_stream2->stream_id()); 401ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 402ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 403ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 404ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the first GOAWAY frame. 405ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 406ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 407ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 408ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 409ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(session->IsStreamActive(3)); 410a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream2.get()); 411ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session->IsStreamActive(1)); 412ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 413ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(session->IsClosed()); 414ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 415ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the second GOAWAY frame, which should close the 416ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // session. 417ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 418ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 419ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 420ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 421ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 422ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Have a session with active streams receive a GOAWAY frame and then 423ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// close it. It should handle the close properly (i.e., not try to 424ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// make itself unavailable in its pool twice). 425ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) { 426ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 427ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 428ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 429ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 430ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 431ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway, 2), 432ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 3) // EOF 433ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 434ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req1( 435ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 436ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req2( 437ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); 438ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockWrite writes[] = { 439ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req1, 0), 440ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req2, 1), 441ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 442ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 443ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch writes, arraysize(writes)); 444ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 445ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 446ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 447ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 448ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 449ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 450ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 451ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 452ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 453ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 454ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 455ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 456ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 457ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL url("http://www.google.com"); 458ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 459ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 460ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, MEDIUM, BoundNetLog()); 461ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate1(spdy_stream1); 462ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream1->SetDelegate(&delegate1); 463ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 464ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = 465ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 466ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, MEDIUM, BoundNetLog()); 467ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate2(spdy_stream2); 468ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream2->SetDelegate(&delegate2); 469ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 470ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 471ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 472ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); 473ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 474ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 475ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 476ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 477ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 478ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 479ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(2); 480ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 481ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(1u, spdy_stream1->stream_id()); 482ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(3u, spdy_stream2->stream_id()); 483ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 484ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 485ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 486ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the GOAWAY frame. 487ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 488ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 489ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 490ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 491ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(session->IsStreamActive(3)); 492ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(NULL, spdy_stream2.get()); 493ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session->IsStreamActive(1)); 494ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 495ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(session->IsClosed()); 496ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 497ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, "Aborting session"); 498ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 499ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(NULL, spdy_stream1.get()); 500ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 501ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 502ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 503ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Try to create a stream after receiving a GOAWAY frame. It should 504ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// fail. 505ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, CreateStreamAfterGoAway) { 506ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const char kStreamUrl[] = "http://www.google.com"; 507ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 508ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 509ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 510ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 511ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 512ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway, 1), 513ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 2) // EOF 514ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 515ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req( 516ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 517ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockWrite writes[] = { 518ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req, 0), 519ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 520ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 521ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch writes, arraysize(writes)); 522ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 523ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 524ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 525ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 526ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 527ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 528ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 529ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 530ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 531ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 532ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 533ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 534ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 535ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL url(kStreamUrl); 536ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream = 537ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 538ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, MEDIUM, BoundNetLog()); 539ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate(spdy_stream); 540ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream->SetDelegate(&delegate); 541ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 542ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 543ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 544ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 545ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); 546ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 547ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 548ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 549ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(1u, spdy_stream->stream_id()); 550ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 551ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 552ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 553ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the GOAWAY frame. 554ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 555ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 556ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 557ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session->IsStreamActive(1)); 558ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 559ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SpdyStreamRequest stream_request; 560ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int rv = stream_request.StartRequest( 561ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog(), 562ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CompletionCallback()); 563ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(ERR_FAILED, rv); 564ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 565ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process EOF. 566ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 567ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 568ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 569ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 570ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 571ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Receiving a SYN_STREAM frame after a GOAWAY frame should result in 572ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// the stream being refused. 573ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, SynStreamAfterGoAway) { 574ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const char kStreamUrl[] = "http://www.google.com"; 575ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 576ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 577ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 578ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 579ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> 580ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl)); 581ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 582ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*goaway, 1), 583ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*push, 2), 584ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 4) // EOF 585ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 586ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req( 587ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 588ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> rst( 589ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); 590ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockWrite writes[] = { 591ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req, 0), 592ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*rst, 3) 593ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 594ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 595ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch writes, arraysize(writes)); 596ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 597ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 598ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 599ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 600ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 601ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 602ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 603ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 604ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 605ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 606ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 607ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 608ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 609ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL url(kStreamUrl); 610ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream = 611ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 612ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, MEDIUM, BoundNetLog()); 613ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate(spdy_stream); 614ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream->SetDelegate(&delegate); 615ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 616ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 617ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 618ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 619ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); 620ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 621ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 622ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 623ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(1u, spdy_stream->stream_id()); 624ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 625ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 626ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 627ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the GOAWAY frame. 628ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 629ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 630ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 631ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session->IsStreamActive(1)); 632ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 633ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read and process the SYN_STREAM frame, the subsequent RST_STREAM, 634ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // and EOF. 635ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(3); 636ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 637ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ClientPing) { 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.enable_ping = true; 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 64590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1)); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 647ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockRead(*read_ping, 1), 648ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 0, 2) // EOF 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 65090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1)); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 652ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*write_ping, 0), 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 654ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data( 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reads, arraysize(reads), writes, arraysize(writes)); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 657ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 660ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 662ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 664ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 6657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 667a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 66890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 66990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 67190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL); 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks before_ping_time = base::TimeTicks::Now(); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->set_connection_at_risk_of_loss_time( 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromSeconds(-1)); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->set_hung_interval(base::TimeDelta::FromMilliseconds(50)); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->SendPrefacePingIfNoneInFlight(); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 682ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(2); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->CheckPingStatus(before_ping_time); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, session->pings_in_flight()); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1)); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(session->check_ping_status_pending()); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(session->last_activity_time(), before_ping_time); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 691ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 692ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 693ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 696ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ServerPing) { 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 70390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(2)); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockRead(*read_ping), 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(SYNCHRONOUS, 0, 0) // EOF 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 70890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(2)); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateMockWrite(*write_ping), 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StaticSocketDataProvider data( 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reads, arraysize(reads), writes, arraysize(writes)); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 722ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 7237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 72690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 72790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 72990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL); 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 732ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Flush the read completion task. 73390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 737ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 738a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 741ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Cause a ping to be sent out while producing a write. The write loop 742ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// should handle this properly, i.e. another DoWriteLoop task should 743ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// not be posted. This is a regression test for 744ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// http://crbug.com/261043 . 745ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, PingAndWriteLoop) { 746ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.enable_ping = true; 747ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.time_func = TheNearFuture; 748ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 749ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 750ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1)); 751ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyFrame> req( 752ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 753ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockWrite writes[] = { 754ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*req, 0), 755ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateMockWrite(*write_ping, 1), 756ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 757ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 758ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead reads[] = { 759ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 2) // EOF 760ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 761ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 762ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 763ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 764ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 765ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch writes, arraysize(writes)); 766ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.set_connect_data(connect_data); 767ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 768ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 769ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 770ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 771ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 772ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 773ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 774ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 775ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 776ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 777ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL url("http://www.google.com"); 778ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream = 779ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 780ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, url, LOWEST, BoundNetLog()); 781ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch test::StreamDelegateDoNothing delegate(spdy_stream); 782ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream->SetDelegate(&delegate); 783ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 784ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 785ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 786ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 787ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 788ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Shift time so that a ping will be sent out. 789ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch g_time_delta = base::TimeDelta::FromSeconds(11); 790ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 791ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(2); 792ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 793ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, "Aborting"); 794ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 795ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 7967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, DeleteExpiredPushStreams) { 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.time_func = TheNearFuture; 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 8067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateFakeSpdySession(spdy_session_pool_, key_); 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session->buffered_spdy_framer_.reset( 8097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new BufferedSpdyFramer(spdy_util_.spdy_version(), false)); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the associated stream and add to active streams. 8127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyHeaderBlock> request_headers( 8137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructGetHeaderBlock("http://www.google.com/")); 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<SpdyStream> stream(new SpdyStream(SPDY_REQUEST_RESPONSE_STREAM, 816ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, 817ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL(), 818868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DEFAULT_PRIORITY, 819868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kSpdyStreamInitialWindowSize, 820868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kSpdyStreamInitialWindowSize, 821868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) session->net_log_)); 82290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(request_headers.Pass(), NO_MORE_DATA_TO_SEND); 823a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) SpdyStream* stream_ptr = stream.get(); 824a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) session->InsertCreatedStream(stream.Pass()); 825a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) stream = session->ActivateCreatedStream(stream_ptr); 826a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) session->InsertActivatedStream(stream.Pass()); 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyHeaderBlock headers; 8297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.AddUrlToHeaderBlock("http://www.google.com/a.dat", &headers); 8307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 831ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // OnSynStream() expects |in_io_loop_| to be true. 832ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->in_io_loop_ = true; 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->OnSynStream(2, 1, 0, 0, true, false, headers); 834ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->in_io_loop_ = false; 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that there is one unclaimed push stream. 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, session->num_unclaimed_pushed_streams()); 83890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdySession::PushedStreamMap::iterator iter = 839ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->unclaimed_pushed_streams_.find( 840ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL("http://www.google.com/a.dat")); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 843ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Shift time to expire the push stream. 844ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch g_time_delta = base::TimeDelta::FromSeconds(301); 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.AddUrlToHeaderBlock("http://www.google.com/b.dat", &headers); 847ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->in_io_loop_ = true; 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->OnSynStream(4, 1, 0, 0, true, false, headers); 849ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->in_io_loop_ = false; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that the second pushed stream evicted the first pushed stream. 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, session->num_unclaimed_pushed_streams()); 853ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch iter = session->unclaimed_pushed_streams_.find( 854ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL("http://www.google.com/b.dat")); 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter); 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, FailedPing) { 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 863ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockRead(ASYNC, 0, 0, 0) // EOF 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 86590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1)); 866ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), NULL, 0); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 868ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 871ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 873ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 8767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 878a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 87990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 88090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 88290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL); 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0)); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->set_hung_interval(base::TimeDelta::FromSeconds(0)); 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send a PING frame. 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->WritePingFrame(1); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(0, session->pings_in_flight()); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1)); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(session->check_ping_status_pending()); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assert session is not closed. 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(session->IsClosed()); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(0u, session->num_active_streams() + session->num_created_streams()); 8977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We set last time we have received any data in 1 sec less than now. 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CheckPingStatus will trigger timeout because hung interval is zero. 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks now = base::TimeTicks::Now(); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->last_activity_time_ = now - base::TimeDelta::FromSeconds(1); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->CheckPingStatus(now); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 9067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 908ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 909a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 912a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Request kInitialMaxConcurrentStreams + 1 streams. Receive a 913a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// settings frame increasing the max concurrent streams by 1. Make 914a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// sure nothing blows up. This is a regression test for 915a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// http://crbug.com/57331 . 9167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, OnSettings) { 9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 919ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const SpdySettingsIds kSpdySettingsIds = SETTINGS_MAX_CONCURRENT_STREAMS; 920ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsMap new_settings; 922a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1; 923ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch new_settings[kSpdySettingsIds] = 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); 92590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> settings_frame( 92690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdySettings(new_settings)); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 928a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateMockRead(*settings_frame, 0), 929a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockRead(ASYNC, 0, 1), 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 932a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), NULL, 0); 933ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 935ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 938ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 940ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 942ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 9437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Create the maximum number of concurrent streams. 946a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) { 947a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = 948a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 949a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 950a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(spdy_stream != NULL); 951a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 953a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) StreamReleaserCallback stream_releaser; 9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdyStreamRequest request; 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, 95690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request.StartRequest( 95790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, 95890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BoundNetLog(), 95990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream_releaser.MakeCallback(&request))); 960ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 961a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) data.RunFor(1); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9639ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch EXPECT_EQ(OK, stream_releaser.WaitForResult()); 964ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 965ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 966ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 969a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Start with a persisted value for max concurrent streams. Receive a 970a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// settings frame increasing the max concurrent streams by 1 and which 971a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// also clears the persisted data. Verify that persisted data is 972a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// correct. 9737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ClearSettings) { 974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SettingsMap new_settings; 977a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1; 978a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = 979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); 98090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> settings_frame( 98190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdySettings(new_settings)); 982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint8 flags = SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; 983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::SetFrameFlags(settings_frame.get(), flags, spdy_util_.spdy_version()); 984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockRead reads[] = { 985a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateMockRead(*settings_frame, 0), 986a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockRead(ASYNC, 0, 1), 987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 989a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), NULL, 0); 990ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.set_connect_data(connect_data); 992ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 995ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 997ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateDeterministicNetworkSession(); 998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 999a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Initialize the SpdySetting with the default. 1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) spdy_session_pool_->http_server_properties()->SetSpdySetting( 1001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) test_host_port_pair_, 1002a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SETTINGS_MAX_CONCURRENT_STREAMS, 1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SETTINGS_FLAG_PLEASE_PERSIST, 1004a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) kInitialMaxConcurrentStreams); 1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1006a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_FALSE( 1007a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) spdy_session_pool_->http_server_properties()->GetSpdySettings( 1008a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) test_host_port_pair_).empty()); 1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1010ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 10117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 1012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1013a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Create the maximum number of concurrent streams. 1014a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) { 1015a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = 1016a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 1017a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 1018a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(spdy_stream != NULL); 1019a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1021a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) StreamReleaserCallback stream_releaser; 1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyStreamRequest request; 1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, 102590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request.StartRequest( 102690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, 102790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BoundNetLog(), 102890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream_releaser.MakeCallback(&request))); 1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1030a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) data.RunFor(1); 1031ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 10329ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch EXPECT_EQ(OK, stream_releaser.WaitForResult()); 1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure that persisted data is cleared. 1035a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE( 1036a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) spdy_session_pool_->http_server_properties()->GetSpdySettings( 1037a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) test_host_port_pair_).empty()); 1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1039a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Make sure session's max_concurrent_streams is correct. 1040a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(kInitialMaxConcurrentStreams + 1, 1041a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session->max_concurrent_streams()); 10427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1043ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 1044ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 1045c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1047a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Start with max concurrent streams set to 1. Request two streams. 1048a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// When the first completes, have the callback close its stream, which 1049a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// should trigger the second stream creation. Then cancel that one 1050a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// immediately. Don't crash. This is a regression test for 1051a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// http://crbug.com/63532 . 10527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, CancelPendingCreateStream) { 10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the SpdySetting with 1 max concurrent streams. 10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_session_pool_->http_server_properties()->SetSpdySetting( 10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_host_port_pair_, 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SETTINGS_MAX_CONCURRENT_STREAMS, 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SETTINGS_FLAG_PLEASE_PERSIST, 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1); 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1077ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 10787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1080a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Leave room for only one more stream to be created. 1081a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) { 1082a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = 1083a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 1084a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 1085a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(spdy_stream != NULL); 1086a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1087a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1088a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Create 2 more streams. First will succeed. Second will be pending. 1089a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 109090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 109190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use scoped_ptr to let us invalidate the memory when we want to, to trigger 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a valgrind error if the callback is invoked when it's not supposed to be. 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback); 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdyStreamRequest request; 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, 110090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request.StartRequest( 110190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, 110290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BoundNetLog(), 110390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback->callback())); 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Release the first one, this will allow the second to be created. 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_stream1->Cancel(); 1107a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.CancelRequest(); 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.reset(); 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should not crash when running the pending callback. 111390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_P(SpdySessionTest, SendInitialDataOnNewSession) { 11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsMap settings; 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS; 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpdySettingsIds kSpdySettingsIds2 = SETTINGS_INITIAL_WINDOW_SIZE; 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32 kInitialRecvWindowSize = 10 * 1024 * 1024; 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings[kSpdySettingsIds1] = 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); 11297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (spdy_util_.spdy_version() >= SPDY3) { 11307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) settings[kSpdySettingsIds2] = 11317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kInitialRecvWindowSize); 11327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 113490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> settings_frame( 113590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdySettings(settings)); 1136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> initial_window_update( 1137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate( 1138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSessionFlowControlStreamId, 1139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize)); 1140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<MockWrite> writes; 1141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (GetParam() == kProtoHTTP2Draft04) { 1142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) writes.push_back( 1143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockWrite(ASYNC, 1144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) kHttp2ConnectionHeaderPrefix, 1145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) kHttp2ConnectionHeaderPrefixSize)); 1146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) writes.push_back(CreateMockWrite(*settings_frame)); 1148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (GetParam() >= kProtoSPDY31) { 1149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) writes.push_back(CreateMockWrite(*initial_window_update)); 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SettingsMap server_settings; 1153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const uint32 initial_max_concurrent_streams = 1; 1154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) server_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = 1155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED, 1156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) initial_max_concurrent_streams); 1157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<SpdyFrame> server_settings_frame( 1158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) spdy_util_.ConstructSpdySettings(server_settings)); 1159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) writes.push_back(CreateMockWrite(*server_settings_frame)); 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session_deps_.stream_initial_recv_window_size = kInitialRecvWindowSize; 1162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), 1164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) vector_as_array(&writes), writes.size()); 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_session_pool_->http_server_properties()->SetSpdySetting( 11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_host_port_pair_, 1175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SETTINGS_MAX_CONCURRENT_STREAMS, 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SETTINGS_FLAG_PLEASE_PERSIST, 1177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) initial_max_concurrent_streams); 1178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SpdySessionPoolPeer pool_peer(spdy_session_pool_); 1180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pool_peer.SetEnableSendingInitialData(true); 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1182ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 11837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 118590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 11867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(data.at_write_eof()); 11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ClearSettingsStorageOnIPAddressChanged) { 11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1192ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<HttpServerProperties> test_http_server_properties = 11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_session_pool_->http_server_properties(); 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndValue flags_and_value1(SETTINGS_FLAG_PLEASE_PERSIST, 2); 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_http_server_properties->SetSpdySetting( 11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_host_port_pair_, 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SETTINGS_MAX_CONCURRENT_STREAMS, 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SETTINGS_FLAG_PLEASE_PERSIST, 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2); 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(0u, test_http_server_properties->GetSpdySettings( 12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_host_port_pair_).size()); 12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_session_pool_->OnIPAddressChanged(); 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings( 12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_host_port_pair_).size()); 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, Initialize) { 1208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CapturingBoundNetLog log; 1209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.net_log = log.bound().net_log(); 1210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 1211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 1213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockRead reads[] = { 1214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 1215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 1216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 1218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.set_connect_data(connect_data); 1219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 1220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 1222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 1223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateNetworkSession(); 1225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 12277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, log.bound()); 12287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 1229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1230ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Flush the read completion task. 123190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::CapturingNetLog::CapturedEntryList entries; 1234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) log.GetEntries(&entries); 1235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_LT(0u, entries.size()); 1236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check that we logged TYPE_SPDY_SESSION_INITIALIZED correctly. 1238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int pos = net::ExpectLogContainsSomewhere( 1239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries, 0, 1240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::NetLog::TYPE_SPDY_SESSION_INITIALIZED, 1241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::NetLog::PHASE_NONE); 1242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_LT(0, pos); 1243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CapturingNetLog::CapturedEntry entry = entries[pos]; 1245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NetLog::Source socket_source; 1246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NetLog::Source::FromEventParameters(entry.params.get(), 1247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &socket_source)); 1248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(socket_source.IsValid()); 1249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_NE(log.bound().source().id, socket_source.id); 1250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 12527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, CloseSessionOnError) { 12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 125690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway()); 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*goaway), 12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead(SYNCHRONOUS, 0, 0) // EOF 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CapturingBoundNetLog log; 1272ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 12737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, log.bound()); 12747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1276ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Flush the read completion task. 127790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 1280ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check that the NetLog was filled reasonably. 12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::CapturingNetLog::CapturedEntryList entries; 12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) log.GetEntries(&entries); 12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_LT(0u, entries.size()); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check that we logged SPDY_SESSION_CLOSE correctly. 12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int pos = net::ExpectLogContainsSomewhere( 12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entries, 0, 12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::NetLog::TYPE_SPDY_SESSION_CLOSE, 12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::NetLog::PHASE_NONE); 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (pos < static_cast<int>(entries.size())) { 1294ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CapturingNetLog::CapturedEntry entry = entries[pos]; 1295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int error_code = 0; 1296ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ASSERT_TRUE(entry.GetNetErrorCode(&error_code)); 1297ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, error_code); 1298ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else { 1299ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ADD_FAILURE(); 1300ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Queue up a low-priority SYN_STREAM followed by a high-priority 1304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// one. The high priority one should still send first and receive 1305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// first. 13067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, OutOfOrderSynStreams) { 13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Construct the request. 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 1309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req_highest( 131090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, HIGHEST, true)); 1311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req_lowest( 131290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 1314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req_highest, 0), 1315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req_lowest, 1), 13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp_highest( 1319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 1320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body_highest( 1321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, true)); 1322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp_lowest( 1323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 1324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body_lowest( 1325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(3, true)); 13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 1327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp_highest, 2), 1328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body_highest, 3), 1329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp_lowest, 4), 1330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body_lowest, 5), 1331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 6) // EOF 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 1337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 1339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 1342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1346ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 13477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url("http://www.google.com"); 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream_lowest = 135290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 135390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, LOWEST, BoundNetLog()); 1354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream_lowest); 1355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream_lowest->stream_id()); 1356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateDoNothing delegate_lowest(spdy_stream_lowest); 1357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream_lowest->SetDelegate(&delegate_lowest); 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream_highest = 136090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 136190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, HIGHEST, BoundNetLog()); 1362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream_highest); 1363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream_highest->stream_id()); 1364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateDoNothing delegate_highest(spdy_stream_highest); 1365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream_highest->SetDelegate(&delegate_highest); 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Queue the lower priority one first. 1368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers_lowest( 1370b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url.spec())); 1371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream_lowest->SendRequestHeaders( 1372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch headers_lowest.Pass(), NO_MORE_DATA_TO_SEND); 1373ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream_lowest->HasUrlFromHeaders()); 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers_highest( 1376b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url.spec())); 1377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream_highest->SendRequestHeaders( 1378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch headers_highest.Pass(), NO_MORE_DATA_TO_SEND); 1379ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream_highest->HasUrlFromHeaders()); 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(7); 13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(spdy_stream_lowest); 1384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(spdy_stream_highest); 1385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(3u, delegate_lowest.stream_id()); 1386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, delegate_highest.stream_id()); 13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, CancelStream) { 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Request 1, at HIGHEST priority, will be cancelled before it writes data. 13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Request 2, at LOWEST priority, will be a full request and will be id 1. 139390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 139490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockWrite(*req2, 0), 13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 14007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*resp2, 1), 14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*body2, 2), 14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead(ASYNC, 0, 3) // EOF 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1419ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 14207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url1("http://www.google.com"); 1423a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 142490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 142590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url1, HIGHEST, BoundNetLog()); 14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 1428a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateDoNothing delegate1(spdy_stream1); 1429a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url2("http://www.google.com"); 1432a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream2 = 143390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 143490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url2, LOWEST, BoundNetLog()); 14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream2.get() != NULL); 14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream2->stream_id()); 1437a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateDoNothing delegate2(spdy_stream2); 1438a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) spdy_stream2->SetDelegate(&delegate2); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 144090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 1441b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 144290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 1443ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 144590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers2( 1446b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url2.spec())); 144790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 1448ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) spdy_stream1->Cancel(); 1453a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(0u, delegate1.stream_id()); 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.RunFor(1); 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1459a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(0u, delegate1.stream_id()); 1460a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(1u, delegate2.stream_id()); 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_stream2->Cancel(); 1463a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream2.get()); 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Create two streams that are set to re-close themselves on close, 1467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// and then close the session. Nothing should blow up. Also a 1468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// regression test for http://crbug.com/139518 . 1469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) { 14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No actual data will be sent. 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite(ASYNC, 0, 1) // EOF 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1492ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 14937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url1("http://www.google.com"); 1496a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 149790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 149890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url1, HIGHEST, BoundNetLog()); 14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url2("http://www.google.com"); 1503a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream2 = 150490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 150590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url2, LOWEST, BoundNetLog()); 15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream2.get() != NULL); 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, spdy_stream2->stream_id()); 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate1(spdy_stream1); 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate2(spdy_stream2); 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_stream2->SetDelegate(&delegate2); 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 151590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 151690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 151790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 1518ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 151990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 152090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers2( 152190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url2.spec())); 152290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 1523ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the streams have not yet been activated and assigned an id. 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, spdy_stream2->stream_id()); 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure we don't crash while closing the session. 15307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, std::string()); 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1532a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 1533a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream2.get()); 1534a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1535a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_TRUE(delegate1.StreamIsClosed()); 1536a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_TRUE(delegate2.StreamIsClosed()); 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1538ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Create two streams that are set to close each other on close, and 1542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// then close the session. Nothing should blow up. 1543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) { 15442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 15452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No actual data will be sent. 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite(ASYNC, 0, 1) // EOF 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead(ASYNC, 0, 0) // EOF 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1566ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 15677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url1("http://www.google.com"); 1570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 1571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 1572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url1, HIGHEST, BoundNetLog()); 1573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 1574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url2("http://www.google.com"); 1577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = 1578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 1579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url2, LOWEST, BoundNetLog()); 1580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream2.get() != NULL); 1581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream2->stream_id()); 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Make |spdy_stream1| close |spdy_stream2|. 1584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate1(spdy_stream2); 1585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SetDelegate(&delegate1); 1586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1587eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Make |spdy_stream2| close |spdy_stream1|. 1588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate2(spdy_stream1); 1589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->SetDelegate(&delegate2); 1590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers( 1592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url1.spec())); 1593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 1594ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 1595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers2( 1597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url2.spec())); 1598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 1599ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 16007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1601eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure that the streams have not yet been activated and assigned an id. 1602eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 1603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream2->stream_id()); 1604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure we don't crash while closing the session. 16067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, std::string()); 1607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream1.get()); 1609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream2.get()); 1610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate1.StreamIsClosed()); 1612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate2.StreamIsClosed()); 1613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1614ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 1615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 1616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Create two streams that are set to re-close themselves on close, 1618eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// activate them, and then close the session. Nothing should blow up. 1619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) { 16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req1( 1625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 1626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2( 1627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockWrite writes[] = { 1629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 1630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 1), 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRead reads[] = { 1634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 2) // EOF 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writes, arraysize(writes)); 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 16402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 16432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1647ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 16487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 16492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url1("http://www.google.com"); 1651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 1652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 1653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url1, MEDIUM, BoundNetLog()); 1654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 1655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url2("http://www.google.com"); 1658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = 1659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 1660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url2, MEDIUM, BoundNetLog()); 1661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream2.get() != NULL); 1662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream2->stream_id()); 16637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate1(spdy_stream1); 1665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SetDelegate(&delegate1); 16662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate2(spdy_stream2); 1668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->SetDelegate(&delegate2); 16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers( 1671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url1.spec())); 1672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 1673ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers2( 1676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url2.spec())); 1677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 1678ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure that the streams have not yet been activated and assigned an id. 1681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 1682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream2->stream_id()); 16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(2); 16852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, spdy_stream1->stream_id()); 1687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(3u, spdy_stream2->stream_id()); 1688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure we don't crash while closing the session. 16907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, std::string()); 1691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream1.get()); 1693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream2.get()); 1694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate1.StreamIsClosed()); 1696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate2.StreamIsClosed()); 1697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1698ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 1699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 1700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Create two streams that are set to close each other on close, 1702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// activate them, and then close the session. Nothing should blow up. 1703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) { 1704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 1705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 1707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req1( 1709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 1710eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2( 1711eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); 1712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 1713eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 1714eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 1), 1715eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 1718eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 2) // EOF 17192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1731ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 17327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 17332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url1("http://www.google.com"); 1735a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 173690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 1737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url1, MEDIUM, BoundNetLog()); 17382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 17392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url2("http://www.google.com"); 1742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = 1743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 1744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url2, MEDIUM, BoundNetLog()); 1745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream2.get() != NULL); 1746eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream2->stream_id()); 17472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Make |spdy_stream1| close |spdy_stream2|. 1749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate1(spdy_stream2); 1750eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SetDelegate(&delegate1); 17512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Make |spdy_stream2| close |spdy_stream1|. 1753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::ClosingDelegate delegate2(spdy_stream1); 1754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->SetDelegate(&delegate2); 17552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 175690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 1757b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 175890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 1759ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 17602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 176190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers2( 176290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url2.spec())); 1763eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 1764ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); 17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1766eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure that the streams have not yet been activated and assigned an id. 17672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 1768eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream2->stream_id()); 17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1770eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(2); 17712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1772eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, spdy_stream1->stream_id()); 1773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(3u, spdy_stream2->stream_id()); 17742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1775eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ensure we don't crash while closing the session. 17767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, std::string()); 17772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1778a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 1779a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream2.get()); 17802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1781eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate1.StreamIsClosed()); 1782eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate2.StreamIsClosed()); 1783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1784ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 17852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 17862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1787bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Delegate that closes a given session when the stream is closed. 1788bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochclass SessionClosingDelegate : public test::StreamDelegateDoNothing { 1789bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch public: 1790bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch SessionClosingDelegate(const base::WeakPtr<SpdyStream>& stream, 1791bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const base::WeakPtr<SpdySession>& session_to_close) 1792bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch : StreamDelegateDoNothing(stream), 1793bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_to_close_(session_to_close) {} 1794bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1795bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch virtual ~SessionClosingDelegate() {} 1796bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1797bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch virtual void OnClose(int status) OVERRIDE { 1798bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_to_close_->CloseSessionOnError(ERR_ABORTED, "Aborted"); 1799bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 1800bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1801bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch private: 1802bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::WeakPtr<SpdySession> session_to_close_; 1803bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}; 1804bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1805bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Close an activated stream that closes its session. Nothing should 1806bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// blow up. This is a regression test for http://crbug.com/263691 . 1807bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) { 1808bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 1809bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1810bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 1811bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1812bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<SpdyFrame> req( 1813bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 1814bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockWrite writes[] = { 1815bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateMockWrite(*req, 0), 1816bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch }; 1817bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1818bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockRead reads[] = { 1819bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockRead(ASYNC, 0, 1) // EOF 1820bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch }; 1821bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 1822bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch writes, arraysize(writes)); 1823bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch data.set_connect_data(connect_data); 1824bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 1825bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1826bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 1827bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 1828bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1829bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateDeterministicNetworkSession(); 1830bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1831bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::WeakPtr<SpdySession> session = 1832bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 1833bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1834bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch GURL url("http://www.google.com"); 1835bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream = 1836bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 1837bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session, url, MEDIUM, BoundNetLog()); 1838bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ASSERT_TRUE(spdy_stream.get() != NULL); 1839bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(0u, spdy_stream->stream_id()); 1840bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1841bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch SessionClosingDelegate delegate(spdy_stream, session); 1842bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_stream->SetDelegate(&delegate); 1843bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1844bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 1845bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 1846bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 1847bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); 1848bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1849bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(0u, spdy_stream->stream_id()); 1850bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1851bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch data.RunFor(1); 1852bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1853bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(1u, spdy_stream->stream_id()); 1854bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1855bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Ensure we don't crash while closing the stream (which closes the 1856bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // session). 1857bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_stream->Cancel(); 1858bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1859bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(NULL, spdy_stream.get()); 1860bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE(delegate.StreamIsClosed()); 1861bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE(session == NULL); 1862bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 1863bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1864eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, VerifyDomainAuthentication) { 1865eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 18667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 1868eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1869eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // No actual data will be sent. 1870eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 1871eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite(ASYNC, 0, 1) // EOF 1872eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 1873eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 18742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 1875eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0) // EOF 18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1877eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 1878eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 1880eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 1881eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1882eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Load a cert that is valid for: 1883eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // www.example.org 1884eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // mail.example.org 1885eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // www.example.com 1886eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::FilePath certs_dir = GetTestCertsDirectory(); 1887eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<X509Certificate> test_cert( 1888eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ImportCertFromFile(certs_dir, "spdy_pooling.pem")); 1889eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); 18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 1892eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ssl.cert = test_cert; 1893eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1895eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 18962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1897ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 18987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateSecureSpdySession(http_session_, key_, BoundNetLog()); 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1900eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org")); 1901eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org")); 1902eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.com")); 1903eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com")); 19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1906eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, ConnectionPooledWithTlsChannelId) { 1907eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 19087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 1910eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1911eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // No actual data will be sent. 19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 1913eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite(ASYNC, 0, 1) // EOF 19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1915eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1916eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 1917eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0) // EOF 1918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 1919eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 1920eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 19212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 1922eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 1923eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1924eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Load a cert that is valid for: 1925eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // www.example.org 1926eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // mail.example.org 1927eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // www.example.com 1928eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::FilePath certs_dir = GetTestCertsDirectory(); 1929eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<X509Certificate> test_cert( 1930eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ImportCertFromFile(certs_dir, "spdy_pooling.pem")); 1931eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); 19322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 19342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ssl.channel_id_sent = true; 1935eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ssl.cert = test_cert; 1936eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 19372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1938eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 19392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1940ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 19417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateSecureSpdySession(http_session_, key_, BoundNetLog()); 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1943eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org")); 1944eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org")); 1945eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(session->VerifyDomainAuthentication("mail.example.com")); 1946eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com")); 19472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 19482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1949eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseTwoStalledCreateStream) { 1950eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(rtenneti): Define a helper class/methods and move the common code in 1951eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // this file. 19522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 19537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1954eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsMap new_settings; 1955eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS; 1956eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint32 max_concurrent_streams = 1; 1957eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new_settings[kSpdySettingsIds1] = 1958eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); 19592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 196090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 1961eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 1962eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2( 1963eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 1964eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req3( 1965eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true)); 19662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 1967eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 1), 1968eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 4), 1969eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req3, 7), 19702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 19712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1972eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Set up the socket so we read a SETTINGS frame that sets max concurrent 1973eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // streams to 1. 1974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> settings_frame( 1975eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdySettings(new_settings)); 19762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 1978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 1979eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 1981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true)); 1982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5)); 1984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true)); 19852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 1987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*settings_frame), 1988eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp1, 2), 1989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body1, 3), 1990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp2, 5), 1991eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body2, 6), 1992eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp3, 8), 1993eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*body3, 9), 1994eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 10) // EOF 19952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 19962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 19982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 19992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 20002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 20012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 20032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 20042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 20062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2007ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 20087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 20092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Read the settings frame. 2011eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 2012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 20132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url1("http://www.google.com"); 2014a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 201590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 2016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url1, LOWEST, BoundNetLog()); 20172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 20182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 2019a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateDoNothing delegate1(spdy_stream1); 2020a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 20212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2022eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback2; 2023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url2("http://www.google.com"); 2024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamRequest request2; 2025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(ERR_IO_PENDING, 2026eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request2.StartRequest( 2027eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SPDY_REQUEST_RESPONSE_STREAM, 2028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url2, LOWEST, BoundNetLog(), callback2.callback())); 2029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2030eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback3; 2031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url3("http://www.google.com"); 2032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamRequest request3; 2033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(ERR_IO_PENDING, 2034eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request3.StartRequest( 2035eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SPDY_REQUEST_RESPONSE_STREAM, 2036eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url3, LOWEST, BoundNetLog(), callback3.callback())); 2037eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2038a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2039a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(1u, session->num_created_streams()); 20407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST)); 2041eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2042eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers( 2043b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 2044eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 2045ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 20462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2047a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Run until 1st stream is activated and then closed. 2048a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(0u, delegate1.stream_id()); 2049eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(3); 2050a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 2051eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, delegate1.stream_id()); 2052a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2053a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2054a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_created_streams()); 2055a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST)); 2056a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2057a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Pump loop for SpdySession::ProcessPendingStreamRequests() to 2058a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // create the 2nd stream. 2059a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2060a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2061a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2062a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(1u, session->num_created_streams()); 2063a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST)); 20642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2065eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream2 = request2.ReleaseStream(); 2066eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateDoNothing delegate2(stream2); 2067eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2->SetDelegate(&delegate2); 2068eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers2( 2069eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url2.spec())); 2070eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); 2071ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream2->HasUrlFromHeaders()); 2072eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2073a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Run until 2nd stream is activated and then closed. 2074eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, delegate2.stream_id()); 2075eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(3); 2076eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, stream2.get()); 2077eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(3u, delegate2.stream_id()); 2078a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2079a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2080a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_created_streams()); 2081a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); 2082a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2083a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Pump loop for SpdySession::ProcessPendingStreamRequests() to 2084a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // create the 3rd stream. 2085a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2086a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2087a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2088a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(1u, session->num_created_streams()); 20897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); 2090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2091eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream3 = request3.ReleaseStream(); 2092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateDoNothing delegate3(stream3); 2093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream3->SetDelegate(&delegate3); 2094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers3( 2095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url3.spec())); 2096eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream3->SendRequestHeaders(headers3.Pass(), NO_MORE_DATA_TO_SEND); 2097ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream3->HasUrlFromHeaders()); 2098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2099a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Run until 2nd stream is activated and then closed. 2100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, delegate3.stream_id()); 2101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(3); 2102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, stream3.get()); 2103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(5u, delegate3.stream_id()); 2104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_created_streams()); 21077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); 2108ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2109ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 2110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CancelTwoStalledCreateStream) { 2113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 2114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 2116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 2117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 2120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 2121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 2123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 2124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 2126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateNetworkSession(); 2129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2130ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 21317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 2132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Leave room for only one more stream to be created. 2134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) { 2135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream = 2136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 2137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session, test_url_, MEDIUM, BoundNetLog()); 2138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(spdy_stream != NULL); 2139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 2140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url1("http://www.google.com"); 2142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 2143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 2144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url1, LOWEST, BoundNetLog()); 2145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 2146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 2147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback2; 2149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url2("http://www.google.com"); 2150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamRequest request2; 2151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(ERR_IO_PENDING, 2152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request2.StartRequest( 2153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SPDY_BIDIRECTIONAL_STREAM, session, url2, LOWEST, BoundNetLog(), 2154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback2.callback())); 2155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback3; 2157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url3("http://www.google.com"); 2158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamRequest request3; 2159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(ERR_IO_PENDING, 2160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request3.StartRequest( 2161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SPDY_BIDIRECTIONAL_STREAM, session, url3, LOWEST, BoundNetLog(), 2162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback3.callback())); 2163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams()); 21667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST)); 2167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Cancel the first stream; this will allow the second stream to be created. 2169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(spdy_stream1.get() != NULL); 2170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->Cancel(); 2171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream1.get()); 2172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(OK, callback2.WaitForResult()); 2174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams()); 2176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST)); 2177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Cancel the second stream; this will allow the third stream to be created. 2179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = request2.ReleaseStream(); 2180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->Cancel(); 2181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream2.get()); 2182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2183a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(OK, callback3.WaitForResult()); 2184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams()); 21867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); 2187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Cancel the third stream. 2189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream3 = request3.ReleaseStream(); 2190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream3->Cancel(); 2191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream3.get()); 2192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(0u, session->num_active_streams()); 2193a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(kInitialMaxConcurrentStreams - 1, session->num_created_streams()); 21947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); 2195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, NeedsCredentials) { 2198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 2199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 2200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 2201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 2203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 2204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 2205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 2207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ssl.channel_id_sent = true; 2208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ssl.protocol_negotiated = GetParam(); 2209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateNetworkSession(); 2212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const GURL url("https://www.foo.com"); 2214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostPortPair test_host_port_pair(url.host(), 443); 2215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key(test_host_port_pair, ProxyServer::Direct(), 2216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kPrivacyModeDisabled); 2217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 22197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateSecureSpdySession(http_session_, key, BoundNetLog()); 2220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(spdy_util_.spdy_version() >= SPDY3, session->NeedsCredentials()); 2222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2223ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Flush the read completion task. 2224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->RunUntilIdle(); 2225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 22267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, std::string()); 2227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2229ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that SpdySession::DoReadLoop reads data from the socket 2230ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// without yielding. This test makes 32k - 1 bytes of data available 2231ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// on the socket for reading. It then verifies that it has read all 2232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// the available data without yielding. 2233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, ReadDataWithoutYielding) { 2234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 2235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 2236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req1( 2238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 2239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 2240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 2241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2243ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Build buffer of size kMaxReadBytesWithoutYielding / 4 2244ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // (-spdy_data_frame_size). 2245ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding); 2246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int kPayloadSize = 2247ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize(); 2248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestDataStream test_stream; 2249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize)); 2250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch char* payload_data = payload->data(); 2251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test_stream.GetBytes(payload_data, kPayloadSize); 2252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> partial_data_frame( 2254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); 2255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> finish_data_frame( 2256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch framer.CreateDataFrame(1, payload_data, kPayloadSize - 1, DATA_FLAG_FIN)); 2257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k 2261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // bytes. 2262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 2263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp1, 1), 2264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*partial_data_frame, 2), 2265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS), 2266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS), 2267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*finish_data_frame, 5, SYNCHRONOUS), 2268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 6) // EOF 2269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create SpdySession and SpdyStream and send the request. 2272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 2273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 2274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 2275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 2276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 2277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 2279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 2280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 2282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2283ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 22847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 2285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url1("http://www.google.com"); 2287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 2288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 2289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url1, MEDIUM, BoundNetLog()); 2290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 2291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, spdy_stream1->stream_id()); 2292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateDoNothing delegate1(spdy_stream1); 2293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SetDelegate(&delegate1); 2294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers1( 2296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url1.spec())); 2297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); 2298ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 2299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2300ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Set up the TaskObserver to verify SpdySession::DoReadLoop doesn't 2301ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // post a task. 2302ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop"); 2303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Run until 1st read. 2305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, delegate1.stream_id()); 2306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(2); 2307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, delegate1.stream_id()); 2308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, observer.executed_count()); 2309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2310ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read all the data and verify SpdySession::DoReadLoop has not 2311ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // posted a task. 2312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(4); 2313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream1.get()); 2314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify task observer's executed_count is zero, which indicates DoRead read 2316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // all the available data. 2317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0u, observer.executed_count()); 23182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 23192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 23202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 23212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2322ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that SpdySession::DoReadLoop yields while reading the 2323ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// data. This test makes 32k + 1 bytes of data available on the socket 2324ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// for reading. It then verifies that DoRead has yielded even though 2325ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// there is data available for it to read (i.e, socket()->Read didn't 2326ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// return ERR_IO_PENDING during socket reads). 23277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, TestYieldingDuringReadData) { 23282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 23297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 23302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 233190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 233290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 23332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 23342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockWrite(*req1, 0), 23352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 23362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2337ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Build buffer of size kMaxReadBytesWithoutYielding / 4 2338ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // (-spdy_data_frame_size). 2339ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding); 23402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kPayloadSize = 2341ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize(); 23422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestDataStream test_stream; 23432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize)); 23442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* payload_data = payload->data(); 23452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_stream.GetBytes(payload_data, kPayloadSize); 23462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> partial_data_frame( 23482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); 23492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> finish_data_frame( 23502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN)); 23512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 23532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Write 1 byte more than kMaxReadBytes to check that DoRead yields. 23552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 23562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*resp1, 1), 23572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*partial_data_frame, 2), 23582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS), 23592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS), 23602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*partial_data_frame, 5, SYNCHRONOUS), 23612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*finish_data_frame, 6, SYNCHRONOUS), 23622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead(ASYNC, 0, 7) // EOF 23632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 23642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create SpdySession and SpdyStream and send the request. 23662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 23672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 23682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 23692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 23702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 23712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 23732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 23742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 23762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2377ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 23787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 23792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url1("http://www.google.com"); 2381a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 238290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 238390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url1, MEDIUM, BoundNetLog()); 23842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 23852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 2386a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateDoNothing delegate1(spdy_stream1); 2387a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 23882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 238990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers1( 2390b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 239190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); 2392ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 23932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2394ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Set up the TaskObserver to verify SpdySession::DoReadLoop posts a 2395ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // task. 2396ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop"); 23972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Run until 1st read. 2399a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(0u, delegate1.stream_id()); 24002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(2); 2401a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(1u, delegate1.stream_id()); 24022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, observer.executed_count()); 24032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2404ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read all the data and verify SpdySession::DoReadLoop has posted a 2405ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // task. 24062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(6); 2407a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 24082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify task observer's executed_count is 1, which indicates DoRead has 24102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // posted only one task and thus yielded though there is data available for it 24112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to read. 24122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1u, observer.executed_count()); 24132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 24142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 24152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 24162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2417ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that SpdySession::DoReadLoop() tests interactions of yielding 2418ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// + async, by doing the following MockReads. 24192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 24202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// MockRead of SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K 24212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ASYNC 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K. 24222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2423ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// The above reads 26K synchronously. Since that is less that 32K, we 2424ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// will attempt to read again. However, that DoRead() will return 2425ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// ERR_IO_PENDING (because of async read), so DoReadLoop() will 2426ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// yield. When we come back, DoRead() will read the results from the 2427ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// async read, and rest of the data synchronously. 24287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) { 24292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 24307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 24312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 243290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 243390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 24342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 24352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockWrite(*req1, 0), 24362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 24372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2438ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Build buffer of size kMaxReadBytesWithoutYielding / 4 2439ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // (-spdy_data_frame_size). 2440ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding); 24412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestDataStream test_stream; 24422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kEightKPayloadSize = 2443ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize(); 24442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<net::IOBuffer> eightk_payload( 24452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new net::IOBuffer(kEightKPayloadSize)); 24462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* eightk_payload_data = eightk_payload->data(); 24472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_stream.GetBytes(eightk_payload_data, kEightKPayloadSize); 24482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Build buffer of 2k size. 24502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestDataStream test_stream2; 24512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kTwoKPayloadSize = kEightKPayloadSize - 6 * 1024; 24522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<net::IOBuffer> twok_payload( 24532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new net::IOBuffer(kTwoKPayloadSize)); 24542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* twok_payload_data = twok_payload->data(); 24552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize); 24562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> eightk_data_frame(framer.CreateDataFrame( 24582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1, eightk_payload_data, kEightKPayloadSize, DATA_FLAG_NONE)); 24592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> twok_data_frame(framer.CreateDataFrame( 24602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1, twok_payload_data, kTwoKPayloadSize, DATA_FLAG_NONE)); 24612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame( 24622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1, "h", 1, DATA_FLAG_FIN)); 24632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 24652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 24672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*resp1, 1), 24682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 2), 24692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 3, SYNCHRONOUS), 24702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 4, SYNCHRONOUS), 24712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*twok_data_frame, 5, SYNCHRONOUS), 24722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 6, ASYNC), 24732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 7, SYNCHRONOUS), 24742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 8, SYNCHRONOUS), 24752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*eightk_data_frame, 9, SYNCHRONOUS), 24762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*twok_data_frame, 10, SYNCHRONOUS), 24772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*finish_data_frame, 11, SYNCHRONOUS), 24782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead(ASYNC, 0, 12) // EOF 24792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 24802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create SpdySession and SpdyStream and send the request. 24822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 24832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 24842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 24852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 24862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 24872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 24892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 24902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 24922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2493ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 24947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 24952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url1("http://www.google.com"); 2497a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 249890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 249990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url1, MEDIUM, BoundNetLog()); 25002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 25012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 2502a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateDoNothing delegate1(spdy_stream1); 2503a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 25042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 250590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers1( 2506b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 250790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); 2508ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 25092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2510ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Set up the TaskObserver to monitor SpdySession::DoReadLoop 2511ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // posting of tasks. 2512ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop"); 25132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Run until 1st read. 2515a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(0u, delegate1.stream_id()); 25162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(2); 2517a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(1u, delegate1.stream_id()); 25182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, observer.executed_count()); 25192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2520ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Read all the data and verify SpdySession::DoReadLoop has posted a 2521ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // task. 25222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(12); 2523a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 25242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify task observer's executed_count is 1, which indicates DoRead has 25262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // posted only one task and thus yielded though there is data available for 25272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // it to read. 25282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1u, observer.executed_count()); 25292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 25302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 25312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 25322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2533ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Send a GoAway frame when SpdySession is in DoReadLoop. Make sure 2534ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// nothing blows up. 2535ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdySessionTest, GoAwayWhileInDoReadLoop) { 25362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 25377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 25382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 253990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 254090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 25412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 25422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockWrite(*req1, 0), 25432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 25442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 25467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 254790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway()); 25482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 25502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*resp1, 1), 25512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*body1, 2), 25522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateMockRead(*goaway, 3), 25532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 25542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create SpdySession and SpdyStream and send the request. 25562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 25572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 25582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 25592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 25602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 25612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 25632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 25642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 25662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2567ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 25687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 25692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url1("http://www.google.com"); 2571a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> spdy_stream1 = 257290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 257390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url1, MEDIUM, BoundNetLog()); 257490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateDoNothing delegate1(spdy_stream1); 257590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SetDelegate(&delegate1); 25762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(spdy_stream1.get() != NULL); 25772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 25782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 257990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers1( 2580b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructGetHeaderBlock(url1.spec())); 258190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); 2582ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 25832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Run until 1st read. 25852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, spdy_stream1->stream_id()); 25862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(1); 25872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1u, spdy_stream1->stream_id()); 25882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Run until GoAway. 2590ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(3); 2591a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, spdy_stream1.get()); 25922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 25932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 2594ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 25952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 25962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Within this framework, a SpdySession should be initialized with 25987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// flow control disabled for protocol version 2, with flow control 25997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// enabled only for streams for protocol version 3, and with flow 26007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// control enabled for streams and sessions for higher versions. 26017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ProtocolNegotiation) { 26022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 26032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 26042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 26052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 26062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead(SYNCHRONOUS, 0, 0) // EOF 26072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 26082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 26092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 26102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 26112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 26122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 2613ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 26147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateFakeSpdySession(spdy_session_pool_, key_); 26152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 26167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(spdy_util_.spdy_version(), 26177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session->buffered_spdy_framer_->protocol_version()); 26187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() == kProtoSPDY2) { 26197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(SpdySession::FLOW_CONTROL_NONE, session->flow_control_state()); 26207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(0, session->session_send_window_size_); 26217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(0, session->session_recv_window_size_); 26227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } else if (GetParam() == kProtoSPDY3) { 26237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state()); 26247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(0, session->session_send_window_size_); 26257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(0, session->session_recv_window_size_); 26267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } else { 26277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 26287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session->flow_control_state()); 26297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, 26307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session->session_send_window_size_); 2631eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, 26327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session->session_recv_window_size_); 26337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 26342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 26352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 26362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Tests the case of a non-SPDY request closing an idle SPDY session when no 2638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// pointers to the idle session are currently held. 2639eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseOneIdleConnection) { 2640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ClientSocketPoolManager::set_max_sockets_per_group( 2641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 2642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ClientSocketPoolManager::set_max_sockets_per_pool( 2643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 26442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 26452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 26462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 2647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 26482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 2649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 26502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 2651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 2652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 26532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateNetworkSession(); 26552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransportClientSocketPool* pool = 2657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch http_session_->GetTransportSocketPool( 2658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL); 26592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create an idle SPDY session. 2661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(), 2662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kPrivacyModeDisabled); 2663ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session1 = 26647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key1, BoundNetLog()); 2665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(pool->IsStalled()); 26662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Trying to create a new connection should cause the pool to be stalled, and 2668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // post a task asynchronously to try and close the session. 2669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback2; 2670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostPortPair host_port2("2.com", 80); 2671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<TransportSocketParams> params2( 2672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false, 2673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OnHostResolutionCallback())); 2674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); 2675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 2676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY, 2677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback2.callback(), pool, BoundNetLog())); 2678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(pool->IsStalled()); 26792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The socket pool should close the connection asynchronously and establish a 2681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // new connection. 2682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, callback2.WaitForResult()); 2683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(pool->IsStalled()); 2684ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session1 == NULL); 26852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 26862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Tests the case of a non-SPDY request closing an idle SPDY session when no 2688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// pointers to the idle session are currently held, in the case the SPDY session 2689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// has an alias. 2690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) { 2691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ClientSocketPoolManager::set_max_sockets_per_group( 2692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 2693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ClientSocketPoolManager::set_max_sockets_per_pool( 2694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 26952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 26962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 26972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 2698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 26992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 27002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 27012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 27022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 2703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 2704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 2706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->rules()->AddIPLiteralRule( 2707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "1.com", "192.168.0.2", std::string()); 2708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->rules()->AddIPLiteralRule( 2709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "2.com", "192.168.0.2", std::string()); 2710eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Not strictly needed. 2711eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->rules()->AddIPLiteralRule( 2712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "3.com", "192.168.0.3", std::string()); 27132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 27142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateNetworkSession(); 27152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2716eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransportClientSocketPool* pool = 2717eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch http_session_->GetTransportSocketPool( 2718eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL); 27192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2720eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create an idle SPDY session. 2721eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(), 2722eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kPrivacyModeDisabled); 2723ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session1 = 27247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key1, BoundNetLog()); 2725eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(pool->IsStalled()); 27262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2727eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Set up an alias for the idle SPDY session, increasing its ref count to 2. 2728eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key2(HostPortPair("2.com", 80), ProxyServer::Direct(), 2729eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kPrivacyModeDisabled); 2730eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostResolver::RequestInfo info(key2.host_port_pair()); 2731eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddressList addresses; 2732eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Pre-populate the DNS cache, since a synchronous resolution is required in 2733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // order to create the alias. 2734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->Resolve( 2735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch info, &addresses, CompletionCallback(), NULL, BoundNetLog()); 2736eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Get a session for |key2|, which should return the session created earlier. 2737ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session2 = 27387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch spdy_session_pool_->FindAvailableSession(key2, BoundNetLog()); 2739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(session1.get(), session2.get()); 2740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(pool->IsStalled()); 27412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Trying to create a new connection should cause the pool to be stalled, and 2743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // post a task asynchronously to try and close the session. 2744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback3; 2745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostPortPair host_port3("3.com", 80); 2746eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<TransportSocketParams> params3( 2747eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new TransportSocketParams(host_port3, DEFAULT_PRIORITY, false, false, 2748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OnHostResolutionCallback())); 2749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle); 2750eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 2751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY, 2752eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback3.callback(), pool, BoundNetLog())); 2753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(pool->IsStalled()); 27547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2755eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The socket pool should close the connection asynchronously and establish a 2756eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // new connection. 2757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, callback3.WaitForResult()); 2758eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(pool->IsStalled()); 2759ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session1 == NULL); 2760ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session2 == NULL); 2761eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2762eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2763eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Tests that a non-SPDY request can't close a SPDY session that's currently in 2764eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// use. 2765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, CloseOneIdleConnectionFailsWhenSessionInUse) { 2766eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ClientSocketPoolManager::set_max_sockets_per_group( 2767eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 2768eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ClientSocketPoolManager::set_max_sockets_per_pool( 2769eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL, 1); 2770eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2771eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 2772eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 2773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 2774eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2775eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req1( 2776eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2777eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> cancel1( 2778eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 2779eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 2780eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 1), 2781eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*cancel1, 1), 2782eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), 2784eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 2785eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 2786eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 2787eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateNetworkSession(); 2789eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TransportClientSocketPool* pool = 2791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch http_session_->GetTransportSocketPool( 2792eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpNetworkSession::NORMAL_SOCKET_POOL); 2793eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create a SPDY session. 2795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url1("http://www.google.com"); 2796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key1(HostPortPair(url1.host(), 80), 2797eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ProxyServer::Direct(), kPrivacyModeDisabled); 2798ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session1 = 27997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key1, BoundNetLog()); 2800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(pool->IsStalled()); 2801eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2802eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create a stream using the session, and send a request. 2803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback1; 2805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 2806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 2807eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session1, url1, DEFAULT_PRIORITY, 2808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BoundNetLog()); 2809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get()); 2810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateDoNothing delegate1(spdy_stream1); 2811eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SetDelegate(&delegate1); 2812eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2813eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers1( 2814eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(url1.spec())); 2815eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 2816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->SendRequestHeaders( 2817eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch headers1.Pass(), NO_MORE_DATA_TO_SEND)); 2818ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); 2819eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->RunUntilIdle(); 2821eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Trying to create a new connection should cause the pool to be stalled, and 2823eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // post a task asynchronously to try and close the session. 2824eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback2; 2825eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostPortPair host_port2("2.com", 80); 2826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<TransportSocketParams> params2( 2827eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false, 2828eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OnHostResolutionCallback())); 2829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); 2830eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 2831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY, 2832eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback2.callback(), pool, BoundNetLog())); 2833eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(pool->IsStalled()); 2834eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2835eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Running the message loop should cause the socket pool to ask the SPDY 2836eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // session to close an idle socket, but since the socket is in use, nothing 2837eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // happens. 2838eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::RunLoop().RunUntilIdle(); 2839eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(pool->IsStalled()); 2840eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(callback2.have_result()); 2841eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2842eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Cancelling the request should still not release the session's socket, 2843eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // since the session is still kept alive by the SpdySessionPool. 2844eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get()); 2845eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->Cancel(); 2846eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::RunLoop().RunUntilIdle(); 2847eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(pool->IsStalled()); 2848eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(callback2.have_result()); 2849ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session1 != NULL); 2850eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2851eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2852eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Verify that SpdySessionKey and therefore SpdySession is different when 2853eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// privacy mode is enabled or disabled. 2854eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) { 2855eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 2856eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2857eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostPortPair host_port_pair("www.google.com", 443); 2858eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(), 2859eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kPrivacyModeEnabled); 2860eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(), 2861eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kPrivacyModeDisabled); 2862eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 28637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); 28647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); 2865eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2866eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add SpdySession with PrivacyMode Enabled to the pool. 2867ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session_privacy_enabled = 28687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateFakeSpdySession(spdy_session_pool_, key_privacy_enabled); 2869eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 28707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); 28717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); 2872eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2873eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add SpdySession with PrivacyMode Disabled to the pool. 2874ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session_privacy_disabled = 28757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateFakeSpdySession(spdy_session_pool_, key_privacy_disabled); 2876eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 28777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); 28787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); 2879eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 28807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session_privacy_enabled->CloseSessionOnError(ERR_ABORTED, std::string()); 28817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); 28827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); 2883eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 28847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session_privacy_disabled->CloseSessionOnError(ERR_ABORTED, std::string()); 28857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); 28867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); 2887eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2888eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2889bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Delegate that creates another stream when its stream is closed. 2890bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochclass StreamCreatingDelegate : public test::StreamDelegateDoNothing { 2891bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch public: 2892bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch StreamCreatingDelegate(const base::WeakPtr<SpdyStream>& stream, 2893bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const base::WeakPtr<SpdySession>& session) 2894bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch : StreamDelegateDoNothing(stream), 2895bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_(session) {} 2896bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2897bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch virtual ~StreamCreatingDelegate() {} 2898bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2899bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch virtual void OnClose(int status) OVERRIDE { 2900bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch GURL url("http://www.google.com"); 2901bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ignore_result( 2902bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 2903bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_, url, MEDIUM, BoundNetLog())); 2904bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 2905bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2906bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch private: 2907bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const base::WeakPtr<SpdySession> session_; 2908bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}; 2909bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2910bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Create another stream in response to a stream being reset. Nothing 2911bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// should blow up. This is a regression test for 2912bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// http://crbug.com/263690 . 2913bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_P(SpdySessionTest, CreateStreamOnStreamReset) { 2914bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 2915bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2916bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 2917bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2918bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<SpdyFrame> req( 2919bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 2920bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockWrite writes[] = { 2921bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateMockWrite(*req, 0), 2922bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch }; 2923bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2924bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<SpdyFrame> rst( 2925bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM)); 2926bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockRead reads[] = { 2927bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateMockRead(*rst, 1), 2928bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MockRead(ASYNC, 0, 2) // EOF 2929bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch }; 2930bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DeterministicSocketData data(reads, arraysize(reads), 2931bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch writes, arraysize(writes)); 2932bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch data.set_connect_data(connect_data); 2933bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 2934bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2935bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 2936bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 2937bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2938bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateDeterministicNetworkSession(); 2939bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2940bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::WeakPtr<SpdySession> session = 2941bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 2942bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2943bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch GURL url("http://www.google.com"); 2944bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::WeakPtr<SpdyStream> spdy_stream = 2945bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 2946bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch session, url, MEDIUM, BoundNetLog()); 2947bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ASSERT_TRUE(spdy_stream.get() != NULL); 2948bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(0u, spdy_stream->stream_id()); 2949bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2950bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch StreamCreatingDelegate delegate(spdy_stream, session); 2951bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_stream->SetDelegate(&delegate); 2952bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2953bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<SpdyHeaderBlock> headers( 2954bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_util_.ConstructGetHeaderBlock(url.spec())); 2955bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); 2956bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); 2957bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2958bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(0u, spdy_stream->stream_id()); 2959bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2960bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch data.RunFor(1); 2961bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2962bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(1u, spdy_stream->stream_id()); 2963bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2964bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Cause the stream to be reset, which should cause another stream 2965bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // to be created. 2966bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch data.RunFor(1); 2967bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2968bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(NULL, spdy_stream.get()); 2969bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE(delegate.StreamIsClosed()); 2970bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(0u, session->num_active_streams()); 2971bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(1u, session->num_created_streams()); 2972bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 2973bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The tests below are only for SPDY/3 and above. 2975eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2976eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, SendCredentials) { 2977eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam() < kProtoSPDY3) 2978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 2979eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 2981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 2982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 2983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsMap settings; 2985eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> settings_frame( 2986eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdySettings(settings)); 2987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 2988eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*settings_frame), 2989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 2990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), 2991eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 2992eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 2993eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 2994eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2995eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 2996eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ssl.channel_id_sent = true; 2997eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ssl.protocol_negotiated = GetParam(); 2998eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 2999eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateNetworkSession(); 3001eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3002eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const GURL kTestUrl("https://www.foo.com"); 3003eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HostPortPair test_host_port_pair(kTestUrl.host(), 443); 3004eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionKey key(test_host_port_pair, ProxyServer::Direct(), 3005eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kPrivacyModeDisabled); 3006eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3007ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 30087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateSecureSpdySession(http_session_, key, BoundNetLog()); 3009eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->NeedsCredentials()); 3011eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3012ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Flush the read completion task. 3013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->RunUntilIdle(); 3014eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 30157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->CloseSessionOnError(ERR_ABORTED, std::string()); 30167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key)); 3017eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) { 3020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam() < kProtoSPDY3) 3021eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 3022eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE 3024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // gets sent. 3025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsMap new_settings; 3026eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int32 window_size = 1; 3027eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new_settings[SETTINGS_INITIAL_WINDOW_SIZE] = 3028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size); 3029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3030eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Set up the socket so we read a SETTINGS frame that sets 3031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // INITIAL_WINDOW_SIZE. 3032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 3033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> settings_frame( 3034eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdySettings(new_settings)); 3035eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 3036eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*settings_frame, 0), 3037eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 1) // EOF 3038eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 3039eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3040eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 3041eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3042eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<DeterministicSocketData> data( 3043eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new DeterministicSocketData(reads, arraysize(reads), NULL, 0)); 3044eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data->set_connect_data(connect_data); 3045eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(data.get()); 3046eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3047eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 3048eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); 3049eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3050eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 3051eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3052ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 30537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 3054eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream1 = 3055eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 3056eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, test_url_, MEDIUM, BoundNetLog()); 3057eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream1.get() != NULL); 3058eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallback callback1; 3059eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_NE(spdy_stream1->send_window_size(), window_size); 3060eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3061eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data->RunFor(1); // Process the SETTINGS frame, but not the EOF 3062eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->RunUntilIdle(); 3063eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(session->stream_initial_send_window_size(), window_size); 3064eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(spdy_stream1->send_window_size(), window_size); 3065eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3066eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Release the first one, this will allow the second to be created. 3067eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream1->Cancel(); 3068eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream1.get()); 3069eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3070eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> spdy_stream2 = 3071eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 3072eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, test_url_, MEDIUM, BoundNetLog()); 3073eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(spdy_stream2.get() != NULL); 3074eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(spdy_stream2->send_window_size(), window_size); 3075eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_stream2->Cancel(); 3076eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, spdy_stream2.get()); 3077eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3078eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3079eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The tests below are only for SPDY/3.1 and above. 3080eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3081eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// SpdySession::{Increase,Decrease}RecvWindowSize should properly 3082eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// adjust the session receive window size for SPDY 3.1 and higher. In 3083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// addition, SpdySession::IncreaseRecvWindowSize should trigger 3084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// sending a WINDOW_UPDATE frame for a large enough delta. 3085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, AdjustRecvWindowSize) { 3086eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam() < kProtoSPDY31) 3087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 3088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 3090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3091eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int32 delta_window_size = 100; 3092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 3094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 3095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 1) // EOF 3096eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 3097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> window_update( 3098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyWindowUpdate( 3099eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSessionFlowControlStreamId, 3100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSpdySessionInitialWindowSize + delta_window_size)); 3101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockWrite writes[] = { 3102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*window_update, 0), 3103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 3104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 3105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 3106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 3107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 3108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 3110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 3113ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 31147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 3115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 3116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->flow_control_state()); 3117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 3120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->IncreaseRecvWindowSize(delta_window_size); 3122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size, 3123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->session_recv_window_size_); 3124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(delta_window_size, session->session_unacked_recv_window_bytes_); 3125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Should trigger sending a WINDOW_UPDATE frame. 3127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->IncreaseRecvWindowSize(kSpdySessionInitialWindowSize); 3128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size + 3129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSpdySessionInitialWindowSize, 3130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->session_recv_window_size_); 3131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 3132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 3134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // DecreaseRecvWindowSize() expects |in_io_loop_| to be true. 3136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->in_io_loop_ = true; 3137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->DecreaseRecvWindowSize( 3138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSpdySessionInitialWindowSize + delta_window_size + 3139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSpdySessionInitialWindowSize); 3140ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->in_io_loop_ = false; 3141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, session->session_recv_window_size_); 3142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 3143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// SpdySession::{Increase,Decrease}SendWindowSize should properly 3146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// adjust the session send window size when the "enable_spdy_31" flag 3147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// is set. 3148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, AdjustSendWindowSize) { 3149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam() < kProtoSPDY31) 3150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 3151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 3153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 3155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 3156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(SYNCHRONOUS, 0, 0) // EOF 3157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 3158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 3159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 3160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.socket_factory->AddSocketDataProvider(&data); 3161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateNetworkSession(); 3163ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 31647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateFakeSpdySession(spdy_session_pool_, key_); 3165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 3166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->flow_control_state()); 3167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int32 delta_window_size = 100; 3169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->IncreaseSendWindowSize(delta_window_size); 3173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size, 3174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->session_send_window_size_); 3175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->DecreaseSendWindowSize(delta_window_size); 3177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Incoming data for an inactive stream should not cause the session 3181c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch// receive window size to decrease, but it should cause the unacked 3182c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch// bytes to increase. 3183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, SessionFlowControlInactiveStream) { 3184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam() < kProtoSPDY31) 3185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 3186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 3188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 3190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyBodyFrame(1, false)); 3191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 3192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 0), 3193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 1) // EOF 3194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 3195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), NULL, 0); 3196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 3197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 3198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 3200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 3203ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 32047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 3205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 3206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->flow_control_state()); 3207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 3210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 3212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3214c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_); 3215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 3216ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch data.RunFor(1); 3217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// A delegate that drops any received data. 3220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate { 3221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 3222a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream, 3223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::StringPiece data) 322490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : StreamDelegateSendImmediate(stream, data) {} 3225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~DropReceivedDataDelegate() {} 3227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Drop any received data. 3229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE {} 3230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 3231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Send data back and forth but use a delegate that drops its received 3233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// data. The receive window should still increase to its original 3234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// value, i.e. we shouldn't "leak" receive window bytes. 32357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) { 32367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 32377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 3238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 32397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const char kStreamUrl[] = "http://www.google.com/"; 3240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int32 msg_data_size = 100; 3242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string msg_data(msg_data_size, 'a'); 3243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 3245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 32477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 32487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0)); 3249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyFrame> msg( 32507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame( 32517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1, msg_data.data(), msg_data_size, false)); 3252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockWrite writes[] = { 3253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 0), 3254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*msg, 2), 3255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 3256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 32577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyFrame> echo( 32597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame( 32607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1, msg_data.data(), msg_data_size, false)); 3261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyFrame> window_update( 326290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyWindowUpdate( 3263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kSessionFlowControlStreamId, msg_data_size)); 3264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockRead reads[] = { 3265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 1), 3266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*echo, 3), 3267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 4) // EOF 3268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 3269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create SpdySession and SpdyStream and send the request. 3271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 3272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writes, arraysize(writes)); 3273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.set_connect_data(connect_data); 3274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 3275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 3276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 3278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateDeterministicNetworkSession(); 3281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3282ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 32837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 3284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL url(kStreamUrl); 3286a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 328790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 328890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, MEDIUM, BoundNetLog()); 3289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 3290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(0u, stream->stream_id()); 3291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DropReceivedDataDelegate delegate(stream, msg_data); 3293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->SetDelegate(&delegate); 3294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 329590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 3296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size)); 329790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 329890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 3299ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 3300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 3303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(4); 3305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 3307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 3308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); 3311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->Close(); 3313a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, stream.get()); 3314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(OK, delegate.WaitForClose()); 3316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); 3319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Send data back and forth but close the stream before its data frame 3322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// can be written to the socket. The send window should then increase 3323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// to its original value, i.e. we shouldn't "leak" send window bytes. 33247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) { 33257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 33267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 3327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 33287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const char kStreamUrl[] = "http://www.google.com/"; 3329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int32 msg_data_size = 100; 3331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string msg_data(msg_data_size, 'a'); 3332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 3334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 33367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 33377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0)); 3338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockWrite writes[] = { 3339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 0), 3340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 3341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 33427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockRead reads[] = { 3344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 1), 3345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 2) // EOF 3346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 3347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create SpdySession and SpdyStream and send the request. 3349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 3350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writes, arraysize(writes)); 3351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.set_connect_data(connect_data); 3352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 3353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 3354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 3356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 3357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateDeterministicNetworkSession(); 3359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3360ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 33617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 3362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL url(kStreamUrl); 3364a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 336590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 336690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, MEDIUM, BoundNetLog()); 3367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 3368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(0u, stream->stream_id()); 3369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 337090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateSendImmediate delegate(stream, msg_data); 3371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->SetDelegate(&delegate); 3372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 337390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 3374b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size)); 337590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 337690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 3377ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 3378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 3382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data.RunFor(1); 3386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 3388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 3389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size, 3391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session->session_send_window_size_); 3392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Closing the stream should increase the session's send window. 3394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->Close(); 3395a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, stream.get()); 3396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(OK, delegate.WaitForClose()); 3400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Send data back and forth; the send and receive windows should 34032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// change appropriately. 34047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) { 34057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 34067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 34072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const char kStreamUrl[] = "http://www.google.com/"; 34092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int32 msg_data_size = 100; 34112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string msg_data(msg_data_size, 'a'); 34122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 34142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 34167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 34177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0)); 34182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> msg( 34197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame( 34207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1, msg_data.data(), msg_data_size, false)); 34212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 3422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 0), 3423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*msg, 2), 34242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 34252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 34272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> echo( 34287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame( 34297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1, msg_data.data(), msg_data_size, false)); 34302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> window_update( 343190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyWindowUpdate( 34322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kSessionFlowControlStreamId, msg_data_size)); 34332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 3434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 1), 3435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*echo, 3), 3436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*window_update, 4), 3437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 5) // EOF 34382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 34392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create SpdySession and SpdyStream and send the request. 34412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 34422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 34432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 34442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 34452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 34462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 34482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); 34492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 34512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3452ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 34537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 34542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 3456a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 345790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 345890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, MEDIUM, BoundNetLog()); 34592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 34602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, stream->stream_id()); 34612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 346290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateSendImmediate delegate(stream, msg_data); 34632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream->SetDelegate(&delegate); 34642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 346590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 3466b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size)); 346790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 346890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 3469ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 34702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 34732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 34742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 34762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 34792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 34802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(1); 34822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size, 34842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->session_send_window_size_); 3485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 34862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 34872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(1); 34892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size, 34912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->session_send_window_size_); 3492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 34932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 34942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(1); 34962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size, 34982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->session_send_window_size_); 3499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size, 35002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->session_recv_window_size_); 35012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 35022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(1); 35042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size, 35072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->session_recv_window_size_); 35082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 35092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 35112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data.at_read_eof()); 35122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(msg_data, delegate.TakeReceivedData()); 35142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Draining the delegate's read queue should increase the session's 3516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // receive window. 3517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 35192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); 35202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream->Close(); 3522a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, stream.get()); 35232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(OK, delegate.WaitForClose()); 3525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 3527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_); 3528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); 35292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 35302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Given a stall function and an unstall function, runs a test to make 3532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// sure that a stream resumes after unstall. 35337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void SpdySessionTest::RunResumeAfterUnstallTest( 35347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function, 353590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Callback<void(SpdySession*, SpdyStream*, int32)>& 353690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) unstall_function) { 35372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kStreamUrl[] = "http://www.google.com/"; 35382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 35392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 35412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 35437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 35447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); 354590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> body( 35467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true)); 35472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 3548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req, 0), 3549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*body, 1), 35502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 35512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp( 35537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 35542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> echo( 35557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false)); 35562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 3557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp, 2), 3558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 3), // EOF 35592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 35602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 35622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 35632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 35642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 35652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 35672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 3569ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 35707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 35712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 35722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->flow_control_state()); 35732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3574a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 357590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 357690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, LOWEST, BoundNetLog()); 35772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 35782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3579a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateWithBody delegate(stream, kBodyDataStringPiece); 35802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream->SetDelegate(&delegate); 35812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3582ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream->HasUrlFromHeaders()); 358390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(stream->send_stalled_by_flow_control()); 35842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 358590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 3586b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 358790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 358890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 3589ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 3590ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 35912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch stall_function.Run(session.get(), stream.get()); 35932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3594eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 35952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream->send_stalled_by_flow_control()); 35972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unstall_function.Run(session.get(), stream.get(), kBodyDataSize); 35992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 36002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream->send_stalled_by_flow_control()); 36012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 36022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(3); 36032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 36042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 36052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 36062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(delegate.send_headers_completed()); 36072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status")); 36082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version")); 360990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(std::string(), delegate.TakeReceivedData()); 361090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 36112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 36122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Run the resume-after-unstall test with all possible stall and 3614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// unstall sequences. 3615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ResumeAfterUnstallSession) { 36177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 36187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 36197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 36207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunResumeAfterUnstallTest( 36217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::StallSessionOnly, 3622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 36237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::UnstallSessionOnly, 3624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 3625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Equivalent to 36287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// SpdyStreamTest.ResumeAfterSendWindowSizeIncrease. 36297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ResumeAfterUnstallStream) { 36307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 36317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 36327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 36337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunResumeAfterUnstallTest( 36347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::StallStreamOnly, 3635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 36367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::UnstallStreamOnly, 3637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 3638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, StallSessionStreamResumeAfterUnstallSessionStream) { 36417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 36427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 36437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 36447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunResumeAfterUnstallTest( 36457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::StallSessionStream, 3646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 36477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::UnstallSessionStream, 3648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 3649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, StallStreamSessionResumeAfterUnstallSessionStream) { 36527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 36537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 36547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 36557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunResumeAfterUnstallTest( 36567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::StallStreamSession, 3657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 36587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::UnstallSessionStream, 3659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 3660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, StallStreamSessionResumeAfterUnstallStreamSession) { 36637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 36647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 36657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 36667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunResumeAfterUnstallTest( 36677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::StallStreamSession, 3668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 36697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::UnstallStreamSession, 3670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 3671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, StallSessionStreamResumeAfterUnstallStreamSession) { 36747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 36757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 36767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 36777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunResumeAfterUnstallTest( 36787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::StallSessionStream, 3679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 36807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&SpdySessionTest::UnstallStreamSession, 3681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 3682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Cause a stall by reducing the flow control send window to 0. The 36852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// streams should resume in priority order when that window is then 36862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// increased. 36877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) { 36887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 36897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 36907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 36912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kStreamUrl[] = "http://www.google.com/"; 36922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 36932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 36942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 36952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 36962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 36977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 36987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); 36992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 37007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 37017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 3, kBodyDataSize, MEDIUM, NULL, 0)); 370290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> body1( 37037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true)); 370490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> body2( 37057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true)); 37062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 3707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 3708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 1), 3709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*body2, 2), 3710eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*body1, 3), 37112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 37122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 37147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 37152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 3716eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp1, 4), 3717eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp2, 5), 3718eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 6), // EOF 37192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 37202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 37222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 37232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 37242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 37252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 37272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 3729ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 37307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 37312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 37322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->flow_control_state()); 37332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3734a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream1 = 373590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 373690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, LOWEST, BoundNetLog()); 37372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream1.get() != NULL); 37382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3739a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); 37402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream1->SetDelegate(&delegate1); 37412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3742ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream1->HasUrlFromHeaders()); 37432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3744a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream2 = 374590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 374690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, MEDIUM, BoundNetLog()); 37472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream2.get() != NULL); 37482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3749a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece); 37502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream2->SetDelegate(&delegate2); 37512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3752ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream2->HasUrlFromHeaders()); 37532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream1->send_stalled_by_flow_control()); 37552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 37562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) StallSessionSend(session.get()); 37582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 375990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers1( 376090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 376190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 376290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); 3763ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream1->HasUrlFromHeaders()); 3764ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec()); 37652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3766eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 376790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(1u, stream1->stream_id()); 37682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream1->send_stalled_by_flow_control()); 376990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 377090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers2( 377190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 377290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 377390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); 3774ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream2->HasUrlFromHeaders()); 3775ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec()); 377690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 377790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data.RunFor(1); 377890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(3u, stream2->stream_id()); 37792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream2->send_stalled_by_flow_control()); 37802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This should unstall only stream2. 3782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UnstallSessionSend(session.get(), kBodyDataSize); 37832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream1->send_stalled_by_flow_control()); 37852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 37862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 378790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data.RunFor(1); 37882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream1->send_stalled_by_flow_control()); 37902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 37912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This should then unstall stream1. 3793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UnstallSessionSend(session.get(), kBodyDataSize); 37942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(stream1->send_stalled_by_flow_control()); 3796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 37972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(4); 37992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); 38012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); 38022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(delegate1.send_headers_completed()); 3804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status")); 3805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version")); 3806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); 38072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(delegate2.send_headers_completed()); 38092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); 38102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version")); 381190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); 38122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 381390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 381490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 38152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Delegate that closes a given stream after sending its body. 3817eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass StreamClosingDelegate : public test::StreamDelegateWithBody { 3818eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 3819eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream, 3820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::StringPiece data) 3821eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : StreamDelegateWithBody(stream, data) {} 3822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3823eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual ~StreamClosingDelegate() {} 3824eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3825eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) { 3826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream_to_close_ = stream_to_close; 3827eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 3828eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void OnDataSent() OVERRIDE { 3830eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateWithBody::OnDataSent(); 3831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (stream_to_close_.get()) { 3832eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream_to_close_->Close(); 3833eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, stream_to_close_.get()); 3834eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 3835eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 3836eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3837eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 3838eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream_to_close_; 3839eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 3840eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 38412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Cause a stall by reducing the flow control send window to 3842eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 0. Unstalling the session should properly handle deleted streams. 3843eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) { 38447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (GetParam() < kProtoSPDY31) 38457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 38467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 38472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kStreamUrl[] = "http://www.google.com/"; 38482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 38492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.host_resolver->set_synchronous_mode(true); 38512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 38537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 38547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); 38552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req2( 38567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 38577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0)); 3858eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req3( 3859eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyPost( 3860eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kStreamUrl, 5, kBodyDataSize, LOWEST, NULL, 0)); 3861eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body2( 3862eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true)); 38632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockWrite writes[] = { 3864eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 3865eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 1), 3866eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req3, 2), 3867eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*body2, 3), 38682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 38692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3870eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 38712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRead reads[] = { 3872eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockRead(*resp2, 4), 3873eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 5), // EOF 38742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 38752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeterministicSocketData data(reads, arraysize(reads), 38772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes, arraysize(writes)); 38782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 38792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 38802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 38822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDeterministicNetworkSession(); 3884ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 38857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 38862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 38872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->flow_control_state()); 38882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3889a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream1 = 389090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 389190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, LOWEST, BoundNetLog()); 38922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream1.get() != NULL); 38932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 389490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); 38952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream1->SetDelegate(&delegate1); 38962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3897ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream1->HasUrlFromHeaders()); 38982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3899a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream2 = 390090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 390190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session, url, LOWEST, BoundNetLog()); 39022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream2.get() != NULL); 39032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3904eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece); 39052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream2->SetDelegate(&delegate2); 39062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3907ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream2->HasUrlFromHeaders()); 39082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3909eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream3 = 3910eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 3911eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url, LOWEST, BoundNetLog()); 3912eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream3.get() != NULL); 3913eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3914eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece); 3915eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream3->SetDelegate(&delegate3); 3916eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3917ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream3->HasUrlFromHeaders()); 3918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 39192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream1->send_stalled_by_flow_control()); 39202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 3921eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(stream3->send_stalled_by_flow_control()); 39222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) StallSessionSend(session.get()); 39242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers1( 392690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 392790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 392890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); 3929ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream1->HasUrlFromHeaders()); 3930ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec()); 39312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3932eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 393390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(1u, stream1->stream_id()); 39342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream1->send_stalled_by_flow_control()); 393590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 393690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers2( 393790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 393890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 393990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); 3940ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream2->HasUrlFromHeaders()); 3941ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec()); 394290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 394390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data.RunFor(1); 394490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(3u, stream2->stream_id()); 39452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream2->send_stalled_by_flow_control()); 39462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3947eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers3( 3948eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 3949a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 3950eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream3->SendRequestHeaders(headers3.Pass(), MORE_DATA_TO_SEND)); 3951ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream3->HasUrlFromHeaders()); 3952ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream3->GetUrlFromHeaders().spec()); 3953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3954eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 3955eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(5u, stream3->stream_id()); 3956eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(stream3->send_stalled_by_flow_control()); 3957868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3958eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamId stream_id1 = stream1->stream_id(); 3959eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamId stream_id2 = stream2->stream_id(); 3960eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyStreamId stream_id3 = stream3->stream_id(); 3961868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3962eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Close stream1 preemptively. 3963eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED); 3964eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, stream1.get()); 3965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3966eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(session->IsStreamActive(stream_id1)); 3967eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->IsStreamActive(stream_id2)); 3968eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->IsStreamActive(stream_id3)); 39697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3970eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Unstall stream2, which should then close stream3. 3971eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delegate2.set_stream_to_close(stream3); 3972eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UnstallSessionSend(session.get(), kBodyDataSize); 3973a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 3975eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, stream3.get()); 3976a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3977eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 3978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(session->IsStreamActive(stream_id1)); 3979eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(session->IsStreamActive(stream_id2)); 3980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(session->IsStreamActive(stream_id3)); 3981a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(2); 3983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(NULL, stream2.get()); 3984a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3985eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); 3986eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); 3987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, delegate3.WaitForClose()); 3988a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate1.send_headers_completed()); 3990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); 3991a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3992eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate2.send_headers_completed()); 3993eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); 3994eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version")); 3995eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); 3996a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3997eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate3.send_headers_completed()); 3998eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(std::string(), delegate3.TakeReceivedData()); 3999eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()); 4001a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 4002a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4003eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Cause a stall by reducing the flow control send window to 4004eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 0. Unstalling the session should properly handle the session itself 4005eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// being closed. 4006eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) { 4007eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetParam() < kProtoSPDY31) 40087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 40097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char kStreamUrl[] = "http://www.google.com/"; 4011eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url(kStreamUrl); 4012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.host_resolver->set_synchronous_mode(true); 4014a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 401590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req1( 4016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyPost( 4017eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); 4018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> req2( 4019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyPost( 4020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0)); 4021eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> body1( 4022eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false)); 4023a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) MockWrite writes[] = { 4024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req1, 0), 4025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateMockWrite(*req2, 1), 4026a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) }; 4027eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead reads[] = { 4029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockRead(ASYNC, 0, 0, 2), // EOF 4030eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 4031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(reads, arraysize(reads), 4033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writes, arraysize(writes)); 4034eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 4035a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) data.set_connect_data(connect_data); 4036a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4037eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 4038a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4039eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateDeterministicNetworkSession(); 4040ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session = 40417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 4042eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 4043eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->flow_control_state()); 4044a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4045eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream1 = 4046eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 4047eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url, LOWEST, BoundNetLog()); 4048eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream1.get() != NULL); 4049a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4050eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); 4051eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1->SetDelegate(&delegate1); 4052a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4053ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream1->HasUrlFromHeaders()); 4054eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4055eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream2 = 405690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 4057eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, url, LOWEST, BoundNetLog()); 4058eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream2.get() != NULL); 4059a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4060eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece); 4061eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2->SetDelegate(&delegate2); 4062a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4063ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream2->HasUrlFromHeaders()); 4064a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4065eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(stream1->send_stalled_by_flow_control()); 4066eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 4067a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4068eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StallSessionSend(session.get()); 4069eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4070eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers1( 4071eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 4072a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 4073eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); 4074ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream1->HasUrlFromHeaders()); 4075ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec()); 4076a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4077eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 4078eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(1u, stream1->stream_id()); 4079eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(stream1->send_stalled_by_flow_control()); 4080a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4081eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers2( 4082eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 4083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 4084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); 4085ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream2->HasUrlFromHeaders()); 4086ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec()); 4087a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 4089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(3u, stream2->stream_id()); 4090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(stream2->send_stalled_by_flow_control()); 409190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 40927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 409390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Unstall stream1. 4095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UnstallSessionSend(session.get(), kBodyDataSize); 409690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Close the session (since we can't do it from within the delegate 4098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // method, since it's in the stream's loop). 40997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session"); 4100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(session == NULL); 410190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 41027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 410390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); 4105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); 410690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate1.send_headers_completed()); 4108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); 410990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(delegate2.send_headers_completed()); 4111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); 411290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(data.at_write_eof()); 411490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 411590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 4117