1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_session.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <algorithm>
8*6777b538SAndroid Build Coastguard Worker #include <optional>
9*6777b538SAndroid Build Coastguard Worker #include <string>
10*6777b538SAndroid Build Coastguard Worker #include <string_view>
11*6777b538SAndroid Build Coastguard Worker #include <tuple>
12*6777b538SAndroid Build Coastguard Worker #include <utility>
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker #include "base/base64.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/containers/contains.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/test/metrics/histogram_tester.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_feature_list.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
26*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/base/features.h"
28*6777b538SAndroid Build Coastguard Worker #include "net/base/hex_utils.h"
29*6777b538SAndroid Build Coastguard Worker #include "net/base/host_port_pair.h"
30*6777b538SAndroid Build Coastguard Worker #include "net/base/io_buffer.h"
31*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_endpoint.h"
32*6777b538SAndroid Build Coastguard Worker #include "net/base/network_anonymization_key.h"
33*6777b538SAndroid Build Coastguard Worker #include "net/base/privacy_mode.h"
34*6777b538SAndroid Build Coastguard Worker #include "net/base/proxy_chain.h"
35*6777b538SAndroid Build Coastguard Worker #include "net/base/proxy_delegate.h"
36*6777b538SAndroid Build Coastguard Worker #include "net/base/proxy_server.h"
37*6777b538SAndroid Build Coastguard Worker #include "net/base/request_priority.h"
38*6777b538SAndroid Build Coastguard Worker #include "net/base/schemeful_site.h"
39*6777b538SAndroid Build Coastguard Worker #include "net/base/session_usage.h"
40*6777b538SAndroid Build Coastguard Worker #include "net/base/test_completion_callback.h"
41*6777b538SAndroid Build Coastguard Worker #include "net/base/test_data_stream.h"
42*6777b538SAndroid Build Coastguard Worker #include "net/cert/ct_policy_status.h"
43*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/host_resolver_results.h"
44*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/secure_dns_policy.h"
45*6777b538SAndroid Build Coastguard Worker #include "net/http/http_request_info.h"
46*6777b538SAndroid Build Coastguard Worker #include "net/http/transport_security_state_test_util.h"
47*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log.h"
48*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_event_type.h"
49*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_source.h"
50*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log.h"
51*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log_util.h"
52*6777b538SAndroid Build Coastguard Worker #include "net/nqe/network_quality_estimator_test_util.h"
53*6777b538SAndroid Build Coastguard Worker #include "net/socket/client_socket_pool.h"
54*6777b538SAndroid Build Coastguard Worker #include "net/socket/client_socket_pool_manager.h"
55*6777b538SAndroid Build Coastguard Worker #include "net/socket/socket_tag.h"
56*6777b538SAndroid Build Coastguard Worker #include "net/socket/socket_test_util.h"
57*6777b538SAndroid Build Coastguard Worker #include "net/socket/transport_connect_job.h"
58*6777b538SAndroid Build Coastguard Worker #include "net/spdy/alps_decoder.h"
59*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_http_utils.h"
60*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_session_pool.h"
61*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_session_test_util.h"
62*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_stream.h"
63*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_stream_test_util.h"
64*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_test_util_common.h"
65*6777b538SAndroid Build Coastguard Worker #include "net/test/cert_test_util.h"
66*6777b538SAndroid Build Coastguard Worker #include "net/test/gtest_util.h"
67*6777b538SAndroid Build Coastguard Worker #include "net/test/test_data_directory.h"
68*6777b538SAndroid Build Coastguard Worker #include "net/test/test_with_task_environment.h"
69*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/spdy/test_tools/spdy_test_utils.h"
70*6777b538SAndroid Build Coastguard Worker #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
71*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
72*6777b538SAndroid Build Coastguard Worker #include "testing/platform_test.h"
73*6777b538SAndroid Build Coastguard Worker #include "url/gurl.h"
74*6777b538SAndroid Build Coastguard Worker #include "url/scheme_host_port.h"
75*6777b538SAndroid Build Coastguard Worker #include "url/url_constants.h"
76*6777b538SAndroid Build Coastguard Worker
77*6777b538SAndroid Build Coastguard Worker using net::test::IsError;
78*6777b538SAndroid Build Coastguard Worker using net::test::IsOk;
79*6777b538SAndroid Build Coastguard Worker using testing::_;
80*6777b538SAndroid Build Coastguard Worker
81*6777b538SAndroid Build Coastguard Worker namespace net {
82*6777b538SAndroid Build Coastguard Worker
83*6777b538SAndroid Build Coastguard Worker namespace {
84*6777b538SAndroid Build Coastguard Worker
85*6777b538SAndroid Build Coastguard Worker const char kBodyData[] = "Body data";
86*6777b538SAndroid Build Coastguard Worker const size_t kBodyDataSize = std::size(kBodyData);
87*6777b538SAndroid Build Coastguard Worker const std::string_view kBodyDataStringPiece(kBodyData, kBodyDataSize);
88*6777b538SAndroid Build Coastguard Worker
89*6777b538SAndroid Build Coastguard Worker static base::TimeDelta g_time_delta;
90*6777b538SAndroid Build Coastguard Worker static base::TimeTicks g_time_now;
91*6777b538SAndroid Build Coastguard Worker
TheNearFuture()92*6777b538SAndroid Build Coastguard Worker base::TimeTicks TheNearFuture() {
93*6777b538SAndroid Build Coastguard Worker return base::TimeTicks::Now() + g_time_delta;
94*6777b538SAndroid Build Coastguard Worker }
95*6777b538SAndroid Build Coastguard Worker
SlowReads()96*6777b538SAndroid Build Coastguard Worker base::TimeTicks SlowReads() {
97*6777b538SAndroid Build Coastguard Worker g_time_delta += base::Milliseconds(2 * kYieldAfterDurationMilliseconds);
98*6777b538SAndroid Build Coastguard Worker return base::TimeTicks::Now() + g_time_delta;
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker
InstantaneousReads()101*6777b538SAndroid Build Coastguard Worker base::TimeTicks InstantaneousReads() {
102*6777b538SAndroid Build Coastguard Worker return g_time_now;
103*6777b538SAndroid Build Coastguard Worker }
104*6777b538SAndroid Build Coastguard Worker
105*6777b538SAndroid Build Coastguard Worker class MockRequireCTDelegate : public TransportSecurityState::RequireCTDelegate {
106*6777b538SAndroid Build Coastguard Worker public:
107*6777b538SAndroid Build Coastguard Worker MOCK_METHOD3(IsCTRequiredForHost,
108*6777b538SAndroid Build Coastguard Worker CTRequirementLevel(const std::string& host,
109*6777b538SAndroid Build Coastguard Worker const X509Certificate* chain,
110*6777b538SAndroid Build Coastguard Worker const HashValueVector& hashes));
111*6777b538SAndroid Build Coastguard Worker };
112*6777b538SAndroid Build Coastguard Worker
113*6777b538SAndroid Build Coastguard Worker // SpdySessionRequest::Delegate implementation that does nothing. The test it's
114*6777b538SAndroid Build Coastguard Worker // used in need to create a session request to trigger the creation of a session
115*6777b538SAndroid Build Coastguard Worker // alias, but doesn't care about when or if OnSpdySessionAvailable() is invoked.
116*6777b538SAndroid Build Coastguard Worker class SpdySessionRequestDelegate
117*6777b538SAndroid Build Coastguard Worker : public SpdySessionPool::SpdySessionRequest::Delegate {
118*6777b538SAndroid Build Coastguard Worker public:
119*6777b538SAndroid Build Coastguard Worker SpdySessionRequestDelegate() = default;
120*6777b538SAndroid Build Coastguard Worker
121*6777b538SAndroid Build Coastguard Worker SpdySessionRequestDelegate(const SpdySessionRequestDelegate&) = delete;
122*6777b538SAndroid Build Coastguard Worker SpdySessionRequestDelegate& operator=(const SpdySessionRequestDelegate&) =
123*6777b538SAndroid Build Coastguard Worker delete;
124*6777b538SAndroid Build Coastguard Worker
125*6777b538SAndroid Build Coastguard Worker ~SpdySessionRequestDelegate() override = default;
126*6777b538SAndroid Build Coastguard Worker
OnSpdySessionAvailable(base::WeakPtr<SpdySession> spdy_session)127*6777b538SAndroid Build Coastguard Worker void OnSpdySessionAvailable(
128*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdySession> spdy_session) override {}
129*6777b538SAndroid Build Coastguard Worker };
130*6777b538SAndroid Build Coastguard Worker
131*6777b538SAndroid Build Coastguard Worker } // namespace
132*6777b538SAndroid Build Coastguard Worker
133*6777b538SAndroid Build Coastguard Worker class SpdySessionTest : public PlatformTest, public WithTaskEnvironment {
134*6777b538SAndroid Build Coastguard Worker public:
135*6777b538SAndroid Build Coastguard Worker // Functions used with RunResumeAfterUnstallTest().
136*6777b538SAndroid Build Coastguard Worker
StallSessionOnly(SpdyStream * stream)137*6777b538SAndroid Build Coastguard Worker void StallSessionOnly(SpdyStream* stream) { StallSessionSend(); }
138*6777b538SAndroid Build Coastguard Worker
StallStreamOnly(SpdyStream * stream)139*6777b538SAndroid Build Coastguard Worker void StallStreamOnly(SpdyStream* stream) { StallStreamSend(stream); }
140*6777b538SAndroid Build Coastguard Worker
StallSessionStream(SpdyStream * stream)141*6777b538SAndroid Build Coastguard Worker void StallSessionStream(SpdyStream* stream) {
142*6777b538SAndroid Build Coastguard Worker StallSessionSend();
143*6777b538SAndroid Build Coastguard Worker StallStreamSend(stream);
144*6777b538SAndroid Build Coastguard Worker }
145*6777b538SAndroid Build Coastguard Worker
StallStreamSession(SpdyStream * stream)146*6777b538SAndroid Build Coastguard Worker void StallStreamSession(SpdyStream* stream) {
147*6777b538SAndroid Build Coastguard Worker StallStreamSend(stream);
148*6777b538SAndroid Build Coastguard Worker StallSessionSend();
149*6777b538SAndroid Build Coastguard Worker }
150*6777b538SAndroid Build Coastguard Worker
UnstallSessionOnly(SpdyStream * stream,int32_t delta_window_size)151*6777b538SAndroid Build Coastguard Worker void UnstallSessionOnly(SpdyStream* stream, int32_t delta_window_size) {
152*6777b538SAndroid Build Coastguard Worker UnstallSessionSend(delta_window_size);
153*6777b538SAndroid Build Coastguard Worker }
154*6777b538SAndroid Build Coastguard Worker
UnstallStreamOnly(SpdyStream * stream,int32_t delta_window_size)155*6777b538SAndroid Build Coastguard Worker void UnstallStreamOnly(SpdyStream* stream, int32_t delta_window_size) {
156*6777b538SAndroid Build Coastguard Worker UnstallStreamSend(stream, delta_window_size);
157*6777b538SAndroid Build Coastguard Worker }
158*6777b538SAndroid Build Coastguard Worker
UnstallSessionStream(SpdyStream * stream,int32_t delta_window_size)159*6777b538SAndroid Build Coastguard Worker void UnstallSessionStream(SpdyStream* stream, int32_t delta_window_size) {
160*6777b538SAndroid Build Coastguard Worker UnstallSessionSend(delta_window_size);
161*6777b538SAndroid Build Coastguard Worker UnstallStreamSend(stream, delta_window_size);
162*6777b538SAndroid Build Coastguard Worker }
163*6777b538SAndroid Build Coastguard Worker
UnstallStreamSession(SpdyStream * stream,int32_t delta_window_size)164*6777b538SAndroid Build Coastguard Worker void UnstallStreamSession(SpdyStream* stream, int32_t delta_window_size) {
165*6777b538SAndroid Build Coastguard Worker UnstallStreamSend(stream, delta_window_size);
166*6777b538SAndroid Build Coastguard Worker UnstallSessionSend(delta_window_size);
167*6777b538SAndroid Build Coastguard Worker }
168*6777b538SAndroid Build Coastguard Worker
169*6777b538SAndroid Build Coastguard Worker protected:
170*6777b538SAndroid Build Coastguard Worker // Used by broken connection detection tests.
171*6777b538SAndroid Build Coastguard Worker static constexpr base::TimeDelta kHeartbeatInterval = base::Seconds(10);
172*6777b538SAndroid Build Coastguard Worker
SpdySessionTest(base::test::TaskEnvironment::TimeSource time_source=base::test::TaskEnvironment::TimeSource::DEFAULT)173*6777b538SAndroid Build Coastguard Worker explicit SpdySessionTest(base::test::TaskEnvironment::TimeSource time_source =
174*6777b538SAndroid Build Coastguard Worker base::test::TaskEnvironment::TimeSource::DEFAULT)
175*6777b538SAndroid Build Coastguard Worker : WithTaskEnvironment(time_source),
176*6777b538SAndroid Build Coastguard Worker old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
177*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL)),
178*6777b538SAndroid Build Coastguard Worker old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
179*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL)),
180*6777b538SAndroid Build Coastguard Worker test_url_(kDefaultUrl),
181*6777b538SAndroid Build Coastguard Worker test_server_(test_url_),
182*6777b538SAndroid Build Coastguard Worker key_(HostPortPair::FromURL(test_url_),
183*6777b538SAndroid Build Coastguard Worker PRIVACY_MODE_DISABLED,
184*6777b538SAndroid Build Coastguard Worker ProxyChain::Direct(),
185*6777b538SAndroid Build Coastguard Worker SessionUsage::kDestination,
186*6777b538SAndroid Build Coastguard Worker SocketTag(),
187*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey(),
188*6777b538SAndroid Build Coastguard Worker SecureDnsPolicy::kAllow,
189*6777b538SAndroid Build Coastguard Worker /*disable_cert_verification_network_fetches=*/false),
190*6777b538SAndroid Build Coastguard Worker ssl_(SYNCHRONOUS, OK) {}
191*6777b538SAndroid Build Coastguard Worker
~SpdySessionTest()192*6777b538SAndroid Build Coastguard Worker ~SpdySessionTest() override {
193*6777b538SAndroid Build Coastguard Worker // Important to restore the per-pool limit first, since the pool limit must
194*6777b538SAndroid Build Coastguard Worker // always be greater than group limit, and the tests reduce both limits.
195*6777b538SAndroid Build Coastguard Worker ClientSocketPoolManager::set_max_sockets_per_pool(
196*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
197*6777b538SAndroid Build Coastguard Worker ClientSocketPoolManager::set_max_sockets_per_group(
198*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
199*6777b538SAndroid Build Coastguard Worker }
200*6777b538SAndroid Build Coastguard Worker
SetUp()201*6777b538SAndroid Build Coastguard Worker void SetUp() override {
202*6777b538SAndroid Build Coastguard Worker g_time_delta = base::TimeDelta();
203*6777b538SAndroid Build Coastguard Worker g_time_now = base::TimeTicks::Now();
204*6777b538SAndroid Build Coastguard Worker session_deps_.net_log = NetLog::Get();
205*6777b538SAndroid Build Coastguard Worker session_deps_.enable_server_push_cancellation = true;
206*6777b538SAndroid Build Coastguard Worker }
207*6777b538SAndroid Build Coastguard Worker
CreateNetworkSession()208*6777b538SAndroid Build Coastguard Worker void CreateNetworkSession() {
209*6777b538SAndroid Build Coastguard Worker DCHECK(!http_session_);
210*6777b538SAndroid Build Coastguard Worker DCHECK(!spdy_session_pool_);
211*6777b538SAndroid Build Coastguard Worker http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
212*6777b538SAndroid Build Coastguard Worker spdy_session_pool_ = http_session_->spdy_session_pool();
213*6777b538SAndroid Build Coastguard Worker }
214*6777b538SAndroid Build Coastguard Worker
AddSSLSocketData()215*6777b538SAndroid Build Coastguard Worker void AddSSLSocketData() {
216*6777b538SAndroid Build Coastguard Worker ssl_.ssl_info.cert =
217*6777b538SAndroid Build Coastguard Worker ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
218*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(ssl_.ssl_info.cert);
219*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
220*6777b538SAndroid Build Coastguard Worker }
221*6777b538SAndroid Build Coastguard Worker
CreateSpdySession()222*6777b538SAndroid Build Coastguard Worker void CreateSpdySession() {
223*6777b538SAndroid Build Coastguard Worker DCHECK(!session_);
224*6777b538SAndroid Build Coastguard Worker session_ = ::net::CreateSpdySession(http_session_.get(), key_,
225*6777b538SAndroid Build Coastguard Worker net_log_with_source_);
226*6777b538SAndroid Build Coastguard Worker }
227*6777b538SAndroid Build Coastguard Worker
StallSessionSend()228*6777b538SAndroid Build Coastguard Worker void StallSessionSend() {
229*6777b538SAndroid Build Coastguard Worker // Reduce the send window size to 0 to stall.
230*6777b538SAndroid Build Coastguard Worker while (session_send_window_size() > 0) {
231*6777b538SAndroid Build Coastguard Worker DecreaseSendWindowSize(
232*6777b538SAndroid Build Coastguard Worker std::min(kMaxSpdyFrameChunkSize, session_send_window_size()));
233*6777b538SAndroid Build Coastguard Worker }
234*6777b538SAndroid Build Coastguard Worker }
235*6777b538SAndroid Build Coastguard Worker
UnstallSessionSend(int32_t delta_window_size)236*6777b538SAndroid Build Coastguard Worker void UnstallSessionSend(int32_t delta_window_size) {
237*6777b538SAndroid Build Coastguard Worker IncreaseSendWindowSize(delta_window_size);
238*6777b538SAndroid Build Coastguard Worker }
239*6777b538SAndroid Build Coastguard Worker
StallStreamSend(SpdyStream * stream)240*6777b538SAndroid Build Coastguard Worker void StallStreamSend(SpdyStream* stream) {
241*6777b538SAndroid Build Coastguard Worker // Reduce the send window size to 0 to stall.
242*6777b538SAndroid Build Coastguard Worker while (stream->send_window_size() > 0) {
243*6777b538SAndroid Build Coastguard Worker stream->DecreaseSendWindowSize(
244*6777b538SAndroid Build Coastguard Worker std::min(kMaxSpdyFrameChunkSize, stream->send_window_size()));
245*6777b538SAndroid Build Coastguard Worker }
246*6777b538SAndroid Build Coastguard Worker }
247*6777b538SAndroid Build Coastguard Worker
UnstallStreamSend(SpdyStream * stream,int32_t delta_window_size)248*6777b538SAndroid Build Coastguard Worker void UnstallStreamSend(SpdyStream* stream, int32_t delta_window_size) {
249*6777b538SAndroid Build Coastguard Worker stream->IncreaseSendWindowSize(delta_window_size);
250*6777b538SAndroid Build Coastguard Worker }
251*6777b538SAndroid Build Coastguard Worker
252*6777b538SAndroid Build Coastguard Worker void RunResumeAfterUnstallTest(
253*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(SpdyStream*)> stall_function,
254*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(SpdyStream*, int32_t)> unstall_function);
255*6777b538SAndroid Build Coastguard Worker
256*6777b538SAndroid Build Coastguard Worker // SpdySession private methods.
257*6777b538SAndroid Build Coastguard Worker
MaybeSendPrefacePing()258*6777b538SAndroid Build Coastguard Worker void MaybeSendPrefacePing() { session_->MaybeSendPrefacePing(); }
259*6777b538SAndroid Build Coastguard Worker
WritePingFrame(spdy::SpdyPingId unique_id,bool is_ack)260*6777b538SAndroid Build Coastguard Worker void WritePingFrame(spdy::SpdyPingId unique_id, bool is_ack) {
261*6777b538SAndroid Build Coastguard Worker session_->WritePingFrame(unique_id, is_ack);
262*6777b538SAndroid Build Coastguard Worker }
263*6777b538SAndroid Build Coastguard Worker
CheckPingStatus(base::TimeTicks last_check_time)264*6777b538SAndroid Build Coastguard Worker void CheckPingStatus(base::TimeTicks last_check_time) {
265*6777b538SAndroid Build Coastguard Worker session_->CheckPingStatus(last_check_time);
266*6777b538SAndroid Build Coastguard Worker }
267*6777b538SAndroid Build Coastguard Worker
OnUnknownFrame(spdy::SpdyStreamId stream_id,uint8_t frame_type)268*6777b538SAndroid Build Coastguard Worker bool OnUnknownFrame(spdy::SpdyStreamId stream_id, uint8_t frame_type) {
269*6777b538SAndroid Build Coastguard Worker return session_->OnUnknownFrame(stream_id, frame_type);
270*6777b538SAndroid Build Coastguard Worker }
271*6777b538SAndroid Build Coastguard Worker
IncreaseSendWindowSize(int delta_window_size)272*6777b538SAndroid Build Coastguard Worker void IncreaseSendWindowSize(int delta_window_size) {
273*6777b538SAndroid Build Coastguard Worker session_->IncreaseSendWindowSize(delta_window_size);
274*6777b538SAndroid Build Coastguard Worker }
275*6777b538SAndroid Build Coastguard Worker
DecreaseSendWindowSize(int32_t delta_window_size)276*6777b538SAndroid Build Coastguard Worker void DecreaseSendWindowSize(int32_t delta_window_size) {
277*6777b538SAndroid Build Coastguard Worker session_->DecreaseSendWindowSize(delta_window_size);
278*6777b538SAndroid Build Coastguard Worker }
279*6777b538SAndroid Build Coastguard Worker
IncreaseRecvWindowSize(int delta_window_size)280*6777b538SAndroid Build Coastguard Worker void IncreaseRecvWindowSize(int delta_window_size) {
281*6777b538SAndroid Build Coastguard Worker session_->IncreaseRecvWindowSize(delta_window_size);
282*6777b538SAndroid Build Coastguard Worker }
283*6777b538SAndroid Build Coastguard Worker
DecreaseRecvWindowSize(int32_t delta_window_size)284*6777b538SAndroid Build Coastguard Worker void DecreaseRecvWindowSize(int32_t delta_window_size) {
285*6777b538SAndroid Build Coastguard Worker session_->DecreaseRecvWindowSize(delta_window_size);
286*6777b538SAndroid Build Coastguard Worker }
287*6777b538SAndroid Build Coastguard Worker
288*6777b538SAndroid Build Coastguard Worker // Accessors for SpdySession private members.
289*6777b538SAndroid Build Coastguard Worker
set_in_io_loop(bool in_io_loop)290*6777b538SAndroid Build Coastguard Worker void set_in_io_loop(bool in_io_loop) { session_->in_io_loop_ = in_io_loop; }
291*6777b538SAndroid Build Coastguard Worker
set_stream_hi_water_mark(spdy::SpdyStreamId stream_hi_water_mark)292*6777b538SAndroid Build Coastguard Worker void set_stream_hi_water_mark(spdy::SpdyStreamId stream_hi_water_mark) {
293*6777b538SAndroid Build Coastguard Worker session_->stream_hi_water_mark_ = stream_hi_water_mark;
294*6777b538SAndroid Build Coastguard Worker }
295*6777b538SAndroid Build Coastguard Worker
max_concurrent_streams()296*6777b538SAndroid Build Coastguard Worker size_t max_concurrent_streams() { return session_->max_concurrent_streams_; }
297*6777b538SAndroid Build Coastguard Worker
set_max_concurrent_streams(size_t max_concurrent_streams)298*6777b538SAndroid Build Coastguard Worker void set_max_concurrent_streams(size_t max_concurrent_streams) {
299*6777b538SAndroid Build Coastguard Worker session_->max_concurrent_streams_ = max_concurrent_streams;
300*6777b538SAndroid Build Coastguard Worker }
301*6777b538SAndroid Build Coastguard Worker
ping_in_flight()302*6777b538SAndroid Build Coastguard Worker bool ping_in_flight() { return session_->ping_in_flight_; }
303*6777b538SAndroid Build Coastguard Worker
next_ping_id()304*6777b538SAndroid Build Coastguard Worker spdy::SpdyPingId next_ping_id() { return session_->next_ping_id_; }
305*6777b538SAndroid Build Coastguard Worker
last_read_time()306*6777b538SAndroid Build Coastguard Worker base::TimeTicks last_read_time() { return session_->last_read_time_; }
307*6777b538SAndroid Build Coastguard Worker
check_ping_status_pending()308*6777b538SAndroid Build Coastguard Worker bool check_ping_status_pending() {
309*6777b538SAndroid Build Coastguard Worker return session_->check_ping_status_pending_;
310*6777b538SAndroid Build Coastguard Worker }
311*6777b538SAndroid Build Coastguard Worker
session_send_window_size()312*6777b538SAndroid Build Coastguard Worker int32_t session_send_window_size() {
313*6777b538SAndroid Build Coastguard Worker return session_->session_send_window_size_;
314*6777b538SAndroid Build Coastguard Worker }
315*6777b538SAndroid Build Coastguard Worker
session_recv_window_size()316*6777b538SAndroid Build Coastguard Worker int32_t session_recv_window_size() {
317*6777b538SAndroid Build Coastguard Worker return session_->session_recv_window_size_;
318*6777b538SAndroid Build Coastguard Worker }
319*6777b538SAndroid Build Coastguard Worker
set_session_recv_window_size(int32_t session_recv_window_size)320*6777b538SAndroid Build Coastguard Worker void set_session_recv_window_size(int32_t session_recv_window_size) {
321*6777b538SAndroid Build Coastguard Worker session_->session_recv_window_size_ = session_recv_window_size;
322*6777b538SAndroid Build Coastguard Worker }
323*6777b538SAndroid Build Coastguard Worker
session_unacked_recv_window_bytes()324*6777b538SAndroid Build Coastguard Worker int32_t session_unacked_recv_window_bytes() {
325*6777b538SAndroid Build Coastguard Worker return session_->session_unacked_recv_window_bytes_;
326*6777b538SAndroid Build Coastguard Worker }
327*6777b538SAndroid Build Coastguard Worker
stream_initial_send_window_size()328*6777b538SAndroid Build Coastguard Worker int32_t stream_initial_send_window_size() {
329*6777b538SAndroid Build Coastguard Worker return session_->stream_initial_send_window_size_;
330*6777b538SAndroid Build Coastguard Worker }
331*6777b538SAndroid Build Coastguard Worker
set_connection_at_risk_of_loss_time(base::TimeDelta duration)332*6777b538SAndroid Build Coastguard Worker void set_connection_at_risk_of_loss_time(base::TimeDelta duration) {
333*6777b538SAndroid Build Coastguard Worker session_->connection_at_risk_of_loss_time_ = duration;
334*6777b538SAndroid Build Coastguard Worker }
335*6777b538SAndroid Build Coastguard Worker
336*6777b538SAndroid Build Coastguard Worker // Quantities derived from SpdySession private members.
337*6777b538SAndroid Build Coastguard Worker
pending_create_stream_queue_size(RequestPriority priority)338*6777b538SAndroid Build Coastguard Worker size_t pending_create_stream_queue_size(RequestPriority priority) {
339*6777b538SAndroid Build Coastguard Worker DCHECK_GE(priority, MINIMUM_PRIORITY);
340*6777b538SAndroid Build Coastguard Worker DCHECK_LE(priority, MAXIMUM_PRIORITY);
341*6777b538SAndroid Build Coastguard Worker return session_->pending_create_stream_queues_[priority].size();
342*6777b538SAndroid Build Coastguard Worker }
343*6777b538SAndroid Build Coastguard Worker
num_active_streams()344*6777b538SAndroid Build Coastguard Worker size_t num_active_streams() { return session_->active_streams_.size(); }
345*6777b538SAndroid Build Coastguard Worker
num_created_streams()346*6777b538SAndroid Build Coastguard Worker size_t num_created_streams() { return session_->created_streams_.size(); }
347*6777b538SAndroid Build Coastguard Worker
header_encoder_table_size() const348*6777b538SAndroid Build Coastguard Worker uint32_t header_encoder_table_size() const {
349*6777b538SAndroid Build Coastguard Worker return session_->buffered_spdy_framer_->header_encoder_table_size();
350*6777b538SAndroid Build Coastguard Worker }
351*6777b538SAndroid Build Coastguard Worker
352*6777b538SAndroid Build Coastguard Worker RecordingNetLogObserver net_log_observer_;
353*6777b538SAndroid Build Coastguard Worker NetLogWithSource net_log_with_source_{
354*6777b538SAndroid Build Coastguard Worker NetLogWithSource::Make(NetLogSourceType::NONE)};
355*6777b538SAndroid Build Coastguard Worker
356*6777b538SAndroid Build Coastguard Worker // Original socket limits. Some tests set these. Safest to always restore
357*6777b538SAndroid Build Coastguard Worker // them once each test has been run.
358*6777b538SAndroid Build Coastguard Worker int old_max_group_sockets_;
359*6777b538SAndroid Build Coastguard Worker int old_max_pool_sockets_;
360*6777b538SAndroid Build Coastguard Worker
361*6777b538SAndroid Build Coastguard Worker SpdyTestUtil spdy_util_;
362*6777b538SAndroid Build Coastguard Worker SpdySessionDependencies session_deps_;
363*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HttpNetworkSession> http_session_;
364*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdySession> session_;
365*6777b538SAndroid Build Coastguard Worker raw_ptr<SpdySessionPool> spdy_session_pool_ = nullptr;
366*6777b538SAndroid Build Coastguard Worker const GURL test_url_;
367*6777b538SAndroid Build Coastguard Worker const url::SchemeHostPort test_server_;
368*6777b538SAndroid Build Coastguard Worker SpdySessionKey key_;
369*6777b538SAndroid Build Coastguard Worker SSLSocketDataProvider ssl_;
370*6777b538SAndroid Build Coastguard Worker };
371*6777b538SAndroid Build Coastguard Worker
372*6777b538SAndroid Build Coastguard Worker class SpdySessionTestWithMockTime : public SpdySessionTest {
373*6777b538SAndroid Build Coastguard Worker protected:
SpdySessionTestWithMockTime()374*6777b538SAndroid Build Coastguard Worker SpdySessionTestWithMockTime()
375*6777b538SAndroid Build Coastguard Worker : SpdySessionTest(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
376*6777b538SAndroid Build Coastguard Worker };
377*6777b538SAndroid Build Coastguard Worker
378*6777b538SAndroid Build Coastguard Worker // Try to create a SPDY session that will fail during
379*6777b538SAndroid Build Coastguard Worker // initialization. Nothing should blow up.
TEST_F(SpdySessionTest,InitialReadError)380*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, InitialReadError) {
381*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {MockRead(ASYNC, ERR_CONNECTION_CLOSED, 0)};
382*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, base::span<MockWrite>());
383*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
384*6777b538SAndroid Build Coastguard Worker
385*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
386*6777b538SAndroid Build Coastguard Worker
387*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
388*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
389*6777b538SAndroid Build Coastguard Worker
390*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_);
391*6777b538SAndroid Build Coastguard Worker // Flush the read.
392*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
393*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
394*6777b538SAndroid Build Coastguard Worker }
395*6777b538SAndroid Build Coastguard Worker
396*6777b538SAndroid Build Coastguard Worker namespace {
397*6777b538SAndroid Build Coastguard Worker
398*6777b538SAndroid Build Coastguard Worker // A helper class that vends a callback that, when fired, destroys a
399*6777b538SAndroid Build Coastguard Worker // given SpdyStreamRequest.
400*6777b538SAndroid Build Coastguard Worker class StreamRequestDestroyingCallback : public TestCompletionCallbackBase {
401*6777b538SAndroid Build Coastguard Worker public:
402*6777b538SAndroid Build Coastguard Worker StreamRequestDestroyingCallback() = default;
403*6777b538SAndroid Build Coastguard Worker
404*6777b538SAndroid Build Coastguard Worker ~StreamRequestDestroyingCallback() override = default;
405*6777b538SAndroid Build Coastguard Worker
SetRequestToDestroy(std::unique_ptr<SpdyStreamRequest> request)406*6777b538SAndroid Build Coastguard Worker void SetRequestToDestroy(std::unique_ptr<SpdyStreamRequest> request) {
407*6777b538SAndroid Build Coastguard Worker request_ = std::move(request);
408*6777b538SAndroid Build Coastguard Worker }
409*6777b538SAndroid Build Coastguard Worker
MakeCallback()410*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback MakeCallback() {
411*6777b538SAndroid Build Coastguard Worker return base::BindOnce(&StreamRequestDestroyingCallback::OnComplete,
412*6777b538SAndroid Build Coastguard Worker base::Unretained(this));
413*6777b538SAndroid Build Coastguard Worker }
414*6777b538SAndroid Build Coastguard Worker
415*6777b538SAndroid Build Coastguard Worker private:
OnComplete(int result)416*6777b538SAndroid Build Coastguard Worker void OnComplete(int result) {
417*6777b538SAndroid Build Coastguard Worker request_.reset();
418*6777b538SAndroid Build Coastguard Worker SetResult(result);
419*6777b538SAndroid Build Coastguard Worker }
420*6777b538SAndroid Build Coastguard Worker
421*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SpdyStreamRequest> request_;
422*6777b538SAndroid Build Coastguard Worker };
423*6777b538SAndroid Build Coastguard Worker
424*6777b538SAndroid Build Coastguard Worker } // namespace
425*6777b538SAndroid Build Coastguard Worker
426*6777b538SAndroid Build Coastguard Worker // Request kH2InitialMaxConcurrentStreamsParam.Get() streams. Request two more
427*6777b538SAndroid Build Coastguard Worker // streams, but have the callback for one destroy the second stream
428*6777b538SAndroid Build Coastguard Worker // request. Close the session. Nothing should blow up. This is a
429*6777b538SAndroid Build Coastguard Worker // regression test for http://crbug.com/250841 .
TEST_F(SpdySessionTest,PendingStreamCancellingAnother)430*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, PendingStreamCancellingAnother) {
431*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {MockRead(ASYNC, 0, 0), };
432*6777b538SAndroid Build Coastguard Worker
433*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, base::span<MockWrite>());
434*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
435*6777b538SAndroid Build Coastguard Worker
436*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
437*6777b538SAndroid Build Coastguard Worker
438*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
439*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
440*6777b538SAndroid Build Coastguard Worker
441*6777b538SAndroid Build Coastguard Worker // Create the maximum number of concurrent streams.
442*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < kH2InitialMaxConcurrentStreams.Get(); ++i) {
443*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
444*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_,
445*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
446*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream);
447*6777b538SAndroid Build Coastguard Worker }
448*6777b538SAndroid Build Coastguard Worker
449*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest request1;
450*6777b538SAndroid Build Coastguard Worker auto request2 = std::make_unique<SpdyStreamRequest>();
451*6777b538SAndroid Build Coastguard Worker
452*6777b538SAndroid Build Coastguard Worker StreamRequestDestroyingCallback callback1;
453*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(ERR_IO_PENDING,
454*6777b538SAndroid Build Coastguard Worker request1.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_,
455*6777b538SAndroid Build Coastguard Worker test_url_, false, MEDIUM, SocketTag(),
456*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), callback1.MakeCallback(),
457*6777b538SAndroid Build Coastguard Worker TRAFFIC_ANNOTATION_FOR_TESTS));
458*6777b538SAndroid Build Coastguard Worker
459*6777b538SAndroid Build Coastguard Worker // |callback2| is never called.
460*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback2;
461*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(ERR_IO_PENDING,
462*6777b538SAndroid Build Coastguard Worker request2->StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_,
463*6777b538SAndroid Build Coastguard Worker test_url_, false, MEDIUM, SocketTag(),
464*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), callback2.callback(),
465*6777b538SAndroid Build Coastguard Worker TRAFFIC_ANNOTATION_FOR_TESTS));
466*6777b538SAndroid Build Coastguard Worker
467*6777b538SAndroid Build Coastguard Worker callback1.SetRequestToDestroy(std::move(request2));
468*6777b538SAndroid Build Coastguard Worker
469*6777b538SAndroid Build Coastguard Worker session_->CloseSessionOnError(ERR_ABORTED, "Aborting session");
470*6777b538SAndroid Build Coastguard Worker
471*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_ABORTED));
472*6777b538SAndroid Build Coastguard Worker }
473*6777b538SAndroid Build Coastguard Worker
474*6777b538SAndroid Build Coastguard Worker // A session receiving a GOAWAY frame with no active streams should close.
TEST_F(SpdySessionTest,GoAwayWithNoActiveStreams)475*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, GoAwayWithNoActiveStreams) {
476*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
477*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
478*6777b538SAndroid Build Coastguard Worker CreateMockRead(goaway, 0),
479*6777b538SAndroid Build Coastguard Worker };
480*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, base::span<MockWrite>());
481*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
482*6777b538SAndroid Build Coastguard Worker
483*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
484*6777b538SAndroid Build Coastguard Worker
485*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
486*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
487*6777b538SAndroid Build Coastguard Worker
488*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
489*6777b538SAndroid Build Coastguard Worker
490*6777b538SAndroid Build Coastguard Worker // Read and process the GOAWAY frame.
491*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
492*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
493*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
494*6777b538SAndroid Build Coastguard Worker }
495*6777b538SAndroid Build Coastguard Worker
496*6777b538SAndroid Build Coastguard Worker // A session receiving a GOAWAY frame immediately with no active
497*6777b538SAndroid Build Coastguard Worker // streams should then close.
TEST_F(SpdySessionTest,GoAwayImmediatelyWithNoActiveStreams)498*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) {
499*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
500*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
501*6777b538SAndroid Build Coastguard Worker CreateMockRead(goaway, 0, SYNCHRONOUS), MockRead(ASYNC, 0, 1) // EOF
502*6777b538SAndroid Build Coastguard Worker };
503*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, base::span<MockWrite>());
504*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
505*6777b538SAndroid Build Coastguard Worker
506*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
507*6777b538SAndroid Build Coastguard Worker
508*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
509*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
510*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
511*6777b538SAndroid Build Coastguard Worker
512*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
513*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
514*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(data.AllReadDataConsumed());
515*6777b538SAndroid Build Coastguard Worker }
516*6777b538SAndroid Build Coastguard Worker
517*6777b538SAndroid Build Coastguard Worker // A session receiving a GOAWAY frame with active streams should close
518*6777b538SAndroid Build Coastguard Worker // when the last active stream is closed.
TEST_F(SpdySessionTest,GoAwayWithActiveStreams)519*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, GoAwayWithActiveStreams) {
520*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
521*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
522*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(goaway, 3),
523*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 4), MockRead(ASYNC, 0, 5) // EOF
524*6777b538SAndroid Build Coastguard Worker };
525*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
526*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
527*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(
528*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
529*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
530*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
531*6777b538SAndroid Build Coastguard Worker };
532*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
533*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
534*6777b538SAndroid Build Coastguard Worker
535*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
536*6777b538SAndroid Build Coastguard Worker
537*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
538*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
539*6777b538SAndroid Build Coastguard Worker
540*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
541*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
542*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
543*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
544*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
545*6777b538SAndroid Build Coastguard Worker
546*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 =
547*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
548*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
549*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate2(spdy_stream2);
550*6777b538SAndroid Build Coastguard Worker spdy_stream2->SetDelegate(&delegate2);
551*6777b538SAndroid Build Coastguard Worker
552*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
553*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
554*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(headers.Clone());
555*6777b538SAndroid Build Coastguard Worker
556*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
557*6777b538SAndroid Build Coastguard Worker spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
558*6777b538SAndroid Build Coastguard Worker
559*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
560*6777b538SAndroid Build Coastguard Worker
561*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream1->stream_id());
562*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, spdy_stream2->stream_id());
563*6777b538SAndroid Build Coastguard Worker
564*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
565*6777b538SAndroid Build Coastguard Worker
566*6777b538SAndroid Build Coastguard Worker // Read and process the GOAWAY frame.
567*6777b538SAndroid Build Coastguard Worker data.Resume();
568*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
569*6777b538SAndroid Build Coastguard Worker
570*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
571*6777b538SAndroid Build Coastguard Worker
572*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->IsStreamActive(3));
573*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream2);
574*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsStreamActive(1));
575*6777b538SAndroid Build Coastguard Worker
576*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsGoingAway());
577*6777b538SAndroid Build Coastguard Worker
578*6777b538SAndroid Build Coastguard Worker // Should close the session.
579*6777b538SAndroid Build Coastguard Worker spdy_stream1->Close();
580*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
581*6777b538SAndroid Build Coastguard Worker
582*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_);
583*6777b538SAndroid Build Coastguard Worker data.Resume();
584*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
585*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
586*6777b538SAndroid Build Coastguard Worker }
587*6777b538SAndroid Build Coastguard Worker
588*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/547130.
TEST_F(SpdySessionTest,GoAwayWithActiveAndCreatedStream)589*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, GoAwayWithActiveAndCreatedStream) {
590*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(0));
591*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
592*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(goaway, 2),
593*6777b538SAndroid Build Coastguard Worker };
594*6777b538SAndroid Build Coastguard Worker
595*6777b538SAndroid Build Coastguard Worker // No |req2|, because the second stream will never get activated.
596*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
597*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
598*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
599*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0),
600*6777b538SAndroid Build Coastguard Worker };
601*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
602*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
603*6777b538SAndroid Build Coastguard Worker
604*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
605*6777b538SAndroid Build Coastguard Worker
606*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
607*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
608*6777b538SAndroid Build Coastguard Worker
609*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
610*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
611*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
612*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
613*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
614*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers1(
615*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
616*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
617*6777b538SAndroid Build Coastguard Worker
618*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
619*6777b538SAndroid Build Coastguard Worker
620*6777b538SAndroid Build Coastguard Worker // Active stream 1.
621*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
622*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream1->stream_id());
623*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsStreamActive(1));
624*6777b538SAndroid Build Coastguard Worker
625*6777b538SAndroid Build Coastguard Worker // Create stream corresponding to the next request.
626*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 =
627*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
628*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
629*6777b538SAndroid Build Coastguard Worker
630*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream2->stream_id());
631*6777b538SAndroid Build Coastguard Worker
632*6777b538SAndroid Build Coastguard Worker // Read and process the GOAWAY frame before the second stream could be
633*6777b538SAndroid Build Coastguard Worker // activated.
634*6777b538SAndroid Build Coastguard Worker data.Resume();
635*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
636*6777b538SAndroid Build Coastguard Worker
637*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
638*6777b538SAndroid Build Coastguard Worker
639*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
640*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
641*6777b538SAndroid Build Coastguard Worker }
642*6777b538SAndroid Build Coastguard Worker
643*6777b538SAndroid Build Coastguard Worker // Have a session receive two GOAWAY frames, with the last one causing
644*6777b538SAndroid Build Coastguard Worker // the last active stream to be closed. The session should then be
645*6777b538SAndroid Build Coastguard Worker // closed after the second GOAWAY frame.
TEST_F(SpdySessionTest,GoAwayTwice)646*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, GoAwayTwice) {
647*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway1(spdy_util_.ConstructSpdyGoAway(1));
648*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway2(spdy_util_.ConstructSpdyGoAway(0));
649*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
650*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(goaway1, 3),
651*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 4), CreateMockRead(goaway2, 5),
652*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 6), MockRead(ASYNC, 0, 7) // EOF
653*6777b538SAndroid Build Coastguard Worker };
654*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
655*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
656*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(
657*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
658*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
659*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
660*6777b538SAndroid Build Coastguard Worker };
661*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
662*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
663*6777b538SAndroid Build Coastguard Worker
664*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
665*6777b538SAndroid Build Coastguard Worker
666*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
667*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
668*6777b538SAndroid Build Coastguard Worker
669*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
670*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
671*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
672*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
673*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
674*6777b538SAndroid Build Coastguard Worker
675*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 =
676*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
677*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
678*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate2(spdy_stream2);
679*6777b538SAndroid Build Coastguard Worker spdy_stream2->SetDelegate(&delegate2);
680*6777b538SAndroid Build Coastguard Worker
681*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
682*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
683*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(headers.Clone());
684*6777b538SAndroid Build Coastguard Worker
685*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
686*6777b538SAndroid Build Coastguard Worker spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
687*6777b538SAndroid Build Coastguard Worker
688*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
689*6777b538SAndroid Build Coastguard Worker
690*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream1->stream_id());
691*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, spdy_stream2->stream_id());
692*6777b538SAndroid Build Coastguard Worker
693*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
694*6777b538SAndroid Build Coastguard Worker
695*6777b538SAndroid Build Coastguard Worker // Read and process the first GOAWAY frame.
696*6777b538SAndroid Build Coastguard Worker data.Resume();
697*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
698*6777b538SAndroid Build Coastguard Worker
699*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
700*6777b538SAndroid Build Coastguard Worker
701*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->IsStreamActive(3));
702*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream2);
703*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsStreamActive(1));
704*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsGoingAway());
705*6777b538SAndroid Build Coastguard Worker
706*6777b538SAndroid Build Coastguard Worker // Read and process the second GOAWAY frame, which should close the
707*6777b538SAndroid Build Coastguard Worker // session.
708*6777b538SAndroid Build Coastguard Worker data.Resume();
709*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
710*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
711*6777b538SAndroid Build Coastguard Worker }
712*6777b538SAndroid Build Coastguard Worker
713*6777b538SAndroid Build Coastguard Worker // Have a session with active streams receive a GOAWAY frame and then
714*6777b538SAndroid Build Coastguard Worker // close it. It should handle the close properly (i.e., not try to
715*6777b538SAndroid Build Coastguard Worker // make itself unavailable in its pool twice).
TEST_F(SpdySessionTest,GoAwayWithActiveStreamsThenClose)716*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
717*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
718*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
719*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(goaway, 3),
720*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 4), MockRead(ASYNC, 0, 5) // EOF
721*6777b538SAndroid Build Coastguard Worker };
722*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
723*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
724*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(
725*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
726*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
727*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
728*6777b538SAndroid Build Coastguard Worker };
729*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
730*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
731*6777b538SAndroid Build Coastguard Worker
732*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
733*6777b538SAndroid Build Coastguard Worker
734*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
735*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
736*6777b538SAndroid Build Coastguard Worker
737*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
738*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
739*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
740*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
741*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
742*6777b538SAndroid Build Coastguard Worker
743*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 =
744*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
745*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
746*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate2(spdy_stream2);
747*6777b538SAndroid Build Coastguard Worker spdy_stream2->SetDelegate(&delegate2);
748*6777b538SAndroid Build Coastguard Worker
749*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
750*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
751*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(headers.Clone());
752*6777b538SAndroid Build Coastguard Worker
753*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
754*6777b538SAndroid Build Coastguard Worker spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
755*6777b538SAndroid Build Coastguard Worker
756*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
757*6777b538SAndroid Build Coastguard Worker
758*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream1->stream_id());
759*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, spdy_stream2->stream_id());
760*6777b538SAndroid Build Coastguard Worker
761*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
762*6777b538SAndroid Build Coastguard Worker
763*6777b538SAndroid Build Coastguard Worker // Read and process the GOAWAY frame.
764*6777b538SAndroid Build Coastguard Worker data.Resume();
765*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
766*6777b538SAndroid Build Coastguard Worker
767*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
768*6777b538SAndroid Build Coastguard Worker
769*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->IsStreamActive(3));
770*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream2);
771*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsStreamActive(1));
772*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsGoingAway());
773*6777b538SAndroid Build Coastguard Worker
774*6777b538SAndroid Build Coastguard Worker session_->CloseSessionOnError(ERR_ABORTED, "Aborting session");
775*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
776*6777b538SAndroid Build Coastguard Worker
777*6777b538SAndroid Build Coastguard Worker data.Resume();
778*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
779*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
780*6777b538SAndroid Build Coastguard Worker }
781*6777b538SAndroid Build Coastguard Worker
782*6777b538SAndroid Build Coastguard Worker // Process a joint read buffer which causes the session to begin draining, and
783*6777b538SAndroid Build Coastguard Worker // then processes a GOAWAY. The session should gracefully drain. Regression test
784*6777b538SAndroid Build Coastguard Worker // for crbug.com/379469
TEST_F(SpdySessionTest,GoAwayWhileDraining)785*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, GoAwayWhileDraining) {
786*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
787*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
788*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
789*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0),
790*6777b538SAndroid Build Coastguard Worker };
791*6777b538SAndroid Build Coastguard Worker
792*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp(
793*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
794*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
795*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
796*6777b538SAndroid Build Coastguard Worker size_t joint_size = goaway.size() * 2 + body.size();
797*6777b538SAndroid Build Coastguard Worker
798*6777b538SAndroid Build Coastguard Worker // Compose interleaved |goaway| and |body| frames into a single read.
799*6777b538SAndroid Build Coastguard Worker auto buffer = std::make_unique<char[]>(joint_size);
800*6777b538SAndroid Build Coastguard Worker {
801*6777b538SAndroid Build Coastguard Worker size_t out = 0;
802*6777b538SAndroid Build Coastguard Worker memcpy(&buffer[out], goaway.data(), goaway.size());
803*6777b538SAndroid Build Coastguard Worker out += goaway.size();
804*6777b538SAndroid Build Coastguard Worker memcpy(&buffer[out], body.data(), body.size());
805*6777b538SAndroid Build Coastguard Worker out += body.size();
806*6777b538SAndroid Build Coastguard Worker memcpy(&buffer[out], goaway.data(), goaway.size());
807*6777b538SAndroid Build Coastguard Worker out += goaway.size();
808*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(out, joint_size);
809*6777b538SAndroid Build Coastguard Worker }
810*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame joint_frames(
811*6777b538SAndroid Build Coastguard Worker spdy::test::MakeSerializedFrame(buffer.get(), joint_size));
812*6777b538SAndroid Build Coastguard Worker
813*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
814*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp, 1), CreateMockRead(joint_frames, 2),
815*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3) // EOF
816*6777b538SAndroid Build Coastguard Worker };
817*6777b538SAndroid Build Coastguard Worker
818*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
819*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
820*6777b538SAndroid Build Coastguard Worker
821*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
822*6777b538SAndroid Build Coastguard Worker
823*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
824*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
825*6777b538SAndroid Build Coastguard Worker
826*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
827*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
828*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
829*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate(spdy_stream);
830*6777b538SAndroid Build Coastguard Worker spdy_stream->SetDelegate(&delegate);
831*6777b538SAndroid Build Coastguard Worker
832*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
833*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
834*6777b538SAndroid Build Coastguard Worker spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
835*6777b538SAndroid Build Coastguard Worker
836*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
837*6777b538SAndroid Build Coastguard Worker
838*6777b538SAndroid Build Coastguard Worker // Stream and session closed gracefully.
839*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate.StreamIsClosed());
840*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate.WaitForClose(), IsOk());
841*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kUploadData, delegate.TakeReceivedData());
842*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
843*6777b538SAndroid Build Coastguard Worker }
844*6777b538SAndroid Build Coastguard Worker
845*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/1510327.
846*6777b538SAndroid Build Coastguard Worker // Have a session with active streams receive a GOAWAY frame. Ensure that
847*6777b538SAndroid Build Coastguard Worker // the session is drained after all streams receive DATA frames of which
848*6777b538SAndroid Build Coastguard Worker // END_STREAM flag is set, even when the peer doesn't close the connection.
TEST_F(SpdySessionTest,GoAwayWithActiveStreamsThenEndStreams)849*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, GoAwayWithActiveStreamsThenEndStreams) {
850*6777b538SAndroid Build Coastguard Worker const int kStreamId1 = 1;
851*6777b538SAndroid Build Coastguard Worker const int kStreamId2 = 3;
852*6777b538SAndroid Build Coastguard Worker
853*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
854*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, kStreamId1, MEDIUM));
855*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(
856*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, kStreamId2, MEDIUM));
857*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
858*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0),
859*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req2, 1),
860*6777b538SAndroid Build Coastguard Worker };
861*6777b538SAndroid Build Coastguard Worker
862*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp1(
863*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, kStreamId1));
864*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp2(
865*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, kStreamId2));
866*6777b538SAndroid Build Coastguard Worker
867*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body1(
868*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(kStreamId1, true));
869*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body2(
870*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(kStreamId2, true));
871*6777b538SAndroid Build Coastguard Worker
872*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(kStreamId2));
873*6777b538SAndroid Build Coastguard Worker
874*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
875*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp1, 2), CreateMockRead(resp2, 3),
876*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 4), // (1)
877*6777b538SAndroid Build Coastguard Worker CreateMockRead(goaway, 5), CreateMockRead(body1, 6),
878*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 7), // (2)
879*6777b538SAndroid Build Coastguard Worker CreateMockRead(body2, 8),
880*6777b538SAndroid Build Coastguard Worker // No EOF.
881*6777b538SAndroid Build Coastguard Worker };
882*6777b538SAndroid Build Coastguard Worker
883*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
884*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
885*6777b538SAndroid Build Coastguard Worker
886*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
887*6777b538SAndroid Build Coastguard Worker
888*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
889*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
890*6777b538SAndroid Build Coastguard Worker
891*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
892*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
893*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
894*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
895*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
896*6777b538SAndroid Build Coastguard Worker
897*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 =
898*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
899*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
900*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate2(spdy_stream2);
901*6777b538SAndroid Build Coastguard Worker spdy_stream2->SetDelegate(&delegate2);
902*6777b538SAndroid Build Coastguard Worker
903*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
904*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
905*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(headers.Clone());
906*6777b538SAndroid Build Coastguard Worker
907*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
908*6777b538SAndroid Build Coastguard Worker spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
909*6777b538SAndroid Build Coastguard Worker
910*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
911*6777b538SAndroid Build Coastguard Worker
912*6777b538SAndroid Build Coastguard Worker // (1) Read and process the GOAWAY frame and the response for kStreamId1.
913*6777b538SAndroid Build Coastguard Worker data.Resume();
914*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
915*6777b538SAndroid Build Coastguard Worker
916*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
917*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(spdy_stream2);
918*6777b538SAndroid Build Coastguard Worker
919*6777b538SAndroid Build Coastguard Worker // (2) Read and process the response for kStreamId2.
920*6777b538SAndroid Build Coastguard Worker data.Resume();
921*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
922*6777b538SAndroid Build Coastguard Worker
923*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
924*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream2);
925*6777b538SAndroid Build Coastguard Worker
926*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
927*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
928*6777b538SAndroid Build Coastguard Worker
929*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
930*6777b538SAndroid Build Coastguard Worker }
931*6777b538SAndroid Build Coastguard Worker
932*6777b538SAndroid Build Coastguard Worker // Try to create a stream after receiving a GOAWAY frame. It should
933*6777b538SAndroid Build Coastguard Worker // fail.
TEST_F(SpdySessionTest,CreateStreamAfterGoAway)934*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CreateStreamAfterGoAway) {
935*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
936*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
937*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(goaway, 2),
938*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 3), MockRead(ASYNC, 0, 4) // EOF
939*6777b538SAndroid Build Coastguard Worker };
940*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
941*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
942*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
943*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0),
944*6777b538SAndroid Build Coastguard Worker };
945*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
946*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
947*6777b538SAndroid Build Coastguard Worker
948*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
949*6777b538SAndroid Build Coastguard Worker
950*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
951*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
952*6777b538SAndroid Build Coastguard Worker
953*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
954*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
955*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
956*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate(spdy_stream);
957*6777b538SAndroid Build Coastguard Worker spdy_stream->SetDelegate(&delegate);
958*6777b538SAndroid Build Coastguard Worker
959*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
960*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
961*6777b538SAndroid Build Coastguard Worker spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
962*6777b538SAndroid Build Coastguard Worker
963*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
964*6777b538SAndroid Build Coastguard Worker
965*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream->stream_id());
966*6777b538SAndroid Build Coastguard Worker
967*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
968*6777b538SAndroid Build Coastguard Worker
969*6777b538SAndroid Build Coastguard Worker // Read and process the GOAWAY frame.
970*6777b538SAndroid Build Coastguard Worker data.Resume();
971*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
972*6777b538SAndroid Build Coastguard Worker
973*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
974*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsStreamActive(1));
975*6777b538SAndroid Build Coastguard Worker
976*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest stream_request;
977*6777b538SAndroid Build Coastguard Worker int rv = stream_request.StartRequest(
978*6777b538SAndroid Build Coastguard Worker SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, false, MEDIUM,
979*6777b538SAndroid Build Coastguard Worker SocketTag(), NetLogWithSource(), CompletionOnceCallback(),
980*6777b538SAndroid Build Coastguard Worker TRAFFIC_ANNOTATION_FOR_TESTS);
981*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(rv, IsError(ERR_FAILED));
982*6777b538SAndroid Build Coastguard Worker
983*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_);
984*6777b538SAndroid Build Coastguard Worker data.Resume();
985*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
986*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
987*6777b538SAndroid Build Coastguard Worker }
988*6777b538SAndroid Build Coastguard Worker
989*6777b538SAndroid Build Coastguard Worker // Receiving a HEADERS frame after a GOAWAY frame should result in
990*6777b538SAndroid Build Coastguard Worker // the stream being refused.
TEST_F(SpdySessionTest,HeadersAfterGoAway)991*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, HeadersAfterGoAway) {
992*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway_received(spdy_util_.ConstructSpdyGoAway(1));
993*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame push(spdy_util_.ConstructSpdyPushPromise(1, 2, {}));
994*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
995*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(goaway_received, 2),
996*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 3), CreateMockRead(push, 4),
997*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 6) // EOF
998*6777b538SAndroid Build Coastguard Worker };
999*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
1000*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
1001*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway_sent(spdy_util_.ConstructSpdyGoAway(
1002*6777b538SAndroid Build Coastguard Worker 0, spdy::ERROR_CODE_PROTOCOL_ERROR, "PUSH_PROMISE received"));
1003*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(req, 0),
1004*6777b538SAndroid Build Coastguard Worker CreateMockWrite(goaway_sent, 5)};
1005*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
1006*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1007*6777b538SAndroid Build Coastguard Worker
1008*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1009*6777b538SAndroid Build Coastguard Worker
1010*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1011*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1012*6777b538SAndroid Build Coastguard Worker
1013*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
1014*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
1015*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
1016*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate(spdy_stream);
1017*6777b538SAndroid Build Coastguard Worker spdy_stream->SetDelegate(&delegate);
1018*6777b538SAndroid Build Coastguard Worker
1019*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
1020*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
1021*6777b538SAndroid Build Coastguard Worker spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
1022*6777b538SAndroid Build Coastguard Worker
1023*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1024*6777b538SAndroid Build Coastguard Worker
1025*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream->stream_id());
1026*6777b538SAndroid Build Coastguard Worker
1027*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
1028*6777b538SAndroid Build Coastguard Worker
1029*6777b538SAndroid Build Coastguard Worker // Read and process the GOAWAY frame.
1030*6777b538SAndroid Build Coastguard Worker data.Resume();
1031*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1032*6777b538SAndroid Build Coastguard Worker
1033*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
1034*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsStreamActive(1));
1035*6777b538SAndroid Build Coastguard Worker
1036*6777b538SAndroid Build Coastguard Worker // Read and process the HEADERS frame, the subsequent RST_STREAM,
1037*6777b538SAndroid Build Coastguard Worker // and EOF.
1038*6777b538SAndroid Build Coastguard Worker data.Resume();
1039*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1040*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
1041*6777b538SAndroid Build Coastguard Worker }
1042*6777b538SAndroid Build Coastguard Worker
1043*6777b538SAndroid Build Coastguard Worker // A session observing a network change with active streams should close
1044*6777b538SAndroid Build Coastguard Worker // when the last active stream is closed.
TEST_F(SpdySessionTest,NetworkChangeWithActiveStreams)1045*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, NetworkChangeWithActiveStreams) {
1046*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
1047*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2) // EOF
1048*6777b538SAndroid Build Coastguard Worker };
1049*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
1050*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
1051*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
1052*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0),
1053*6777b538SAndroid Build Coastguard Worker };
1054*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
1055*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1056*6777b538SAndroid Build Coastguard Worker
1057*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1058*6777b538SAndroid Build Coastguard Worker
1059*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1060*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1061*6777b538SAndroid Build Coastguard Worker
1062*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
1063*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
1064*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
1065*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate(spdy_stream);
1066*6777b538SAndroid Build Coastguard Worker spdy_stream->SetDelegate(&delegate);
1067*6777b538SAndroid Build Coastguard Worker
1068*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
1069*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
1070*6777b538SAndroid Build Coastguard Worker
1071*6777b538SAndroid Build Coastguard Worker spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
1072*6777b538SAndroid Build Coastguard Worker
1073*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1074*6777b538SAndroid Build Coastguard Worker
1075*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream->stream_id());
1076*6777b538SAndroid Build Coastguard Worker
1077*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
1078*6777b538SAndroid Build Coastguard Worker
1079*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->OnIPAddressChanged();
1080*6777b538SAndroid Build Coastguard Worker
1081*6777b538SAndroid Build Coastguard Worker // The SpdySessionPool behavior differs based on how the OSs reacts to
1082*6777b538SAndroid Build Coastguard Worker // network changes; see comment in SpdySessionPool::OnIPAddressChanged().
1083*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_IOS)
1084*6777b538SAndroid Build Coastguard Worker // For OSs where the TCP connections will close upon relevant network
1085*6777b538SAndroid Build Coastguard Worker // changes, SpdySessionPool doesn't need to force them to close, so in these
1086*6777b538SAndroid Build Coastguard Worker // cases verify the session has become unavailable but remains open and the
1087*6777b538SAndroid Build Coastguard Worker // pre-existing stream is still active.
1088*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
1089*6777b538SAndroid Build Coastguard Worker
1090*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsGoingAway());
1091*6777b538SAndroid Build Coastguard Worker
1092*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsStreamActive(1));
1093*6777b538SAndroid Build Coastguard Worker
1094*6777b538SAndroid Build Coastguard Worker // Should close the session.
1095*6777b538SAndroid Build Coastguard Worker spdy_stream->Close();
1096*6777b538SAndroid Build Coastguard Worker #endif
1097*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream);
1098*6777b538SAndroid Build Coastguard Worker
1099*6777b538SAndroid Build Coastguard Worker data.Resume();
1100*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1101*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
1102*6777b538SAndroid Build Coastguard Worker }
1103*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTestWithMockTime,ClientPing)1104*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTestWithMockTime, ClientPing) {
1105*6777b538SAndroid Build Coastguard Worker session_deps_.enable_ping = true;
1106*6777b538SAndroid Build Coastguard Worker
1107*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame read_ping(spdy_util_.ConstructSpdyPing(1, true));
1108*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
1109*6777b538SAndroid Build Coastguard Worker CreateMockRead(read_ping, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1110*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3) // EOF
1111*6777b538SAndroid Build Coastguard Worker };
1112*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame write_ping(spdy_util_.ConstructSpdyPing(1, false));
1113*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
1114*6777b538SAndroid Build Coastguard Worker CreateMockWrite(write_ping, 0),
1115*6777b538SAndroid Build Coastguard Worker };
1116*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
1117*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1118*6777b538SAndroid Build Coastguard Worker
1119*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1120*6777b538SAndroid Build Coastguard Worker
1121*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1122*6777b538SAndroid Build Coastguard Worker TestNetworkQualityEstimator estimator;
1123*6777b538SAndroid Build Coastguard Worker
1124*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->set_network_quality_estimator(&estimator);
1125*6777b538SAndroid Build Coastguard Worker
1126*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1127*6777b538SAndroid Build Coastguard Worker
1128*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
1129*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
1130*6777b538SAndroid Build Coastguard Worker MEDIUM, NetLogWithSource());
1131*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
1132*6777b538SAndroid Build Coastguard Worker test::StreamDelegateSendImmediate delegate(spdy_stream1, "");
1133*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate);
1134*6777b538SAndroid Build Coastguard Worker
1135*6777b538SAndroid Build Coastguard Worker base::TimeTicks before_ping_time = base::TimeTicks::Now();
1136*6777b538SAndroid Build Coastguard Worker
1137*6777b538SAndroid Build Coastguard Worker // Negative value means a preface ping will always be sent.
1138*6777b538SAndroid Build Coastguard Worker set_connection_at_risk_of_loss_time(base::Seconds(-1));
1139*6777b538SAndroid Build Coastguard Worker
1140*6777b538SAndroid Build Coastguard Worker // Send a PING frame. This posts CheckPingStatus() with delay.
1141*6777b538SAndroid Build Coastguard Worker MaybeSendPrefacePing();
1142*6777b538SAndroid Build Coastguard Worker
1143*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(ping_in_flight());
1144*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2u, next_ping_id());
1145*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(check_ping_status_pending());
1146*6777b538SAndroid Build Coastguard Worker
1147*6777b538SAndroid Build Coastguard Worker // MaybeSendPrefacePing() should not send another PING frame if there is
1148*6777b538SAndroid Build Coastguard Worker // already one in flight.
1149*6777b538SAndroid Build Coastguard Worker MaybeSendPrefacePing();
1150*6777b538SAndroid Build Coastguard Worker
1151*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(ping_in_flight());
1152*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2u, next_ping_id());
1153*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(check_ping_status_pending());
1154*6777b538SAndroid Build Coastguard Worker
1155*6777b538SAndroid Build Coastguard Worker // Run posted CheckPingStatus() task.
1156*6777b538SAndroid Build Coastguard Worker FastForwardUntilNoTasksRemain();
1157*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1158*6777b538SAndroid Build Coastguard Worker
1159*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(ping_in_flight());
1160*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2u, next_ping_id());
1161*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(check_ping_status_pending());
1162*6777b538SAndroid Build Coastguard Worker EXPECT_GE(last_read_time(), before_ping_time);
1163*6777b538SAndroid Build Coastguard Worker
1164*6777b538SAndroid Build Coastguard Worker data.Resume();
1165*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1166*6777b538SAndroid Build Coastguard Worker
1167*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
1168*6777b538SAndroid Build Coastguard Worker
1169*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(MainThreadIsIdle());
1170*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
1171*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
1172*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
1173*6777b538SAndroid Build Coastguard Worker
1174*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
1175*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
1176*6777b538SAndroid Build Coastguard Worker
1177*6777b538SAndroid Build Coastguard Worker EXPECT_LE(1u, estimator.ping_rtt_received_count());
1178*6777b538SAndroid Build Coastguard Worker }
1179*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,ServerPing)1180*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, ServerPing) {
1181*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame read_ping(spdy_util_.ConstructSpdyPing(2, false));
1182*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
1183*6777b538SAndroid Build Coastguard Worker CreateMockRead(read_ping), MockRead(SYNCHRONOUS, 0, 0) // EOF
1184*6777b538SAndroid Build Coastguard Worker };
1185*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame write_ping(spdy_util_.ConstructSpdyPing(2, true));
1186*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
1187*6777b538SAndroid Build Coastguard Worker CreateMockWrite(write_ping),
1188*6777b538SAndroid Build Coastguard Worker };
1189*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, writes);
1190*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1191*6777b538SAndroid Build Coastguard Worker
1192*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1193*6777b538SAndroid Build Coastguard Worker
1194*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1195*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1196*6777b538SAndroid Build Coastguard Worker
1197*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
1198*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
1199*6777b538SAndroid Build Coastguard Worker MEDIUM, NetLogWithSource());
1200*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
1201*6777b538SAndroid Build Coastguard Worker test::StreamDelegateSendImmediate delegate(spdy_stream1, "");
1202*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate);
1203*6777b538SAndroid Build Coastguard Worker
1204*6777b538SAndroid Build Coastguard Worker // Flush the read completion task.
1205*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1206*6777b538SAndroid Build Coastguard Worker
1207*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
1208*6777b538SAndroid Build Coastguard Worker
1209*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
1210*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
1211*6777b538SAndroid Build Coastguard Worker }
1212*6777b538SAndroid Build Coastguard Worker
1213*6777b538SAndroid Build Coastguard Worker // Cause a ping to be sent out while producing a write. The write loop
1214*6777b538SAndroid Build Coastguard Worker // should handle this properly, i.e. another DoWriteLoop task should
1215*6777b538SAndroid Build Coastguard Worker // not be posted. This is a regression test for
1216*6777b538SAndroid Build Coastguard Worker // http://crbug.com/261043 .
TEST_F(SpdySessionTest,PingAndWriteLoop)1217*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, PingAndWriteLoop) {
1218*6777b538SAndroid Build Coastguard Worker session_deps_.enable_ping = true;
1219*6777b538SAndroid Build Coastguard Worker session_deps_.time_func = TheNearFuture;
1220*6777b538SAndroid Build Coastguard Worker
1221*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame write_ping(spdy_util_.ConstructSpdyPing(1, false));
1222*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
1223*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
1224*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
1225*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0), CreateMockWrite(write_ping, 1),
1226*6777b538SAndroid Build Coastguard Worker };
1227*6777b538SAndroid Build Coastguard Worker
1228*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
1229*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3) // EOF
1230*6777b538SAndroid Build Coastguard Worker };
1231*6777b538SAndroid Build Coastguard Worker
1232*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
1233*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1234*6777b538SAndroid Build Coastguard Worker
1235*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1236*6777b538SAndroid Build Coastguard Worker
1237*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1238*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1239*6777b538SAndroid Build Coastguard Worker
1240*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
1241*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
1242*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
1243*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate(spdy_stream);
1244*6777b538SAndroid Build Coastguard Worker spdy_stream->SetDelegate(&delegate);
1245*6777b538SAndroid Build Coastguard Worker
1246*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
1247*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
1248*6777b538SAndroid Build Coastguard Worker spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
1249*6777b538SAndroid Build Coastguard Worker
1250*6777b538SAndroid Build Coastguard Worker // Shift time so that a ping will be sent out.
1251*6777b538SAndroid Build Coastguard Worker g_time_delta = base::Seconds(11);
1252*6777b538SAndroid Build Coastguard Worker
1253*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1254*6777b538SAndroid Build Coastguard Worker session_->CloseSessionOnError(ERR_ABORTED, "Aborting");
1255*6777b538SAndroid Build Coastguard Worker
1256*6777b538SAndroid Build Coastguard Worker data.Resume();
1257*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1258*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
1259*6777b538SAndroid Build Coastguard Worker }
1260*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTestWithMockTime,DetectBrokenConnectionPing)1261*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTestWithMockTime, DetectBrokenConnectionPing) {
1262*6777b538SAndroid Build Coastguard Worker session_deps_.enable_ping = true;
1263*6777b538SAndroid Build Coastguard Worker
1264*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame read_ping1(spdy_util_.ConstructSpdyPing(1, true));
1265*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame read_ping2(spdy_util_.ConstructSpdyPing(2, true));
1266*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
1267*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 1),
1268*6777b538SAndroid Build Coastguard Worker CreateMockRead(read_ping1, 2),
1269*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 3),
1270*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 5),
1271*6777b538SAndroid Build Coastguard Worker CreateMockRead(read_ping2, 6),
1272*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 7),
1273*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 8) // EOF
1274*6777b538SAndroid Build Coastguard Worker };
1275*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame write_ping1(spdy_util_.ConstructSpdyPing(1, false));
1276*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame write_ping2(spdy_util_.ConstructSpdyPing(2, false));
1277*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(write_ping1, 0),
1278*6777b538SAndroid Build Coastguard Worker CreateMockWrite(write_ping2, 4)};
1279*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
1280*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1281*6777b538SAndroid Build Coastguard Worker
1282*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1283*6777b538SAndroid Build Coastguard Worker
1284*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1285*6777b538SAndroid Build Coastguard Worker TestNetworkQualityEstimator estimator;
1286*6777b538SAndroid Build Coastguard Worker
1287*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->set_network_quality_estimator(&estimator);
1288*6777b538SAndroid Build Coastguard Worker
1289*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1290*6777b538SAndroid Build Coastguard Worker
1291*6777b538SAndroid Build Coastguard Worker constexpr base::TimeDelta kHeartbeatInterval = base::Seconds(15);
1292*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(session_->IsBrokenConnectionDetectionEnabled());
1293*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
1294*6777b538SAndroid Build Coastguard Worker SPDY_BIDIRECTIONAL_STREAM, session_, test_url_, MEDIUM,
1295*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), true, kHeartbeatInterval);
1296*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
1297*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(session_->IsBrokenConnectionDetectionEnabled());
1298*6777b538SAndroid Build Coastguard Worker test::StreamDelegateSendImmediate delegate(spdy_stream1, "");
1299*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate);
1300*6777b538SAndroid Build Coastguard Worker
1301*6777b538SAndroid Build Coastguard Worker // Negative value means a preface ping will always be sent.
1302*6777b538SAndroid Build Coastguard Worker set_connection_at_risk_of_loss_time(base::Seconds(-1));
1303*6777b538SAndroid Build Coastguard Worker
1304*6777b538SAndroid Build Coastguard Worker // Initially there should be no PING in flight or check pending.
1305*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(ping_in_flight());
1306*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(check_ping_status_pending());
1307*6777b538SAndroid Build Coastguard Worker // After kHeartbeatInterval time has passed the first PING should be in flight
1308*6777b538SAndroid Build Coastguard Worker // and its status check pending.
1309*6777b538SAndroid Build Coastguard Worker FastForwardBy(kHeartbeatInterval);
1310*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(ping_in_flight());
1311*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(check_ping_status_pending());
1312*6777b538SAndroid Build Coastguard Worker
1313*6777b538SAndroid Build Coastguard Worker // Consume the PING ack.
1314*6777b538SAndroid Build Coastguard Worker data.Resume();
1315*6777b538SAndroid Build Coastguard Worker base::RunLoop run_loop;
1316*6777b538SAndroid Build Coastguard Worker base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
1317*6777b538SAndroid Build Coastguard Worker FROM_HERE, run_loop.QuitClosure());
1318*6777b538SAndroid Build Coastguard Worker run_loop.Run();
1319*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(ping_in_flight());
1320*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(check_ping_status_pending());
1321*6777b538SAndroid Build Coastguard Worker // Consume the pending check_ping_status callback, we should be back to the
1322*6777b538SAndroid Build Coastguard Worker // starting state.
1323*6777b538SAndroid Build Coastguard Worker FastForwardBy(NextMainThreadPendingTaskDelay());
1324*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(ping_in_flight());
1325*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(check_ping_status_pending());
1326*6777b538SAndroid Build Coastguard Worker
1327*6777b538SAndroid Build Coastguard Worker // Unblock data and trigger the next heartbeat.
1328*6777b538SAndroid Build Coastguard Worker data.Resume();
1329*6777b538SAndroid Build Coastguard Worker FastForwardBy(NextMainThreadPendingTaskDelay());
1330*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(ping_in_flight());
1331*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(check_ping_status_pending());
1332*6777b538SAndroid Build Coastguard Worker
1333*6777b538SAndroid Build Coastguard Worker // Consume PING ack and check_ping_status callback.
1334*6777b538SAndroid Build Coastguard Worker data.Resume();
1335*6777b538SAndroid Build Coastguard Worker FastForwardBy(NextMainThreadPendingTaskDelay());
1336*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(ping_in_flight());
1337*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(check_ping_status_pending());
1338*6777b538SAndroid Build Coastguard Worker
1339*6777b538SAndroid Build Coastguard Worker data.Resume();
1340*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1341*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
1342*6777b538SAndroid Build Coastguard Worker
1343*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(MainThreadIsIdle());
1344*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
1345*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
1346*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
1347*6777b538SAndroid Build Coastguard Worker
1348*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
1349*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
1350*6777b538SAndroid Build Coastguard Worker
1351*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2u, estimator.ping_rtt_received_count());
1352*6777b538SAndroid Build Coastguard Worker }
1353*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,StreamIdSpaceExhausted)1354*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, StreamIdSpaceExhausted) {
1355*6777b538SAndroid Build Coastguard Worker // Test setup: |stream_hi_water_mark_| and |max_concurrent_streams_| are
1356*6777b538SAndroid Build Coastguard Worker // fixed to allow for two stream ID assignments, and three concurrent
1357*6777b538SAndroid Build Coastguard Worker // streams. Four streams are started, and two are activated. Verify the
1358*6777b538SAndroid Build Coastguard Worker // session goes away, and that the created (but not activated) and
1359*6777b538SAndroid Build Coastguard Worker // stalled streams are aborted. Also verify the activated streams complete,
1360*6777b538SAndroid Build Coastguard Worker // at which point the session closes.
1361*6777b538SAndroid Build Coastguard Worker
1362*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
1363*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, kLastStreamId - 2, MEDIUM));
1364*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(
1365*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, kLastStreamId, MEDIUM));
1366*6777b538SAndroid Build Coastguard Worker
1367*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
1368*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
1369*6777b538SAndroid Build Coastguard Worker };
1370*6777b538SAndroid Build Coastguard Worker
1371*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp1(
1372*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, kLastStreamId - 2));
1373*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp2(
1374*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, kLastStreamId));
1375*6777b538SAndroid Build Coastguard Worker
1376*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body1(
1377*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(kLastStreamId - 2, true));
1378*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body2(
1379*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(kLastStreamId, true));
1380*6777b538SAndroid Build Coastguard Worker
1381*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
1382*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp1, 2), CreateMockRead(resp2, 3),
1383*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 4), CreateMockRead(body1, 5),
1384*6777b538SAndroid Build Coastguard Worker CreateMockRead(body2, 6), MockRead(ASYNC, 0, 7) // EOF
1385*6777b538SAndroid Build Coastguard Worker };
1386*6777b538SAndroid Build Coastguard Worker
1387*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
1388*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1389*6777b538SAndroid Build Coastguard Worker
1390*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1391*6777b538SAndroid Build Coastguard Worker
1392*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1393*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1394*6777b538SAndroid Build Coastguard Worker
1395*6777b538SAndroid Build Coastguard Worker // Fix stream_hi_water_mark_ to allow for two stream activations.
1396*6777b538SAndroid Build Coastguard Worker set_stream_hi_water_mark(kLastStreamId - 2);
1397*6777b538SAndroid Build Coastguard Worker // Fix max_concurrent_streams to allow for three stream creations.
1398*6777b538SAndroid Build Coastguard Worker set_max_concurrent_streams(3);
1399*6777b538SAndroid Build Coastguard Worker
1400*6777b538SAndroid Build Coastguard Worker // Create three streams synchronously, and begin a fourth (which is stalled).
1401*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream1 =
1402*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
1403*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
1404*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(stream1);
1405*6777b538SAndroid Build Coastguard Worker stream1->SetDelegate(&delegate1);
1406*6777b538SAndroid Build Coastguard Worker
1407*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream2 =
1408*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
1409*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
1410*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate2(stream2);
1411*6777b538SAndroid Build Coastguard Worker stream2->SetDelegate(&delegate2);
1412*6777b538SAndroid Build Coastguard Worker
1413*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream3 =
1414*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
1415*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
1416*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate3(stream3);
1417*6777b538SAndroid Build Coastguard Worker stream3->SetDelegate(&delegate3);
1418*6777b538SAndroid Build Coastguard Worker
1419*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest request4;
1420*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback4;
1421*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING,
1422*6777b538SAndroid Build Coastguard Worker request4.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_,
1423*6777b538SAndroid Build Coastguard Worker test_url_, false, MEDIUM, SocketTag(),
1424*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), callback4.callback(),
1425*6777b538SAndroid Build Coastguard Worker TRAFFIC_ANNOTATION_FOR_TESTS));
1426*6777b538SAndroid Build Coastguard Worker
1427*6777b538SAndroid Build Coastguard Worker // Streams 1-3 were created. 4th is stalled. No streams are active yet.
1428*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_active_streams());
1429*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, num_created_streams());
1430*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));
1431*6777b538SAndroid Build Coastguard Worker
1432*6777b538SAndroid Build Coastguard Worker // Activate stream 1. One ID remains available.
1433*6777b538SAndroid Build Coastguard Worker stream1->SendRequestHeaders(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl),
1434*6777b538SAndroid Build Coastguard Worker NO_MORE_DATA_TO_SEND);
1435*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1436*6777b538SAndroid Build Coastguard Worker
1437*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kLastStreamId - 2u, stream1->stream_id());
1438*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, num_active_streams());
1439*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2u, num_created_streams());
1440*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));
1441*6777b538SAndroid Build Coastguard Worker
1442*6777b538SAndroid Build Coastguard Worker // Activate stream 2. ID space is exhausted.
1443*6777b538SAndroid Build Coastguard Worker stream2->SendRequestHeaders(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl),
1444*6777b538SAndroid Build Coastguard Worker NO_MORE_DATA_TO_SEND);
1445*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1446*6777b538SAndroid Build Coastguard Worker
1447*6777b538SAndroid Build Coastguard Worker // Active streams remain active.
1448*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kLastStreamId, stream2->stream_id());
1449*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2u, num_active_streams());
1450*6777b538SAndroid Build Coastguard Worker
1451*6777b538SAndroid Build Coastguard Worker // Session is going away. Created and stalled streams were aborted.
1452*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsGoingAway());
1453*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate3.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
1454*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(callback4.WaitForResult(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
1455*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_created_streams());
1456*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));
1457*6777b538SAndroid Build Coastguard Worker
1458*6777b538SAndroid Build Coastguard Worker // Read responses on remaining active streams.
1459*6777b538SAndroid Build Coastguard Worker data.Resume();
1460*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1461*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate1.WaitForClose(), IsOk());
1462*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kUploadData, delegate1.TakeReceivedData());
1463*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate2.WaitForClose(), IsOk());
1464*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kUploadData, delegate2.TakeReceivedData());
1465*6777b538SAndroid Build Coastguard Worker
1466*6777b538SAndroid Build Coastguard Worker // Session was destroyed.
1467*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
1468*6777b538SAndroid Build Coastguard Worker }
1469*6777b538SAndroid Build Coastguard Worker
1470*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/481009.
TEST_F(SpdySessionTest,MaxConcurrentStreamsZero)1471*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, MaxConcurrentStreamsZero) {
1472*6777b538SAndroid Build Coastguard Worker
1473*6777b538SAndroid Build Coastguard Worker // Receive SETTINGS frame that sets max_concurrent_streams to zero.
1474*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings_zero;
1475*6777b538SAndroid Build Coastguard Worker settings_zero[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = 0;
1476*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_frame_zero(
1477*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(settings_zero));
1478*6777b538SAndroid Build Coastguard Worker
1479*6777b538SAndroid Build Coastguard Worker // Acknowledge it.
1480*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_ack0(
1481*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettingsAck());
1482*6777b538SAndroid Build Coastguard Worker
1483*6777b538SAndroid Build Coastguard Worker // Receive SETTINGS frame that sets max_concurrent_streams to one.
1484*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings_one;
1485*6777b538SAndroid Build Coastguard Worker settings_one[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = 1;
1486*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_frame_one(
1487*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(settings_one));
1488*6777b538SAndroid Build Coastguard Worker
1489*6777b538SAndroid Build Coastguard Worker // Acknowledge it.
1490*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_ack1(
1491*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettingsAck());
1492*6777b538SAndroid Build Coastguard Worker
1493*6777b538SAndroid Build Coastguard Worker // Request and response.
1494*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
1495*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
1496*6777b538SAndroid Build Coastguard Worker
1497*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp(
1498*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1499*6777b538SAndroid Build Coastguard Worker
1500*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
1501*6777b538SAndroid Build Coastguard Worker
1502*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {CreateMockRead(settings_frame_zero, 0),
1503*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
1504*6777b538SAndroid Build Coastguard Worker CreateMockRead(settings_frame_one, 3),
1505*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp, 6),
1506*6777b538SAndroid Build Coastguard Worker CreateMockRead(body, 7),
1507*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 8)};
1508*6777b538SAndroid Build Coastguard Worker
1509*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(settings_ack0, 1),
1510*6777b538SAndroid Build Coastguard Worker CreateMockWrite(settings_ack1, 4),
1511*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 5)};
1512*6777b538SAndroid Build Coastguard Worker
1513*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
1514*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1515*6777b538SAndroid Build Coastguard Worker
1516*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1517*6777b538SAndroid Build Coastguard Worker
1518*6777b538SAndroid Build Coastguard Worker // Create session.
1519*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1520*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1521*6777b538SAndroid Build Coastguard Worker
1522*6777b538SAndroid Build Coastguard Worker // Receive SETTINGS frame that sets max_concurrent_streams to zero.
1523*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1524*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, max_concurrent_streams());
1525*6777b538SAndroid Build Coastguard Worker
1526*6777b538SAndroid Build Coastguard Worker // Start request.
1527*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest request;
1528*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback;
1529*6777b538SAndroid Build Coastguard Worker int rv =
1530*6777b538SAndroid Build Coastguard Worker request.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_,
1531*6777b538SAndroid Build Coastguard Worker false, MEDIUM, SocketTag(), NetLogWithSource(),
1532*6777b538SAndroid Build Coastguard Worker callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
1533*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1534*6777b538SAndroid Build Coastguard Worker
1535*6777b538SAndroid Build Coastguard Worker // Stream is stalled.
1536*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));
1537*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_created_streams());
1538*6777b538SAndroid Build Coastguard Worker
1539*6777b538SAndroid Build Coastguard Worker // Receive SETTINGS frame that sets max_concurrent_streams to one.
1540*6777b538SAndroid Build Coastguard Worker data.Resume();
1541*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1542*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, max_concurrent_streams());
1543*6777b538SAndroid Build Coastguard Worker
1544*6777b538SAndroid Build Coastguard Worker // Stream is created.
1545*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));
1546*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, num_created_streams());
1547*6777b538SAndroid Build Coastguard Worker
1548*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(callback.WaitForResult(), IsOk());
1549*6777b538SAndroid Build Coastguard Worker
1550*6777b538SAndroid Build Coastguard Worker // Send request.
1551*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream = request.ReleaseStream();
1552*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate(stream);
1553*6777b538SAndroid Build Coastguard Worker stream->SetDelegate(&delegate);
1554*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
1555*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
1556*6777b538SAndroid Build Coastguard Worker stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
1557*6777b538SAndroid Build Coastguard Worker
1558*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate.WaitForClose(), IsOk());
1559*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("hello!", delegate.TakeReceivedData());
1560*6777b538SAndroid Build Coastguard Worker
1561*6777b538SAndroid Build Coastguard Worker // Finish async network reads/writes.
1562*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1563*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
1564*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
1565*6777b538SAndroid Build Coastguard Worker
1566*6777b538SAndroid Build Coastguard Worker // Session is destroyed.
1567*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
1568*6777b538SAndroid Build Coastguard Worker }
1569*6777b538SAndroid Build Coastguard Worker
1570*6777b538SAndroid Build Coastguard Worker // Verifies that an unstalled pending stream creation racing with a new stream
1571*6777b538SAndroid Build Coastguard Worker // creation doesn't violate the maximum stream concurrency. Regression test for
1572*6777b538SAndroid Build Coastguard Worker // crbug.com/373858.
TEST_F(SpdySessionTest,UnstallRacesWithStreamCreation)1573*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, UnstallRacesWithStreamCreation) {
1574*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
1575*6777b538SAndroid Build Coastguard Worker MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
1576*6777b538SAndroid Build Coastguard Worker };
1577*6777b538SAndroid Build Coastguard Worker
1578*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
1579*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1580*6777b538SAndroid Build Coastguard Worker
1581*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1582*6777b538SAndroid Build Coastguard Worker
1583*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1584*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1585*6777b538SAndroid Build Coastguard Worker
1586*6777b538SAndroid Build Coastguard Worker // Fix max_concurrent_streams to allow for one open stream.
1587*6777b538SAndroid Build Coastguard Worker set_max_concurrent_streams(1);
1588*6777b538SAndroid Build Coastguard Worker
1589*6777b538SAndroid Build Coastguard Worker // Create two streams: one synchronously, and one which stalls.
1590*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream1 =
1591*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
1592*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
1593*6777b538SAndroid Build Coastguard Worker
1594*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest request2;
1595*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback2;
1596*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING,
1597*6777b538SAndroid Build Coastguard Worker request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_,
1598*6777b538SAndroid Build Coastguard Worker test_url_, false, MEDIUM, SocketTag(),
1599*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), callback2.callback(),
1600*6777b538SAndroid Build Coastguard Worker TRAFFIC_ANNOTATION_FOR_TESTS));
1601*6777b538SAndroid Build Coastguard Worker
1602*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, num_created_streams());
1603*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));
1604*6777b538SAndroid Build Coastguard Worker
1605*6777b538SAndroid Build Coastguard Worker // Cancel the first stream. A callback to unstall the second stream was
1606*6777b538SAndroid Build Coastguard Worker // posted. Don't run it yet.
1607*6777b538SAndroid Build Coastguard Worker stream1->Cancel(ERR_ABORTED);
1608*6777b538SAndroid Build Coastguard Worker
1609*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_created_streams());
1610*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));
1611*6777b538SAndroid Build Coastguard Worker
1612*6777b538SAndroid Build Coastguard Worker // Create a third stream prior to the second stream's callback.
1613*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream3 =
1614*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
1615*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
1616*6777b538SAndroid Build Coastguard Worker
1617*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, num_created_streams());
1618*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));
1619*6777b538SAndroid Build Coastguard Worker
1620*6777b538SAndroid Build Coastguard Worker // Now run the message loop. The unstalled stream will re-stall itself.
1621*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1622*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, num_created_streams());
1623*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));
1624*6777b538SAndroid Build Coastguard Worker
1625*6777b538SAndroid Build Coastguard Worker // Cancel the third stream and run the message loop. Verify that the second
1626*6777b538SAndroid Build Coastguard Worker // stream creation now completes.
1627*6777b538SAndroid Build Coastguard Worker stream3->Cancel(ERR_ABORTED);
1628*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1629*6777b538SAndroid Build Coastguard Worker
1630*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, num_created_streams());
1631*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));
1632*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(callback2.WaitForResult(), IsOk());
1633*6777b538SAndroid Build Coastguard Worker }
1634*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTestWithMockTime,FailedPing)1635*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTestWithMockTime, FailedPing) {
1636*6777b538SAndroid Build Coastguard Worker session_deps_.enable_ping = true;
1637*6777b538SAndroid Build Coastguard Worker session_deps_.time_func = TheNearFuture;
1638*6777b538SAndroid Build Coastguard Worker
1639*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; // Stall forever.
1640*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame write_ping(spdy_util_.ConstructSpdyPing(1, false));
1641*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
1642*6777b538SAndroid Build Coastguard Worker 0, spdy::ERROR_CODE_PROTOCOL_ERROR, "Failed ping."));
1643*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(write_ping), CreateMockWrite(goaway)};
1644*6777b538SAndroid Build Coastguard Worker
1645*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, writes);
1646*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1647*6777b538SAndroid Build Coastguard Worker
1648*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1649*6777b538SAndroid Build Coastguard Worker
1650*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1651*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1652*6777b538SAndroid Build Coastguard Worker
1653*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
1654*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
1655*6777b538SAndroid Build Coastguard Worker MEDIUM, NetLogWithSource());
1656*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
1657*6777b538SAndroid Build Coastguard Worker test::StreamDelegateSendImmediate delegate(spdy_stream1, "");
1658*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate);
1659*6777b538SAndroid Build Coastguard Worker
1660*6777b538SAndroid Build Coastguard Worker // Negative value means a preface ping will always be sent.
1661*6777b538SAndroid Build Coastguard Worker set_connection_at_risk_of_loss_time(base::Seconds(-1));
1662*6777b538SAndroid Build Coastguard Worker
1663*6777b538SAndroid Build Coastguard Worker // Send a PING frame. This posts CheckPingStatus() with delay.
1664*6777b538SAndroid Build Coastguard Worker MaybeSendPrefacePing();
1665*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(ping_in_flight());
1666*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2u, next_ping_id());
1667*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(check_ping_status_pending());
1668*6777b538SAndroid Build Coastguard Worker
1669*6777b538SAndroid Build Coastguard Worker // Assert session is not closed.
1670*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsAvailable());
1671*6777b538SAndroid Build Coastguard Worker EXPECT_LT(0u, num_active_streams() + num_created_streams());
1672*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
1673*6777b538SAndroid Build Coastguard Worker
1674*6777b538SAndroid Build Coastguard Worker // Run CheckPingStatus() and make it believe hung_interval has passed.
1675*6777b538SAndroid Build Coastguard Worker g_time_delta = base::Seconds(15);
1676*6777b538SAndroid Build Coastguard Worker FastForwardUntilNoTasksRemain();
1677*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1678*6777b538SAndroid Build Coastguard Worker
1679*6777b538SAndroid Build Coastguard Worker // Since no response to PING has been received,
1680*6777b538SAndroid Build Coastguard Worker // CheckPingStatus() closes the connection.
1681*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(MainThreadIsIdle());
1682*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
1683*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
1684*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
1685*6777b538SAndroid Build Coastguard Worker
1686*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
1687*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
1688*6777b538SAndroid Build Coastguard Worker }
1689*6777b538SAndroid Build Coastguard Worker
1690*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/784975.
TEST_F(SpdySessionTestWithMockTime,NoPingSentWhenCheckPingPending)1691*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTestWithMockTime, NoPingSentWhenCheckPingPending) {
1692*6777b538SAndroid Build Coastguard Worker session_deps_.enable_ping = true;
1693*6777b538SAndroid Build Coastguard Worker session_deps_.time_func = TheNearFuture;
1694*6777b538SAndroid Build Coastguard Worker
1695*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame read_ping(spdy_util_.ConstructSpdyPing(1, true));
1696*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {CreateMockRead(read_ping, 1),
1697*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
1698*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3)};
1699*6777b538SAndroid Build Coastguard Worker
1700*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame write_ping0(spdy_util_.ConstructSpdyPing(1, false));
1701*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(write_ping0, 0)};
1702*6777b538SAndroid Build Coastguard Worker
1703*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
1704*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1705*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1706*6777b538SAndroid Build Coastguard Worker
1707*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1708*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1709*6777b538SAndroid Build Coastguard Worker
1710*6777b538SAndroid Build Coastguard Worker // Negative value means a preface ping will always be sent.
1711*6777b538SAndroid Build Coastguard Worker set_connection_at_risk_of_loss_time(base::Seconds(-1));
1712*6777b538SAndroid Build Coastguard Worker
1713*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
1714*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
1715*6777b538SAndroid Build Coastguard Worker MEDIUM, NetLogWithSource());
1716*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
1717*6777b538SAndroid Build Coastguard Worker test::StreamDelegateSendImmediate delegate(spdy_stream1, "");
1718*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate);
1719*6777b538SAndroid Build Coastguard Worker
1720*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(ping_in_flight());
1721*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, next_ping_id());
1722*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(check_ping_status_pending());
1723*6777b538SAndroid Build Coastguard Worker
1724*6777b538SAndroid Build Coastguard Worker // Send preface ping and post CheckPingStatus() task with delay.
1725*6777b538SAndroid Build Coastguard Worker MaybeSendPrefacePing();
1726*6777b538SAndroid Build Coastguard Worker
1727*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(ping_in_flight());
1728*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2u, next_ping_id());
1729*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(check_ping_status_pending());
1730*6777b538SAndroid Build Coastguard Worker
1731*6777b538SAndroid Build Coastguard Worker // Read PING ACK.
1732*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1733*6777b538SAndroid Build Coastguard Worker
1734*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(ping_in_flight());
1735*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(check_ping_status_pending());
1736*6777b538SAndroid Build Coastguard Worker
1737*6777b538SAndroid Build Coastguard Worker // Fast forward mock time so that normally another ping would be sent out.
1738*6777b538SAndroid Build Coastguard Worker // However, since CheckPingStatus() is still pending, no new ping is sent.
1739*6777b538SAndroid Build Coastguard Worker g_time_delta = base::Seconds(15);
1740*6777b538SAndroid Build Coastguard Worker MaybeSendPrefacePing();
1741*6777b538SAndroid Build Coastguard Worker
1742*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(ping_in_flight());
1743*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2u, next_ping_id());
1744*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(check_ping_status_pending());
1745*6777b538SAndroid Build Coastguard Worker
1746*6777b538SAndroid Build Coastguard Worker // Run CheckPingStatus().
1747*6777b538SAndroid Build Coastguard Worker FastForwardUntilNoTasksRemain();
1748*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1749*6777b538SAndroid Build Coastguard Worker
1750*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(check_ping_status_pending());
1751*6777b538SAndroid Build Coastguard Worker
1752*6777b538SAndroid Build Coastguard Worker // Read EOF.
1753*6777b538SAndroid Build Coastguard Worker data.Resume();
1754*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
1755*6777b538SAndroid Build Coastguard Worker
1756*6777b538SAndroid Build Coastguard Worker // Finish going away.
1757*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1758*6777b538SAndroid Build Coastguard Worker
1759*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
1760*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
1761*6777b538SAndroid Build Coastguard Worker
1762*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
1763*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
1764*6777b538SAndroid Build Coastguard Worker }
1765*6777b538SAndroid Build Coastguard Worker
1766*6777b538SAndroid Build Coastguard Worker // Request kH2InitialMaxConcurrentStreamsParam.Get() + 1 streams. Receive a
1767*6777b538SAndroid Build Coastguard Worker // settings frame increasing the max concurrent streams by 1. Make
1768*6777b538SAndroid Build Coastguard Worker // sure nothing blows up. This is a regression test for
1769*6777b538SAndroid Build Coastguard Worker // http://crbug.com/57331 .
TEST_F(SpdySessionTest,OnSettings)1770*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, OnSettings) {
1771*6777b538SAndroid Build Coastguard Worker const spdy::SpdySettingsId kSpdySettingsId =
1772*6777b538SAndroid Build Coastguard Worker spdy::SETTINGS_MAX_CONCURRENT_STREAMS;
1773*6777b538SAndroid Build Coastguard Worker
1774*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap new_settings;
1775*6777b538SAndroid Build Coastguard Worker const uint32_t max_concurrent_streams =
1776*6777b538SAndroid Build Coastguard Worker kH2InitialMaxConcurrentStreams.Get() + 1;
1777*6777b538SAndroid Build Coastguard Worker new_settings[kSpdySettingsId] = max_concurrent_streams;
1778*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_frame(
1779*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(new_settings));
1780*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
1781*6777b538SAndroid Build Coastguard Worker CreateMockRead(settings_frame, 0), MockRead(ASYNC, ERR_IO_PENDING, 2),
1782*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3),
1783*6777b538SAndroid Build Coastguard Worker };
1784*6777b538SAndroid Build Coastguard Worker
1785*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
1786*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(settings_ack, 1)};
1787*6777b538SAndroid Build Coastguard Worker
1788*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
1789*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1790*6777b538SAndroid Build Coastguard Worker
1791*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1792*6777b538SAndroid Build Coastguard Worker
1793*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1794*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1795*6777b538SAndroid Build Coastguard Worker
1796*6777b538SAndroid Build Coastguard Worker // Create the maximum number of concurrent streams.
1797*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < kH2InitialMaxConcurrentStreams.Get(); ++i) {
1798*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
1799*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_,
1800*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
1801*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream);
1802*6777b538SAndroid Build Coastguard Worker }
1803*6777b538SAndroid Build Coastguard Worker
1804*6777b538SAndroid Build Coastguard Worker StreamReleaserCallback stream_releaser;
1805*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest request;
1806*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(ERR_IO_PENDING,
1807*6777b538SAndroid Build Coastguard Worker request.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
1808*6777b538SAndroid Build Coastguard Worker false, MEDIUM, SocketTag(), NetLogWithSource(),
1809*6777b538SAndroid Build Coastguard Worker stream_releaser.MakeCallback(&request),
1810*6777b538SAndroid Build Coastguard Worker TRAFFIC_ANNOTATION_FOR_TESTS));
1811*6777b538SAndroid Build Coastguard Worker
1812*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1813*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(stream_releaser.WaitForResult(), IsOk());
1814*6777b538SAndroid Build Coastguard Worker
1815*6777b538SAndroid Build Coastguard Worker data.Resume();
1816*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1817*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
1818*6777b538SAndroid Build Coastguard Worker
1819*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
1820*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
1821*6777b538SAndroid Build Coastguard Worker }
1822*6777b538SAndroid Build Coastguard Worker
1823*6777b538SAndroid Build Coastguard Worker // Create one more stream than maximum number of concurrent streams,
1824*6777b538SAndroid Build Coastguard Worker // so that one of them is pending. Cancel one stream, which should trigger the
1825*6777b538SAndroid Build Coastguard Worker // creation of the pending stream. Then cancel that one immediately as well,
1826*6777b538SAndroid Build Coastguard Worker // and make sure this does not lead to a crash.
1827*6777b538SAndroid Build Coastguard Worker // This is a regression test for https://crbug.com/63532.
TEST_F(SpdySessionTest,CancelPendingCreateStream)1828*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CancelPendingCreateStream) {
1829*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
1830*6777b538SAndroid Build Coastguard Worker MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
1831*6777b538SAndroid Build Coastguard Worker };
1832*6777b538SAndroid Build Coastguard Worker
1833*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
1834*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1835*6777b538SAndroid Build Coastguard Worker
1836*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1837*6777b538SAndroid Build Coastguard Worker
1838*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1839*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1840*6777b538SAndroid Build Coastguard Worker
1841*6777b538SAndroid Build Coastguard Worker // Leave room for only one more stream to be created.
1842*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < kH2InitialMaxConcurrentStreams.Get() - 1; ++i) {
1843*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
1844*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_,
1845*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
1846*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream);
1847*6777b538SAndroid Build Coastguard Worker }
1848*6777b538SAndroid Build Coastguard Worker
1849*6777b538SAndroid Build Coastguard Worker // Create 2 more streams. First will succeed. Second will be pending.
1850*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
1851*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
1852*6777b538SAndroid Build Coastguard Worker MEDIUM, NetLogWithSource());
1853*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
1854*6777b538SAndroid Build Coastguard Worker
1855*6777b538SAndroid Build Coastguard Worker // Use unique_ptr to let us invalidate the memory when we want to, to trigger
1856*6777b538SAndroid Build Coastguard Worker // an error in memory corruption detectors if the callback is invoked when
1857*6777b538SAndroid Build Coastguard Worker // it's not supposed to be.
1858*6777b538SAndroid Build Coastguard Worker auto callback = std::make_unique<TestCompletionCallback>();
1859*6777b538SAndroid Build Coastguard Worker
1860*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest request;
1861*6777b538SAndroid Build Coastguard Worker ASSERT_THAT(
1862*6777b538SAndroid Build Coastguard Worker request.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
1863*6777b538SAndroid Build Coastguard Worker false, MEDIUM, SocketTag(), NetLogWithSource(),
1864*6777b538SAndroid Build Coastguard Worker callback->callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
1865*6777b538SAndroid Build Coastguard Worker IsError(ERR_IO_PENDING));
1866*6777b538SAndroid Build Coastguard Worker
1867*6777b538SAndroid Build Coastguard Worker // Release the first one, this will allow the second to be created.
1868*6777b538SAndroid Build Coastguard Worker spdy_stream1->Cancel(ERR_ABORTED);
1869*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
1870*6777b538SAndroid Build Coastguard Worker
1871*6777b538SAndroid Build Coastguard Worker request.CancelRequest();
1872*6777b538SAndroid Build Coastguard Worker callback.reset();
1873*6777b538SAndroid Build Coastguard Worker
1874*6777b538SAndroid Build Coastguard Worker // Should not crash when running the pending callback.
1875*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1876*6777b538SAndroid Build Coastguard Worker }
1877*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,ChangeStreamRequestPriority)1878*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, ChangeStreamRequestPriority) {
1879*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
1880*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING) // Stall forever.
1881*6777b538SAndroid Build Coastguard Worker };
1882*6777b538SAndroid Build Coastguard Worker
1883*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
1884*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1885*6777b538SAndroid Build Coastguard Worker
1886*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1887*6777b538SAndroid Build Coastguard Worker
1888*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1889*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1890*6777b538SAndroid Build Coastguard Worker
1891*6777b538SAndroid Build Coastguard Worker set_max_concurrent_streams(1);
1892*6777b538SAndroid Build Coastguard Worker
1893*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback1;
1894*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest request1;
1895*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(OK, request1.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_,
1896*6777b538SAndroid Build Coastguard Worker test_url_, false, LOWEST, SocketTag(),
1897*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), callback1.callback(),
1898*6777b538SAndroid Build Coastguard Worker TRAFFIC_ANNOTATION_FOR_TESTS));
1899*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback2;
1900*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest request2;
1901*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(ERR_IO_PENDING,
1902*6777b538SAndroid Build Coastguard Worker request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_,
1903*6777b538SAndroid Build Coastguard Worker test_url_, false, LOWEST, SocketTag(),
1904*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), callback2.callback(),
1905*6777b538SAndroid Build Coastguard Worker TRAFFIC_ANNOTATION_FOR_TESTS));
1906*6777b538SAndroid Build Coastguard Worker
1907*6777b538SAndroid Build Coastguard Worker request1.SetPriority(HIGHEST);
1908*6777b538SAndroid Build Coastguard Worker request2.SetPriority(MEDIUM);
1909*6777b538SAndroid Build Coastguard Worker
1910*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(0u, pending_create_stream_queue_size(HIGHEST));
1911*6777b538SAndroid Build Coastguard Worker // Priority of queued request is changed.
1912*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(1u, pending_create_stream_queue_size(MEDIUM));
1913*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(0u, pending_create_stream_queue_size(LOWEST));
1914*6777b538SAndroid Build Coastguard Worker
1915*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream1 = request1.ReleaseStream();
1916*6777b538SAndroid Build Coastguard Worker // Priority of stream is updated if request has been fulfilled.
1917*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(HIGHEST, stream1->priority());
1918*6777b538SAndroid Build Coastguard Worker }
1919*6777b538SAndroid Build Coastguard Worker
1920*6777b538SAndroid Build Coastguard Worker // Attempts to extract a NetLogSource from a set of event parameters. Returns
1921*6777b538SAndroid Build Coastguard Worker // true and writes the result to |source| on success. Returns false and
1922*6777b538SAndroid Build Coastguard Worker // makes |source| an invalid source on failure.
NetLogSourceFromEventParameters(const base::Value::Dict * event_params,NetLogSource * source)1923*6777b538SAndroid Build Coastguard Worker bool NetLogSourceFromEventParameters(const base::Value::Dict* event_params,
1924*6777b538SAndroid Build Coastguard Worker NetLogSource* source) {
1925*6777b538SAndroid Build Coastguard Worker const base::Value::Dict* source_dict = nullptr;
1926*6777b538SAndroid Build Coastguard Worker int source_id = -1;
1927*6777b538SAndroid Build Coastguard Worker int source_type = static_cast<int>(NetLogSourceType::COUNT);
1928*6777b538SAndroid Build Coastguard Worker if (!event_params) {
1929*6777b538SAndroid Build Coastguard Worker *source = NetLogSource();
1930*6777b538SAndroid Build Coastguard Worker return false;
1931*6777b538SAndroid Build Coastguard Worker }
1932*6777b538SAndroid Build Coastguard Worker source_dict = event_params->FindDict("source_dependency");
1933*6777b538SAndroid Build Coastguard Worker if (!source_dict) {
1934*6777b538SAndroid Build Coastguard Worker *source = NetLogSource();
1935*6777b538SAndroid Build Coastguard Worker return false;
1936*6777b538SAndroid Build Coastguard Worker }
1937*6777b538SAndroid Build Coastguard Worker std::optional<int> opt_int;
1938*6777b538SAndroid Build Coastguard Worker opt_int = source_dict->FindInt("id");
1939*6777b538SAndroid Build Coastguard Worker if (!opt_int) {
1940*6777b538SAndroid Build Coastguard Worker *source = NetLogSource();
1941*6777b538SAndroid Build Coastguard Worker return false;
1942*6777b538SAndroid Build Coastguard Worker }
1943*6777b538SAndroid Build Coastguard Worker source_id = opt_int.value();
1944*6777b538SAndroid Build Coastguard Worker opt_int = source_dict->FindInt("type");
1945*6777b538SAndroid Build Coastguard Worker if (!opt_int) {
1946*6777b538SAndroid Build Coastguard Worker *source = NetLogSource();
1947*6777b538SAndroid Build Coastguard Worker return false;
1948*6777b538SAndroid Build Coastguard Worker }
1949*6777b538SAndroid Build Coastguard Worker source_type = opt_int.value();
1950*6777b538SAndroid Build Coastguard Worker
1951*6777b538SAndroid Build Coastguard Worker DCHECK_GE(source_id, 0);
1952*6777b538SAndroid Build Coastguard Worker DCHECK_LT(source_type, static_cast<int>(NetLogSourceType::COUNT));
1953*6777b538SAndroid Build Coastguard Worker *source = NetLogSource(static_cast<NetLogSourceType>(source_type), source_id);
1954*6777b538SAndroid Build Coastguard Worker return true;
1955*6777b538SAndroid Build Coastguard Worker }
1956*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,Initialize)1957*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, Initialize) {
1958*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
1959*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 0) // EOF
1960*6777b538SAndroid Build Coastguard Worker };
1961*6777b538SAndroid Build Coastguard Worker
1962*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
1963*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1964*6777b538SAndroid Build Coastguard Worker
1965*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
1966*6777b538SAndroid Build Coastguard Worker
1967*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
1968*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
1969*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
1970*6777b538SAndroid Build Coastguard Worker
1971*6777b538SAndroid Build Coastguard Worker // Flush the read completion task.
1972*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1973*6777b538SAndroid Build Coastguard Worker
1974*6777b538SAndroid Build Coastguard Worker auto entries = net_log_observer_.GetEntries();
1975*6777b538SAndroid Build Coastguard Worker EXPECT_LT(0u, entries.size());
1976*6777b538SAndroid Build Coastguard Worker
1977*6777b538SAndroid Build Coastguard Worker // Check that we logged HTTP2_SESSION_INITIALIZED correctly.
1978*6777b538SAndroid Build Coastguard Worker int pos = ExpectLogContainsSomewhere(
1979*6777b538SAndroid Build Coastguard Worker entries, 0, NetLogEventType::HTTP2_SESSION_INITIALIZED,
1980*6777b538SAndroid Build Coastguard Worker NetLogEventPhase::NONE);
1981*6777b538SAndroid Build Coastguard Worker EXPECT_LT(0, pos);
1982*6777b538SAndroid Build Coastguard Worker
1983*6777b538SAndroid Build Coastguard Worker NetLogSource socket_source;
1984*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(
1985*6777b538SAndroid Build Coastguard Worker NetLogSourceFromEventParameters(&entries[pos].params, &socket_source));
1986*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(socket_source.IsValid());
1987*6777b538SAndroid Build Coastguard Worker EXPECT_NE(net_log_with_source_.source().id, socket_source.id);
1988*6777b538SAndroid Build Coastguard Worker }
1989*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,NetLogOnSessionGoaway)1990*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, NetLogOnSessionGoaway) {
1991*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
1992*6777b538SAndroid Build Coastguard Worker 42, spdy::ERROR_CODE_ENHANCE_YOUR_CALM, "foo"));
1993*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
1994*6777b538SAndroid Build Coastguard Worker CreateMockRead(goaway), MockRead(SYNCHRONOUS, 0, 0) // EOF
1995*6777b538SAndroid Build Coastguard Worker };
1996*6777b538SAndroid Build Coastguard Worker
1997*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
1998*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
1999*6777b538SAndroid Build Coastguard Worker
2000*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2001*6777b538SAndroid Build Coastguard Worker
2002*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2003*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2004*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
2005*6777b538SAndroid Build Coastguard Worker
2006*6777b538SAndroid Build Coastguard Worker // Flush the read completion task.
2007*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2008*6777b538SAndroid Build Coastguard Worker
2009*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
2010*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
2011*6777b538SAndroid Build Coastguard Worker
2012*6777b538SAndroid Build Coastguard Worker // Check that the NetLog was filled reasonably.
2013*6777b538SAndroid Build Coastguard Worker auto entries = net_log_observer_.GetEntries();
2014*6777b538SAndroid Build Coastguard Worker EXPECT_LT(0u, entries.size());
2015*6777b538SAndroid Build Coastguard Worker
2016*6777b538SAndroid Build Coastguard Worker int pos = ExpectLogContainsSomewhere(
2017*6777b538SAndroid Build Coastguard Worker entries, 0, NetLogEventType::HTTP2_SESSION_RECV_GOAWAY,
2018*6777b538SAndroid Build Coastguard Worker NetLogEventPhase::NONE);
2019*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(0, GetIntegerValueFromParams(entries[pos], "active_streams"));
2020*6777b538SAndroid Build Coastguard Worker ASSERT_EQ("11 (ENHANCE_YOUR_CALM)",
2021*6777b538SAndroid Build Coastguard Worker GetStringValueFromParams(entries[pos], "error_code"));
2022*6777b538SAndroid Build Coastguard Worker ASSERT_EQ("foo", GetStringValueFromParams(entries[pos], "debug_data"));
2023*6777b538SAndroid Build Coastguard Worker
2024*6777b538SAndroid Build Coastguard Worker // Check that we logged SPDY_SESSION_CLOSE correctly.
2025*6777b538SAndroid Build Coastguard Worker pos = ExpectLogContainsSomewhere(
2026*6777b538SAndroid Build Coastguard Worker entries, 0, NetLogEventType::HTTP2_SESSION_CLOSE, NetLogEventPhase::NONE);
2027*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(GetNetErrorCodeFromParams(entries[pos]), IsOk());
2028*6777b538SAndroid Build Coastguard Worker }
2029*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,NetLogOnSessionEOF)2030*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, NetLogOnSessionEOF) {
2031*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
2032*6777b538SAndroid Build Coastguard Worker MockRead(SYNCHRONOUS, 0, 0) // EOF
2033*6777b538SAndroid Build Coastguard Worker };
2034*6777b538SAndroid Build Coastguard Worker
2035*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
2036*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2037*6777b538SAndroid Build Coastguard Worker
2038*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2039*6777b538SAndroid Build Coastguard Worker
2040*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2041*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2042*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
2043*6777b538SAndroid Build Coastguard Worker
2044*6777b538SAndroid Build Coastguard Worker // Flush the read completion task.
2045*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2046*6777b538SAndroid Build Coastguard Worker
2047*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
2048*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
2049*6777b538SAndroid Build Coastguard Worker
2050*6777b538SAndroid Build Coastguard Worker // Check that the NetLog was filled reasonably.
2051*6777b538SAndroid Build Coastguard Worker auto entries = net_log_observer_.GetEntries();
2052*6777b538SAndroid Build Coastguard Worker EXPECT_LT(0u, entries.size());
2053*6777b538SAndroid Build Coastguard Worker
2054*6777b538SAndroid Build Coastguard Worker // Check that we logged SPDY_SESSION_CLOSE correctly.
2055*6777b538SAndroid Build Coastguard Worker int pos = ExpectLogContainsSomewhere(
2056*6777b538SAndroid Build Coastguard Worker entries, 0, NetLogEventType::HTTP2_SESSION_CLOSE, NetLogEventPhase::NONE);
2057*6777b538SAndroid Build Coastguard Worker
2058*6777b538SAndroid Build Coastguard Worker if (pos < static_cast<int>(entries.size())) {
2059*6777b538SAndroid Build Coastguard Worker ASSERT_THAT(GetNetErrorCodeFromParams(entries[pos]),
2060*6777b538SAndroid Build Coastguard Worker IsError(ERR_CONNECTION_CLOSED));
2061*6777b538SAndroid Build Coastguard Worker } else {
2062*6777b538SAndroid Build Coastguard Worker ADD_FAILURE();
2063*6777b538SAndroid Build Coastguard Worker }
2064*6777b538SAndroid Build Coastguard Worker }
2065*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,HeadersCompressionHistograms)2066*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, HeadersCompressionHistograms) {
2067*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
2068*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
2069*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
2070*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0),
2071*6777b538SAndroid Build Coastguard Worker };
2072*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
2073*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2) // EOF
2074*6777b538SAndroid Build Coastguard Worker };
2075*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
2076*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2077*6777b538SAndroid Build Coastguard Worker
2078*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2079*6777b538SAndroid Build Coastguard Worker
2080*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2081*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2082*6777b538SAndroid Build Coastguard Worker
2083*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
2084*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2085*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
2086*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate(spdy_stream);
2087*6777b538SAndroid Build Coastguard Worker spdy_stream->SetDelegate(&delegate);
2088*6777b538SAndroid Build Coastguard Worker
2089*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
2090*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2091*6777b538SAndroid Build Coastguard Worker spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
2092*6777b538SAndroid Build Coastguard Worker
2093*6777b538SAndroid Build Coastguard Worker // Write request headers & capture resulting histogram update.
2094*6777b538SAndroid Build Coastguard Worker base::HistogramTester histogram_tester;
2095*6777b538SAndroid Build Coastguard Worker
2096*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2097*6777b538SAndroid Build Coastguard Worker // Regression test of compression performance under the request fixture.
2098*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectBucketCount("Net.SpdyHeadersCompressionPercentage", 76,
2099*6777b538SAndroid Build Coastguard Worker 1);
2100*6777b538SAndroid Build Coastguard Worker
2101*6777b538SAndroid Build Coastguard Worker // Read and process EOF.
2102*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_);
2103*6777b538SAndroid Build Coastguard Worker data.Resume();
2104*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2105*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
2106*6777b538SAndroid Build Coastguard Worker }
2107*6777b538SAndroid Build Coastguard Worker
2108*6777b538SAndroid Build Coastguard Worker // Queue up a low-priority HEADERS followed by a high-priority
2109*6777b538SAndroid Build Coastguard Worker // one. The high priority one should still send first and receive
2110*6777b538SAndroid Build Coastguard Worker // first.
TEST_F(SpdySessionTest,OutOfOrderHeaders)2111*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, OutOfOrderHeaders) {
2112*6777b538SAndroid Build Coastguard Worker // Construct the request.
2113*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req_highest(
2114*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
2115*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req_lowest(
2116*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
2117*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
2118*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req_highest, 0), CreateMockWrite(req_lowest, 1),
2119*6777b538SAndroid Build Coastguard Worker };
2120*6777b538SAndroid Build Coastguard Worker
2121*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp_highest(
2122*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2123*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body_highest(
2124*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, true));
2125*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp_lowest(
2126*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
2127*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body_lowest(
2128*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(3, true));
2129*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
2130*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp_highest, 2), CreateMockRead(body_highest, 3),
2131*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp_lowest, 4), CreateMockRead(body_lowest, 5),
2132*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 6) // EOF
2133*6777b538SAndroid Build Coastguard Worker };
2134*6777b538SAndroid Build Coastguard Worker
2135*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
2136*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2137*6777b538SAndroid Build Coastguard Worker
2138*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2139*6777b538SAndroid Build Coastguard Worker
2140*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2141*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2142*6777b538SAndroid Build Coastguard Worker
2143*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream_lowest =
2144*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2145*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
2146*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream_lowest);
2147*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream_lowest->stream_id());
2148*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate_lowest(spdy_stream_lowest);
2149*6777b538SAndroid Build Coastguard Worker spdy_stream_lowest->SetDelegate(&delegate_lowest);
2150*6777b538SAndroid Build Coastguard Worker
2151*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream_highest =
2152*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2153*6777b538SAndroid Build Coastguard Worker test_url_, HIGHEST, NetLogWithSource());
2154*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream_highest);
2155*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream_highest->stream_id());
2156*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate_highest(spdy_stream_highest);
2157*6777b538SAndroid Build Coastguard Worker spdy_stream_highest->SetDelegate(&delegate_highest);
2158*6777b538SAndroid Build Coastguard Worker
2159*6777b538SAndroid Build Coastguard Worker // Queue the lower priority one first.
2160*6777b538SAndroid Build Coastguard Worker
2161*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers_lowest(
2162*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2163*6777b538SAndroid Build Coastguard Worker spdy_stream_lowest->SendRequestHeaders(std::move(headers_lowest),
2164*6777b538SAndroid Build Coastguard Worker NO_MORE_DATA_TO_SEND);
2165*6777b538SAndroid Build Coastguard Worker
2166*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers_highest(
2167*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2168*6777b538SAndroid Build Coastguard Worker spdy_stream_highest->SendRequestHeaders(std::move(headers_highest),
2169*6777b538SAndroid Build Coastguard Worker NO_MORE_DATA_TO_SEND);
2170*6777b538SAndroid Build Coastguard Worker
2171*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2172*6777b538SAndroid Build Coastguard Worker
2173*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream_lowest);
2174*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream_highest);
2175*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, delegate_lowest.stream_id());
2176*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, delegate_highest.stream_id());
2177*6777b538SAndroid Build Coastguard Worker }
2178*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,CancelStream)2179*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CancelStream) {
2180*6777b538SAndroid Build Coastguard Worker // Request 1, at HIGHEST priority, will be cancelled before it writes data.
2181*6777b538SAndroid Build Coastguard Worker // Request 2, at LOWEST priority, will be a full request and will be id 1.
2182*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(
2183*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
2184*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
2185*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req2, 0),
2186*6777b538SAndroid Build Coastguard Worker };
2187*6777b538SAndroid Build Coastguard Worker
2188*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp2(
2189*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2190*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
2191*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
2192*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp2, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
2193*6777b538SAndroid Build Coastguard Worker CreateMockRead(body2, 3), MockRead(ASYNC, 0, 4) // EOF
2194*6777b538SAndroid Build Coastguard Worker };
2195*6777b538SAndroid Build Coastguard Worker
2196*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
2197*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2198*6777b538SAndroid Build Coastguard Worker
2199*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2200*6777b538SAndroid Build Coastguard Worker
2201*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2202*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2203*6777b538SAndroid Build Coastguard Worker
2204*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
2205*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2206*6777b538SAndroid Build Coastguard Worker test_url_, HIGHEST, NetLogWithSource());
2207*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
2208*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2209*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
2210*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
2211*6777b538SAndroid Build Coastguard Worker
2212*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 =
2213*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2214*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
2215*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream2);
2216*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream2->stream_id());
2217*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate2(spdy_stream2);
2218*6777b538SAndroid Build Coastguard Worker spdy_stream2->SetDelegate(&delegate2);
2219*6777b538SAndroid Build Coastguard Worker
2220*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
2221*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2222*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
2223*6777b538SAndroid Build Coastguard Worker
2224*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(
2225*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2226*6777b538SAndroid Build Coastguard Worker spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
2227*6777b538SAndroid Build Coastguard Worker
2228*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2229*6777b538SAndroid Build Coastguard Worker
2230*6777b538SAndroid Build Coastguard Worker spdy_stream1->Cancel(ERR_ABORTED);
2231*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
2232*6777b538SAndroid Build Coastguard Worker
2233*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, delegate1.stream_id());
2234*6777b538SAndroid Build Coastguard Worker
2235*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2236*6777b538SAndroid Build Coastguard Worker
2237*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, delegate1.stream_id());
2238*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, delegate2.stream_id());
2239*6777b538SAndroid Build Coastguard Worker
2240*6777b538SAndroid Build Coastguard Worker spdy_stream2->Cancel(ERR_ABORTED);
2241*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream2);
2242*6777b538SAndroid Build Coastguard Worker }
2243*6777b538SAndroid Build Coastguard Worker
2244*6777b538SAndroid Build Coastguard Worker // Create two streams that are set to re-close themselves on close,
2245*6777b538SAndroid Build Coastguard Worker // and then close the session. Nothing should blow up. Also a
2246*6777b538SAndroid Build Coastguard Worker // regression test for http://crbug.com/139518 .
TEST_F(SpdySessionTest,CloseSessionWithTwoCreatedSelfClosingStreams)2247*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) {
2248*6777b538SAndroid Build Coastguard Worker // No actual data will be sent.
2249*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
2250*6777b538SAndroid Build Coastguard Worker MockWrite(ASYNC, 0, 1) // EOF
2251*6777b538SAndroid Build Coastguard Worker };
2252*6777b538SAndroid Build Coastguard Worker
2253*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
2254*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 0) // EOF
2255*6777b538SAndroid Build Coastguard Worker };
2256*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
2257*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2258*6777b538SAndroid Build Coastguard Worker
2259*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2260*6777b538SAndroid Build Coastguard Worker
2261*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2262*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2263*6777b538SAndroid Build Coastguard Worker
2264*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
2265*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
2266*6777b538SAndroid Build Coastguard Worker HIGHEST, NetLogWithSource());
2267*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
2268*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2269*6777b538SAndroid Build Coastguard Worker
2270*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 =
2271*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
2272*6777b538SAndroid Build Coastguard Worker LOWEST, NetLogWithSource());
2273*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream2);
2274*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream2->stream_id());
2275*6777b538SAndroid Build Coastguard Worker
2276*6777b538SAndroid Build Coastguard Worker test::ClosingDelegate delegate1(spdy_stream1);
2277*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
2278*6777b538SAndroid Build Coastguard Worker
2279*6777b538SAndroid Build Coastguard Worker test::ClosingDelegate delegate2(spdy_stream2);
2280*6777b538SAndroid Build Coastguard Worker spdy_stream2->SetDelegate(&delegate2);
2281*6777b538SAndroid Build Coastguard Worker
2282*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
2283*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2284*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
2285*6777b538SAndroid Build Coastguard Worker
2286*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(
2287*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2288*6777b538SAndroid Build Coastguard Worker spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
2289*6777b538SAndroid Build Coastguard Worker
2290*6777b538SAndroid Build Coastguard Worker // Ensure that the streams have not yet been activated and assigned an id.
2291*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2292*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream2->stream_id());
2293*6777b538SAndroid Build Coastguard Worker
2294*6777b538SAndroid Build Coastguard Worker // Ensure we don't crash while closing the session.
2295*6777b538SAndroid Build Coastguard Worker session_->CloseSessionOnError(ERR_ABORTED, std::string());
2296*6777b538SAndroid Build Coastguard Worker
2297*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
2298*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream2);
2299*6777b538SAndroid Build Coastguard Worker
2300*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate1.StreamIsClosed());
2301*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate2.StreamIsClosed());
2302*6777b538SAndroid Build Coastguard Worker
2303*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2304*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
2305*6777b538SAndroid Build Coastguard Worker }
2306*6777b538SAndroid Build Coastguard Worker
2307*6777b538SAndroid Build Coastguard Worker // Create two streams that are set to close each other on close, and
2308*6777b538SAndroid Build Coastguard Worker // then close the session. Nothing should blow up.
TEST_F(SpdySessionTest,CloseSessionWithTwoCreatedMutuallyClosingStreams)2309*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) {
2310*6777b538SAndroid Build Coastguard Worker SequencedSocketData data;
2311*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2312*6777b538SAndroid Build Coastguard Worker
2313*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2314*6777b538SAndroid Build Coastguard Worker
2315*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2316*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2317*6777b538SAndroid Build Coastguard Worker
2318*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
2319*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
2320*6777b538SAndroid Build Coastguard Worker HIGHEST, NetLogWithSource());
2321*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
2322*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2323*6777b538SAndroid Build Coastguard Worker
2324*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 =
2325*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
2326*6777b538SAndroid Build Coastguard Worker LOWEST, NetLogWithSource());
2327*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream2);
2328*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream2->stream_id());
2329*6777b538SAndroid Build Coastguard Worker
2330*6777b538SAndroid Build Coastguard Worker // Make |spdy_stream1| close |spdy_stream2|.
2331*6777b538SAndroid Build Coastguard Worker test::ClosingDelegate delegate1(spdy_stream2);
2332*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
2333*6777b538SAndroid Build Coastguard Worker
2334*6777b538SAndroid Build Coastguard Worker // Make |spdy_stream2| close |spdy_stream1|.
2335*6777b538SAndroid Build Coastguard Worker test::ClosingDelegate delegate2(spdy_stream1);
2336*6777b538SAndroid Build Coastguard Worker spdy_stream2->SetDelegate(&delegate2);
2337*6777b538SAndroid Build Coastguard Worker
2338*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
2339*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2340*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
2341*6777b538SAndroid Build Coastguard Worker
2342*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(
2343*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2344*6777b538SAndroid Build Coastguard Worker spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
2345*6777b538SAndroid Build Coastguard Worker
2346*6777b538SAndroid Build Coastguard Worker // Ensure that the streams have not yet been activated and assigned an id.
2347*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2348*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream2->stream_id());
2349*6777b538SAndroid Build Coastguard Worker
2350*6777b538SAndroid Build Coastguard Worker // Ensure we don't crash while closing the session.
2351*6777b538SAndroid Build Coastguard Worker session_->CloseSessionOnError(ERR_ABORTED, std::string());
2352*6777b538SAndroid Build Coastguard Worker
2353*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
2354*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream2);
2355*6777b538SAndroid Build Coastguard Worker
2356*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate1.StreamIsClosed());
2357*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate2.StreamIsClosed());
2358*6777b538SAndroid Build Coastguard Worker
2359*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2360*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
2361*6777b538SAndroid Build Coastguard Worker }
2362*6777b538SAndroid Build Coastguard Worker
2363*6777b538SAndroid Build Coastguard Worker // Create two streams that are set to re-close themselves on close,
2364*6777b538SAndroid Build Coastguard Worker // activate them, and then close the session. Nothing should blow up.
TEST_F(SpdySessionTest,CloseSessionWithTwoActivatedSelfClosingStreams)2365*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) {
2366*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
2367*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
2368*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(
2369*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
2370*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
2371*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
2372*6777b538SAndroid Build Coastguard Worker };
2373*6777b538SAndroid Build Coastguard Worker
2374*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
2375*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3) // EOF
2376*6777b538SAndroid Build Coastguard Worker };
2377*6777b538SAndroid Build Coastguard Worker
2378*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
2379*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2380*6777b538SAndroid Build Coastguard Worker
2381*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2382*6777b538SAndroid Build Coastguard Worker
2383*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2384*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2385*6777b538SAndroid Build Coastguard Worker
2386*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
2387*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2388*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
2389*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
2390*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2391*6777b538SAndroid Build Coastguard Worker
2392*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 =
2393*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2394*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
2395*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream2);
2396*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream2->stream_id());
2397*6777b538SAndroid Build Coastguard Worker
2398*6777b538SAndroid Build Coastguard Worker test::ClosingDelegate delegate1(spdy_stream1);
2399*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
2400*6777b538SAndroid Build Coastguard Worker
2401*6777b538SAndroid Build Coastguard Worker test::ClosingDelegate delegate2(spdy_stream2);
2402*6777b538SAndroid Build Coastguard Worker spdy_stream2->SetDelegate(&delegate2);
2403*6777b538SAndroid Build Coastguard Worker
2404*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
2405*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2406*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
2407*6777b538SAndroid Build Coastguard Worker
2408*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(
2409*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2410*6777b538SAndroid Build Coastguard Worker spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
2411*6777b538SAndroid Build Coastguard Worker
2412*6777b538SAndroid Build Coastguard Worker // Ensure that the streams have not yet been activated and assigned an id.
2413*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2414*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream2->stream_id());
2415*6777b538SAndroid Build Coastguard Worker
2416*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2417*6777b538SAndroid Build Coastguard Worker
2418*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream1->stream_id());
2419*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, spdy_stream2->stream_id());
2420*6777b538SAndroid Build Coastguard Worker
2421*6777b538SAndroid Build Coastguard Worker // Ensure we don't crash while closing the session.
2422*6777b538SAndroid Build Coastguard Worker session_->CloseSessionOnError(ERR_ABORTED, std::string());
2423*6777b538SAndroid Build Coastguard Worker
2424*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
2425*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream2);
2426*6777b538SAndroid Build Coastguard Worker
2427*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate1.StreamIsClosed());
2428*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate2.StreamIsClosed());
2429*6777b538SAndroid Build Coastguard Worker
2430*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_);
2431*6777b538SAndroid Build Coastguard Worker data.Resume();
2432*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2433*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
2434*6777b538SAndroid Build Coastguard Worker }
2435*6777b538SAndroid Build Coastguard Worker
2436*6777b538SAndroid Build Coastguard Worker // Create two streams that are set to close each other on close,
2437*6777b538SAndroid Build Coastguard Worker // activate them, and then close the session. Nothing should blow up.
TEST_F(SpdySessionTest,CloseSessionWithTwoActivatedMutuallyClosingStreams)2438*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) {
2439*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
2440*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
2441*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(
2442*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
2443*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
2444*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
2445*6777b538SAndroid Build Coastguard Worker };
2446*6777b538SAndroid Build Coastguard Worker
2447*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
2448*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3) // EOF
2449*6777b538SAndroid Build Coastguard Worker };
2450*6777b538SAndroid Build Coastguard Worker
2451*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
2452*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2453*6777b538SAndroid Build Coastguard Worker
2454*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2455*6777b538SAndroid Build Coastguard Worker
2456*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2457*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2458*6777b538SAndroid Build Coastguard Worker
2459*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
2460*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2461*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
2462*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
2463*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2464*6777b538SAndroid Build Coastguard Worker
2465*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 =
2466*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2467*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
2468*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream2);
2469*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream2->stream_id());
2470*6777b538SAndroid Build Coastguard Worker
2471*6777b538SAndroid Build Coastguard Worker // Make |spdy_stream1| close |spdy_stream2|.
2472*6777b538SAndroid Build Coastguard Worker test::ClosingDelegate delegate1(spdy_stream2);
2473*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
2474*6777b538SAndroid Build Coastguard Worker
2475*6777b538SAndroid Build Coastguard Worker // Make |spdy_stream2| close |spdy_stream1|.
2476*6777b538SAndroid Build Coastguard Worker test::ClosingDelegate delegate2(spdy_stream1);
2477*6777b538SAndroid Build Coastguard Worker spdy_stream2->SetDelegate(&delegate2);
2478*6777b538SAndroid Build Coastguard Worker
2479*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
2480*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2481*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
2482*6777b538SAndroid Build Coastguard Worker
2483*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(
2484*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2485*6777b538SAndroid Build Coastguard Worker spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
2486*6777b538SAndroid Build Coastguard Worker
2487*6777b538SAndroid Build Coastguard Worker // Ensure that the streams have not yet been activated and assigned an id.
2488*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2489*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream2->stream_id());
2490*6777b538SAndroid Build Coastguard Worker
2491*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2492*6777b538SAndroid Build Coastguard Worker
2493*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream1->stream_id());
2494*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, spdy_stream2->stream_id());
2495*6777b538SAndroid Build Coastguard Worker
2496*6777b538SAndroid Build Coastguard Worker // Ensure we don't crash while closing the session.
2497*6777b538SAndroid Build Coastguard Worker session_->CloseSessionOnError(ERR_ABORTED, std::string());
2498*6777b538SAndroid Build Coastguard Worker
2499*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
2500*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream2);
2501*6777b538SAndroid Build Coastguard Worker
2502*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate1.StreamIsClosed());
2503*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate2.StreamIsClosed());
2504*6777b538SAndroid Build Coastguard Worker
2505*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_);
2506*6777b538SAndroid Build Coastguard Worker data.Resume();
2507*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2508*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
2509*6777b538SAndroid Build Coastguard Worker }
2510*6777b538SAndroid Build Coastguard Worker
2511*6777b538SAndroid Build Coastguard Worker // Delegate that closes a given session when the stream is closed.
2512*6777b538SAndroid Build Coastguard Worker class SessionClosingDelegate : public test::StreamDelegateDoNothing {
2513*6777b538SAndroid Build Coastguard Worker public:
SessionClosingDelegate(const base::WeakPtr<SpdyStream> & stream,const base::WeakPtr<SpdySession> & session_to_close)2514*6777b538SAndroid Build Coastguard Worker SessionClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
2515*6777b538SAndroid Build Coastguard Worker const base::WeakPtr<SpdySession>& session_to_close)
2516*6777b538SAndroid Build Coastguard Worker : StreamDelegateDoNothing(stream),
2517*6777b538SAndroid Build Coastguard Worker session_to_close_(session_to_close) {}
2518*6777b538SAndroid Build Coastguard Worker
2519*6777b538SAndroid Build Coastguard Worker ~SessionClosingDelegate() override = default;
2520*6777b538SAndroid Build Coastguard Worker
OnClose(int status)2521*6777b538SAndroid Build Coastguard Worker void OnClose(int status) override {
2522*6777b538SAndroid Build Coastguard Worker session_to_close_->CloseSessionOnError(ERR_HTTP2_PROTOCOL_ERROR, "Error");
2523*6777b538SAndroid Build Coastguard Worker }
2524*6777b538SAndroid Build Coastguard Worker
2525*6777b538SAndroid Build Coastguard Worker private:
2526*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdySession> session_to_close_;
2527*6777b538SAndroid Build Coastguard Worker };
2528*6777b538SAndroid Build Coastguard Worker
2529*6777b538SAndroid Build Coastguard Worker // Close an activated stream that closes its session. Nothing should
2530*6777b538SAndroid Build Coastguard Worker // blow up. This is a regression test for https://crbug.com/263691.
TEST_F(SpdySessionTest,CloseActivatedStreamThatClosesSession)2531*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CloseActivatedStreamThatClosesSession) {
2532*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
2533*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
2534*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame rst(
2535*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
2536*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
2537*6777b538SAndroid Build Coastguard Worker 0, spdy::ERROR_CODE_PROTOCOL_ERROR, "Error"));
2538*6777b538SAndroid Build Coastguard Worker // The GOAWAY has higher-priority than the RST_STREAM, and is written first
2539*6777b538SAndroid Build Coastguard Worker // despite being queued second.
2540*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
2541*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0), CreateMockWrite(goaway, 1),
2542*6777b538SAndroid Build Coastguard Worker CreateMockWrite(rst, 3),
2543*6777b538SAndroid Build Coastguard Worker };
2544*6777b538SAndroid Build Coastguard Worker
2545*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
2546*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 2) // EOF
2547*6777b538SAndroid Build Coastguard Worker };
2548*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
2549*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2550*6777b538SAndroid Build Coastguard Worker
2551*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2552*6777b538SAndroid Build Coastguard Worker
2553*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2554*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2555*6777b538SAndroid Build Coastguard Worker
2556*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
2557*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2558*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
2559*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream);
2560*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream->stream_id());
2561*6777b538SAndroid Build Coastguard Worker
2562*6777b538SAndroid Build Coastguard Worker SessionClosingDelegate delegate(spdy_stream, session_);
2563*6777b538SAndroid Build Coastguard Worker spdy_stream->SetDelegate(&delegate);
2564*6777b538SAndroid Build Coastguard Worker
2565*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
2566*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2567*6777b538SAndroid Build Coastguard Worker spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
2568*6777b538SAndroid Build Coastguard Worker
2569*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream->stream_id());
2570*6777b538SAndroid Build Coastguard Worker
2571*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2572*6777b538SAndroid Build Coastguard Worker
2573*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream->stream_id());
2574*6777b538SAndroid Build Coastguard Worker
2575*6777b538SAndroid Build Coastguard Worker // Ensure we don't crash while closing the stream (which closes the
2576*6777b538SAndroid Build Coastguard Worker // session).
2577*6777b538SAndroid Build Coastguard Worker spdy_stream->Cancel(ERR_ABORTED);
2578*6777b538SAndroid Build Coastguard Worker
2579*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream);
2580*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate.StreamIsClosed());
2581*6777b538SAndroid Build Coastguard Worker
2582*6777b538SAndroid Build Coastguard Worker // Write the RST_STREAM & GOAWAY.
2583*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2584*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
2585*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
2586*6777b538SAndroid Build Coastguard Worker }
2587*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,VerifyDomainAuthentication)2588*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, VerifyDomainAuthentication) {
2589*6777b538SAndroid Build Coastguard Worker SequencedSocketData data;
2590*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2591*6777b538SAndroid Build Coastguard Worker
2592*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2593*6777b538SAndroid Build Coastguard Worker
2594*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2595*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2596*6777b538SAndroid Build Coastguard Worker
2597*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->VerifyDomainAuthentication("www.example.org"));
2598*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->VerifyDomainAuthentication("mail.example.org"));
2599*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->VerifyDomainAuthentication("mail.example.com"));
2600*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->VerifyDomainAuthentication("mail.google.com"));
2601*6777b538SAndroid Build Coastguard Worker }
2602*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,CloseTwoStalledCreateStream)2603*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CloseTwoStalledCreateStream) {
2604*6777b538SAndroid Build Coastguard Worker // TODO(rtenneti): Define a helper class/methods and move the common code in
2605*6777b538SAndroid Build Coastguard Worker // this file.
2606*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap new_settings;
2607*6777b538SAndroid Build Coastguard Worker const spdy::SpdySettingsId kSpdySettingsId1 =
2608*6777b538SAndroid Build Coastguard Worker spdy::SETTINGS_MAX_CONCURRENT_STREAMS;
2609*6777b538SAndroid Build Coastguard Worker const uint32_t max_concurrent_streams = 1;
2610*6777b538SAndroid Build Coastguard Worker new_settings[kSpdySettingsId1] = max_concurrent_streams;
2611*6777b538SAndroid Build Coastguard Worker
2612*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
2613*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
2614*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
2615*6777b538SAndroid Build Coastguard Worker spdy_util_.UpdateWithStreamDestruction(1);
2616*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(
2617*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
2618*6777b538SAndroid Build Coastguard Worker spdy_util_.UpdateWithStreamDestruction(3);
2619*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req3(
2620*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST));
2621*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
2622*6777b538SAndroid Build Coastguard Worker CreateMockWrite(settings_ack, 1), CreateMockWrite(req1, 2),
2623*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req2, 5), CreateMockWrite(req3, 8),
2624*6777b538SAndroid Build Coastguard Worker };
2625*6777b538SAndroid Build Coastguard Worker
2626*6777b538SAndroid Build Coastguard Worker // Set up the socket so we read a SETTINGS frame that sets max concurrent
2627*6777b538SAndroid Build Coastguard Worker // streams to 1.
2628*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_frame(
2629*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(new_settings));
2630*6777b538SAndroid Build Coastguard Worker
2631*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp1(
2632*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2633*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
2634*6777b538SAndroid Build Coastguard Worker
2635*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp2(
2636*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
2637*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
2638*6777b538SAndroid Build Coastguard Worker
2639*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp3(
2640*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
2641*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(5, true));
2642*6777b538SAndroid Build Coastguard Worker
2643*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
2644*6777b538SAndroid Build Coastguard Worker CreateMockRead(settings_frame, 0),
2645*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp1, 3),
2646*6777b538SAndroid Build Coastguard Worker CreateMockRead(body1, 4),
2647*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp2, 6),
2648*6777b538SAndroid Build Coastguard Worker CreateMockRead(body2, 7),
2649*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp3, 9),
2650*6777b538SAndroid Build Coastguard Worker CreateMockRead(body3, 10),
2651*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 11),
2652*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 12) // EOF
2653*6777b538SAndroid Build Coastguard Worker };
2654*6777b538SAndroid Build Coastguard Worker
2655*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
2656*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2657*6777b538SAndroid Build Coastguard Worker
2658*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2659*6777b538SAndroid Build Coastguard Worker
2660*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2661*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2662*6777b538SAndroid Build Coastguard Worker
2663*6777b538SAndroid Build Coastguard Worker // Read the settings frame.
2664*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2665*6777b538SAndroid Build Coastguard Worker
2666*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
2667*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2668*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
2669*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
2670*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2671*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
2672*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
2673*6777b538SAndroid Build Coastguard Worker
2674*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback2;
2675*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest request2;
2676*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(ERR_IO_PENDING,
2677*6777b538SAndroid Build Coastguard Worker request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_,
2678*6777b538SAndroid Build Coastguard Worker test_url_, false, LOWEST, SocketTag(),
2679*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), callback2.callback(),
2680*6777b538SAndroid Build Coastguard Worker TRAFFIC_ANNOTATION_FOR_TESTS));
2681*6777b538SAndroid Build Coastguard Worker
2682*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback3;
2683*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest request3;
2684*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(ERR_IO_PENDING,
2685*6777b538SAndroid Build Coastguard Worker request3.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_,
2686*6777b538SAndroid Build Coastguard Worker test_url_, false, LOWEST, SocketTag(),
2687*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), callback3.callback(),
2688*6777b538SAndroid Build Coastguard Worker TRAFFIC_ANNOTATION_FOR_TESTS));
2689*6777b538SAndroid Build Coastguard Worker
2690*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_active_streams());
2691*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, num_created_streams());
2692*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2u, pending_create_stream_queue_size(LOWEST));
2693*6777b538SAndroid Build Coastguard Worker
2694*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
2695*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2696*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
2697*6777b538SAndroid Build Coastguard Worker
2698*6777b538SAndroid Build Coastguard Worker // Run until 1st stream is activated and then closed.
2699*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, delegate1.stream_id());
2700*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2701*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
2702*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, delegate1.stream_id());
2703*6777b538SAndroid Build Coastguard Worker
2704*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_active_streams());
2705*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, pending_create_stream_queue_size(LOWEST));
2706*6777b538SAndroid Build Coastguard Worker
2707*6777b538SAndroid Build Coastguard Worker // Pump loop for SpdySession::ProcessPendingStreamRequests() to
2708*6777b538SAndroid Build Coastguard Worker // create the 2nd stream.
2709*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2710*6777b538SAndroid Build Coastguard Worker
2711*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_active_streams());
2712*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, num_created_streams());
2713*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, pending_create_stream_queue_size(LOWEST));
2714*6777b538SAndroid Build Coastguard Worker
2715*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream2 = request2.ReleaseStream();
2716*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate2(stream2);
2717*6777b538SAndroid Build Coastguard Worker stream2->SetDelegate(&delegate2);
2718*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(
2719*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2720*6777b538SAndroid Build Coastguard Worker stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
2721*6777b538SAndroid Build Coastguard Worker
2722*6777b538SAndroid Build Coastguard Worker // Run until 2nd stream is activated and then closed.
2723*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, delegate2.stream_id());
2724*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2725*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream2);
2726*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, delegate2.stream_id());
2727*6777b538SAndroid Build Coastguard Worker
2728*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_active_streams());
2729*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));
2730*6777b538SAndroid Build Coastguard Worker
2731*6777b538SAndroid Build Coastguard Worker // Pump loop for SpdySession::ProcessPendingStreamRequests() to
2732*6777b538SAndroid Build Coastguard Worker // create the 3rd stream.
2733*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2734*6777b538SAndroid Build Coastguard Worker
2735*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_active_streams());
2736*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, num_created_streams());
2737*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));
2738*6777b538SAndroid Build Coastguard Worker
2739*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream3 = request3.ReleaseStream();
2740*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate3(stream3);
2741*6777b538SAndroid Build Coastguard Worker stream3->SetDelegate(&delegate3);
2742*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers3(
2743*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2744*6777b538SAndroid Build Coastguard Worker stream3->SendRequestHeaders(std::move(headers3), NO_MORE_DATA_TO_SEND);
2745*6777b538SAndroid Build Coastguard Worker
2746*6777b538SAndroid Build Coastguard Worker // Run until 2nd stream is activated and then closed.
2747*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, delegate3.stream_id());
2748*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2749*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream3);
2750*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(5u, delegate3.stream_id());
2751*6777b538SAndroid Build Coastguard Worker
2752*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_active_streams());
2753*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_created_streams());
2754*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));
2755*6777b538SAndroid Build Coastguard Worker
2756*6777b538SAndroid Build Coastguard Worker data.Resume();
2757*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2758*6777b538SAndroid Build Coastguard Worker }
2759*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,CancelTwoStalledCreateStream)2760*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CancelTwoStalledCreateStream) {
2761*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
2762*6777b538SAndroid Build Coastguard Worker MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
2763*6777b538SAndroid Build Coastguard Worker };
2764*6777b538SAndroid Build Coastguard Worker
2765*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
2766*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2767*6777b538SAndroid Build Coastguard Worker
2768*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2769*6777b538SAndroid Build Coastguard Worker
2770*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2771*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2772*6777b538SAndroid Build Coastguard Worker
2773*6777b538SAndroid Build Coastguard Worker // Leave room for only one more stream to be created.
2774*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < kH2InitialMaxConcurrentStreams.Get() - 1; ++i) {
2775*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
2776*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_,
2777*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
2778*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream);
2779*6777b538SAndroid Build Coastguard Worker }
2780*6777b538SAndroid Build Coastguard Worker
2781*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
2782*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
2783*6777b538SAndroid Build Coastguard Worker LOWEST, NetLogWithSource());
2784*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
2785*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2786*6777b538SAndroid Build Coastguard Worker
2787*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback2;
2788*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest request2;
2789*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(ERR_IO_PENDING,
2790*6777b538SAndroid Build Coastguard Worker request2.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_,
2791*6777b538SAndroid Build Coastguard Worker test_url_, false, LOWEST, SocketTag(),
2792*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), callback2.callback(),
2793*6777b538SAndroid Build Coastguard Worker TRAFFIC_ANNOTATION_FOR_TESTS));
2794*6777b538SAndroid Build Coastguard Worker
2795*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback3;
2796*6777b538SAndroid Build Coastguard Worker SpdyStreamRequest request3;
2797*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(ERR_IO_PENDING,
2798*6777b538SAndroid Build Coastguard Worker request3.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_,
2799*6777b538SAndroid Build Coastguard Worker test_url_, false, LOWEST, SocketTag(),
2800*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), callback3.callback(),
2801*6777b538SAndroid Build Coastguard Worker TRAFFIC_ANNOTATION_FOR_TESTS));
2802*6777b538SAndroid Build Coastguard Worker
2803*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_active_streams());
2804*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(kH2InitialMaxConcurrentStreams.Get()),
2805*6777b538SAndroid Build Coastguard Worker num_created_streams());
2806*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2u, pending_create_stream_queue_size(LOWEST));
2807*6777b538SAndroid Build Coastguard Worker
2808*6777b538SAndroid Build Coastguard Worker // Cancel the first stream; this will allow the second stream to be created.
2809*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(spdy_stream1);
2810*6777b538SAndroid Build Coastguard Worker spdy_stream1->Cancel(ERR_ABORTED);
2811*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
2812*6777b538SAndroid Build Coastguard Worker
2813*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(callback2.WaitForResult(), IsOk());
2814*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_active_streams());
2815*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(kH2InitialMaxConcurrentStreams.Get()),
2816*6777b538SAndroid Build Coastguard Worker num_created_streams());
2817*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, pending_create_stream_queue_size(LOWEST));
2818*6777b538SAndroid Build Coastguard Worker
2819*6777b538SAndroid Build Coastguard Worker // Cancel the second stream; this will allow the third stream to be created.
2820*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 = request2.ReleaseStream();
2821*6777b538SAndroid Build Coastguard Worker spdy_stream2->Cancel(ERR_ABORTED);
2822*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream2);
2823*6777b538SAndroid Build Coastguard Worker
2824*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(callback3.WaitForResult(), IsOk());
2825*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_active_streams());
2826*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(kH2InitialMaxConcurrentStreams.Get()),
2827*6777b538SAndroid Build Coastguard Worker num_created_streams());
2828*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));
2829*6777b538SAndroid Build Coastguard Worker
2830*6777b538SAndroid Build Coastguard Worker // Cancel the third stream.
2831*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream3 = request3.ReleaseStream();
2832*6777b538SAndroid Build Coastguard Worker spdy_stream3->Cancel(ERR_ABORTED);
2833*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream3);
2834*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_active_streams());
2835*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(kH2InitialMaxConcurrentStreams.Get()) - 1,
2836*6777b538SAndroid Build Coastguard Worker num_created_streams());
2837*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));
2838*6777b538SAndroid Build Coastguard Worker }
2839*6777b538SAndroid Build Coastguard Worker
2840*6777b538SAndroid Build Coastguard Worker // Test that SpdySession::DoReadLoop reads data from the socket
2841*6777b538SAndroid Build Coastguard Worker // without yielding. This test makes 32k - 1 bytes of data available
2842*6777b538SAndroid Build Coastguard Worker // on the socket for reading. It then verifies that it has read all
2843*6777b538SAndroid Build Coastguard Worker // the available data without yielding.
TEST_F(SpdySessionTest,ReadDataWithoutYielding)2844*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, ReadDataWithoutYielding) {
2845*6777b538SAndroid Build Coastguard Worker session_deps_.time_func = InstantaneousReads;
2846*6777b538SAndroid Build Coastguard Worker
2847*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
2848*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
2849*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
2850*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0),
2851*6777b538SAndroid Build Coastguard Worker };
2852*6777b538SAndroid Build Coastguard Worker
2853*6777b538SAndroid Build Coastguard Worker // Build buffer of size kYieldAfterBytesRead / 4
2854*6777b538SAndroid Build Coastguard Worker // (-spdy_data_frame_size).
2855*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(32 * 1024, kYieldAfterBytesRead);
2856*6777b538SAndroid Build Coastguard Worker const int kPayloadSize = kYieldAfterBytesRead / 4 - spdy::kFrameHeaderSize;
2857*6777b538SAndroid Build Coastguard Worker TestDataStream test_stream;
2858*6777b538SAndroid Build Coastguard Worker auto payload = base::MakeRefCounted<IOBufferWithSize>(kPayloadSize);
2859*6777b538SAndroid Build Coastguard Worker char* payload_data = payload->data();
2860*6777b538SAndroid Build Coastguard Worker test_stream.GetBytes(payload_data, kPayloadSize);
2861*6777b538SAndroid Build Coastguard Worker
2862*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame partial_data_frame(
2863*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(
2864*6777b538SAndroid Build Coastguard Worker 1, std::string_view(payload_data, kPayloadSize), /*fin=*/false));
2865*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame finish_data_frame(spdy_util_.ConstructSpdyDataFrame(
2866*6777b538SAndroid Build Coastguard Worker 1, std::string_view(payload_data, kPayloadSize - 1), /*fin=*/true));
2867*6777b538SAndroid Build Coastguard Worker
2868*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp1(
2869*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2870*6777b538SAndroid Build Coastguard Worker
2871*6777b538SAndroid Build Coastguard Worker // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k
2872*6777b538SAndroid Build Coastguard Worker // bytes.
2873*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
2874*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp1, 1),
2875*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
2876*6777b538SAndroid Build Coastguard Worker CreateMockRead(partial_data_frame, 3),
2877*6777b538SAndroid Build Coastguard Worker CreateMockRead(partial_data_frame, 4, SYNCHRONOUS),
2878*6777b538SAndroid Build Coastguard Worker CreateMockRead(partial_data_frame, 5, SYNCHRONOUS),
2879*6777b538SAndroid Build Coastguard Worker CreateMockRead(finish_data_frame, 6, SYNCHRONOUS),
2880*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 7) // EOF
2881*6777b538SAndroid Build Coastguard Worker };
2882*6777b538SAndroid Build Coastguard Worker
2883*6777b538SAndroid Build Coastguard Worker // Create SpdySession and SpdyStream and send the request.
2884*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
2885*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2886*6777b538SAndroid Build Coastguard Worker
2887*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2888*6777b538SAndroid Build Coastguard Worker
2889*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2890*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2891*6777b538SAndroid Build Coastguard Worker
2892*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
2893*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2894*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
2895*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
2896*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2897*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
2898*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
2899*6777b538SAndroid Build Coastguard Worker
2900*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers1(
2901*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2902*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
2903*6777b538SAndroid Build Coastguard Worker
2904*6777b538SAndroid Build Coastguard Worker // Set up the TaskObserver to verify SpdySession::DoReadLoop doesn't
2905*6777b538SAndroid Build Coastguard Worker // post a task.
2906*6777b538SAndroid Build Coastguard Worker SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
2907*6777b538SAndroid Build Coastguard Worker
2908*6777b538SAndroid Build Coastguard Worker // Run until 1st read.
2909*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, delegate1.stream_id());
2910*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2911*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, delegate1.stream_id());
2912*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, observer.executed_count());
2913*6777b538SAndroid Build Coastguard Worker
2914*6777b538SAndroid Build Coastguard Worker // Read all the data and verify SpdySession::DoReadLoop has not
2915*6777b538SAndroid Build Coastguard Worker // posted a task.
2916*6777b538SAndroid Build Coastguard Worker data.Resume();
2917*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2918*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
2919*6777b538SAndroid Build Coastguard Worker
2920*6777b538SAndroid Build Coastguard Worker // Verify task observer's executed_count is zero, which indicates DoRead read
2921*6777b538SAndroid Build Coastguard Worker // all the available data.
2922*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, observer.executed_count());
2923*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
2924*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
2925*6777b538SAndroid Build Coastguard Worker }
2926*6777b538SAndroid Build Coastguard Worker
2927*6777b538SAndroid Build Coastguard Worker // Test that SpdySession::DoReadLoop yields if more than
2928*6777b538SAndroid Build Coastguard Worker // |kYieldAfterDurationMilliseconds| has passed. This test uses a mock time
2929*6777b538SAndroid Build Coastguard Worker // function that makes the response frame look very slow to read.
TEST_F(SpdySessionTest,TestYieldingSlowReads)2930*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, TestYieldingSlowReads) {
2931*6777b538SAndroid Build Coastguard Worker session_deps_.time_func = SlowReads;
2932*6777b538SAndroid Build Coastguard Worker
2933*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
2934*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
2935*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
2936*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0),
2937*6777b538SAndroid Build Coastguard Worker };
2938*6777b538SAndroid Build Coastguard Worker
2939*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp1(
2940*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2941*6777b538SAndroid Build Coastguard Worker
2942*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
2943*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp1, 1), MockRead(ASYNC, 0, 2) // EOF
2944*6777b538SAndroid Build Coastguard Worker };
2945*6777b538SAndroid Build Coastguard Worker
2946*6777b538SAndroid Build Coastguard Worker // Create SpdySession and SpdyStream and send the request.
2947*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
2948*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
2949*6777b538SAndroid Build Coastguard Worker
2950*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
2951*6777b538SAndroid Build Coastguard Worker
2952*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
2953*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
2954*6777b538SAndroid Build Coastguard Worker
2955*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
2956*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
2957*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
2958*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
2959*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
2960*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
2961*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
2962*6777b538SAndroid Build Coastguard Worker
2963*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers1(
2964*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2965*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
2966*6777b538SAndroid Build Coastguard Worker
2967*6777b538SAndroid Build Coastguard Worker // Set up the TaskObserver to verify that SpdySession::DoReadLoop posts a
2968*6777b538SAndroid Build Coastguard Worker // task.
2969*6777b538SAndroid Build Coastguard Worker SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
2970*6777b538SAndroid Build Coastguard Worker
2971*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, delegate1.stream_id());
2972*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, observer.executed_count());
2973*6777b538SAndroid Build Coastguard Worker
2974*6777b538SAndroid Build Coastguard Worker // Read all the data and verify that SpdySession::DoReadLoop has posted a
2975*6777b538SAndroid Build Coastguard Worker // task.
2976*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
2977*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, delegate1.stream_id());
2978*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
2979*6777b538SAndroid Build Coastguard Worker
2980*6777b538SAndroid Build Coastguard Worker // Verify task that the observer's executed_count is 1, which indicates DoRead
2981*6777b538SAndroid Build Coastguard Worker // has posted only one task and thus yielded though there is data available
2982*6777b538SAndroid Build Coastguard Worker // for it to read.
2983*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, observer.executed_count());
2984*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
2985*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
2986*6777b538SAndroid Build Coastguard Worker }
2987*6777b538SAndroid Build Coastguard Worker
2988*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/531570.
2989*6777b538SAndroid Build Coastguard Worker // Test the case where DoRead() takes long but returns synchronously.
TEST_F(SpdySessionTest,TestYieldingSlowSynchronousReads)2990*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, TestYieldingSlowSynchronousReads) {
2991*6777b538SAndroid Build Coastguard Worker session_deps_.time_func = SlowReads;
2992*6777b538SAndroid Build Coastguard Worker
2993*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
2994*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
2995*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
2996*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0),
2997*6777b538SAndroid Build Coastguard Worker };
2998*6777b538SAndroid Build Coastguard Worker
2999*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame partial_data_frame(
3000*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, "foo ", /*fin=*/false));
3001*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame finish_data_frame(
3002*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, "bar", /*fin=*/true));
3003*6777b538SAndroid Build Coastguard Worker
3004*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp1(
3005*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3006*6777b538SAndroid Build Coastguard Worker
3007*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3008*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp1, 1),
3009*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
3010*6777b538SAndroid Build Coastguard Worker CreateMockRead(partial_data_frame, 3, ASYNC),
3011*6777b538SAndroid Build Coastguard Worker CreateMockRead(partial_data_frame, 4, SYNCHRONOUS),
3012*6777b538SAndroid Build Coastguard Worker CreateMockRead(partial_data_frame, 5, SYNCHRONOUS),
3013*6777b538SAndroid Build Coastguard Worker CreateMockRead(finish_data_frame, 6, SYNCHRONOUS),
3014*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 7) // EOF
3015*6777b538SAndroid Build Coastguard Worker };
3016*6777b538SAndroid Build Coastguard Worker
3017*6777b538SAndroid Build Coastguard Worker // Create SpdySession and SpdyStream and send the request.
3018*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
3019*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3020*6777b538SAndroid Build Coastguard Worker
3021*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3022*6777b538SAndroid Build Coastguard Worker
3023*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3024*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
3025*6777b538SAndroid Build Coastguard Worker
3026*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
3027*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
3028*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
3029*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
3030*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
3031*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
3032*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
3033*6777b538SAndroid Build Coastguard Worker
3034*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers1(
3035*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
3036*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
3037*6777b538SAndroid Build Coastguard Worker
3038*6777b538SAndroid Build Coastguard Worker // Run until 1st read.
3039*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, delegate1.stream_id());
3040*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3041*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, delegate1.stream_id());
3042*6777b538SAndroid Build Coastguard Worker
3043*6777b538SAndroid Build Coastguard Worker // Read all the data and verify SpdySession::DoReadLoop has posted a task.
3044*6777b538SAndroid Build Coastguard Worker data.Resume();
3045*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3046*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("foo foo foo bar", delegate1.TakeReceivedData());
3047*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
3048*6777b538SAndroid Build Coastguard Worker
3049*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
3050*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
3051*6777b538SAndroid Build Coastguard Worker }
3052*6777b538SAndroid Build Coastguard Worker
3053*6777b538SAndroid Build Coastguard Worker // Test that SpdySession::DoReadLoop yields while reading the
3054*6777b538SAndroid Build Coastguard Worker // data. This test makes 32k + 1 bytes of data available on the socket
3055*6777b538SAndroid Build Coastguard Worker // for reading. It then verifies that DoRead has yielded even though
3056*6777b538SAndroid Build Coastguard Worker // there is data available for it to read (i.e, socket()->Read didn't
3057*6777b538SAndroid Build Coastguard Worker // return ERR_IO_PENDING during socket reads).
TEST_F(SpdySessionTest,TestYieldingDuringReadData)3058*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, TestYieldingDuringReadData) {
3059*6777b538SAndroid Build Coastguard Worker session_deps_.time_func = InstantaneousReads;
3060*6777b538SAndroid Build Coastguard Worker
3061*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
3062*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
3063*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
3064*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0),
3065*6777b538SAndroid Build Coastguard Worker };
3066*6777b538SAndroid Build Coastguard Worker
3067*6777b538SAndroid Build Coastguard Worker // Build buffer of size kYieldAfterBytesRead / 4
3068*6777b538SAndroid Build Coastguard Worker // (-spdy_data_frame_size).
3069*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(32 * 1024, kYieldAfterBytesRead);
3070*6777b538SAndroid Build Coastguard Worker const int kPayloadSize = kYieldAfterBytesRead / 4 - spdy::kFrameHeaderSize;
3071*6777b538SAndroid Build Coastguard Worker TestDataStream test_stream;
3072*6777b538SAndroid Build Coastguard Worker auto payload = base::MakeRefCounted<IOBufferWithSize>(kPayloadSize);
3073*6777b538SAndroid Build Coastguard Worker char* payload_data = payload->data();
3074*6777b538SAndroid Build Coastguard Worker test_stream.GetBytes(payload_data, kPayloadSize);
3075*6777b538SAndroid Build Coastguard Worker
3076*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame partial_data_frame(
3077*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(
3078*6777b538SAndroid Build Coastguard Worker 1, std::string_view(payload_data, kPayloadSize), /*fin=*/false));
3079*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame finish_data_frame(
3080*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, "h", /*fin=*/true));
3081*6777b538SAndroid Build Coastguard Worker
3082*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp1(
3083*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3084*6777b538SAndroid Build Coastguard Worker
3085*6777b538SAndroid Build Coastguard Worker // Write 1 byte more than kMaxReadBytes to check that DoRead yields.
3086*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3087*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp1, 1),
3088*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
3089*6777b538SAndroid Build Coastguard Worker CreateMockRead(partial_data_frame, 3),
3090*6777b538SAndroid Build Coastguard Worker CreateMockRead(partial_data_frame, 4, SYNCHRONOUS),
3091*6777b538SAndroid Build Coastguard Worker CreateMockRead(partial_data_frame, 5, SYNCHRONOUS),
3092*6777b538SAndroid Build Coastguard Worker CreateMockRead(partial_data_frame, 6, SYNCHRONOUS),
3093*6777b538SAndroid Build Coastguard Worker CreateMockRead(finish_data_frame, 7, SYNCHRONOUS),
3094*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 8) // EOF
3095*6777b538SAndroid Build Coastguard Worker };
3096*6777b538SAndroid Build Coastguard Worker
3097*6777b538SAndroid Build Coastguard Worker // Create SpdySession and SpdyStream and send the request.
3098*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
3099*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3100*6777b538SAndroid Build Coastguard Worker
3101*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3102*6777b538SAndroid Build Coastguard Worker
3103*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3104*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
3105*6777b538SAndroid Build Coastguard Worker
3106*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
3107*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
3108*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
3109*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
3110*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
3111*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
3112*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
3113*6777b538SAndroid Build Coastguard Worker
3114*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers1(
3115*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
3116*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
3117*6777b538SAndroid Build Coastguard Worker
3118*6777b538SAndroid Build Coastguard Worker // Set up the TaskObserver to verify SpdySession::DoReadLoop posts a task.
3119*6777b538SAndroid Build Coastguard Worker SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
3120*6777b538SAndroid Build Coastguard Worker
3121*6777b538SAndroid Build Coastguard Worker // Run until 1st read.
3122*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, delegate1.stream_id());
3123*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3124*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, delegate1.stream_id());
3125*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, observer.executed_count());
3126*6777b538SAndroid Build Coastguard Worker
3127*6777b538SAndroid Build Coastguard Worker // Read all the data and verify SpdySession::DoReadLoop has posted a task.
3128*6777b538SAndroid Build Coastguard Worker data.Resume();
3129*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3130*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
3131*6777b538SAndroid Build Coastguard Worker
3132*6777b538SAndroid Build Coastguard Worker // Verify task observer's executed_count is 1, which indicates DoRead has
3133*6777b538SAndroid Build Coastguard Worker // posted only one task and thus yielded though there is data available for it
3134*6777b538SAndroid Build Coastguard Worker // to read.
3135*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, observer.executed_count());
3136*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
3137*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
3138*6777b538SAndroid Build Coastguard Worker }
3139*6777b538SAndroid Build Coastguard Worker
3140*6777b538SAndroid Build Coastguard Worker // Test that SpdySession::DoReadLoop() tests interactions of yielding
3141*6777b538SAndroid Build Coastguard Worker // + async, by doing the following MockReads.
3142*6777b538SAndroid Build Coastguard Worker //
3143*6777b538SAndroid Build Coastguard Worker // MockRead of SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K
3144*6777b538SAndroid Build Coastguard Worker // ASYNC 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K.
3145*6777b538SAndroid Build Coastguard Worker //
3146*6777b538SAndroid Build Coastguard Worker // The above reads 26K synchronously. Since that is less that 32K, we
3147*6777b538SAndroid Build Coastguard Worker // will attempt to read again. However, that DoRead() will return
3148*6777b538SAndroid Build Coastguard Worker // ERR_IO_PENDING (because of async read), so DoReadLoop() will
3149*6777b538SAndroid Build Coastguard Worker // yield. When we come back, DoRead() will read the results from the
3150*6777b538SAndroid Build Coastguard Worker // async read, and rest of the data synchronously.
TEST_F(SpdySessionTest,TestYieldingDuringAsyncReadData)3151*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, TestYieldingDuringAsyncReadData) {
3152*6777b538SAndroid Build Coastguard Worker session_deps_.time_func = InstantaneousReads;
3153*6777b538SAndroid Build Coastguard Worker
3154*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
3155*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
3156*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
3157*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0),
3158*6777b538SAndroid Build Coastguard Worker };
3159*6777b538SAndroid Build Coastguard Worker
3160*6777b538SAndroid Build Coastguard Worker // Build buffer of size kYieldAfterBytesRead / 4
3161*6777b538SAndroid Build Coastguard Worker // (-spdy_data_frame_size).
3162*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(32 * 1024, kYieldAfterBytesRead);
3163*6777b538SAndroid Build Coastguard Worker TestDataStream test_stream;
3164*6777b538SAndroid Build Coastguard Worker const int kEightKPayloadSize =
3165*6777b538SAndroid Build Coastguard Worker kYieldAfterBytesRead / 4 - spdy::kFrameHeaderSize;
3166*6777b538SAndroid Build Coastguard Worker auto eightk_payload =
3167*6777b538SAndroid Build Coastguard Worker base::MakeRefCounted<IOBufferWithSize>(kEightKPayloadSize);
3168*6777b538SAndroid Build Coastguard Worker char* eightk_payload_data = eightk_payload->data();
3169*6777b538SAndroid Build Coastguard Worker test_stream.GetBytes(eightk_payload_data, kEightKPayloadSize);
3170*6777b538SAndroid Build Coastguard Worker
3171*6777b538SAndroid Build Coastguard Worker // Build buffer of 2k size.
3172*6777b538SAndroid Build Coastguard Worker TestDataStream test_stream2;
3173*6777b538SAndroid Build Coastguard Worker const int kTwoKPayloadSize = kEightKPayloadSize - 6 * 1024;
3174*6777b538SAndroid Build Coastguard Worker auto twok_payload = base::MakeRefCounted<IOBufferWithSize>(kTwoKPayloadSize);
3175*6777b538SAndroid Build Coastguard Worker char* twok_payload_data = twok_payload->data();
3176*6777b538SAndroid Build Coastguard Worker test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize);
3177*6777b538SAndroid Build Coastguard Worker
3178*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame eightk_data_frame(spdy_util_.ConstructSpdyDataFrame(
3179*6777b538SAndroid Build Coastguard Worker 1, std::string_view(eightk_payload_data, kEightKPayloadSize),
3180*6777b538SAndroid Build Coastguard Worker /*fin=*/false));
3181*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame twok_data_frame(spdy_util_.ConstructSpdyDataFrame(
3182*6777b538SAndroid Build Coastguard Worker 1, std::string_view(twok_payload_data, kTwoKPayloadSize),
3183*6777b538SAndroid Build Coastguard Worker /*fin=*/false));
3184*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame finish_data_frame(
3185*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, "h", /*fin=*/true));
3186*6777b538SAndroid Build Coastguard Worker
3187*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp1(
3188*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3189*6777b538SAndroid Build Coastguard Worker
3190*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3191*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp1, 1),
3192*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
3193*6777b538SAndroid Build Coastguard Worker CreateMockRead(eightk_data_frame, 3),
3194*6777b538SAndroid Build Coastguard Worker CreateMockRead(eightk_data_frame, 4, SYNCHRONOUS),
3195*6777b538SAndroid Build Coastguard Worker CreateMockRead(eightk_data_frame, 5, SYNCHRONOUS),
3196*6777b538SAndroid Build Coastguard Worker CreateMockRead(twok_data_frame, 6, SYNCHRONOUS),
3197*6777b538SAndroid Build Coastguard Worker CreateMockRead(eightk_data_frame, 7, ASYNC),
3198*6777b538SAndroid Build Coastguard Worker CreateMockRead(eightk_data_frame, 8, SYNCHRONOUS),
3199*6777b538SAndroid Build Coastguard Worker CreateMockRead(eightk_data_frame, 9, SYNCHRONOUS),
3200*6777b538SAndroid Build Coastguard Worker CreateMockRead(eightk_data_frame, 10, SYNCHRONOUS),
3201*6777b538SAndroid Build Coastguard Worker CreateMockRead(twok_data_frame, 11, SYNCHRONOUS),
3202*6777b538SAndroid Build Coastguard Worker CreateMockRead(finish_data_frame, 12, SYNCHRONOUS),
3203*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 13) // EOF
3204*6777b538SAndroid Build Coastguard Worker };
3205*6777b538SAndroid Build Coastguard Worker
3206*6777b538SAndroid Build Coastguard Worker // Create SpdySession and SpdyStream and send the request.
3207*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
3208*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3209*6777b538SAndroid Build Coastguard Worker
3210*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3211*6777b538SAndroid Build Coastguard Worker
3212*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3213*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
3214*6777b538SAndroid Build Coastguard Worker
3215*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
3216*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
3217*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
3218*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
3219*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
3220*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
3221*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
3222*6777b538SAndroid Build Coastguard Worker
3223*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers1(
3224*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
3225*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
3226*6777b538SAndroid Build Coastguard Worker
3227*6777b538SAndroid Build Coastguard Worker // Set up the TaskObserver to monitor SpdySession::DoReadLoop
3228*6777b538SAndroid Build Coastguard Worker // posting of tasks.
3229*6777b538SAndroid Build Coastguard Worker SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
3230*6777b538SAndroid Build Coastguard Worker
3231*6777b538SAndroid Build Coastguard Worker // Run until 1st read.
3232*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, delegate1.stream_id());
3233*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3234*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, delegate1.stream_id());
3235*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, observer.executed_count());
3236*6777b538SAndroid Build Coastguard Worker
3237*6777b538SAndroid Build Coastguard Worker // Read all the data and verify SpdySession::DoReadLoop has posted a
3238*6777b538SAndroid Build Coastguard Worker // task.
3239*6777b538SAndroid Build Coastguard Worker data.Resume();
3240*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3241*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
3242*6777b538SAndroid Build Coastguard Worker
3243*6777b538SAndroid Build Coastguard Worker // Verify task observer's executed_count is 1, which indicates DoRead has
3244*6777b538SAndroid Build Coastguard Worker // posted only one task and thus yielded though there is data available for
3245*6777b538SAndroid Build Coastguard Worker // it to read.
3246*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, observer.executed_count());
3247*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
3248*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
3249*6777b538SAndroid Build Coastguard Worker }
3250*6777b538SAndroid Build Coastguard Worker
3251*6777b538SAndroid Build Coastguard Worker // Send a GoAway frame when SpdySession is in DoReadLoop. Make sure
3252*6777b538SAndroid Build Coastguard Worker // nothing blows up.
TEST_F(SpdySessionTest,GoAwayWhileInDoReadLoop)3253*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, GoAwayWhileInDoReadLoop) {
3254*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
3255*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
3256*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
3257*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0),
3258*6777b538SAndroid Build Coastguard Worker };
3259*6777b538SAndroid Build Coastguard Worker
3260*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp1(
3261*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3262*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
3263*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(0));
3264*6777b538SAndroid Build Coastguard Worker
3265*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3266*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
3267*6777b538SAndroid Build Coastguard Worker CreateMockRead(body1, 3), CreateMockRead(goaway, 4),
3268*6777b538SAndroid Build Coastguard Worker };
3269*6777b538SAndroid Build Coastguard Worker
3270*6777b538SAndroid Build Coastguard Worker // Create SpdySession and SpdyStream and send the request.
3271*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
3272*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3273*6777b538SAndroid Build Coastguard Worker
3274*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3275*6777b538SAndroid Build Coastguard Worker
3276*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3277*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
3278*6777b538SAndroid Build Coastguard Worker
3279*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
3280*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
3281*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
3282*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
3283*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
3284*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
3285*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
3286*6777b538SAndroid Build Coastguard Worker
3287*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers1(
3288*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
3289*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
3290*6777b538SAndroid Build Coastguard Worker
3291*6777b538SAndroid Build Coastguard Worker // Run until 1st read.
3292*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream1->stream_id());
3293*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3294*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream1->stream_id());
3295*6777b538SAndroid Build Coastguard Worker
3296*6777b538SAndroid Build Coastguard Worker // Run until GoAway.
3297*6777b538SAndroid Build Coastguard Worker data.Resume();
3298*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3299*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
3300*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
3301*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
3302*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
3303*6777b538SAndroid Build Coastguard Worker }
3304*6777b538SAndroid Build Coastguard Worker
3305*6777b538SAndroid Build Coastguard Worker // Within this framework, a SpdySession should be initialized with
3306*6777b538SAndroid Build Coastguard Worker // flow control disabled for protocol version 2, with flow control
3307*6777b538SAndroid Build Coastguard Worker // enabled only for streams for protocol version 3, and with flow
3308*6777b538SAndroid Build Coastguard Worker // control enabled for streams and sessions for higher versions.
TEST_F(SpdySessionTest,ProtocolNegotiation)3309*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, ProtocolNegotiation) {
3310*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3311*6777b538SAndroid Build Coastguard Worker MockRead(SYNCHRONOUS, 0, 0) // EOF
3312*6777b538SAndroid Build Coastguard Worker };
3313*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
3314*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3315*6777b538SAndroid Build Coastguard Worker
3316*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3317*6777b538SAndroid Build Coastguard Worker session_ = CreateFakeSpdySession(spdy_session_pool_, key_);
3318*6777b538SAndroid Build Coastguard Worker
3319*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultInitialWindowSize, session_send_window_size());
3320*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
3321*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
3322*6777b538SAndroid Build Coastguard Worker }
3323*6777b538SAndroid Build Coastguard Worker
3324*6777b538SAndroid Build Coastguard Worker // Tests the case of a non-SPDY request closing an idle SPDY session when no
3325*6777b538SAndroid Build Coastguard Worker // pointers to the idle session are currently held.
TEST_F(SpdySessionTest,CloseOneIdleConnection)3326*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CloseOneIdleConnection) {
3327*6777b538SAndroid Build Coastguard Worker ClientSocketPoolManager::set_max_sockets_per_group(
3328*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3329*6777b538SAndroid Build Coastguard Worker ClientSocketPoolManager::set_max_sockets_per_pool(
3330*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3331*6777b538SAndroid Build Coastguard Worker
3332*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3333*6777b538SAndroid Build Coastguard Worker MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
3334*6777b538SAndroid Build Coastguard Worker };
3335*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
3336*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3337*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3338*6777b538SAndroid Build Coastguard Worker
3339*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3340*6777b538SAndroid Build Coastguard Worker
3341*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3342*6777b538SAndroid Build Coastguard Worker
3343*6777b538SAndroid Build Coastguard Worker ClientSocketPool* pool = http_session_->GetSocketPool(
3344*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct());
3345*6777b538SAndroid Build Coastguard Worker
3346*6777b538SAndroid Build Coastguard Worker // Create an idle SPDY session.
3347*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
3348*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(pool->IsStalled());
3349*6777b538SAndroid Build Coastguard Worker
3350*6777b538SAndroid Build Coastguard Worker // Trying to create a new connection should cause the pool to be stalled, and
3351*6777b538SAndroid Build Coastguard Worker // post a task asynchronously to try and close the session.
3352*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback2;
3353*6777b538SAndroid Build Coastguard Worker auto connection2 = std::make_unique<ClientSocketHandle>();
3354*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(
3355*6777b538SAndroid Build Coastguard Worker ERR_IO_PENDING,
3356*6777b538SAndroid Build Coastguard Worker connection2->Init(
3357*6777b538SAndroid Build Coastguard Worker ClientSocketPool::GroupId(
3358*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(url::kHttpScheme, "2.com", 80),
3359*6777b538SAndroid Build Coastguard Worker PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
3360*6777b538SAndroid Build Coastguard Worker SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
3361*6777b538SAndroid Build Coastguard Worker ClientSocketPool::SocketParams::CreateForHttpForTesting(),
3362*6777b538SAndroid Build Coastguard Worker std::nullopt /* proxy_annotation_tag */, DEFAULT_PRIORITY,
3363*6777b538SAndroid Build Coastguard Worker SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3364*6777b538SAndroid Build Coastguard Worker callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool,
3365*6777b538SAndroid Build Coastguard Worker NetLogWithSource()));
3366*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(pool->IsStalled());
3367*6777b538SAndroid Build Coastguard Worker
3368*6777b538SAndroid Build Coastguard Worker // The socket pool should close the connection asynchronously and establish a
3369*6777b538SAndroid Build Coastguard Worker // new connection.
3370*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(callback2.WaitForResult(), IsOk());
3371*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(pool->IsStalled());
3372*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
3373*6777b538SAndroid Build Coastguard Worker }
3374*6777b538SAndroid Build Coastguard Worker
3375*6777b538SAndroid Build Coastguard Worker // Tests the case of a non-SPDY request closing an idle SPDY session when no
3376*6777b538SAndroid Build Coastguard Worker // pointers to the idle session are currently held, in the case the SPDY session
3377*6777b538SAndroid Build Coastguard Worker // has an alias.
TEST_F(SpdySessionTest,CloseOneIdleConnectionWithAlias)3378*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
3379*6777b538SAndroid Build Coastguard Worker ClientSocketPoolManager::set_max_sockets_per_group(
3380*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3381*6777b538SAndroid Build Coastguard Worker ClientSocketPoolManager::set_max_sockets_per_pool(
3382*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3383*6777b538SAndroid Build Coastguard Worker
3384*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3385*6777b538SAndroid Build Coastguard Worker MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
3386*6777b538SAndroid Build Coastguard Worker };
3387*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
3388*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3389*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3390*6777b538SAndroid Build Coastguard Worker
3391*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3392*6777b538SAndroid Build Coastguard Worker
3393*6777b538SAndroid Build Coastguard Worker session_deps_.host_resolver->rules()->AddIPLiteralRule(
3394*6777b538SAndroid Build Coastguard Worker "www.example.org", "192.168.0.2", std::string());
3395*6777b538SAndroid Build Coastguard Worker
3396*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3397*6777b538SAndroid Build Coastguard Worker
3398*6777b538SAndroid Build Coastguard Worker ClientSocketPool* pool = http_session_->GetSocketPool(
3399*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct());
3400*6777b538SAndroid Build Coastguard Worker
3401*6777b538SAndroid Build Coastguard Worker // Create an idle SPDY session.
3402*6777b538SAndroid Build Coastguard Worker SpdySessionKey key1(HostPortPair("www.example.org", 80),
3403*6777b538SAndroid Build Coastguard Worker PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
3404*6777b538SAndroid Build Coastguard Worker SessionUsage::kDestination, SocketTag(),
3405*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
3406*6777b538SAndroid Build Coastguard Worker /*disable_cert_verification_network_fetches=*/false);
3407*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdySession> session1 =
3408*6777b538SAndroid Build Coastguard Worker ::net::CreateSpdySession(http_session_.get(), key1, NetLogWithSource());
3409*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(pool->IsStalled());
3410*6777b538SAndroid Build Coastguard Worker
3411*6777b538SAndroid Build Coastguard Worker // Set up an alias for the idle SPDY session, increasing its ref count to 2.
3412*6777b538SAndroid Build Coastguard Worker SpdySessionKey key2(HostPortPair("mail.example.org", 80),
3413*6777b538SAndroid Build Coastguard Worker PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
3414*6777b538SAndroid Build Coastguard Worker SessionUsage::kDestination, SocketTag(),
3415*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
3416*6777b538SAndroid Build Coastguard Worker /*disable_cert_verification_network_fetches=*/false);
3417*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SpdySessionPool::SpdySessionRequest> request;
3418*6777b538SAndroid Build Coastguard Worker bool is_blocking_request_for_session = false;
3419*6777b538SAndroid Build Coastguard Worker SpdySessionRequestDelegate request_delegate;
3420*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_session_pool_->RequestSession(
3421*6777b538SAndroid Build Coastguard Worker key2, /* enable_ip_based_pooling = */ true,
3422*6777b538SAndroid Build Coastguard Worker /* is_websocket = */ false, NetLogWithSource(),
3423*6777b538SAndroid Build Coastguard Worker /* on_blocking_request_destroyed_callback = */ base::RepeatingClosure(),
3424*6777b538SAndroid Build Coastguard Worker &request_delegate, &request, &is_blocking_request_for_session));
3425*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(request);
3426*6777b538SAndroid Build Coastguard Worker
3427*6777b538SAndroid Build Coastguard Worker HostResolverEndpointResult endpoint;
3428*6777b538SAndroid Build Coastguard Worker endpoint.ip_endpoints = {IPEndPoint(IPAddress(192, 168, 0, 2), 80)};
3429*6777b538SAndroid Build Coastguard Worker // Simulate DNS resolution completing, which should set up an alias.
3430*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(OnHostResolutionCallbackResult::kMayBeDeletedAsync,
3431*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->OnHostResolutionComplete(
3432*6777b538SAndroid Build Coastguard Worker key2, /* is_websocket = */ false, {endpoint},
3433*6777b538SAndroid Build Coastguard Worker /*aliases=*/{}));
3434*6777b538SAndroid Build Coastguard Worker
3435*6777b538SAndroid Build Coastguard Worker // Get a session for |key2|, which should return the session created earlier.
3436*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdySession> session2 =
3437*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->FindAvailableSession(
3438*6777b538SAndroid Build Coastguard Worker key2, /* enable_ip_based_pooling = */ true,
3439*6777b538SAndroid Build Coastguard Worker /* is_websocket = */ false, NetLogWithSource());
3440*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session2);
3441*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(session1.get(), session2.get());
3442*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(pool->IsStalled());
3443*6777b538SAndroid Build Coastguard Worker
3444*6777b538SAndroid Build Coastguard Worker // Trying to create a new connection should cause the pool to be stalled, and
3445*6777b538SAndroid Build Coastguard Worker // post a task asynchronously to try and close the session.
3446*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback3;
3447*6777b538SAndroid Build Coastguard Worker auto connection3 = std::make_unique<ClientSocketHandle>();
3448*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(
3449*6777b538SAndroid Build Coastguard Worker ERR_IO_PENDING,
3450*6777b538SAndroid Build Coastguard Worker connection3->Init(
3451*6777b538SAndroid Build Coastguard Worker ClientSocketPool::GroupId(
3452*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(url::kHttpScheme, "3.com", 80),
3453*6777b538SAndroid Build Coastguard Worker PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
3454*6777b538SAndroid Build Coastguard Worker SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
3455*6777b538SAndroid Build Coastguard Worker ClientSocketPool::SocketParams::CreateForHttpForTesting(),
3456*6777b538SAndroid Build Coastguard Worker std::nullopt /* proxy_annotation_tag */, DEFAULT_PRIORITY,
3457*6777b538SAndroid Build Coastguard Worker SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3458*6777b538SAndroid Build Coastguard Worker callback3.callback(), ClientSocketPool::ProxyAuthCallback(), pool,
3459*6777b538SAndroid Build Coastguard Worker NetLogWithSource()));
3460*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(pool->IsStalled());
3461*6777b538SAndroid Build Coastguard Worker
3462*6777b538SAndroid Build Coastguard Worker // The socket pool should close the connection asynchronously and establish a
3463*6777b538SAndroid Build Coastguard Worker // new connection.
3464*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(callback3.WaitForResult(), IsOk());
3465*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(pool->IsStalled());
3466*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session1);
3467*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session2);
3468*6777b538SAndroid Build Coastguard Worker }
3469*6777b538SAndroid Build Coastguard Worker
3470*6777b538SAndroid Build Coastguard Worker // Tests that when a SPDY session becomes idle, it closes itself if there is
3471*6777b538SAndroid Build Coastguard Worker // a lower layer pool stalled on the per-pool socket limit.
TEST_F(SpdySessionTest,CloseSessionOnIdleWhenPoolStalled)3472*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) {
3473*6777b538SAndroid Build Coastguard Worker ClientSocketPoolManager::set_max_sockets_per_group(
3474*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3475*6777b538SAndroid Build Coastguard Worker ClientSocketPoolManager::set_max_sockets_per_pool(
3476*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3477*6777b538SAndroid Build Coastguard Worker
3478*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3479*6777b538SAndroid Build Coastguard Worker MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
3480*6777b538SAndroid Build Coastguard Worker };
3481*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
3482*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3483*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame cancel1(
3484*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
3485*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
3486*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 1), CreateMockWrite(cancel1, 1),
3487*6777b538SAndroid Build Coastguard Worker };
3488*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, writes);
3489*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3490*6777b538SAndroid Build Coastguard Worker
3491*6777b538SAndroid Build Coastguard Worker MockRead http_reads[] = {
3492*6777b538SAndroid Build Coastguard Worker MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
3493*6777b538SAndroid Build Coastguard Worker };
3494*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
3495*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&http_data);
3496*6777b538SAndroid Build Coastguard Worker
3497*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3498*6777b538SAndroid Build Coastguard Worker
3499*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3500*6777b538SAndroid Build Coastguard Worker
3501*6777b538SAndroid Build Coastguard Worker ClientSocketPool* pool = http_session_->GetSocketPool(
3502*6777b538SAndroid Build Coastguard Worker HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct());
3503*6777b538SAndroid Build Coastguard Worker
3504*6777b538SAndroid Build Coastguard Worker // Create a SPDY session.
3505*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
3506*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(pool->IsStalled());
3507*6777b538SAndroid Build Coastguard Worker
3508*6777b538SAndroid Build Coastguard Worker // Create a stream using the session, and send a request.
3509*6777b538SAndroid Build Coastguard Worker
3510*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback1;
3511*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
3512*6777b538SAndroid Build Coastguard Worker SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, DEFAULT_PRIORITY,
3513*6777b538SAndroid Build Coastguard Worker NetLogWithSource());
3514*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1.get());
3515*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
3516*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
3517*6777b538SAndroid Build Coastguard Worker
3518*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers1(
3519*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
3520*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING, spdy_stream1->SendRequestHeaders(
3521*6777b538SAndroid Build Coastguard Worker std::move(headers1), NO_MORE_DATA_TO_SEND));
3522*6777b538SAndroid Build Coastguard Worker
3523*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3524*6777b538SAndroid Build Coastguard Worker
3525*6777b538SAndroid Build Coastguard Worker // Trying to create a new connection should cause the pool to be stalled, and
3526*6777b538SAndroid Build Coastguard Worker // post a task asynchronously to try and close the session.
3527*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback2;
3528*6777b538SAndroid Build Coastguard Worker auto connection2 = std::make_unique<ClientSocketHandle>();
3529*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(
3530*6777b538SAndroid Build Coastguard Worker ERR_IO_PENDING,
3531*6777b538SAndroid Build Coastguard Worker connection2->Init(
3532*6777b538SAndroid Build Coastguard Worker ClientSocketPool::GroupId(
3533*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(url::kHttpScheme, "2.com", 80),
3534*6777b538SAndroid Build Coastguard Worker PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
3535*6777b538SAndroid Build Coastguard Worker SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
3536*6777b538SAndroid Build Coastguard Worker ClientSocketPool::SocketParams::CreateForHttpForTesting(),
3537*6777b538SAndroid Build Coastguard Worker std::nullopt /* proxy_annotation_tag */, DEFAULT_PRIORITY,
3538*6777b538SAndroid Build Coastguard Worker SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3539*6777b538SAndroid Build Coastguard Worker callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool,
3540*6777b538SAndroid Build Coastguard Worker NetLogWithSource()));
3541*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(pool->IsStalled());
3542*6777b538SAndroid Build Coastguard Worker
3543*6777b538SAndroid Build Coastguard Worker // Running the message loop should cause the socket pool to ask the SPDY
3544*6777b538SAndroid Build Coastguard Worker // session to close an idle socket, but since the socket is in use, nothing
3545*6777b538SAndroid Build Coastguard Worker // happens.
3546*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3547*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(pool->IsStalled());
3548*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(callback2.have_result());
3549*6777b538SAndroid Build Coastguard Worker
3550*6777b538SAndroid Build Coastguard Worker // Cancelling the request should result in the session's socket being
3551*6777b538SAndroid Build Coastguard Worker // closed, since the pool is stalled.
3552*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1.get());
3553*6777b538SAndroid Build Coastguard Worker spdy_stream1->Cancel(ERR_ABORTED);
3554*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3555*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(pool->IsStalled());
3556*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(callback2.WaitForResult(), IsOk());
3557*6777b538SAndroid Build Coastguard Worker }
3558*6777b538SAndroid Build Coastguard Worker
3559*6777b538SAndroid Build Coastguard Worker // Verify that SpdySessionKey and therefore SpdySession is different when
3560*6777b538SAndroid Build Coastguard Worker // privacy mode is enabled or disabled.
TEST_F(SpdySessionTest,SpdySessionKeyPrivacyMode)3561*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, SpdySessionKeyPrivacyMode) {
3562*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3563*6777b538SAndroid Build Coastguard Worker
3564*6777b538SAndroid Build Coastguard Worker HostPortPair host_port_pair("www.example.org", 443);
3565*6777b538SAndroid Build Coastguard Worker SpdySessionKey key_privacy_enabled(
3566*6777b538SAndroid Build Coastguard Worker host_port_pair, PRIVACY_MODE_ENABLED, ProxyChain::Direct(),
3567*6777b538SAndroid Build Coastguard Worker SessionUsage::kDestination, SocketTag(), NetworkAnonymizationKey(),
3568*6777b538SAndroid Build Coastguard Worker SecureDnsPolicy::kAllow,
3569*6777b538SAndroid Build Coastguard Worker /*disable_cert_verification_network_fetches=*/false);
3570*6777b538SAndroid Build Coastguard Worker SpdySessionKey key_privacy_disabled(
3571*6777b538SAndroid Build Coastguard Worker host_port_pair, PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
3572*6777b538SAndroid Build Coastguard Worker SessionUsage::kDestination, SocketTag(), NetworkAnonymizationKey(),
3573*6777b538SAndroid Build Coastguard Worker SecureDnsPolicy::kAllow,
3574*6777b538SAndroid Build Coastguard Worker /*disable_cert_verification_network_fetches=*/false);
3575*6777b538SAndroid Build Coastguard Worker
3576*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
3577*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
3578*6777b538SAndroid Build Coastguard Worker
3579*6777b538SAndroid Build Coastguard Worker // Add SpdySession with PrivacyMode Enabled to the pool.
3580*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdySession> session_privacy_enabled =
3581*6777b538SAndroid Build Coastguard Worker CreateFakeSpdySession(spdy_session_pool_, key_privacy_enabled);
3582*6777b538SAndroid Build Coastguard Worker
3583*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
3584*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
3585*6777b538SAndroid Build Coastguard Worker
3586*6777b538SAndroid Build Coastguard Worker // Add SpdySession with PrivacyMode Disabled to the pool.
3587*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdySession> session_privacy_disabled =
3588*6777b538SAndroid Build Coastguard Worker CreateFakeSpdySession(spdy_session_pool_, key_privacy_disabled);
3589*6777b538SAndroid Build Coastguard Worker
3590*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
3591*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
3592*6777b538SAndroid Build Coastguard Worker
3593*6777b538SAndroid Build Coastguard Worker session_privacy_enabled->CloseSessionOnError(ERR_ABORTED, std::string());
3594*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
3595*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
3596*6777b538SAndroid Build Coastguard Worker
3597*6777b538SAndroid Build Coastguard Worker session_privacy_disabled->CloseSessionOnError(ERR_ABORTED, std::string());
3598*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
3599*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
3600*6777b538SAndroid Build Coastguard Worker }
3601*6777b538SAndroid Build Coastguard Worker
3602*6777b538SAndroid Build Coastguard Worker // Delegate that creates another stream when its stream is closed.
3603*6777b538SAndroid Build Coastguard Worker class StreamCreatingDelegate : public test::StreamDelegateDoNothing {
3604*6777b538SAndroid Build Coastguard Worker public:
StreamCreatingDelegate(const base::WeakPtr<SpdyStream> & stream,const base::WeakPtr<SpdySession> & session)3605*6777b538SAndroid Build Coastguard Worker StreamCreatingDelegate(const base::WeakPtr<SpdyStream>& stream,
3606*6777b538SAndroid Build Coastguard Worker const base::WeakPtr<SpdySession>& session)
3607*6777b538SAndroid Build Coastguard Worker : StreamDelegateDoNothing(stream),
3608*6777b538SAndroid Build Coastguard Worker session_(session) {}
3609*6777b538SAndroid Build Coastguard Worker
3610*6777b538SAndroid Build Coastguard Worker ~StreamCreatingDelegate() override = default;
3611*6777b538SAndroid Build Coastguard Worker
OnClose(int status)3612*6777b538SAndroid Build Coastguard Worker void OnClose(int status) override {
3613*6777b538SAndroid Build Coastguard Worker GURL url(kDefaultUrl);
3614*6777b538SAndroid Build Coastguard Worker std::ignore =
3615*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_, url,
3616*6777b538SAndroid Build Coastguard Worker MEDIUM, NetLogWithSource());
3617*6777b538SAndroid Build Coastguard Worker }
3618*6777b538SAndroid Build Coastguard Worker
3619*6777b538SAndroid Build Coastguard Worker private:
3620*6777b538SAndroid Build Coastguard Worker const base::WeakPtr<SpdySession> session_;
3621*6777b538SAndroid Build Coastguard Worker };
3622*6777b538SAndroid Build Coastguard Worker
3623*6777b538SAndroid Build Coastguard Worker // Create another stream in response to a stream being reset. Nothing
3624*6777b538SAndroid Build Coastguard Worker // should blow up. This is a regression test for
3625*6777b538SAndroid Build Coastguard Worker // http://crbug.com/263690 .
TEST_F(SpdySessionTest,CreateStreamOnStreamReset)3626*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, CreateStreamOnStreamReset) {
3627*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
3628*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
3629*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
3630*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0),
3631*6777b538SAndroid Build Coastguard Worker };
3632*6777b538SAndroid Build Coastguard Worker
3633*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame rst(
3634*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_REFUSED_STREAM));
3635*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3636*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(rst, 2),
3637*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 3), MockRead(ASYNC, 0, 4) // EOF
3638*6777b538SAndroid Build Coastguard Worker };
3639*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
3640*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3641*6777b538SAndroid Build Coastguard Worker
3642*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3643*6777b538SAndroid Build Coastguard Worker
3644*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3645*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
3646*6777b538SAndroid Build Coastguard Worker
3647*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
3648*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
3649*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
3650*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream);
3651*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream->stream_id());
3652*6777b538SAndroid Build Coastguard Worker
3653*6777b538SAndroid Build Coastguard Worker StreamCreatingDelegate delegate(spdy_stream, session_);
3654*6777b538SAndroid Build Coastguard Worker spdy_stream->SetDelegate(&delegate);
3655*6777b538SAndroid Build Coastguard Worker
3656*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
3657*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
3658*6777b538SAndroid Build Coastguard Worker spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
3659*6777b538SAndroid Build Coastguard Worker
3660*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream->stream_id());
3661*6777b538SAndroid Build Coastguard Worker
3662*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3663*6777b538SAndroid Build Coastguard Worker
3664*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream->stream_id());
3665*6777b538SAndroid Build Coastguard Worker
3666*6777b538SAndroid Build Coastguard Worker // Cause the stream to be reset, which should cause another stream
3667*6777b538SAndroid Build Coastguard Worker // to be created.
3668*6777b538SAndroid Build Coastguard Worker data.Resume();
3669*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3670*6777b538SAndroid Build Coastguard Worker
3671*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream);
3672*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate.StreamIsClosed());
3673*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, num_active_streams());
3674*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, num_created_streams());
3675*6777b538SAndroid Build Coastguard Worker
3676*6777b538SAndroid Build Coastguard Worker data.Resume();
3677*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3678*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
3679*6777b538SAndroid Build Coastguard Worker }
3680*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,UpdateStreamsSendWindowSize)3681*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, UpdateStreamsSendWindowSize) {
3682*6777b538SAndroid Build Coastguard Worker // Set spdy::SETTINGS_INITIAL_WINDOW_SIZE to a small number so that
3683*6777b538SAndroid Build Coastguard Worker // WINDOW_UPDATE gets sent.
3684*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap new_settings;
3685*6777b538SAndroid Build Coastguard Worker int32_t window_size = 1;
3686*6777b538SAndroid Build Coastguard Worker new_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = window_size;
3687*6777b538SAndroid Build Coastguard Worker
3688*6777b538SAndroid Build Coastguard Worker // Set up the socket so we read a SETTINGS frame that sets
3689*6777b538SAndroid Build Coastguard Worker // INITIAL_WINDOW_SIZE.
3690*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_frame(
3691*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(new_settings));
3692*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3693*6777b538SAndroid Build Coastguard Worker CreateMockRead(settings_frame, 0), MockRead(ASYNC, ERR_IO_PENDING, 1),
3694*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 2) // EOF
3695*6777b538SAndroid Build Coastguard Worker };
3696*6777b538SAndroid Build Coastguard Worker
3697*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
3698*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
3699*6777b538SAndroid Build Coastguard Worker CreateMockWrite(settings_ack, 3),
3700*6777b538SAndroid Build Coastguard Worker };
3701*6777b538SAndroid Build Coastguard Worker
3702*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
3703*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3704*6777b538SAndroid Build Coastguard Worker
3705*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3706*6777b538SAndroid Build Coastguard Worker
3707*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3708*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
3709*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 =
3710*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
3711*6777b538SAndroid Build Coastguard Worker MEDIUM, NetLogWithSource());
3712*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream1);
3713*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback1;
3714*6777b538SAndroid Build Coastguard Worker EXPECT_NE(spdy_stream1->send_window_size(), window_size);
3715*6777b538SAndroid Build Coastguard Worker
3716*6777b538SAndroid Build Coastguard Worker // Process the SETTINGS frame.
3717*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3718*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(stream_initial_send_window_size(), window_size);
3719*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(spdy_stream1->send_window_size(), window_size);
3720*6777b538SAndroid Build Coastguard Worker
3721*6777b538SAndroid Build Coastguard Worker // Release the first one, this will allow the second to be created.
3722*6777b538SAndroid Build Coastguard Worker spdy_stream1->Cancel(ERR_ABORTED);
3723*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
3724*6777b538SAndroid Build Coastguard Worker
3725*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 =
3726*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
3727*6777b538SAndroid Build Coastguard Worker MEDIUM, NetLogWithSource());
3728*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream2);
3729*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
3730*6777b538SAndroid Build Coastguard Worker spdy_stream2->Cancel(ERR_ABORTED);
3731*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream2);
3732*6777b538SAndroid Build Coastguard Worker
3733*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_);
3734*6777b538SAndroid Build Coastguard Worker data.Resume();
3735*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3736*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
3737*6777b538SAndroid Build Coastguard Worker }
3738*6777b538SAndroid Build Coastguard Worker
3739*6777b538SAndroid Build Coastguard Worker // SpdySession::{Increase,Decrease}RecvWindowSize should properly
3740*6777b538SAndroid Build Coastguard Worker // adjust the session receive window size. In addition,
3741*6777b538SAndroid Build Coastguard Worker // SpdySession::IncreaseRecvWindowSize should trigger
3742*6777b538SAndroid Build Coastguard Worker // sending a WINDOW_UPDATE frame for a large enough delta.
TEST_F(SpdySessionTest,AdjustRecvWindowSize)3743*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, AdjustRecvWindowSize) {
3744*6777b538SAndroid Build Coastguard Worker const int32_t initial_window_size = kDefaultInitialWindowSize;
3745*6777b538SAndroid Build Coastguard Worker const int32_t delta_window_size = 100;
3746*6777b538SAndroid Build Coastguard Worker
3747*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3748*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2) // EOF
3749*6777b538SAndroid Build Coastguard Worker };
3750*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame window_update(spdy_util_.ConstructSpdyWindowUpdate(
3751*6777b538SAndroid Build Coastguard Worker spdy::kSessionFlowControlStreamId,
3752*6777b538SAndroid Build Coastguard Worker initial_window_size + delta_window_size));
3753*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
3754*6777b538SAndroid Build Coastguard Worker CreateMockWrite(window_update, 0),
3755*6777b538SAndroid Build Coastguard Worker };
3756*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
3757*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3758*6777b538SAndroid Build Coastguard Worker
3759*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3760*6777b538SAndroid Build Coastguard Worker
3761*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3762*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
3763*6777b538SAndroid Build Coastguard Worker
3764*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_recv_window_size());
3765*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
3766*6777b538SAndroid Build Coastguard Worker
3767*6777b538SAndroid Build Coastguard Worker IncreaseRecvWindowSize(delta_window_size);
3768*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size + delta_window_size,
3769*6777b538SAndroid Build Coastguard Worker session_recv_window_size());
3770*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(delta_window_size, session_unacked_recv_window_bytes());
3771*6777b538SAndroid Build Coastguard Worker
3772*6777b538SAndroid Build Coastguard Worker // Should trigger sending a WINDOW_UPDATE frame.
3773*6777b538SAndroid Build Coastguard Worker IncreaseRecvWindowSize(initial_window_size);
3774*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size + delta_window_size + initial_window_size,
3775*6777b538SAndroid Build Coastguard Worker session_recv_window_size());
3776*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
3777*6777b538SAndroid Build Coastguard Worker
3778*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3779*6777b538SAndroid Build Coastguard Worker
3780*6777b538SAndroid Build Coastguard Worker // DecreaseRecvWindowSize() expects |in_io_loop_| to be true.
3781*6777b538SAndroid Build Coastguard Worker set_in_io_loop(true);
3782*6777b538SAndroid Build Coastguard Worker DecreaseRecvWindowSize(initial_window_size + delta_window_size +
3783*6777b538SAndroid Build Coastguard Worker initial_window_size);
3784*6777b538SAndroid Build Coastguard Worker set_in_io_loop(false);
3785*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_recv_window_size());
3786*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
3787*6777b538SAndroid Build Coastguard Worker
3788*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_);
3789*6777b538SAndroid Build Coastguard Worker data.Resume();
3790*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3791*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
3792*6777b538SAndroid Build Coastguard Worker }
3793*6777b538SAndroid Build Coastguard Worker
3794*6777b538SAndroid Build Coastguard Worker // SpdySession::{Increase,Decrease}RecvWindowSize should properly
3795*6777b538SAndroid Build Coastguard Worker // adjust the session receive window size. In addition,
3796*6777b538SAndroid Build Coastguard Worker // SpdySession::IncreaseRecvWindowSize should trigger
3797*6777b538SAndroid Build Coastguard Worker // sending a WINDOW_UPDATE frame for a small delta after
3798*6777b538SAndroid Build Coastguard Worker // kDefaultTimeToBufferSmallWindowUpdates time has passed.
TEST_F(SpdySessionTestWithMockTime,FlowControlSlowReads)3799*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTestWithMockTime, FlowControlSlowReads) {
3800*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3801*6777b538SAndroid Build Coastguard Worker MockRead(SYNCHRONOUS, 0, 0) // EOF
3802*6777b538SAndroid Build Coastguard Worker };
3803*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
3804*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3805*6777b538SAndroid Build Coastguard Worker
3806*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3807*6777b538SAndroid Build Coastguard Worker session_ = CreateFakeSpdySession(spdy_session_pool_, key_);
3808*6777b538SAndroid Build Coastguard Worker
3809*6777b538SAndroid Build Coastguard Worker // Re-enable the time-based window update buffering. The test harness
3810*6777b538SAndroid Build Coastguard Worker // disables it by default to prevent flakiness.
3811*6777b538SAndroid Build Coastguard Worker session_->SetTimeToBufferSmallWindowUpdates(
3812*6777b538SAndroid Build Coastguard Worker kDefaultTimeToBufferSmallWindowUpdates);
3813*6777b538SAndroid Build Coastguard Worker
3814*6777b538SAndroid Build Coastguard Worker const int32_t initial_window_size = kDefaultInitialWindowSize;
3815*6777b538SAndroid Build Coastguard Worker const int32_t delta_window_size = 100;
3816*6777b538SAndroid Build Coastguard Worker
3817*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_recv_window_size());
3818*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
3819*6777b538SAndroid Build Coastguard Worker
3820*6777b538SAndroid Build Coastguard Worker // Receive data, consuming some of the receive window.
3821*6777b538SAndroid Build Coastguard Worker set_in_io_loop(true);
3822*6777b538SAndroid Build Coastguard Worker DecreaseRecvWindowSize(delta_window_size);
3823*6777b538SAndroid Build Coastguard Worker set_in_io_loop(false);
3824*6777b538SAndroid Build Coastguard Worker
3825*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size - delta_window_size,
3826*6777b538SAndroid Build Coastguard Worker session_recv_window_size());
3827*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
3828*6777b538SAndroid Build Coastguard Worker
3829*6777b538SAndroid Build Coastguard Worker // Consume the data, returning some of the receive window (locally)
3830*6777b538SAndroid Build Coastguard Worker IncreaseRecvWindowSize(delta_window_size);
3831*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_recv_window_size());
3832*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(delta_window_size, session_unacked_recv_window_bytes());
3833*6777b538SAndroid Build Coastguard Worker
3834*6777b538SAndroid Build Coastguard Worker // Receive data, consuming some of the receive window.
3835*6777b538SAndroid Build Coastguard Worker set_in_io_loop(true);
3836*6777b538SAndroid Build Coastguard Worker DecreaseRecvWindowSize(delta_window_size);
3837*6777b538SAndroid Build Coastguard Worker set_in_io_loop(false);
3838*6777b538SAndroid Build Coastguard Worker
3839*6777b538SAndroid Build Coastguard Worker // Window updates after a configured time second should force a WINDOW_UPDATE,
3840*6777b538SAndroid Build Coastguard Worker // draining the unacked window bytes.
3841*6777b538SAndroid Build Coastguard Worker AdvanceClock(kDefaultTimeToBufferSmallWindowUpdates);
3842*6777b538SAndroid Build Coastguard Worker IncreaseRecvWindowSize(delta_window_size);
3843*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_recv_window_size());
3844*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
3845*6777b538SAndroid Build Coastguard Worker }
3846*6777b538SAndroid Build Coastguard Worker
3847*6777b538SAndroid Build Coastguard Worker // SpdySession::{Increase,Decrease}SendWindowSize should properly
3848*6777b538SAndroid Build Coastguard Worker // adjust the session send window size when the "enable_spdy_31" flag
3849*6777b538SAndroid Build Coastguard Worker // is set.
TEST_F(SpdySessionTest,AdjustSendWindowSize)3850*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, AdjustSendWindowSize) {
3851*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3852*6777b538SAndroid Build Coastguard Worker MockRead(SYNCHRONOUS, 0, 0) // EOF
3853*6777b538SAndroid Build Coastguard Worker };
3854*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
3855*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3856*6777b538SAndroid Build Coastguard Worker
3857*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3858*6777b538SAndroid Build Coastguard Worker session_ = CreateFakeSpdySession(spdy_session_pool_, key_);
3859*6777b538SAndroid Build Coastguard Worker
3860*6777b538SAndroid Build Coastguard Worker const int32_t initial_window_size = kDefaultInitialWindowSize;
3861*6777b538SAndroid Build Coastguard Worker const int32_t delta_window_size = 100;
3862*6777b538SAndroid Build Coastguard Worker
3863*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_send_window_size());
3864*6777b538SAndroid Build Coastguard Worker
3865*6777b538SAndroid Build Coastguard Worker IncreaseSendWindowSize(delta_window_size);
3866*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size + delta_window_size,
3867*6777b538SAndroid Build Coastguard Worker session_send_window_size());
3868*6777b538SAndroid Build Coastguard Worker
3869*6777b538SAndroid Build Coastguard Worker DecreaseSendWindowSize(delta_window_size);
3870*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_send_window_size());
3871*6777b538SAndroid Build Coastguard Worker }
3872*6777b538SAndroid Build Coastguard Worker
3873*6777b538SAndroid Build Coastguard Worker // Incoming data for an inactive stream should not cause the session
3874*6777b538SAndroid Build Coastguard Worker // receive window size to decrease, but it should cause the unacked
3875*6777b538SAndroid Build Coastguard Worker // bytes to increase.
TEST_F(SpdySessionTest,SessionFlowControlInactiveStream)3876*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, SessionFlowControlInactiveStream) {
3877*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyDataFrame(1, false));
3878*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3879*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp, 0), MockRead(ASYNC, ERR_IO_PENDING, 1),
3880*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 2) // EOF
3881*6777b538SAndroid Build Coastguard Worker };
3882*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, base::span<MockWrite>());
3883*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3884*6777b538SAndroid Build Coastguard Worker
3885*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3886*6777b538SAndroid Build Coastguard Worker
3887*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3888*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
3889*6777b538SAndroid Build Coastguard Worker
3890*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
3891*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
3892*6777b538SAndroid Build Coastguard Worker
3893*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3894*6777b538SAndroid Build Coastguard Worker
3895*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
3896*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kUploadDataSize, session_unacked_recv_window_bytes());
3897*6777b538SAndroid Build Coastguard Worker
3898*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_);
3899*6777b538SAndroid Build Coastguard Worker data.Resume();
3900*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3901*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
3902*6777b538SAndroid Build Coastguard Worker }
3903*6777b538SAndroid Build Coastguard Worker
3904*6777b538SAndroid Build Coastguard Worker // The frame header is not included in flow control, but frame payload
3905*6777b538SAndroid Build Coastguard Worker // (including optional pad length and padding) is.
TEST_F(SpdySessionTest,SessionFlowControlPadding)3906*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, SessionFlowControlPadding) {
3907*6777b538SAndroid Build Coastguard Worker const int padding_length = 42;
3908*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp(
3909*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, kUploadData, false, padding_length));
3910*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3911*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp, 0), MockRead(ASYNC, ERR_IO_PENDING, 1),
3912*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 2) // EOF
3913*6777b538SAndroid Build Coastguard Worker };
3914*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, base::span<MockWrite>());
3915*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3916*6777b538SAndroid Build Coastguard Worker
3917*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3918*6777b538SAndroid Build Coastguard Worker
3919*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3920*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
3921*6777b538SAndroid Build Coastguard Worker
3922*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
3923*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
3924*6777b538SAndroid Build Coastguard Worker
3925*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3926*6777b538SAndroid Build Coastguard Worker
3927*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
3928*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kUploadDataSize + padding_length,
3929*6777b538SAndroid Build Coastguard Worker session_unacked_recv_window_bytes());
3930*6777b538SAndroid Build Coastguard Worker
3931*6777b538SAndroid Build Coastguard Worker data.Resume();
3932*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3933*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
3934*6777b538SAndroid Build Coastguard Worker }
3935*6777b538SAndroid Build Coastguard Worker
3936*6777b538SAndroid Build Coastguard Worker // Peer sends more data than stream level receiving flow control window.
TEST_F(SpdySessionTest,StreamFlowControlTooMuchData)3937*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, StreamFlowControlTooMuchData) {
3938*6777b538SAndroid Build Coastguard Worker const int32_t stream_max_recv_window_size = 1024;
3939*6777b538SAndroid Build Coastguard Worker const int32_t data_frame_size = 2 * stream_max_recv_window_size;
3940*6777b538SAndroid Build Coastguard Worker
3941*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
3942*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3943*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
3944*6777b538SAndroid Build Coastguard Worker 1, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
3945*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
3946*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0), CreateMockWrite(rst, 4),
3947*6777b538SAndroid Build Coastguard Worker };
3948*6777b538SAndroid Build Coastguard Worker
3949*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp(
3950*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3951*6777b538SAndroid Build Coastguard Worker const std::string payload(data_frame_size, 'a');
3952*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame data_frame(
3953*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, payload, false));
3954*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
3955*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
3956*6777b538SAndroid Build Coastguard Worker CreateMockRead(data_frame, 3), MockRead(ASYNC, ERR_IO_PENDING, 5),
3957*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 6),
3958*6777b538SAndroid Build Coastguard Worker };
3959*6777b538SAndroid Build Coastguard Worker
3960*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
3961*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
3962*6777b538SAndroid Build Coastguard Worker
3963*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
3964*6777b538SAndroid Build Coastguard Worker
3965*6777b538SAndroid Build Coastguard Worker session_deps_.http2_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] =
3966*6777b538SAndroid Build Coastguard Worker stream_max_recv_window_size;
3967*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
3968*6777b538SAndroid Build Coastguard Worker
3969*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
3970*6777b538SAndroid Build Coastguard Worker
3971*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
3972*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
3973*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
3974*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size());
3975*6777b538SAndroid Build Coastguard Worker
3976*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate(spdy_stream);
3977*6777b538SAndroid Build Coastguard Worker spdy_stream->SetDelegate(&delegate);
3978*6777b538SAndroid Build Coastguard Worker
3979*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
3980*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
3981*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders(
3982*6777b538SAndroid Build Coastguard Worker std::move(headers), NO_MORE_DATA_TO_SEND));
3983*6777b538SAndroid Build Coastguard Worker
3984*6777b538SAndroid Build Coastguard Worker // Request and response.
3985*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3986*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream->stream_id());
3987*6777b538SAndroid Build Coastguard Worker
3988*6777b538SAndroid Build Coastguard Worker // Too large data frame causes flow control error, should close stream.
3989*6777b538SAndroid Build Coastguard Worker data.Resume();
3990*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3991*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream);
3992*6777b538SAndroid Build Coastguard Worker
3993*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_);
3994*6777b538SAndroid Build Coastguard Worker data.Resume();
3995*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
3996*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
3997*6777b538SAndroid Build Coastguard Worker }
3998*6777b538SAndroid Build Coastguard Worker
3999*6777b538SAndroid Build Coastguard Worker // Regression test for a bug that was caused by including unsent WINDOW_UPDATE
4000*6777b538SAndroid Build Coastguard Worker // deltas in the receiving window size when checking incoming frames for flow
4001*6777b538SAndroid Build Coastguard Worker // control errors at session level.
TEST_F(SpdySessionTest,SessionFlowControlTooMuchDataTwoDataFrames)4002*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) {
4003*6777b538SAndroid Build Coastguard Worker const int32_t session_max_recv_window_size = 500;
4004*6777b538SAndroid Build Coastguard Worker const int32_t first_data_frame_size = 200;
4005*6777b538SAndroid Build Coastguard Worker const int32_t second_data_frame_size = 400;
4006*6777b538SAndroid Build Coastguard Worker
4007*6777b538SAndroid Build Coastguard Worker // First data frame should not trigger a WINDOW_UPDATE.
4008*6777b538SAndroid Build Coastguard Worker ASSERT_GT(session_max_recv_window_size / 2, first_data_frame_size);
4009*6777b538SAndroid Build Coastguard Worker // Second data frame would be fine had there been a WINDOW_UPDATE.
4010*6777b538SAndroid Build Coastguard Worker ASSERT_GT(session_max_recv_window_size, second_data_frame_size);
4011*6777b538SAndroid Build Coastguard Worker // But in fact, the two data frames together overflow the receiving window at
4012*6777b538SAndroid Build Coastguard Worker // session level.
4013*6777b538SAndroid Build Coastguard Worker ASSERT_LT(session_max_recv_window_size,
4014*6777b538SAndroid Build Coastguard Worker first_data_frame_size + second_data_frame_size);
4015*6777b538SAndroid Build Coastguard Worker
4016*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
4017*6777b538SAndroid Build Coastguard Worker 0, spdy::ERROR_CODE_FLOW_CONTROL_ERROR,
4018*6777b538SAndroid Build Coastguard Worker "delta_window_size is 400 in DecreaseRecvWindowSize, which is larger "
4019*6777b538SAndroid Build Coastguard Worker "than the receive window size of 300"));
4020*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
4021*6777b538SAndroid Build Coastguard Worker CreateMockWrite(goaway, 4),
4022*6777b538SAndroid Build Coastguard Worker };
4023*6777b538SAndroid Build Coastguard Worker
4024*6777b538SAndroid Build Coastguard Worker const std::string first_data_frame(first_data_frame_size, 'a');
4025*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame first(
4026*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, first_data_frame, false));
4027*6777b538SAndroid Build Coastguard Worker const std::string second_data_frame(second_data_frame_size, 'b');
4028*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame second(
4029*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, second_data_frame, false));
4030*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
4031*6777b538SAndroid Build Coastguard Worker CreateMockRead(first, 0), MockRead(ASYNC, ERR_IO_PENDING, 1),
4032*6777b538SAndroid Build Coastguard Worker CreateMockRead(second, 2), MockRead(ASYNC, 0, 3),
4033*6777b538SAndroid Build Coastguard Worker };
4034*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
4035*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4036*6777b538SAndroid Build Coastguard Worker
4037*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4038*6777b538SAndroid Build Coastguard Worker
4039*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4040*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4041*6777b538SAndroid Build Coastguard Worker // Setting session level receiving window size to smaller than initial is not
4042*6777b538SAndroid Build Coastguard Worker // possible via SpdySessionPoolPeer.
4043*6777b538SAndroid Build Coastguard Worker set_session_recv_window_size(session_max_recv_window_size);
4044*6777b538SAndroid Build Coastguard Worker
4045*6777b538SAndroid Build Coastguard Worker // First data frame is immediately consumed and does not trigger
4046*6777b538SAndroid Build Coastguard Worker // WINDOW_UPDATE.
4047*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4048*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(first_data_frame_size, session_unacked_recv_window_bytes());
4049*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(session_max_recv_window_size, session_recv_window_size());
4050*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsAvailable());
4051*6777b538SAndroid Build Coastguard Worker
4052*6777b538SAndroid Build Coastguard Worker // Second data frame overflows receiving window, causes session to close.
4053*6777b538SAndroid Build Coastguard Worker data.Resume();
4054*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4055*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsDraining());
4056*6777b538SAndroid Build Coastguard Worker }
4057*6777b538SAndroid Build Coastguard Worker
4058*6777b538SAndroid Build Coastguard Worker // Regression test for a bug that was caused by including unsent WINDOW_UPDATE
4059*6777b538SAndroid Build Coastguard Worker // deltas in the receiving window size when checking incoming data frames for
4060*6777b538SAndroid Build Coastguard Worker // flow control errors at stream level.
TEST_F(SpdySessionTest,StreamFlowControlTooMuchDataTwoDataFrames)4061*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) {
4062*6777b538SAndroid Build Coastguard Worker const int32_t stream_max_recv_window_size = 500;
4063*6777b538SAndroid Build Coastguard Worker const int32_t first_data_frame_size = 200;
4064*6777b538SAndroid Build Coastguard Worker const int32_t second_data_frame_size = 400;
4065*6777b538SAndroid Build Coastguard Worker
4066*6777b538SAndroid Build Coastguard Worker // First data frame should not trigger a WINDOW_UPDATE.
4067*6777b538SAndroid Build Coastguard Worker ASSERT_GT(stream_max_recv_window_size / 2, first_data_frame_size);
4068*6777b538SAndroid Build Coastguard Worker // Second data frame would be fine had there been a WINDOW_UPDATE.
4069*6777b538SAndroid Build Coastguard Worker ASSERT_GT(stream_max_recv_window_size, second_data_frame_size);
4070*6777b538SAndroid Build Coastguard Worker // But in fact, they should overflow the receiving window at stream level.
4071*6777b538SAndroid Build Coastguard Worker ASSERT_LT(stream_max_recv_window_size,
4072*6777b538SAndroid Build Coastguard Worker first_data_frame_size + second_data_frame_size);
4073*6777b538SAndroid Build Coastguard Worker
4074*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
4075*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
4076*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
4077*6777b538SAndroid Build Coastguard Worker 1, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
4078*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
4079*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0), CreateMockWrite(rst, 6),
4080*6777b538SAndroid Build Coastguard Worker };
4081*6777b538SAndroid Build Coastguard Worker
4082*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp(
4083*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4084*6777b538SAndroid Build Coastguard Worker const std::string first_data_frame(first_data_frame_size, 'a');
4085*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame first(
4086*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, first_data_frame, false));
4087*6777b538SAndroid Build Coastguard Worker const std::string second_data_frame(second_data_frame_size, 'b');
4088*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame second(
4089*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, second_data_frame, false));
4090*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
4091*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
4092*6777b538SAndroid Build Coastguard Worker CreateMockRead(first, 3), MockRead(ASYNC, ERR_IO_PENDING, 4),
4093*6777b538SAndroid Build Coastguard Worker CreateMockRead(second, 5), MockRead(ASYNC, ERR_IO_PENDING, 7),
4094*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 8),
4095*6777b538SAndroid Build Coastguard Worker };
4096*6777b538SAndroid Build Coastguard Worker
4097*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
4098*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4099*6777b538SAndroid Build Coastguard Worker
4100*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4101*6777b538SAndroid Build Coastguard Worker
4102*6777b538SAndroid Build Coastguard Worker session_deps_.http2_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] =
4103*6777b538SAndroid Build Coastguard Worker stream_max_recv_window_size;
4104*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4105*6777b538SAndroid Build Coastguard Worker
4106*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4107*6777b538SAndroid Build Coastguard Worker
4108*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
4109*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
4110*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
4111*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate(spdy_stream);
4112*6777b538SAndroid Build Coastguard Worker spdy_stream->SetDelegate(&delegate);
4113*6777b538SAndroid Build Coastguard Worker
4114*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
4115*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
4116*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders(
4117*6777b538SAndroid Build Coastguard Worker std::move(headers), NO_MORE_DATA_TO_SEND));
4118*6777b538SAndroid Build Coastguard Worker
4119*6777b538SAndroid Build Coastguard Worker // Request and response.
4120*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4121*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(spdy_stream->IsLocallyClosed());
4122*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size());
4123*6777b538SAndroid Build Coastguard Worker
4124*6777b538SAndroid Build Coastguard Worker // First data frame.
4125*6777b538SAndroid Build Coastguard Worker data.Resume();
4126*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4127*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(spdy_stream->IsLocallyClosed());
4128*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(stream_max_recv_window_size - first_data_frame_size,
4129*6777b538SAndroid Build Coastguard Worker spdy_stream->recv_window_size());
4130*6777b538SAndroid Build Coastguard Worker
4131*6777b538SAndroid Build Coastguard Worker // Consume first data frame. This does not trigger a WINDOW_UPDATE.
4132*6777b538SAndroid Build Coastguard Worker std::string received_data = delegate.TakeReceivedData();
4133*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(first_data_frame_size), received_data.size());
4134*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size());
4135*6777b538SAndroid Build Coastguard Worker
4136*6777b538SAndroid Build Coastguard Worker // Second data frame overflows receiving window, causes the stream to close.
4137*6777b538SAndroid Build Coastguard Worker data.Resume();
4138*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4139*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream.get());
4140*6777b538SAndroid Build Coastguard Worker
4141*6777b538SAndroid Build Coastguard Worker // RST_STREAM
4142*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_);
4143*6777b538SAndroid Build Coastguard Worker data.Resume();
4144*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4145*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
4146*6777b538SAndroid Build Coastguard Worker }
4147*6777b538SAndroid Build Coastguard Worker
4148*6777b538SAndroid Build Coastguard Worker // A delegate that drops any received data.
4149*6777b538SAndroid Build Coastguard Worker class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate {
4150*6777b538SAndroid Build Coastguard Worker public:
DropReceivedDataDelegate(const base::WeakPtr<SpdyStream> & stream,std::string_view data)4151*6777b538SAndroid Build Coastguard Worker DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream,
4152*6777b538SAndroid Build Coastguard Worker std::string_view data)
4153*6777b538SAndroid Build Coastguard Worker : StreamDelegateSendImmediate(stream, data) {}
4154*6777b538SAndroid Build Coastguard Worker
4155*6777b538SAndroid Build Coastguard Worker ~DropReceivedDataDelegate() override = default;
4156*6777b538SAndroid Build Coastguard Worker
4157*6777b538SAndroid Build Coastguard Worker // Drop any received data.
OnDataReceived(std::unique_ptr<SpdyBuffer> buffer)4158*6777b538SAndroid Build Coastguard Worker void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override {}
4159*6777b538SAndroid Build Coastguard Worker };
4160*6777b538SAndroid Build Coastguard Worker
4161*6777b538SAndroid Build Coastguard Worker // Send data back and forth but use a delegate that drops its received
4162*6777b538SAndroid Build Coastguard Worker // data. The receive window should still increase to its original
4163*6777b538SAndroid Build Coastguard Worker // value, i.e. we shouldn't "leak" receive window bytes.
TEST_F(SpdySessionTest,SessionFlowControlNoReceiveLeaks)4164*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, SessionFlowControlNoReceiveLeaks) {
4165*6777b538SAndroid Build Coastguard Worker const int32_t kMsgDataSize = 100;
4166*6777b538SAndroid Build Coastguard Worker const std::string msg_data(kMsgDataSize, 'a');
4167*6777b538SAndroid Build Coastguard Worker
4168*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
4169*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 1, kMsgDataSize, MEDIUM, nullptr, 0));
4170*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame msg(
4171*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, msg_data, false));
4172*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
4173*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0), CreateMockWrite(msg, 2),
4174*6777b538SAndroid Build Coastguard Worker };
4175*6777b538SAndroid Build Coastguard Worker
4176*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp(
4177*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4178*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame echo(
4179*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, msg_data, false));
4180*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame window_update(spdy_util_.ConstructSpdyWindowUpdate(
4181*6777b538SAndroid Build Coastguard Worker spdy::kSessionFlowControlStreamId, kMsgDataSize));
4182*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
4183*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp, 1), CreateMockRead(echo, 3),
4184*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 4), MockRead(ASYNC, 0, 5) // EOF
4185*6777b538SAndroid Build Coastguard Worker };
4186*6777b538SAndroid Build Coastguard Worker
4187*6777b538SAndroid Build Coastguard Worker // Create SpdySession and SpdyStream and send the request.
4188*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
4189*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4190*6777b538SAndroid Build Coastguard Worker
4191*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4192*6777b538SAndroid Build Coastguard Worker
4193*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4194*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4195*6777b538SAndroid Build Coastguard Worker
4196*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream =
4197*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
4198*6777b538SAndroid Build Coastguard Worker MEDIUM, NetLogWithSource());
4199*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream);
4200*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, stream->stream_id());
4201*6777b538SAndroid Build Coastguard Worker
4202*6777b538SAndroid Build Coastguard Worker DropReceivedDataDelegate delegate(stream, msg_data);
4203*6777b538SAndroid Build Coastguard Worker stream->SetDelegate(&delegate);
4204*6777b538SAndroid Build Coastguard Worker
4205*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
4206*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kMsgDataSize));
4207*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING,
4208*6777b538SAndroid Build Coastguard Worker stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
4209*6777b538SAndroid Build Coastguard Worker
4210*6777b538SAndroid Build Coastguard Worker const int32_t initial_window_size = kDefaultInitialWindowSize;
4211*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_recv_window_size());
4212*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
4213*6777b538SAndroid Build Coastguard Worker
4214*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4215*6777b538SAndroid Build Coastguard Worker
4216*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_recv_window_size());
4217*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kMsgDataSize, session_unacked_recv_window_bytes());
4218*6777b538SAndroid Build Coastguard Worker
4219*6777b538SAndroid Build Coastguard Worker stream->Close();
4220*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream);
4221*6777b538SAndroid Build Coastguard Worker
4222*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate.WaitForClose(), IsOk());
4223*6777b538SAndroid Build Coastguard Worker
4224*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_recv_window_size());
4225*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kMsgDataSize, session_unacked_recv_window_bytes());
4226*6777b538SAndroid Build Coastguard Worker
4227*6777b538SAndroid Build Coastguard Worker data.Resume();
4228*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4229*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
4230*6777b538SAndroid Build Coastguard Worker }
4231*6777b538SAndroid Build Coastguard Worker
4232*6777b538SAndroid Build Coastguard Worker // Send data back and forth but close the stream before its data frame
4233*6777b538SAndroid Build Coastguard Worker // can be written to the socket. The send window should then increase
4234*6777b538SAndroid Build Coastguard Worker // to its original value, i.e. we shouldn't "leak" send window bytes.
TEST_F(SpdySessionTest,SessionFlowControlNoSendLeaks)4235*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, SessionFlowControlNoSendLeaks) {
4236*6777b538SAndroid Build Coastguard Worker const int32_t kMsgDataSize = 100;
4237*6777b538SAndroid Build Coastguard Worker const std::string msg_data(kMsgDataSize, 'a');
4238*6777b538SAndroid Build Coastguard Worker
4239*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
4240*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 1, kMsgDataSize, MEDIUM, nullptr, 0));
4241*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
4242*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0),
4243*6777b538SAndroid Build Coastguard Worker };
4244*6777b538SAndroid Build Coastguard Worker
4245*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp(
4246*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4247*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
4248*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
4249*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3) // EOF
4250*6777b538SAndroid Build Coastguard Worker };
4251*6777b538SAndroid Build Coastguard Worker
4252*6777b538SAndroid Build Coastguard Worker // Create SpdySession and SpdyStream and send the request.
4253*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
4254*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4255*6777b538SAndroid Build Coastguard Worker
4256*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4257*6777b538SAndroid Build Coastguard Worker
4258*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4259*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4260*6777b538SAndroid Build Coastguard Worker
4261*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream =
4262*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
4263*6777b538SAndroid Build Coastguard Worker MEDIUM, NetLogWithSource());
4264*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream);
4265*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, stream->stream_id());
4266*6777b538SAndroid Build Coastguard Worker
4267*6777b538SAndroid Build Coastguard Worker test::StreamDelegateSendImmediate delegate(stream, msg_data);
4268*6777b538SAndroid Build Coastguard Worker stream->SetDelegate(&delegate);
4269*6777b538SAndroid Build Coastguard Worker
4270*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
4271*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kMsgDataSize));
4272*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING,
4273*6777b538SAndroid Build Coastguard Worker stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
4274*6777b538SAndroid Build Coastguard Worker
4275*6777b538SAndroid Build Coastguard Worker const int32_t initial_window_size = kDefaultInitialWindowSize;
4276*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_send_window_size());
4277*6777b538SAndroid Build Coastguard Worker
4278*6777b538SAndroid Build Coastguard Worker // Write request.
4279*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4280*6777b538SAndroid Build Coastguard Worker
4281*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_send_window_size());
4282*6777b538SAndroid Build Coastguard Worker
4283*6777b538SAndroid Build Coastguard Worker // Read response, but do not run the message loop, so that the body is not
4284*6777b538SAndroid Build Coastguard Worker // written to the socket.
4285*6777b538SAndroid Build Coastguard Worker data.Resume();
4286*6777b538SAndroid Build Coastguard Worker
4287*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size - kMsgDataSize, session_send_window_size());
4288*6777b538SAndroid Build Coastguard Worker
4289*6777b538SAndroid Build Coastguard Worker // Closing the stream should increase the session's send window.
4290*6777b538SAndroid Build Coastguard Worker stream->Close();
4291*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream);
4292*6777b538SAndroid Build Coastguard Worker
4293*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_send_window_size());
4294*6777b538SAndroid Build Coastguard Worker
4295*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate.WaitForClose(), IsOk());
4296*6777b538SAndroid Build Coastguard Worker
4297*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4298*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
4299*6777b538SAndroid Build Coastguard Worker
4300*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
4301*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
4302*6777b538SAndroid Build Coastguard Worker }
4303*6777b538SAndroid Build Coastguard Worker
4304*6777b538SAndroid Build Coastguard Worker // Send data back and forth; the send and receive windows should
4305*6777b538SAndroid Build Coastguard Worker // change appropriately.
TEST_F(SpdySessionTest,SessionFlowControlEndToEnd)4306*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, SessionFlowControlEndToEnd) {
4307*6777b538SAndroid Build Coastguard Worker const int32_t kMsgDataSize = 100;
4308*6777b538SAndroid Build Coastguard Worker const std::string msg_data(kMsgDataSize, 'a');
4309*6777b538SAndroid Build Coastguard Worker
4310*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
4311*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 1, kMsgDataSize, MEDIUM, nullptr, 0));
4312*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame msg(
4313*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, msg_data, false));
4314*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
4315*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0), CreateMockWrite(msg, 2),
4316*6777b538SAndroid Build Coastguard Worker };
4317*6777b538SAndroid Build Coastguard Worker
4318*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp(
4319*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4320*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame echo(
4321*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, msg_data, false));
4322*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame window_update(spdy_util_.ConstructSpdyWindowUpdate(
4323*6777b538SAndroid Build Coastguard Worker spdy::kSessionFlowControlStreamId, kMsgDataSize));
4324*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
4325*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp, 1),
4326*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 3),
4327*6777b538SAndroid Build Coastguard Worker CreateMockRead(echo, 4),
4328*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 5),
4329*6777b538SAndroid Build Coastguard Worker CreateMockRead(window_update, 6),
4330*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 7),
4331*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 8) // EOF
4332*6777b538SAndroid Build Coastguard Worker };
4333*6777b538SAndroid Build Coastguard Worker
4334*6777b538SAndroid Build Coastguard Worker // Create SpdySession and SpdyStream and send the request.
4335*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
4336*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4337*6777b538SAndroid Build Coastguard Worker
4338*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4339*6777b538SAndroid Build Coastguard Worker
4340*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4341*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4342*6777b538SAndroid Build Coastguard Worker
4343*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream =
4344*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
4345*6777b538SAndroid Build Coastguard Worker MEDIUM, NetLogWithSource());
4346*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream);
4347*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, stream->stream_id());
4348*6777b538SAndroid Build Coastguard Worker
4349*6777b538SAndroid Build Coastguard Worker test::StreamDelegateSendImmediate delegate(stream, msg_data);
4350*6777b538SAndroid Build Coastguard Worker stream->SetDelegate(&delegate);
4351*6777b538SAndroid Build Coastguard Worker
4352*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
4353*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kMsgDataSize));
4354*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING,
4355*6777b538SAndroid Build Coastguard Worker stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
4356*6777b538SAndroid Build Coastguard Worker
4357*6777b538SAndroid Build Coastguard Worker const int32_t initial_window_size = kDefaultInitialWindowSize;
4358*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_send_window_size());
4359*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_recv_window_size());
4360*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
4361*6777b538SAndroid Build Coastguard Worker
4362*6777b538SAndroid Build Coastguard Worker // Send request and message.
4363*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4364*6777b538SAndroid Build Coastguard Worker
4365*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size - kMsgDataSize, session_send_window_size());
4366*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_recv_window_size());
4367*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
4368*6777b538SAndroid Build Coastguard Worker
4369*6777b538SAndroid Build Coastguard Worker // Read echo.
4370*6777b538SAndroid Build Coastguard Worker data.Resume();
4371*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4372*6777b538SAndroid Build Coastguard Worker
4373*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size - kMsgDataSize, session_send_window_size());
4374*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size - kMsgDataSize, session_recv_window_size());
4375*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
4376*6777b538SAndroid Build Coastguard Worker
4377*6777b538SAndroid Build Coastguard Worker // Read window update.
4378*6777b538SAndroid Build Coastguard Worker data.Resume();
4379*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4380*6777b538SAndroid Build Coastguard Worker
4381*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_send_window_size());
4382*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size - kMsgDataSize, session_recv_window_size());
4383*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, session_unacked_recv_window_bytes());
4384*6777b538SAndroid Build Coastguard Worker
4385*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(msg_data, delegate.TakeReceivedData());
4386*6777b538SAndroid Build Coastguard Worker
4387*6777b538SAndroid Build Coastguard Worker // Draining the delegate's read queue should increase the session's
4388*6777b538SAndroid Build Coastguard Worker // receive window.
4389*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_send_window_size());
4390*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_recv_window_size());
4391*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kMsgDataSize, session_unacked_recv_window_bytes());
4392*6777b538SAndroid Build Coastguard Worker
4393*6777b538SAndroid Build Coastguard Worker stream->Close();
4394*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream);
4395*6777b538SAndroid Build Coastguard Worker
4396*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate.WaitForClose(), IsOk());
4397*6777b538SAndroid Build Coastguard Worker
4398*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_send_window_size());
4399*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(initial_window_size, session_recv_window_size());
4400*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kMsgDataSize, session_unacked_recv_window_bytes());
4401*6777b538SAndroid Build Coastguard Worker
4402*6777b538SAndroid Build Coastguard Worker data.Resume();
4403*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4404*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
4405*6777b538SAndroid Build Coastguard Worker }
4406*6777b538SAndroid Build Coastguard Worker
4407*6777b538SAndroid Build Coastguard Worker // Given a stall function and an unstall function, runs a test to make
4408*6777b538SAndroid Build Coastguard Worker // sure that a stream resumes after unstall.
RunResumeAfterUnstallTest(base::OnceCallback<void (SpdyStream *)> stall_function,base::OnceCallback<void (SpdyStream *,int32_t)> unstall_function)4409*6777b538SAndroid Build Coastguard Worker void SpdySessionTest::RunResumeAfterUnstallTest(
4410*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(SpdyStream*)> stall_function,
4411*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(SpdyStream*, int32_t)> unstall_function) {
4412*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
4413*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 1, kBodyDataSize, LOWEST, nullptr, 0));
4414*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body(
4415*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, true));
4416*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
4417*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0), CreateMockWrite(body, 1),
4418*6777b538SAndroid Build Coastguard Worker };
4419*6777b538SAndroid Build Coastguard Worker
4420*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp(
4421*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4422*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame echo(
4423*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, false));
4424*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
4425*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp, 2), MockRead(ASYNC, 0, 3) // EOF
4426*6777b538SAndroid Build Coastguard Worker };
4427*6777b538SAndroid Build Coastguard Worker
4428*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
4429*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4430*6777b538SAndroid Build Coastguard Worker
4431*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4432*6777b538SAndroid Build Coastguard Worker
4433*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4434*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4435*6777b538SAndroid Build Coastguard Worker
4436*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream =
4437*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
4438*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
4439*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream);
4440*6777b538SAndroid Build Coastguard Worker
4441*6777b538SAndroid Build Coastguard Worker test::StreamDelegateWithBody delegate(stream, kBodyDataStringPiece);
4442*6777b538SAndroid Build Coastguard Worker stream->SetDelegate(&delegate);
4443*6777b538SAndroid Build Coastguard Worker
4444*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream->send_stalled_by_flow_control());
4445*6777b538SAndroid Build Coastguard Worker
4446*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
4447*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
4448*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING,
4449*6777b538SAndroid Build Coastguard Worker stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
4450*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultUrl, stream->url().spec());
4451*6777b538SAndroid Build Coastguard Worker
4452*6777b538SAndroid Build Coastguard Worker std::move(stall_function).Run(stream.get());
4453*6777b538SAndroid Build Coastguard Worker
4454*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4455*6777b538SAndroid Build Coastguard Worker
4456*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream->send_stalled_by_flow_control());
4457*6777b538SAndroid Build Coastguard Worker
4458*6777b538SAndroid Build Coastguard Worker std::move(unstall_function).Run(stream.get(), kBodyDataSize);
4459*6777b538SAndroid Build Coastguard Worker
4460*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream->send_stalled_by_flow_control());
4461*6777b538SAndroid Build Coastguard Worker
4462*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
4463*6777b538SAndroid Build Coastguard Worker
4464*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate.send_headers_completed());
4465*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
4466*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(), delegate.TakeReceivedData());
4467*6777b538SAndroid Build Coastguard Worker
4468*6777b538SAndroid Build Coastguard Worker // Run SpdySession::PumpWriteLoop which destroys |session_|.
4469*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4470*6777b538SAndroid Build Coastguard Worker
4471*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
4472*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
4473*6777b538SAndroid Build Coastguard Worker }
4474*6777b538SAndroid Build Coastguard Worker
4475*6777b538SAndroid Build Coastguard Worker // Run the resume-after-unstall test with all possible stall and
4476*6777b538SAndroid Build Coastguard Worker // unstall sequences.
4477*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,ResumeAfterUnstallSession)4478*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, ResumeAfterUnstallSession) {
4479*6777b538SAndroid Build Coastguard Worker RunResumeAfterUnstallTest(base::BindOnce(&SpdySessionTest::StallSessionOnly,
4480*6777b538SAndroid Build Coastguard Worker base::Unretained(this)),
4481*6777b538SAndroid Build Coastguard Worker base::BindOnce(&SpdySessionTest::UnstallSessionOnly,
4482*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
4483*6777b538SAndroid Build Coastguard Worker }
4484*6777b538SAndroid Build Coastguard Worker
4485*6777b538SAndroid Build Coastguard Worker // Equivalent to
4486*6777b538SAndroid Build Coastguard Worker // SpdyStreamTest.ResumeAfterSendWindowSizeIncrease.
TEST_F(SpdySessionTest,ResumeAfterUnstallStream)4487*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, ResumeAfterUnstallStream) {
4488*6777b538SAndroid Build Coastguard Worker RunResumeAfterUnstallTest(
4489*6777b538SAndroid Build Coastguard Worker base::BindOnce(&SpdySessionTest::StallStreamOnly, base::Unretained(this)),
4490*6777b538SAndroid Build Coastguard Worker base::BindOnce(&SpdySessionTest::UnstallStreamOnly,
4491*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
4492*6777b538SAndroid Build Coastguard Worker }
4493*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,StallSessionStreamResumeAfterUnstallSessionStream)4494*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, StallSessionStreamResumeAfterUnstallSessionStream) {
4495*6777b538SAndroid Build Coastguard Worker RunResumeAfterUnstallTest(
4496*6777b538SAndroid Build Coastguard Worker base::BindOnce(&SpdySessionTest::StallSessionStream,
4497*6777b538SAndroid Build Coastguard Worker base::Unretained(this)),
4498*6777b538SAndroid Build Coastguard Worker base::BindOnce(&SpdySessionTest::UnstallSessionStream,
4499*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
4500*6777b538SAndroid Build Coastguard Worker }
4501*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,StallStreamSessionResumeAfterUnstallSessionStream)4502*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, StallStreamSessionResumeAfterUnstallSessionStream) {
4503*6777b538SAndroid Build Coastguard Worker RunResumeAfterUnstallTest(
4504*6777b538SAndroid Build Coastguard Worker base::BindOnce(&SpdySessionTest::StallStreamSession,
4505*6777b538SAndroid Build Coastguard Worker base::Unretained(this)),
4506*6777b538SAndroid Build Coastguard Worker base::BindOnce(&SpdySessionTest::UnstallSessionStream,
4507*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
4508*6777b538SAndroid Build Coastguard Worker }
4509*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,StallStreamSessionResumeAfterUnstallStreamSession)4510*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, StallStreamSessionResumeAfterUnstallStreamSession) {
4511*6777b538SAndroid Build Coastguard Worker RunResumeAfterUnstallTest(
4512*6777b538SAndroid Build Coastguard Worker base::BindOnce(&SpdySessionTest::StallStreamSession,
4513*6777b538SAndroid Build Coastguard Worker base::Unretained(this)),
4514*6777b538SAndroid Build Coastguard Worker base::BindOnce(&SpdySessionTest::UnstallStreamSession,
4515*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
4516*6777b538SAndroid Build Coastguard Worker }
4517*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,StallSessionStreamResumeAfterUnstallStreamSession)4518*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, StallSessionStreamResumeAfterUnstallStreamSession) {
4519*6777b538SAndroid Build Coastguard Worker RunResumeAfterUnstallTest(
4520*6777b538SAndroid Build Coastguard Worker base::BindOnce(&SpdySessionTest::StallSessionStream,
4521*6777b538SAndroid Build Coastguard Worker base::Unretained(this)),
4522*6777b538SAndroid Build Coastguard Worker base::BindOnce(&SpdySessionTest::UnstallStreamSession,
4523*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
4524*6777b538SAndroid Build Coastguard Worker }
4525*6777b538SAndroid Build Coastguard Worker
4526*6777b538SAndroid Build Coastguard Worker // Cause a stall by reducing the flow control send window to 0. The
4527*6777b538SAndroid Build Coastguard Worker // streams should resume in priority order when that window is then
4528*6777b538SAndroid Build Coastguard Worker // increased.
TEST_F(SpdySessionTest,ResumeByPriorityAfterSendWindowSizeIncrease)4529*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
4530*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(spdy_util_.ConstructSpdyPost(
4531*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 1, kBodyDataSize, LOWEST, nullptr, 0));
4532*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost(
4533*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 3, kBodyDataSize, MEDIUM, nullptr, 0));
4534*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body1(
4535*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, true));
4536*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body2(
4537*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(3, kBodyDataStringPiece, true));
4538*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
4539*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
4540*6777b538SAndroid Build Coastguard Worker CreateMockWrite(body2, 2), CreateMockWrite(body1, 3),
4541*6777b538SAndroid Build Coastguard Worker };
4542*6777b538SAndroid Build Coastguard Worker
4543*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp1(
4544*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4545*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp2(
4546*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
4547*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
4548*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp1, 4), CreateMockRead(resp2, 5),
4549*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 6) // EOF
4550*6777b538SAndroid Build Coastguard Worker };
4551*6777b538SAndroid Build Coastguard Worker
4552*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
4553*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4554*6777b538SAndroid Build Coastguard Worker
4555*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4556*6777b538SAndroid Build Coastguard Worker
4557*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4558*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4559*6777b538SAndroid Build Coastguard Worker
4560*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream1 =
4561*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
4562*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
4563*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream1);
4564*6777b538SAndroid Build Coastguard Worker
4565*6777b538SAndroid Build Coastguard Worker test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
4566*6777b538SAndroid Build Coastguard Worker stream1->SetDelegate(&delegate1);
4567*6777b538SAndroid Build Coastguard Worker
4568*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream2 =
4569*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
4570*6777b538SAndroid Build Coastguard Worker test_url_, MEDIUM, NetLogWithSource());
4571*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream2);
4572*6777b538SAndroid Build Coastguard Worker
4573*6777b538SAndroid Build Coastguard Worker test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
4574*6777b538SAndroid Build Coastguard Worker stream2->SetDelegate(&delegate2);
4575*6777b538SAndroid Build Coastguard Worker
4576*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream1->send_stalled_by_flow_control());
4577*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream2->send_stalled_by_flow_control());
4578*6777b538SAndroid Build Coastguard Worker
4579*6777b538SAndroid Build Coastguard Worker StallSessionSend();
4580*6777b538SAndroid Build Coastguard Worker
4581*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers1(
4582*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
4583*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
4584*6777b538SAndroid Build Coastguard Worker MORE_DATA_TO_SEND));
4585*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultUrl, stream1->url().spec());
4586*6777b538SAndroid Build Coastguard Worker
4587*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4588*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, stream1->stream_id());
4589*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream1->send_stalled_by_flow_control());
4590*6777b538SAndroid Build Coastguard Worker
4591*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(
4592*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
4593*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
4594*6777b538SAndroid Build Coastguard Worker MORE_DATA_TO_SEND));
4595*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultUrl, stream2->url().spec());
4596*6777b538SAndroid Build Coastguard Worker
4597*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4598*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, stream2->stream_id());
4599*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream2->send_stalled_by_flow_control());
4600*6777b538SAndroid Build Coastguard Worker
4601*6777b538SAndroid Build Coastguard Worker // This should unstall only stream2.
4602*6777b538SAndroid Build Coastguard Worker UnstallSessionSend(kBodyDataSize);
4603*6777b538SAndroid Build Coastguard Worker
4604*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream1->send_stalled_by_flow_control());
4605*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream2->send_stalled_by_flow_control());
4606*6777b538SAndroid Build Coastguard Worker
4607*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4608*6777b538SAndroid Build Coastguard Worker
4609*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream1->send_stalled_by_flow_control());
4610*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream2->send_stalled_by_flow_control());
4611*6777b538SAndroid Build Coastguard Worker
4612*6777b538SAndroid Build Coastguard Worker // This should then unstall stream1.
4613*6777b538SAndroid Build Coastguard Worker UnstallSessionSend(kBodyDataSize);
4614*6777b538SAndroid Build Coastguard Worker
4615*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream1->send_stalled_by_flow_control());
4616*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream2->send_stalled_by_flow_control());
4617*6777b538SAndroid Build Coastguard Worker
4618*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4619*6777b538SAndroid Build Coastguard Worker
4620*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate1.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
4621*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate2.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
4622*6777b538SAndroid Build Coastguard Worker
4623*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate1.send_headers_completed());
4624*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
4625*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
4626*6777b538SAndroid Build Coastguard Worker
4627*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate2.send_headers_completed());
4628*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
4629*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
4630*6777b538SAndroid Build Coastguard Worker
4631*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
4632*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
4633*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
4634*6777b538SAndroid Build Coastguard Worker }
4635*6777b538SAndroid Build Coastguard Worker
4636*6777b538SAndroid Build Coastguard Worker // An upload stream is stalled when the session gets unstalled, then the session
4637*6777b538SAndroid Build Coastguard Worker // is stalled again when the stream gets unstalled. The stream should not fail.
4638*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/761919.
TEST_F(SpdySessionTest,ResumeSessionWithStalledStream)4639*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, ResumeSessionWithStalledStream) {
4640*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(spdy_util_.ConstructSpdyPost(
4641*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 1, kBodyDataSize, LOWEST, nullptr, 0));
4642*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost(
4643*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 3, kBodyDataSize, LOWEST, nullptr, 0));
4644*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body1(
4645*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(3, kBodyDataStringPiece, true));
4646*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body2(
4647*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, true));
4648*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
4649*6777b538SAndroid Build Coastguard Worker CreateMockWrite(body1, 2), CreateMockWrite(body2, 3)};
4650*6777b538SAndroid Build Coastguard Worker
4651*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp1(
4652*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4653*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp2(
4654*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
4655*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {CreateMockRead(resp1, 4), CreateMockRead(resp2, 5),
4656*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 6)};
4657*6777b538SAndroid Build Coastguard Worker
4658*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
4659*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4660*6777b538SAndroid Build Coastguard Worker
4661*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4662*6777b538SAndroid Build Coastguard Worker
4663*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4664*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4665*6777b538SAndroid Build Coastguard Worker
4666*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream1 =
4667*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
4668*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
4669*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream1);
4670*6777b538SAndroid Build Coastguard Worker
4671*6777b538SAndroid Build Coastguard Worker test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
4672*6777b538SAndroid Build Coastguard Worker stream1->SetDelegate(&delegate1);
4673*6777b538SAndroid Build Coastguard Worker
4674*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream2 =
4675*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
4676*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
4677*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream2);
4678*6777b538SAndroid Build Coastguard Worker
4679*6777b538SAndroid Build Coastguard Worker test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
4680*6777b538SAndroid Build Coastguard Worker stream2->SetDelegate(&delegate2);
4681*6777b538SAndroid Build Coastguard Worker
4682*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream1->send_stalled_by_flow_control());
4683*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream2->send_stalled_by_flow_control());
4684*6777b538SAndroid Build Coastguard Worker
4685*6777b538SAndroid Build Coastguard Worker StallSessionSend();
4686*6777b538SAndroid Build Coastguard Worker
4687*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers1(
4688*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
4689*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
4690*6777b538SAndroid Build Coastguard Worker MORE_DATA_TO_SEND));
4691*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultUrl, stream1->url().spec());
4692*6777b538SAndroid Build Coastguard Worker
4693*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4694*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, stream1->stream_id());
4695*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream1->send_stalled_by_flow_control());
4696*6777b538SAndroid Build Coastguard Worker
4697*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(
4698*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
4699*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
4700*6777b538SAndroid Build Coastguard Worker MORE_DATA_TO_SEND));
4701*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultUrl, stream2->url().spec());
4702*6777b538SAndroid Build Coastguard Worker
4703*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4704*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, stream2->stream_id());
4705*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream2->send_stalled_by_flow_control());
4706*6777b538SAndroid Build Coastguard Worker
4707*6777b538SAndroid Build Coastguard Worker StallStreamSend(stream1.get());
4708*6777b538SAndroid Build Coastguard Worker
4709*6777b538SAndroid Build Coastguard Worker // At this point, both |session| and |stream1| are stalled
4710*6777b538SAndroid Build Coastguard Worker // by their respective flow control mechanisms. Now unstall the session.
4711*6777b538SAndroid Build Coastguard Worker // This calls session->ResumeSendStalledStreams(), which calls
4712*6777b538SAndroid Build Coastguard Worker // stream1->PossiblyResumeIfSendStalled(). However, |stream1| is stalled, so
4713*6777b538SAndroid Build Coastguard Worker // no data are sent on that stream. At this point, |stream1| should not be
4714*6777b538SAndroid Build Coastguard Worker // removed from session_->stream_send_unstall_queue_.
4715*6777b538SAndroid Build Coastguard Worker // Then stream2->PossiblyResumeIfSendStalled() is called,
4716*6777b538SAndroid Build Coastguard Worker // data are sent on |stream2|, and |session_| stalls again.
4717*6777b538SAndroid Build Coastguard Worker UnstallSessionSend(kBodyDataSize);
4718*6777b538SAndroid Build Coastguard Worker
4719*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream1->send_stalled_by_flow_control());
4720*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream2->send_stalled_by_flow_control());
4721*6777b538SAndroid Build Coastguard Worker
4722*6777b538SAndroid Build Coastguard Worker // Make sure that the session is stalled. Otherwise
4723*6777b538SAndroid Build Coastguard Worker // stream1->PossiblyResumeIfSendStalled() would resume the stream as soon as
4724*6777b538SAndroid Build Coastguard Worker // the stream is unstalled, hiding the bug.
4725*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsSendStalled());
4726*6777b538SAndroid Build Coastguard Worker UnstallStreamSend(stream1.get(), kBodyDataSize);
4727*6777b538SAndroid Build Coastguard Worker
4728*6777b538SAndroid Build Coastguard Worker // Finally, unstall session.
4729*6777b538SAndroid Build Coastguard Worker UnstallSessionSend(kBodyDataSize);
4730*6777b538SAndroid Build Coastguard Worker
4731*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream1->send_stalled_by_flow_control());
4732*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream2->send_stalled_by_flow_control());
4733*6777b538SAndroid Build Coastguard Worker
4734*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4735*6777b538SAndroid Build Coastguard Worker
4736*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate1.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
4737*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate2.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
4738*6777b538SAndroid Build Coastguard Worker
4739*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate1.send_headers_completed());
4740*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
4741*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
4742*6777b538SAndroid Build Coastguard Worker
4743*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate2.send_headers_completed());
4744*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
4745*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
4746*6777b538SAndroid Build Coastguard Worker
4747*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
4748*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
4749*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
4750*6777b538SAndroid Build Coastguard Worker }
4751*6777b538SAndroid Build Coastguard Worker
4752*6777b538SAndroid Build Coastguard Worker class StreamBrokenConnectionDetectionCheckDelegate
4753*6777b538SAndroid Build Coastguard Worker : public test::StreamDelegateDoNothing {
4754*6777b538SAndroid Build Coastguard Worker public:
StreamBrokenConnectionDetectionCheckDelegate(const base::WeakPtr<SpdyStream> & stream,const base::WeakPtr<SpdySession> & session,bool expected_is_broken_connection_detection_enabled)4755*6777b538SAndroid Build Coastguard Worker StreamBrokenConnectionDetectionCheckDelegate(
4756*6777b538SAndroid Build Coastguard Worker const base::WeakPtr<SpdyStream>& stream,
4757*6777b538SAndroid Build Coastguard Worker const base::WeakPtr<SpdySession>& session,
4758*6777b538SAndroid Build Coastguard Worker bool expected_is_broken_connection_detection_enabled)
4759*6777b538SAndroid Build Coastguard Worker : StreamDelegateDoNothing(stream),
4760*6777b538SAndroid Build Coastguard Worker session_(session),
4761*6777b538SAndroid Build Coastguard Worker expected_is_broken_connection_detection_enabled_(
4762*6777b538SAndroid Build Coastguard Worker expected_is_broken_connection_detection_enabled) {}
4763*6777b538SAndroid Build Coastguard Worker
4764*6777b538SAndroid Build Coastguard Worker ~StreamBrokenConnectionDetectionCheckDelegate() override = default;
4765*6777b538SAndroid Build Coastguard Worker
OnClose(int status)4766*6777b538SAndroid Build Coastguard Worker void OnClose(int status) override {
4767*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(expected_is_broken_connection_detection_enabled_,
4768*6777b538SAndroid Build Coastguard Worker session_->IsBrokenConnectionDetectionEnabled());
4769*6777b538SAndroid Build Coastguard Worker }
4770*6777b538SAndroid Build Coastguard Worker
4771*6777b538SAndroid Build Coastguard Worker private:
4772*6777b538SAndroid Build Coastguard Worker const base::WeakPtr<SpdySession> session_;
4773*6777b538SAndroid Build Coastguard Worker bool expected_is_broken_connection_detection_enabled_;
4774*6777b538SAndroid Build Coastguard Worker };
4775*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,BrokenConnectionDetectionEOF)4776*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, BrokenConnectionDetectionEOF) {
4777*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
4778*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 0), // EOF
4779*6777b538SAndroid Build Coastguard Worker };
4780*6777b538SAndroid Build Coastguard Worker
4781*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, base::span<MockWrite>());
4782*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4783*6777b538SAndroid Build Coastguard Worker
4784*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4785*6777b538SAndroid Build Coastguard Worker
4786*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4787*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4788*6777b538SAndroid Build Coastguard Worker
4789*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(session_->IsBrokenConnectionDetectionEnabled());
4790*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
4791*6777b538SAndroid Build Coastguard Worker SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM,
4792*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), true, kHeartbeatInterval);
4793*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream);
4794*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(session_->IsBrokenConnectionDetectionEnabled());
4795*6777b538SAndroid Build Coastguard Worker StreamBrokenConnectionDetectionCheckDelegate delegate(stream, session_,
4796*6777b538SAndroid Build Coastguard Worker false);
4797*6777b538SAndroid Build Coastguard Worker stream->SetDelegate(&delegate);
4798*6777b538SAndroid Build Coastguard Worker
4799*6777b538SAndroid Build Coastguard Worker // Let the delegate run and check broken connection detection status during
4800*6777b538SAndroid Build Coastguard Worker // OnClose().
4801*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4802*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(session_);
4803*6777b538SAndroid Build Coastguard Worker }
4804*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,BrokenConnectionDetectionCloseSession)4805*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, BrokenConnectionDetectionCloseSession) {
4806*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
4807*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 0), // EOF
4808*6777b538SAndroid Build Coastguard Worker };
4809*6777b538SAndroid Build Coastguard Worker
4810*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, base::span<MockWrite>());
4811*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4812*6777b538SAndroid Build Coastguard Worker
4813*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4814*6777b538SAndroid Build Coastguard Worker
4815*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4816*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4817*6777b538SAndroid Build Coastguard Worker
4818*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(session_->IsBrokenConnectionDetectionEnabled());
4819*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
4820*6777b538SAndroid Build Coastguard Worker SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM,
4821*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), true, kHeartbeatInterval);
4822*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream);
4823*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(session_->IsBrokenConnectionDetectionEnabled());
4824*6777b538SAndroid Build Coastguard Worker StreamBrokenConnectionDetectionCheckDelegate delegate(stream, session_,
4825*6777b538SAndroid Build Coastguard Worker false);
4826*6777b538SAndroid Build Coastguard Worker stream->SetDelegate(&delegate);
4827*6777b538SAndroid Build Coastguard Worker
4828*6777b538SAndroid Build Coastguard Worker session_->CloseSessionOnError(ERR_ABORTED, "Aborting session");
4829*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(session_->IsBrokenConnectionDetectionEnabled());
4830*6777b538SAndroid Build Coastguard Worker
4831*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4832*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(session_);
4833*6777b538SAndroid Build Coastguard Worker }
4834*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,BrokenConnectionDetectionCloseStream)4835*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, BrokenConnectionDetectionCloseStream) {
4836*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
4837*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 0), // EOF
4838*6777b538SAndroid Build Coastguard Worker };
4839*6777b538SAndroid Build Coastguard Worker
4840*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, base::span<MockWrite>());
4841*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4842*6777b538SAndroid Build Coastguard Worker
4843*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4844*6777b538SAndroid Build Coastguard Worker
4845*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4846*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4847*6777b538SAndroid Build Coastguard Worker
4848*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(session_->IsBrokenConnectionDetectionEnabled());
4849*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
4850*6777b538SAndroid Build Coastguard Worker SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM,
4851*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), true, kHeartbeatInterval);
4852*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream);
4853*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(session_->IsBrokenConnectionDetectionEnabled());
4854*6777b538SAndroid Build Coastguard Worker StreamBrokenConnectionDetectionCheckDelegate delegate(stream, session_,
4855*6777b538SAndroid Build Coastguard Worker false);
4856*6777b538SAndroid Build Coastguard Worker stream->SetDelegate(&delegate);
4857*6777b538SAndroid Build Coastguard Worker
4858*6777b538SAndroid Build Coastguard Worker stream->Close();
4859*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(session_->IsBrokenConnectionDetectionEnabled());
4860*6777b538SAndroid Build Coastguard Worker
4861*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4862*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(session_);
4863*6777b538SAndroid Build Coastguard Worker }
4864*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,BrokenConnectionDetectionCancelStream)4865*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, BrokenConnectionDetectionCancelStream) {
4866*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
4867*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 0),
4868*6777b538SAndroid Build Coastguard Worker };
4869*6777b538SAndroid Build Coastguard Worker
4870*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, base::span<MockWrite>());
4871*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4872*6777b538SAndroid Build Coastguard Worker
4873*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4874*6777b538SAndroid Build Coastguard Worker
4875*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4876*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4877*6777b538SAndroid Build Coastguard Worker
4878*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(session_->IsBrokenConnectionDetectionEnabled());
4879*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
4880*6777b538SAndroid Build Coastguard Worker SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM,
4881*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), true, kHeartbeatInterval);
4882*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream);
4883*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(session_->IsBrokenConnectionDetectionEnabled());
4884*6777b538SAndroid Build Coastguard Worker StreamBrokenConnectionDetectionCheckDelegate delegate(stream, session_,
4885*6777b538SAndroid Build Coastguard Worker false);
4886*6777b538SAndroid Build Coastguard Worker stream->SetDelegate(&delegate);
4887*6777b538SAndroid Build Coastguard Worker
4888*6777b538SAndroid Build Coastguard Worker stream->Cancel(ERR_ABORTED);
4889*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(session_->IsBrokenConnectionDetectionEnabled());
4890*6777b538SAndroid Build Coastguard Worker
4891*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4892*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(session_);
4893*6777b538SAndroid Build Coastguard Worker }
4894*6777b538SAndroid Build Coastguard Worker
4895*6777b538SAndroid Build Coastguard Worker // When multiple streams request broken connection detection, only the last one
4896*6777b538SAndroid Build Coastguard Worker // to complete should disable the connection status check.
TEST_F(SpdySessionTest,BrokenConnectionDetectionMultipleRequests)4897*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, BrokenConnectionDetectionMultipleRequests) {
4898*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
4899*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
4900*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(goaway, 3),
4901*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 4), MockRead(ASYNC, 0, 5) // EOF
4902*6777b538SAndroid Build Coastguard Worker };
4903*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(
4904*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
4905*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(
4906*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
4907*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
4908*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0),
4909*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req2, 1),
4910*6777b538SAndroid Build Coastguard Worker };
4911*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
4912*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
4913*6777b538SAndroid Build Coastguard Worker
4914*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
4915*6777b538SAndroid Build Coastguard Worker
4916*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
4917*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
4918*6777b538SAndroid Build Coastguard Worker
4919*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->IsBrokenConnectionDetectionEnabled());
4920*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
4921*6777b538SAndroid Build Coastguard Worker SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM,
4922*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), true, kHeartbeatInterval);
4923*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(spdy_stream1);
4924*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsBrokenConnectionDetectionEnabled());
4925*6777b538SAndroid Build Coastguard Worker StreamBrokenConnectionDetectionCheckDelegate delegate1(spdy_stream1, session_,
4926*6777b538SAndroid Build Coastguard Worker false);
4927*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
4928*6777b538SAndroid Build Coastguard Worker
4929*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream2 = CreateStreamSynchronously(
4930*6777b538SAndroid Build Coastguard Worker SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM,
4931*6777b538SAndroid Build Coastguard Worker NetLogWithSource(), true, kHeartbeatInterval);
4932*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(spdy_stream2);
4933*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsBrokenConnectionDetectionEnabled());
4934*6777b538SAndroid Build Coastguard Worker StreamBrokenConnectionDetectionCheckDelegate delegate2(spdy_stream2, session_,
4935*6777b538SAndroid Build Coastguard Worker true);
4936*6777b538SAndroid Build Coastguard Worker spdy_stream2->SetDelegate(&delegate2);
4937*6777b538SAndroid Build Coastguard Worker
4938*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
4939*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
4940*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(headers.Clone());
4941*6777b538SAndroid Build Coastguard Worker
4942*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
4943*6777b538SAndroid Build Coastguard Worker spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
4944*6777b538SAndroid Build Coastguard Worker
4945*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4946*6777b538SAndroid Build Coastguard Worker
4947*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsBrokenConnectionDetectionEnabled());
4948*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, spdy_stream1->stream_id());
4949*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, spdy_stream2->stream_id());
4950*6777b538SAndroid Build Coastguard Worker
4951*6777b538SAndroid Build Coastguard Worker // Read and process the GOAWAY frame.
4952*6777b538SAndroid Build Coastguard Worker data.Resume();
4953*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4954*6777b538SAndroid Build Coastguard Worker
4955*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsBrokenConnectionDetectionEnabled());
4956*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->IsStreamActive(3));
4957*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream2);
4958*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsStreamActive(1));
4959*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsGoingAway());
4960*6777b538SAndroid Build Coastguard Worker
4961*6777b538SAndroid Build Coastguard Worker // Should close the session.
4962*6777b538SAndroid Build Coastguard Worker spdy_stream1->Close();
4963*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream1);
4964*6777b538SAndroid Build Coastguard Worker
4965*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_);
4966*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->IsBrokenConnectionDetectionEnabled());
4967*6777b538SAndroid Build Coastguard Worker data.Resume();
4968*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
4969*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
4970*6777b538SAndroid Build Coastguard Worker }
4971*6777b538SAndroid Build Coastguard Worker
4972*6777b538SAndroid Build Coastguard Worker // Delegate that closes a given stream after sending its body.
4973*6777b538SAndroid Build Coastguard Worker class StreamClosingDelegate : public test::StreamDelegateWithBody {
4974*6777b538SAndroid Build Coastguard Worker public:
StreamClosingDelegate(const base::WeakPtr<SpdyStream> & stream,std::string_view data)4975*6777b538SAndroid Build Coastguard Worker StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
4976*6777b538SAndroid Build Coastguard Worker std::string_view data)
4977*6777b538SAndroid Build Coastguard Worker : StreamDelegateWithBody(stream, data) {}
4978*6777b538SAndroid Build Coastguard Worker
4979*6777b538SAndroid Build Coastguard Worker ~StreamClosingDelegate() override = default;
4980*6777b538SAndroid Build Coastguard Worker
set_stream_to_close(const base::WeakPtr<SpdyStream> & stream_to_close)4981*6777b538SAndroid Build Coastguard Worker void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) {
4982*6777b538SAndroid Build Coastguard Worker stream_to_close_ = stream_to_close;
4983*6777b538SAndroid Build Coastguard Worker }
4984*6777b538SAndroid Build Coastguard Worker
OnDataSent()4985*6777b538SAndroid Build Coastguard Worker void OnDataSent() override {
4986*6777b538SAndroid Build Coastguard Worker test::StreamDelegateWithBody::OnDataSent();
4987*6777b538SAndroid Build Coastguard Worker if (stream_to_close_.get()) {
4988*6777b538SAndroid Build Coastguard Worker stream_to_close_->Close();
4989*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream_to_close_);
4990*6777b538SAndroid Build Coastguard Worker }
4991*6777b538SAndroid Build Coastguard Worker }
4992*6777b538SAndroid Build Coastguard Worker
4993*6777b538SAndroid Build Coastguard Worker private:
4994*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream_to_close_;
4995*6777b538SAndroid Build Coastguard Worker };
4996*6777b538SAndroid Build Coastguard Worker
4997*6777b538SAndroid Build Coastguard Worker // Cause a stall by reducing the flow control send window to
4998*6777b538SAndroid Build Coastguard Worker // 0. Unstalling the session should properly handle deleted streams.
TEST_F(SpdySessionTest,SendWindowSizeIncreaseWithDeletedStreams)4999*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
5000*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(spdy_util_.ConstructSpdyPost(
5001*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 1, kBodyDataSize, LOWEST, nullptr, 0));
5002*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost(
5003*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 3, kBodyDataSize, LOWEST, nullptr, 0));
5004*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req3(spdy_util_.ConstructSpdyPost(
5005*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 5, kBodyDataSize, LOWEST, nullptr, 0));
5006*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body2(
5007*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(3, kBodyDataStringPiece, true));
5008*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
5009*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
5010*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req3, 2), CreateMockWrite(body2, 3),
5011*6777b538SAndroid Build Coastguard Worker };
5012*6777b538SAndroid Build Coastguard Worker
5013*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp2(
5014*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
5015*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
5016*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp2, 4), MockRead(ASYNC, ERR_IO_PENDING, 5),
5017*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 6) // EOF
5018*6777b538SAndroid Build Coastguard Worker };
5019*6777b538SAndroid Build Coastguard Worker
5020*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
5021*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5022*6777b538SAndroid Build Coastguard Worker
5023*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5024*6777b538SAndroid Build Coastguard Worker
5025*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5026*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5027*6777b538SAndroid Build Coastguard Worker
5028*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream1 =
5029*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
5030*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
5031*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream1);
5032*6777b538SAndroid Build Coastguard Worker
5033*6777b538SAndroid Build Coastguard Worker test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
5034*6777b538SAndroid Build Coastguard Worker stream1->SetDelegate(&delegate1);
5035*6777b538SAndroid Build Coastguard Worker
5036*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream2 =
5037*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
5038*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
5039*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream2);
5040*6777b538SAndroid Build Coastguard Worker
5041*6777b538SAndroid Build Coastguard Worker StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece);
5042*6777b538SAndroid Build Coastguard Worker stream2->SetDelegate(&delegate2);
5043*6777b538SAndroid Build Coastguard Worker
5044*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream3 =
5045*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
5046*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
5047*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream3);
5048*6777b538SAndroid Build Coastguard Worker
5049*6777b538SAndroid Build Coastguard Worker test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece);
5050*6777b538SAndroid Build Coastguard Worker stream3->SetDelegate(&delegate3);
5051*6777b538SAndroid Build Coastguard Worker
5052*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream1->send_stalled_by_flow_control());
5053*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream2->send_stalled_by_flow_control());
5054*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream3->send_stalled_by_flow_control());
5055*6777b538SAndroid Build Coastguard Worker
5056*6777b538SAndroid Build Coastguard Worker StallSessionSend();
5057*6777b538SAndroid Build Coastguard Worker
5058*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers1(
5059*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
5060*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
5061*6777b538SAndroid Build Coastguard Worker MORE_DATA_TO_SEND));
5062*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultUrl, stream1->url().spec());
5063*6777b538SAndroid Build Coastguard Worker
5064*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5065*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, stream1->stream_id());
5066*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream1->send_stalled_by_flow_control());
5067*6777b538SAndroid Build Coastguard Worker
5068*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(
5069*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
5070*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
5071*6777b538SAndroid Build Coastguard Worker MORE_DATA_TO_SEND));
5072*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultUrl, stream2->url().spec());
5073*6777b538SAndroid Build Coastguard Worker
5074*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5075*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, stream2->stream_id());
5076*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream2->send_stalled_by_flow_control());
5077*6777b538SAndroid Build Coastguard Worker
5078*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers3(
5079*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
5080*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING, stream3->SendRequestHeaders(std::move(headers3),
5081*6777b538SAndroid Build Coastguard Worker MORE_DATA_TO_SEND));
5082*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultUrl, stream3->url().spec());
5083*6777b538SAndroid Build Coastguard Worker
5084*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5085*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(5u, stream3->stream_id());
5086*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream3->send_stalled_by_flow_control());
5087*6777b538SAndroid Build Coastguard Worker
5088*6777b538SAndroid Build Coastguard Worker spdy::SpdyStreamId stream_id1 = stream1->stream_id();
5089*6777b538SAndroid Build Coastguard Worker spdy::SpdyStreamId stream_id2 = stream2->stream_id();
5090*6777b538SAndroid Build Coastguard Worker spdy::SpdyStreamId stream_id3 = stream3->stream_id();
5091*6777b538SAndroid Build Coastguard Worker
5092*6777b538SAndroid Build Coastguard Worker // Close stream1 preemptively.
5093*6777b538SAndroid Build Coastguard Worker session_->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED);
5094*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream1);
5095*6777b538SAndroid Build Coastguard Worker
5096*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->IsStreamActive(stream_id1));
5097*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsStreamActive(stream_id2));
5098*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsStreamActive(stream_id3));
5099*6777b538SAndroid Build Coastguard Worker
5100*6777b538SAndroid Build Coastguard Worker // Unstall stream2, which should then close stream3.
5101*6777b538SAndroid Build Coastguard Worker delegate2.set_stream_to_close(stream3);
5102*6777b538SAndroid Build Coastguard Worker UnstallSessionSend(kBodyDataSize);
5103*6777b538SAndroid Build Coastguard Worker
5104*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5105*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream3);
5106*6777b538SAndroid Build Coastguard Worker
5107*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream2->send_stalled_by_flow_control());
5108*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->IsStreamActive(stream_id1));
5109*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsStreamActive(stream_id2));
5110*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->IsStreamActive(stream_id3));
5111*6777b538SAndroid Build Coastguard Worker
5112*6777b538SAndroid Build Coastguard Worker data.Resume();
5113*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5114*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream2);
5115*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
5116*6777b538SAndroid Build Coastguard Worker
5117*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate1.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
5118*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate2.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
5119*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate3.WaitForClose(), IsOk());
5120*6777b538SAndroid Build Coastguard Worker
5121*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate1.send_headers_completed());
5122*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
5123*6777b538SAndroid Build Coastguard Worker
5124*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate2.send_headers_completed());
5125*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
5126*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
5127*6777b538SAndroid Build Coastguard Worker
5128*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate3.send_headers_completed());
5129*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(), delegate3.TakeReceivedData());
5130*6777b538SAndroid Build Coastguard Worker
5131*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
5132*6777b538SAndroid Build Coastguard Worker }
5133*6777b538SAndroid Build Coastguard Worker
5134*6777b538SAndroid Build Coastguard Worker // Cause a stall by reducing the flow control send window to
5135*6777b538SAndroid Build Coastguard Worker // 0. Unstalling the session should properly handle the session itself
5136*6777b538SAndroid Build Coastguard Worker // being closed.
TEST_F(SpdySessionTest,SendWindowSizeIncreaseWithDeletedSession)5137*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
5138*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req1(spdy_util_.ConstructSpdyPost(
5139*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 1, kBodyDataSize, LOWEST, nullptr, 0));
5140*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost(
5141*6777b538SAndroid Build Coastguard Worker kDefaultUrl, 3, kBodyDataSize, LOWEST, nullptr, 0));
5142*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body1(
5143*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, false));
5144*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
5145*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
5146*6777b538SAndroid Build Coastguard Worker };
5147*6777b538SAndroid Build Coastguard Worker
5148*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
5149*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3) // EOF
5150*6777b538SAndroid Build Coastguard Worker };
5151*6777b538SAndroid Build Coastguard Worker
5152*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
5153*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5154*6777b538SAndroid Build Coastguard Worker
5155*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5156*6777b538SAndroid Build Coastguard Worker
5157*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5158*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5159*6777b538SAndroid Build Coastguard Worker
5160*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream1 =
5161*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
5162*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
5163*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream1);
5164*6777b538SAndroid Build Coastguard Worker
5165*6777b538SAndroid Build Coastguard Worker test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
5166*6777b538SAndroid Build Coastguard Worker stream1->SetDelegate(&delegate1);
5167*6777b538SAndroid Build Coastguard Worker
5168*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> stream2 =
5169*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
5170*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
5171*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(stream2);
5172*6777b538SAndroid Build Coastguard Worker
5173*6777b538SAndroid Build Coastguard Worker test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
5174*6777b538SAndroid Build Coastguard Worker stream2->SetDelegate(&delegate2);
5175*6777b538SAndroid Build Coastguard Worker
5176*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream1->send_stalled_by_flow_control());
5177*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(stream2->send_stalled_by_flow_control());
5178*6777b538SAndroid Build Coastguard Worker
5179*6777b538SAndroid Build Coastguard Worker StallSessionSend();
5180*6777b538SAndroid Build Coastguard Worker
5181*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers1(
5182*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
5183*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
5184*6777b538SAndroid Build Coastguard Worker MORE_DATA_TO_SEND));
5185*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultUrl, stream1->url().spec());
5186*6777b538SAndroid Build Coastguard Worker
5187*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5188*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, stream1->stream_id());
5189*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream1->send_stalled_by_flow_control());
5190*6777b538SAndroid Build Coastguard Worker
5191*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers2(
5192*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
5193*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
5194*6777b538SAndroid Build Coastguard Worker MORE_DATA_TO_SEND));
5195*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultUrl, stream2->url().spec());
5196*6777b538SAndroid Build Coastguard Worker
5197*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5198*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, stream2->stream_id());
5199*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(stream2->send_stalled_by_flow_control());
5200*6777b538SAndroid Build Coastguard Worker
5201*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
5202*6777b538SAndroid Build Coastguard Worker
5203*6777b538SAndroid Build Coastguard Worker // Unstall stream1.
5204*6777b538SAndroid Build Coastguard Worker UnstallSessionSend(kBodyDataSize);
5205*6777b538SAndroid Build Coastguard Worker
5206*6777b538SAndroid Build Coastguard Worker // Close the session (since we can't do it from within the delegate
5207*6777b538SAndroid Build Coastguard Worker // method, since it's in the stream's loop).
5208*6777b538SAndroid Build Coastguard Worker session_->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session");
5209*6777b538SAndroid Build Coastguard Worker data.Resume();
5210*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5211*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
5212*6777b538SAndroid Build Coastguard Worker
5213*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
5214*6777b538SAndroid Build Coastguard Worker
5215*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate1.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
5216*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate2.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
5217*6777b538SAndroid Build Coastguard Worker
5218*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate1.send_headers_completed());
5219*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
5220*6777b538SAndroid Build Coastguard Worker
5221*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(delegate2.send_headers_completed());
5222*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
5223*6777b538SAndroid Build Coastguard Worker
5224*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
5225*6777b538SAndroid Build Coastguard Worker }
5226*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,GoAwayOnSessionFlowControlError)5227*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, GoAwayOnSessionFlowControlError) {
5228*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
5229*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
5230*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
5231*6777b538SAndroid Build Coastguard Worker 0, spdy::ERROR_CODE_FLOW_CONTROL_ERROR,
5232*6777b538SAndroid Build Coastguard Worker "delta_window_size is 6 in DecreaseRecvWindowSize, which is larger than "
5233*6777b538SAndroid Build Coastguard Worker "the receive window size of 1"));
5234*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
5235*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0), CreateMockWrite(goaway, 4),
5236*6777b538SAndroid Build Coastguard Worker };
5237*6777b538SAndroid Build Coastguard Worker
5238*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp(
5239*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5240*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5241*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
5242*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
5243*6777b538SAndroid Build Coastguard Worker CreateMockRead(body, 3),
5244*6777b538SAndroid Build Coastguard Worker };
5245*6777b538SAndroid Build Coastguard Worker
5246*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
5247*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5248*6777b538SAndroid Build Coastguard Worker
5249*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5250*6777b538SAndroid Build Coastguard Worker
5251*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5252*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5253*6777b538SAndroid Build Coastguard Worker
5254*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
5255*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
5256*6777b538SAndroid Build Coastguard Worker test_url_, LOWEST, NetLogWithSource());
5257*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream);
5258*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate(spdy_stream);
5259*6777b538SAndroid Build Coastguard Worker spdy_stream->SetDelegate(&delegate);
5260*6777b538SAndroid Build Coastguard Worker
5261*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
5262*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
5263*6777b538SAndroid Build Coastguard Worker spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
5264*6777b538SAndroid Build Coastguard Worker
5265*6777b538SAndroid Build Coastguard Worker // Write request.
5266*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5267*6777b538SAndroid Build Coastguard Worker
5268*6777b538SAndroid Build Coastguard Worker // Put session on the edge of overflowing it's recv window.
5269*6777b538SAndroid Build Coastguard Worker set_session_recv_window_size(1);
5270*6777b538SAndroid Build Coastguard Worker
5271*6777b538SAndroid Build Coastguard Worker // Read response headers & body. Body overflows the session window, and a
5272*6777b538SAndroid Build Coastguard Worker // goaway is written.
5273*6777b538SAndroid Build Coastguard Worker data.Resume();
5274*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5275*6777b538SAndroid Build Coastguard Worker
5276*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_FLOW_CONTROL_ERROR));
5277*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
5278*6777b538SAndroid Build Coastguard Worker }
5279*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,RejectInvalidUnknownFrames)5280*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, RejectInvalidUnknownFrames) {
5281*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
5282*6777b538SAndroid Build Coastguard Worker MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
5283*6777b538SAndroid Build Coastguard Worker };
5284*6777b538SAndroid Build Coastguard Worker
5285*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, base::span<MockWrite>());
5286*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5287*6777b538SAndroid Build Coastguard Worker
5288*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5289*6777b538SAndroid Build Coastguard Worker
5290*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5291*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5292*6777b538SAndroid Build Coastguard Worker
5293*6777b538SAndroid Build Coastguard Worker set_stream_hi_water_mark(5);
5294*6777b538SAndroid Build Coastguard Worker // Low client (odd) ids are fine.
5295*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(OnUnknownFrame(3, 0));
5296*6777b538SAndroid Build Coastguard Worker // Client id exceeding watermark.
5297*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(OnUnknownFrame(9, 0));
5298*6777b538SAndroid Build Coastguard Worker
5299*6777b538SAndroid Build Coastguard Worker // Frames on push streams are rejected.
5300*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(OnUnknownFrame(2, 0));
5301*6777b538SAndroid Build Coastguard Worker }
5302*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,EnableWebSocket)5303*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, EnableWebSocket) {
5304*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings_map;
5305*6777b538SAndroid Build Coastguard Worker settings_map[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
5306*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings(
5307*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(settings_map));
5308*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {CreateMockRead(settings, 0),
5309*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
5310*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3)};
5311*6777b538SAndroid Build Coastguard Worker
5312*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame ack(spdy_util_.ConstructSpdySettingsAck());
5313*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(ack, 1)};
5314*6777b538SAndroid Build Coastguard Worker
5315*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
5316*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5317*6777b538SAndroid Build Coastguard Worker
5318*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5319*6777b538SAndroid Build Coastguard Worker
5320*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5321*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5322*6777b538SAndroid Build Coastguard Worker
5323*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->support_websocket());
5324*6777b538SAndroid Build Coastguard Worker
5325*6777b538SAndroid Build Coastguard Worker // Read SETTINGS frame.
5326*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5327*6777b538SAndroid Build Coastguard Worker
5328*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->support_websocket());
5329*6777b538SAndroid Build Coastguard Worker
5330*6777b538SAndroid Build Coastguard Worker // Read EOF.
5331*6777b538SAndroid Build Coastguard Worker data.Resume();
5332*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5333*6777b538SAndroid Build Coastguard Worker
5334*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
5335*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
5336*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
5337*6777b538SAndroid Build Coastguard Worker }
5338*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,DisableWebSocketDoesNothing)5339*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, DisableWebSocketDoesNothing) {
5340*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings_map;
5341*6777b538SAndroid Build Coastguard Worker settings_map[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 0;
5342*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings(
5343*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(settings_map));
5344*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {CreateMockRead(settings, 0),
5345*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
5346*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3)};
5347*6777b538SAndroid Build Coastguard Worker
5348*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame ack(spdy_util_.ConstructSpdySettingsAck());
5349*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(ack, 1)};
5350*6777b538SAndroid Build Coastguard Worker
5351*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
5352*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5353*6777b538SAndroid Build Coastguard Worker
5354*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5355*6777b538SAndroid Build Coastguard Worker
5356*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5357*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5358*6777b538SAndroid Build Coastguard Worker
5359*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->support_websocket());
5360*6777b538SAndroid Build Coastguard Worker
5361*6777b538SAndroid Build Coastguard Worker // Read SETTINGS frame.
5362*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5363*6777b538SAndroid Build Coastguard Worker
5364*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->support_websocket());
5365*6777b538SAndroid Build Coastguard Worker
5366*6777b538SAndroid Build Coastguard Worker // Read EOF.
5367*6777b538SAndroid Build Coastguard Worker data.Resume();
5368*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5369*6777b538SAndroid Build Coastguard Worker
5370*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
5371*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
5372*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
5373*6777b538SAndroid Build Coastguard Worker }
5374*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,EnableWebSocketThenDisableIsProtocolError)5375*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, EnableWebSocketThenDisableIsProtocolError) {
5376*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings_map1;
5377*6777b538SAndroid Build Coastguard Worker settings_map1[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
5378*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings1(
5379*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(settings_map1));
5380*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings_map2;
5381*6777b538SAndroid Build Coastguard Worker settings_map2[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 0;
5382*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings2(
5383*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(settings_map2));
5384*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {CreateMockRead(settings1, 0),
5385*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
5386*6777b538SAndroid Build Coastguard Worker CreateMockRead(settings2, 3)};
5387*6777b538SAndroid Build Coastguard Worker
5388*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame ack1(spdy_util_.ConstructSpdySettingsAck());
5389*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame ack2(spdy_util_.ConstructSpdySettingsAck());
5390*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
5391*6777b538SAndroid Build Coastguard Worker 0, spdy::ERROR_CODE_PROTOCOL_ERROR,
5392*6777b538SAndroid Build Coastguard Worker "Invalid value for spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL."));
5393*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(ack1, 1), CreateMockWrite(ack2, 4),
5394*6777b538SAndroid Build Coastguard Worker CreateMockWrite(goaway, 5)};
5395*6777b538SAndroid Build Coastguard Worker
5396*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
5397*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5398*6777b538SAndroid Build Coastguard Worker
5399*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5400*6777b538SAndroid Build Coastguard Worker
5401*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5402*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5403*6777b538SAndroid Build Coastguard Worker
5404*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->support_websocket());
5405*6777b538SAndroid Build Coastguard Worker
5406*6777b538SAndroid Build Coastguard Worker // Read first SETTINGS frame.
5407*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5408*6777b538SAndroid Build Coastguard Worker
5409*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->support_websocket());
5410*6777b538SAndroid Build Coastguard Worker
5411*6777b538SAndroid Build Coastguard Worker // Read second SETTINGS frame.
5412*6777b538SAndroid Build Coastguard Worker data.Resume();
5413*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5414*6777b538SAndroid Build Coastguard Worker
5415*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
5416*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
5417*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_);
5418*6777b538SAndroid Build Coastguard Worker }
5419*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,GreaseFrameTypeAfterSettings)5420*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, GreaseFrameTypeAfterSettings) {
5421*6777b538SAndroid Build Coastguard Worker const uint8_t type = 0x0b;
5422*6777b538SAndroid Build Coastguard Worker const uint8_t flags = 0xcc;
5423*6777b538SAndroid Build Coastguard Worker const std::string payload("foo");
5424*6777b538SAndroid Build Coastguard Worker session_deps_.greased_http2_frame =
5425*6777b538SAndroid Build Coastguard Worker std::optional<net::SpdySessionPool::GreasedHttp2Frame>(
5426*6777b538SAndroid Build Coastguard Worker {type, flags, payload});
5427*6777b538SAndroid Build Coastguard Worker
5428*6777b538SAndroid Build Coastguard Worker // Connection preface.
5429*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame preface(spdy::test::MakeSerializedFrame(
5430*6777b538SAndroid Build Coastguard Worker const_cast<char*>(spdy::kHttp2ConnectionHeaderPrefix),
5431*6777b538SAndroid Build Coastguard Worker spdy::kHttp2ConnectionHeaderPrefixSize));
5432*6777b538SAndroid Build Coastguard Worker
5433*6777b538SAndroid Build Coastguard Worker // Initial SETTINGS frame.
5434*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap expected_settings;
5435*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
5436*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] =
5437*6777b538SAndroid Build Coastguard Worker kSpdyMaxHeaderListSize;
5438*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
5439*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_frame(
5440*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(expected_settings));
5441*6777b538SAndroid Build Coastguard Worker
5442*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame combined_frame =
5443*6777b538SAndroid Build Coastguard Worker CombineFrames({&preface, &settings_frame});
5444*6777b538SAndroid Build Coastguard Worker
5445*6777b538SAndroid Build Coastguard Worker // Greased frame sent on stream 0 after initial SETTINGS frame.
5446*6777b538SAndroid Build Coastguard Worker uint8_t kRawFrameData[] = {
5447*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x03, // length
5448*6777b538SAndroid Build Coastguard Worker 0x0b, // type
5449*6777b538SAndroid Build Coastguard Worker 0xcc, // flags
5450*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, // stream ID
5451*6777b538SAndroid Build Coastguard Worker 'f', 'o', 'o' // payload
5452*6777b538SAndroid Build Coastguard Worker };
5453*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame grease(spdy::test::MakeSerializedFrame(
5454*6777b538SAndroid Build Coastguard Worker reinterpret_cast<char*>(kRawFrameData), std::size(kRawFrameData)));
5455*6777b538SAndroid Build Coastguard Worker
5456*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(combined_frame, 0),
5457*6777b538SAndroid Build Coastguard Worker CreateMockWrite(grease, 1)};
5458*6777b538SAndroid Build Coastguard Worker
5459*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {MockRead(ASYNC, 0, 2)};
5460*6777b538SAndroid Build Coastguard Worker
5461*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
5462*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5463*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5464*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5465*6777b538SAndroid Build Coastguard Worker
5466*6777b538SAndroid Build Coastguard Worker SpdySessionPoolPeer pool_peer(spdy_session_pool_);
5467*6777b538SAndroid Build Coastguard Worker pool_peer.SetEnableSendingInitialData(true);
5468*6777b538SAndroid Build Coastguard Worker
5469*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5470*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5471*6777b538SAndroid Build Coastguard Worker
5472*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
5473*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
5474*6777b538SAndroid Build Coastguard Worker }
5475*6777b538SAndroid Build Coastguard Worker
5476*6777b538SAndroid Build Coastguard Worker enum ReadIfReadySupport {
5477*6777b538SAndroid Build Coastguard Worker // ReadIfReady() is implemented by the underlying transport.
5478*6777b538SAndroid Build Coastguard Worker READ_IF_READY_SUPPORTED,
5479*6777b538SAndroid Build Coastguard Worker // ReadIfReady() is unimplemented by the underlying transport.
5480*6777b538SAndroid Build Coastguard Worker READ_IF_READY_NOT_SUPPORTED,
5481*6777b538SAndroid Build Coastguard Worker };
5482*6777b538SAndroid Build Coastguard Worker
5483*6777b538SAndroid Build Coastguard Worker class SpdySessionReadIfReadyTest
5484*6777b538SAndroid Build Coastguard Worker : public SpdySessionTest,
5485*6777b538SAndroid Build Coastguard Worker public testing::WithParamInterface<ReadIfReadySupport> {
5486*6777b538SAndroid Build Coastguard Worker public:
SetUp()5487*6777b538SAndroid Build Coastguard Worker void SetUp() override {
5488*6777b538SAndroid Build Coastguard Worker if (GetParam() == READ_IF_READY_SUPPORTED) {
5489*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->set_enable_read_if_ready(true);
5490*6777b538SAndroid Build Coastguard Worker }
5491*6777b538SAndroid Build Coastguard Worker SpdySessionTest::SetUp();
5492*6777b538SAndroid Build Coastguard Worker }
5493*6777b538SAndroid Build Coastguard Worker };
5494*6777b538SAndroid Build Coastguard Worker
5495*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(All,
5496*6777b538SAndroid Build Coastguard Worker SpdySessionReadIfReadyTest,
5497*6777b538SAndroid Build Coastguard Worker testing::Values(READ_IF_READY_SUPPORTED,
5498*6777b538SAndroid Build Coastguard Worker READ_IF_READY_NOT_SUPPORTED));
5499*6777b538SAndroid Build Coastguard Worker
5500*6777b538SAndroid Build Coastguard Worker // Tests basic functionality of ReadIfReady() when it is enabled or disabled.
TEST_P(SpdySessionReadIfReadyTest,ReadIfReady)5501*6777b538SAndroid Build Coastguard Worker TEST_P(SpdySessionReadIfReadyTest, ReadIfReady) {
5502*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
5503*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
5504*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
5505*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0),
5506*6777b538SAndroid Build Coastguard Worker };
5507*6777b538SAndroid Build Coastguard Worker
5508*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame resp(
5509*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5510*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5511*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
5512*6777b538SAndroid Build Coastguard Worker CreateMockRead(resp, 1), CreateMockRead(body, 2),
5513*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3) // EOF
5514*6777b538SAndroid Build Coastguard Worker };
5515*6777b538SAndroid Build Coastguard Worker
5516*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
5517*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5518*6777b538SAndroid Build Coastguard Worker
5519*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5520*6777b538SAndroid Build Coastguard Worker
5521*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5522*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5523*6777b538SAndroid Build Coastguard Worker
5524*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream =
5525*6777b538SAndroid Build Coastguard Worker CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
5526*6777b538SAndroid Build Coastguard Worker test_url_, HIGHEST, NetLogWithSource());
5527*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_stream);
5528*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, spdy_stream->stream_id());
5529*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate(spdy_stream);
5530*6777b538SAndroid Build Coastguard Worker spdy_stream->SetDelegate(&delegate);
5531*6777b538SAndroid Build Coastguard Worker
5532*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
5533*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
5534*6777b538SAndroid Build Coastguard Worker spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
5535*6777b538SAndroid Build Coastguard Worker
5536*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5537*6777b538SAndroid Build Coastguard Worker
5538*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(spdy_stream);
5539*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, delegate.stream_id());
5540*6777b538SAndroid Build Coastguard Worker }
5541*6777b538SAndroid Build Coastguard Worker
5542*6777b538SAndroid Build Coastguard Worker class SendInitialSettingsOnNewSpdySessionTest : public SpdySessionTest {
5543*6777b538SAndroid Build Coastguard Worker protected:
RunInitialSettingsTest(const spdy::SettingsMap expected_settings)5544*6777b538SAndroid Build Coastguard Worker void RunInitialSettingsTest(const spdy::SettingsMap expected_settings) {
5545*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
5546*6777b538SAndroid Build Coastguard Worker
5547*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame preface(spdy::test::MakeSerializedFrame(
5548*6777b538SAndroid Build Coastguard Worker const_cast<char*>(spdy::kHttp2ConnectionHeaderPrefix),
5549*6777b538SAndroid Build Coastguard Worker spdy::kHttp2ConnectionHeaderPrefixSize));
5550*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_frame(
5551*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(expected_settings));
5552*6777b538SAndroid Build Coastguard Worker
5553*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame combined_frame =
5554*6777b538SAndroid Build Coastguard Worker CombineFrames({&preface, &settings_frame});
5555*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(combined_frame, 0)};
5556*6777b538SAndroid Build Coastguard Worker
5557*6777b538SAndroid Build Coastguard Worker StaticSocketDataProvider data(reads, writes);
5558*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5559*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5560*6777b538SAndroid Build Coastguard Worker
5561*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5562*6777b538SAndroid Build Coastguard Worker
5563*6777b538SAndroid Build Coastguard Worker SpdySessionPoolPeer pool_peer(spdy_session_pool_);
5564*6777b538SAndroid Build Coastguard Worker pool_peer.SetEnableSendingInitialData(true);
5565*6777b538SAndroid Build Coastguard Worker
5566*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5567*6777b538SAndroid Build Coastguard Worker
5568*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5569*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
5570*6777b538SAndroid Build Coastguard Worker }
5571*6777b538SAndroid Build Coastguard Worker };
5572*6777b538SAndroid Build Coastguard Worker
5573*6777b538SAndroid Build Coastguard Worker // Setting values when Params::http2_settings is empty. Note that
5574*6777b538SAndroid Build Coastguard Worker // spdy::SETTINGS_INITIAL_WINDOW_SIZE is sent in production, because it is set
5575*6777b538SAndroid Build Coastguard Worker // to a non-default value, but it is not sent in tests, because the protocol
5576*6777b538SAndroid Build Coastguard Worker // default value is used in tests.
TEST_F(SendInitialSettingsOnNewSpdySessionTest,Empty)5577*6777b538SAndroid Build Coastguard Worker TEST_F(SendInitialSettingsOnNewSpdySessionTest, Empty) {
5578*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap expected_settings;
5579*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
5580*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] =
5581*6777b538SAndroid Build Coastguard Worker kSpdyMaxHeaderListSize;
5582*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
5583*6777b538SAndroid Build Coastguard Worker RunInitialSettingsTest(expected_settings);
5584*6777b538SAndroid Build Coastguard Worker }
5585*6777b538SAndroid Build Coastguard Worker
5586*6777b538SAndroid Build Coastguard Worker // When a setting is set to the protocol default value,
5587*6777b538SAndroid Build Coastguard Worker // no corresponding value is sent on the wire.
TEST_F(SendInitialSettingsOnNewSpdySessionTest,ProtocolDefault)5588*6777b538SAndroid Build Coastguard Worker TEST_F(SendInitialSettingsOnNewSpdySessionTest, ProtocolDefault) {
5589*6777b538SAndroid Build Coastguard Worker // SETTINGS_ENABLE_PUSH is always overridden with value 0.
5590*6777b538SAndroid Build Coastguard Worker session_deps_.http2_settings[spdy::SETTINGS_ENABLE_PUSH] = 1;
5591*6777b538SAndroid Build Coastguard Worker
5592*6777b538SAndroid Build Coastguard Worker // Explicitly set protocol default values for the following settings.
5593*6777b538SAndroid Build Coastguard Worker session_deps_.http2_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = 4096;
5594*6777b538SAndroid Build Coastguard Worker session_deps_.http2_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] =
5595*6777b538SAndroid Build Coastguard Worker 64 * 1024 - 1;
5596*6777b538SAndroid Build Coastguard Worker
5597*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap expected_settings;
5598*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] =
5599*6777b538SAndroid Build Coastguard Worker kSpdyMaxHeaderListSize;
5600*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
5601*6777b538SAndroid Build Coastguard Worker RunInitialSettingsTest(expected_settings);
5602*6777b538SAndroid Build Coastguard Worker }
5603*6777b538SAndroid Build Coastguard Worker
5604*6777b538SAndroid Build Coastguard Worker // Values set in Params::http2_settings overwrite Chromium's default values.
TEST_F(SendInitialSettingsOnNewSpdySessionTest,OverwriteValues)5605*6777b538SAndroid Build Coastguard Worker TEST_F(SendInitialSettingsOnNewSpdySessionTest, OverwriteValues) {
5606*6777b538SAndroid Build Coastguard Worker session_deps_.http2_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = 16 * 1024;
5607*6777b538SAndroid Build Coastguard Worker session_deps_.http2_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
5608*6777b538SAndroid Build Coastguard Worker session_deps_.http2_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = 42;
5609*6777b538SAndroid Build Coastguard Worker session_deps_.http2_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 32 * 1024;
5610*6777b538SAndroid Build Coastguard Worker session_deps_.http2_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] =
5611*6777b538SAndroid Build Coastguard Worker 101 * 1024;
5612*6777b538SAndroid Build Coastguard Worker
5613*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap expected_settings;
5614*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = 16 * 1024;
5615*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
5616*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = 42;
5617*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 32 * 1024;
5618*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] = 101 * 1024;
5619*6777b538SAndroid Build Coastguard Worker RunInitialSettingsTest(expected_settings);
5620*6777b538SAndroid Build Coastguard Worker }
5621*6777b538SAndroid Build Coastguard Worker
5622*6777b538SAndroid Build Coastguard Worker // Unknown parameters should still be sent to the server.
TEST_F(SendInitialSettingsOnNewSpdySessionTest,UnknownSettings)5623*6777b538SAndroid Build Coastguard Worker TEST_F(SendInitialSettingsOnNewSpdySessionTest, UnknownSettings) {
5624*6777b538SAndroid Build Coastguard Worker // The following parameters are not defined in the HTTP/2 specification.
5625*6777b538SAndroid Build Coastguard Worker session_deps_.http2_settings[7] = 1234;
5626*6777b538SAndroid Build Coastguard Worker session_deps_.http2_settings[25] = 5678;
5627*6777b538SAndroid Build Coastguard Worker
5628*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap expected_settings;
5629*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
5630*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] =
5631*6777b538SAndroid Build Coastguard Worker kSpdyMaxHeaderListSize;
5632*6777b538SAndroid Build Coastguard Worker expected_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
5633*6777b538SAndroid Build Coastguard Worker expected_settings[7] = 1234;
5634*6777b538SAndroid Build Coastguard Worker expected_settings[25] = 5678;
5635*6777b538SAndroid Build Coastguard Worker RunInitialSettingsTest(expected_settings);
5636*6777b538SAndroid Build Coastguard Worker }
5637*6777b538SAndroid Build Coastguard Worker
5638*6777b538SAndroid Build Coastguard Worker class AltSvcFrameTest : public SpdySessionTest {
5639*6777b538SAndroid Build Coastguard Worker public:
AltSvcFrameTest()5640*6777b538SAndroid Build Coastguard Worker AltSvcFrameTest()
5641*6777b538SAndroid Build Coastguard Worker : alternative_service_(
5642*6777b538SAndroid Build Coastguard Worker quic::AlpnForVersion(DefaultSupportedQuicVersions().front()),
5643*6777b538SAndroid Build Coastguard Worker "alternative.example.org",
5644*6777b538SAndroid Build Coastguard Worker 443,
5645*6777b538SAndroid Build Coastguard Worker 86400,
5646*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcWireFormat::VersionVector()) {
5647*6777b538SAndroid Build Coastguard Worker // Since the default |alternative_service_| is QUIC, need to enable QUIC for
5648*6777b538SAndroid Build Coastguard Worker // the not added tests to be meaningful.
5649*6777b538SAndroid Build Coastguard Worker session_deps_.enable_quic = true;
5650*6777b538SAndroid Build Coastguard Worker }
5651*6777b538SAndroid Build Coastguard Worker
AddSocketData(const spdy::SpdyAltSvcIR & altsvc_ir)5652*6777b538SAndroid Build Coastguard Worker void AddSocketData(const spdy::SpdyAltSvcIR& altsvc_ir) {
5653*6777b538SAndroid Build Coastguard Worker altsvc_frame_ = spdy_util_.SerializeFrame(altsvc_ir);
5654*6777b538SAndroid Build Coastguard Worker reads_.push_back(CreateMockRead(altsvc_frame_, 0));
5655*6777b538SAndroid Build Coastguard Worker reads_.emplace_back(ASYNC, 0, 1);
5656*6777b538SAndroid Build Coastguard Worker
5657*6777b538SAndroid Build Coastguard Worker data_ =
5658*6777b538SAndroid Build Coastguard Worker std::make_unique<SequencedSocketData>(reads_, base::span<MockWrite>());
5659*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(data_.get());
5660*6777b538SAndroid Build Coastguard Worker }
5661*6777b538SAndroid Build Coastguard Worker
CreateSpdySession()5662*6777b538SAndroid Build Coastguard Worker void CreateSpdySession() {
5663*6777b538SAndroid Build Coastguard Worker session_ =
5664*6777b538SAndroid Build Coastguard Worker ::net::CreateSpdySession(http_session_.get(), key_, NetLogWithSource());
5665*6777b538SAndroid Build Coastguard Worker }
5666*6777b538SAndroid Build Coastguard Worker
5667*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcWireFormat::AlternativeService alternative_service_;
5668*6777b538SAndroid Build Coastguard Worker
5669*6777b538SAndroid Build Coastguard Worker private:
5670*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame altsvc_frame_;
5671*6777b538SAndroid Build Coastguard Worker std::vector<MockRead> reads_;
5672*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SequencedSocketData> data_;
5673*6777b538SAndroid Build Coastguard Worker };
5674*6777b538SAndroid Build Coastguard Worker
TEST_F(AltSvcFrameTest,ProcessAltSvcFrame)5675*6777b538SAndroid Build Coastguard Worker TEST_F(AltSvcFrameTest, ProcessAltSvcFrame) {
5676*6777b538SAndroid Build Coastguard Worker const char origin[] = "https://mail.example.org";
5677*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
5678*6777b538SAndroid Build Coastguard Worker altsvc_ir.add_altsvc(alternative_service_);
5679*6777b538SAndroid Build Coastguard Worker altsvc_ir.set_origin(origin);
5680*6777b538SAndroid Build Coastguard Worker AddSocketData(altsvc_ir);
5681*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5682*6777b538SAndroid Build Coastguard Worker
5683*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5684*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5685*6777b538SAndroid Build Coastguard Worker
5686*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5687*6777b538SAndroid Build Coastguard Worker
5688*6777b538SAndroid Build Coastguard Worker const url::SchemeHostPort session_origin("https", test_url_.host(),
5689*6777b538SAndroid Build Coastguard Worker test_url_.EffectiveIntPort());
5690*6777b538SAndroid Build Coastguard Worker AlternativeServiceInfoVector altsvc_info_vector =
5691*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
5692*6777b538SAndroid Build Coastguard Worker session_origin, NetworkAnonymizationKey());
5693*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(altsvc_info_vector.empty());
5694*6777b538SAndroid Build Coastguard Worker
5695*6777b538SAndroid Build Coastguard Worker altsvc_info_vector =
5696*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
5697*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(GURL(origin)), NetworkAnonymizationKey());
5698*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(1u, altsvc_info_vector.size());
5699*6777b538SAndroid Build Coastguard Worker AlternativeService alternative_service(kProtoQUIC, "alternative.example.org",
5700*6777b538SAndroid Build Coastguard Worker 443u);
5701*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(alternative_service, altsvc_info_vector[0].alternative_service());
5702*6777b538SAndroid Build Coastguard Worker }
5703*6777b538SAndroid Build Coastguard Worker
5704*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/736063.
TEST_F(AltSvcFrameTest,IgnoreQuicAltSvcWithUnsupportedVersion)5705*6777b538SAndroid Build Coastguard Worker TEST_F(AltSvcFrameTest, IgnoreQuicAltSvcWithUnsupportedVersion) {
5706*6777b538SAndroid Build Coastguard Worker session_deps_.enable_quic = true;
5707*6777b538SAndroid Build Coastguard Worker
5708*6777b538SAndroid Build Coastguard Worker // Note that this test only uses the legacy Google-specific Alt-Svc format.
5709*6777b538SAndroid Build Coastguard Worker const char origin[] = "https://mail.example.org";
5710*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
5711*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcWireFormat::AlternativeService quic_alternative_service(
5712*6777b538SAndroid Build Coastguard Worker "quic", "alternative.example.org", 443, 86400,
5713*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcWireFormat::VersionVector());
5714*6777b538SAndroid Build Coastguard Worker quic_alternative_service.version.push_back(/* invalid QUIC version */ 1);
5715*6777b538SAndroid Build Coastguard Worker altsvc_ir.add_altsvc(quic_alternative_service);
5716*6777b538SAndroid Build Coastguard Worker altsvc_ir.set_origin(origin);
5717*6777b538SAndroid Build Coastguard Worker AddSocketData(altsvc_ir);
5718*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5719*6777b538SAndroid Build Coastguard Worker
5720*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5721*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5722*6777b538SAndroid Build Coastguard Worker
5723*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5724*6777b538SAndroid Build Coastguard Worker
5725*6777b538SAndroid Build Coastguard Worker const url::SchemeHostPort session_origin("https", test_url_.host(),
5726*6777b538SAndroid Build Coastguard Worker test_url_.EffectiveIntPort());
5727*6777b538SAndroid Build Coastguard Worker AlternativeServiceInfoVector altsvc_info_vector =
5728*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
5729*6777b538SAndroid Build Coastguard Worker session_origin, NetworkAnonymizationKey());
5730*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(altsvc_info_vector.empty());
5731*6777b538SAndroid Build Coastguard Worker
5732*6777b538SAndroid Build Coastguard Worker altsvc_info_vector =
5733*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
5734*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(GURL(origin)), NetworkAnonymizationKey());
5735*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(0u, altsvc_info_vector.size());
5736*6777b538SAndroid Build Coastguard Worker }
5737*6777b538SAndroid Build Coastguard Worker
TEST_F(AltSvcFrameTest,DoNotProcessAltSvcFrameForOriginNotCoveredByCert)5738*6777b538SAndroid Build Coastguard Worker TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameForOriginNotCoveredByCert) {
5739*6777b538SAndroid Build Coastguard Worker session_deps_.enable_quic = true;
5740*6777b538SAndroid Build Coastguard Worker
5741*6777b538SAndroid Build Coastguard Worker const char origin[] = "https://invalid.example.org";
5742*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
5743*6777b538SAndroid Build Coastguard Worker altsvc_ir.add_altsvc(alternative_service_);
5744*6777b538SAndroid Build Coastguard Worker altsvc_ir.set_origin(origin);
5745*6777b538SAndroid Build Coastguard Worker AddSocketData(altsvc_ir);
5746*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5747*6777b538SAndroid Build Coastguard Worker
5748*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5749*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5750*6777b538SAndroid Build Coastguard Worker
5751*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5752*6777b538SAndroid Build Coastguard Worker
5753*6777b538SAndroid Build Coastguard Worker const url::SchemeHostPort session_origin("https", test_url_.host(),
5754*6777b538SAndroid Build Coastguard Worker test_url_.EffectiveIntPort());
5755*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_session_pool_->http_server_properties()
5756*6777b538SAndroid Build Coastguard Worker ->GetAlternativeServiceInfos(session_origin,
5757*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey())
5758*6777b538SAndroid Build Coastguard Worker .empty());
5759*6777b538SAndroid Build Coastguard Worker
5760*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(
5761*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->http_server_properties()
5762*6777b538SAndroid Build Coastguard Worker ->GetAlternativeServiceInfos(url::SchemeHostPort(GURL(origin)),
5763*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey())
5764*6777b538SAndroid Build Coastguard Worker .empty());
5765*6777b538SAndroid Build Coastguard Worker }
5766*6777b538SAndroid Build Coastguard Worker
5767*6777b538SAndroid Build Coastguard Worker // An ALTSVC frame on stream 0 with empty origin MUST be ignored.
5768*6777b538SAndroid Build Coastguard Worker // (RFC 7838 Section 4)
TEST_F(AltSvcFrameTest,DoNotProcessAltSvcFrameWithEmptyOriginOnStreamZero)5769*6777b538SAndroid Build Coastguard Worker TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameWithEmptyOriginOnStreamZero) {
5770*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
5771*6777b538SAndroid Build Coastguard Worker altsvc_ir.add_altsvc(alternative_service_);
5772*6777b538SAndroid Build Coastguard Worker AddSocketData(altsvc_ir);
5773*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5774*6777b538SAndroid Build Coastguard Worker
5775*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5776*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5777*6777b538SAndroid Build Coastguard Worker
5778*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5779*6777b538SAndroid Build Coastguard Worker
5780*6777b538SAndroid Build Coastguard Worker const url::SchemeHostPort session_origin("https", test_url_.host(),
5781*6777b538SAndroid Build Coastguard Worker test_url_.EffectiveIntPort());
5782*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_session_pool_->http_server_properties()
5783*6777b538SAndroid Build Coastguard Worker ->GetAlternativeServiceInfos(session_origin,
5784*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey())
5785*6777b538SAndroid Build Coastguard Worker .empty());
5786*6777b538SAndroid Build Coastguard Worker }
5787*6777b538SAndroid Build Coastguard Worker
5788*6777b538SAndroid Build Coastguard Worker // An ALTSVC frame on a stream other than stream 0 with non-empty origin MUST be
5789*6777b538SAndroid Build Coastguard Worker // ignored. (RFC 7838 Section 4)
TEST_F(AltSvcFrameTest,DoNotProcessAltSvcFrameWithNonEmptyOriginOnNonZeroStream)5790*6777b538SAndroid Build Coastguard Worker TEST_F(AltSvcFrameTest,
5791*6777b538SAndroid Build Coastguard Worker DoNotProcessAltSvcFrameWithNonEmptyOriginOnNonZeroStream) {
5792*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
5793*6777b538SAndroid Build Coastguard Worker altsvc_ir.add_altsvc(alternative_service_);
5794*6777b538SAndroid Build Coastguard Worker altsvc_ir.set_origin("https://mail.example.org");
5795*6777b538SAndroid Build Coastguard Worker AddSocketData(altsvc_ir);
5796*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5797*6777b538SAndroid Build Coastguard Worker
5798*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5799*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5800*6777b538SAndroid Build Coastguard Worker
5801*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5802*6777b538SAndroid Build Coastguard Worker
5803*6777b538SAndroid Build Coastguard Worker const url::SchemeHostPort session_origin("https", test_url_.host(),
5804*6777b538SAndroid Build Coastguard Worker test_url_.EffectiveIntPort());
5805*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_session_pool_->http_server_properties()
5806*6777b538SAndroid Build Coastguard Worker ->GetAlternativeServiceInfos(session_origin,
5807*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey())
5808*6777b538SAndroid Build Coastguard Worker .empty());
5809*6777b538SAndroid Build Coastguard Worker }
5810*6777b538SAndroid Build Coastguard Worker
TEST_F(AltSvcFrameTest,ProcessAltSvcFrameOnActiveStream)5811*6777b538SAndroid Build Coastguard Worker TEST_F(AltSvcFrameTest, ProcessAltSvcFrameOnActiveStream) {
5812*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
5813*6777b538SAndroid Build Coastguard Worker altsvc_ir.add_altsvc(alternative_service_);
5814*6777b538SAndroid Build Coastguard Worker
5815*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame altsvc_frame(spdy_util_.SerializeFrame(altsvc_ir));
5816*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame rst(
5817*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_REFUSED_STREAM));
5818*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
5819*6777b538SAndroid Build Coastguard Worker CreateMockRead(altsvc_frame, 1), CreateMockRead(rst, 2),
5820*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3) // EOF
5821*6777b538SAndroid Build Coastguard Worker };
5822*6777b538SAndroid Build Coastguard Worker
5823*6777b538SAndroid Build Coastguard Worker const char request_origin[] = "https://mail.example.org";
5824*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
5825*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(request_origin, 1, MEDIUM));
5826*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
5827*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0),
5828*6777b538SAndroid Build Coastguard Worker };
5829*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
5830*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5831*6777b538SAndroid Build Coastguard Worker
5832*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5833*6777b538SAndroid Build Coastguard Worker
5834*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5835*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5836*6777b538SAndroid Build Coastguard Worker
5837*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
5838*6777b538SAndroid Build Coastguard Worker SPDY_REQUEST_RESPONSE_STREAM, session_, GURL(request_origin), MEDIUM,
5839*6777b538SAndroid Build Coastguard Worker NetLogWithSource());
5840*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
5841*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
5842*6777b538SAndroid Build Coastguard Worker
5843*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
5844*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(request_origin));
5845*6777b538SAndroid Build Coastguard Worker
5846*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
5847*6777b538SAndroid Build Coastguard Worker
5848*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5849*6777b538SAndroid Build Coastguard Worker
5850*6777b538SAndroid Build Coastguard Worker const url::SchemeHostPort session_origin("https", test_url_.host(),
5851*6777b538SAndroid Build Coastguard Worker test_url_.EffectiveIntPort());
5852*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_session_pool_->http_server_properties()
5853*6777b538SAndroid Build Coastguard Worker ->GetAlternativeServiceInfos(session_origin,
5854*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey())
5855*6777b538SAndroid Build Coastguard Worker .empty());
5856*6777b538SAndroid Build Coastguard Worker
5857*6777b538SAndroid Build Coastguard Worker AlternativeServiceInfoVector altsvc_info_vector =
5858*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
5859*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(GURL(request_origin)), NetworkAnonymizationKey());
5860*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(1u, altsvc_info_vector.size());
5861*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kProtoQUIC, altsvc_info_vector[0].alternative_service().protocol);
5862*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("alternative.example.org",
5863*6777b538SAndroid Build Coastguard Worker altsvc_info_vector[0].alternative_service().host);
5864*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(443u, altsvc_info_vector[0].alternative_service().port);
5865*6777b538SAndroid Build Coastguard Worker }
5866*6777b538SAndroid Build Coastguard Worker
TEST_F(AltSvcFrameTest,ProcessAltSvcFrameOnActiveStreamWithNetworkAnonymizationKey)5867*6777b538SAndroid Build Coastguard Worker TEST_F(AltSvcFrameTest,
5868*6777b538SAndroid Build Coastguard Worker ProcessAltSvcFrameOnActiveStreamWithNetworkAnonymizationKey) {
5869*6777b538SAndroid Build Coastguard Worker base::test::ScopedFeatureList feature_list;
5870*6777b538SAndroid Build Coastguard Worker feature_list.InitWithFeatures(
5871*6777b538SAndroid Build Coastguard Worker // enabled_features
5872*6777b538SAndroid Build Coastguard Worker {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5873*6777b538SAndroid Build Coastguard Worker // Need to partition connections by NetworkAnonymizationKey for
5874*6777b538SAndroid Build Coastguard Worker // SpdySessionKeys to include NetworkAnonymizationKeys.
5875*6777b538SAndroid Build Coastguard Worker features::kPartitionConnectionsByNetworkIsolationKey},
5876*6777b538SAndroid Build Coastguard Worker // disabled_features
5877*6777b538SAndroid Build Coastguard Worker {});
5878*6777b538SAndroid Build Coastguard Worker // Since HttpServerProperties caches the feature value, have to create a new
5879*6777b538SAndroid Build Coastguard Worker // one.
5880*6777b538SAndroid Build Coastguard Worker session_deps_.http_server_properties =
5881*6777b538SAndroid Build Coastguard Worker std::make_unique<HttpServerProperties>();
5882*6777b538SAndroid Build Coastguard Worker
5883*6777b538SAndroid Build Coastguard Worker const SchemefulSite kSite1(GURL("https://foo.test/"));
5884*6777b538SAndroid Build Coastguard Worker const auto kNetworkAnonymizationKey1 =
5885*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey::CreateSameSite(kSite1);
5886*6777b538SAndroid Build Coastguard Worker const SchemefulSite kSite2(GURL("https://bar.test/"));
5887*6777b538SAndroid Build Coastguard Worker const auto kNetworkAnonymizationKey2 =
5888*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey::CreateSameSite(kSite2);
5889*6777b538SAndroid Build Coastguard Worker key_ = SpdySessionKey(HostPortPair::FromURL(test_url_), PRIVACY_MODE_DISABLED,
5890*6777b538SAndroid Build Coastguard Worker ProxyChain::Direct(), SessionUsage::kDestination,
5891*6777b538SAndroid Build Coastguard Worker SocketTag(), kNetworkAnonymizationKey1,
5892*6777b538SAndroid Build Coastguard Worker SecureDnsPolicy::kAllow,
5893*6777b538SAndroid Build Coastguard Worker /*disable_cert_verification_network_fetches=*/false);
5894*6777b538SAndroid Build Coastguard Worker
5895*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
5896*6777b538SAndroid Build Coastguard Worker altsvc_ir.add_altsvc(alternative_service_);
5897*6777b538SAndroid Build Coastguard Worker
5898*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame altsvc_frame(spdy_util_.SerializeFrame(altsvc_ir));
5899*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame rst(
5900*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_REFUSED_STREAM));
5901*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
5902*6777b538SAndroid Build Coastguard Worker CreateMockRead(altsvc_frame, 1), CreateMockRead(rst, 2),
5903*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3) // EOF
5904*6777b538SAndroid Build Coastguard Worker };
5905*6777b538SAndroid Build Coastguard Worker
5906*6777b538SAndroid Build Coastguard Worker const char request_origin[] = "https://mail.example.org";
5907*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
5908*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(request_origin, 1, MEDIUM));
5909*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
5910*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0),
5911*6777b538SAndroid Build Coastguard Worker };
5912*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
5913*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5914*6777b538SAndroid Build Coastguard Worker
5915*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5916*6777b538SAndroid Build Coastguard Worker
5917*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5918*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5919*6777b538SAndroid Build Coastguard Worker
5920*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
5921*6777b538SAndroid Build Coastguard Worker SPDY_REQUEST_RESPONSE_STREAM, session_, GURL(request_origin), MEDIUM,
5922*6777b538SAndroid Build Coastguard Worker NetLogWithSource());
5923*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
5924*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
5925*6777b538SAndroid Build Coastguard Worker
5926*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
5927*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(request_origin));
5928*6777b538SAndroid Build Coastguard Worker
5929*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
5930*6777b538SAndroid Build Coastguard Worker
5931*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
5932*6777b538SAndroid Build Coastguard Worker
5933*6777b538SAndroid Build Coastguard Worker const url::SchemeHostPort session_origin("https", test_url_.host(),
5934*6777b538SAndroid Build Coastguard Worker test_url_.EffectiveIntPort());
5935*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_session_pool_->http_server_properties()
5936*6777b538SAndroid Build Coastguard Worker ->GetAlternativeServiceInfos(session_origin,
5937*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey())
5938*6777b538SAndroid Build Coastguard Worker .empty());
5939*6777b538SAndroid Build Coastguard Worker
5940*6777b538SAndroid Build Coastguard Worker AlternativeServiceInfoVector altsvc_info_vector =
5941*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
5942*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(GURL(request_origin)), kNetworkAnonymizationKey1);
5943*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(1u, altsvc_info_vector.size());
5944*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kProtoQUIC, altsvc_info_vector[0].alternative_service().protocol);
5945*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("alternative.example.org",
5946*6777b538SAndroid Build Coastguard Worker altsvc_info_vector[0].alternative_service().host);
5947*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(443u, altsvc_info_vector[0].alternative_service().port);
5948*6777b538SAndroid Build Coastguard Worker
5949*6777b538SAndroid Build Coastguard Worker // Make sure the alternative service information is only associated with
5950*6777b538SAndroid Build Coastguard Worker // kNetworkAnonymizationKey1.
5951*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(spdy_session_pool_->http_server_properties()
5952*6777b538SAndroid Build Coastguard Worker ->GetAlternativeServiceInfos(
5953*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(GURL(request_origin)),
5954*6777b538SAndroid Build Coastguard Worker kNetworkAnonymizationKey2)
5955*6777b538SAndroid Build Coastguard Worker .empty());
5956*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(spdy_session_pool_->http_server_properties()
5957*6777b538SAndroid Build Coastguard Worker ->GetAlternativeServiceInfos(
5958*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(GURL(request_origin)),
5959*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey())
5960*6777b538SAndroid Build Coastguard Worker .empty());
5961*6777b538SAndroid Build Coastguard Worker }
5962*6777b538SAndroid Build Coastguard Worker
TEST_F(AltSvcFrameTest,DoNotProcessAltSvcFrameOnStreamWithInsecureOrigin)5963*6777b538SAndroid Build Coastguard Worker TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameOnStreamWithInsecureOrigin) {
5964*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
5965*6777b538SAndroid Build Coastguard Worker altsvc_ir.add_altsvc(alternative_service_);
5966*6777b538SAndroid Build Coastguard Worker
5967*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame altsvc_frame(spdy_util_.SerializeFrame(altsvc_ir));
5968*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame rst(
5969*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_REFUSED_STREAM));
5970*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
5971*6777b538SAndroid Build Coastguard Worker CreateMockRead(altsvc_frame, 1), CreateMockRead(rst, 2),
5972*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3) // EOF
5973*6777b538SAndroid Build Coastguard Worker };
5974*6777b538SAndroid Build Coastguard Worker
5975*6777b538SAndroid Build Coastguard Worker const char request_origin[] = "http://mail.example.org";
5976*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame req(
5977*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdyGet(request_origin, 1, MEDIUM));
5978*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
5979*6777b538SAndroid Build Coastguard Worker CreateMockWrite(req, 0),
5980*6777b538SAndroid Build Coastguard Worker };
5981*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
5982*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
5983*6777b538SAndroid Build Coastguard Worker
5984*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
5985*6777b538SAndroid Build Coastguard Worker
5986*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
5987*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
5988*6777b538SAndroid Build Coastguard Worker
5989*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
5990*6777b538SAndroid Build Coastguard Worker SPDY_REQUEST_RESPONSE_STREAM, session_, GURL(request_origin), MEDIUM,
5991*6777b538SAndroid Build Coastguard Worker NetLogWithSource());
5992*6777b538SAndroid Build Coastguard Worker test::StreamDelegateDoNothing delegate1(spdy_stream1);
5993*6777b538SAndroid Build Coastguard Worker spdy_stream1->SetDelegate(&delegate1);
5994*6777b538SAndroid Build Coastguard Worker
5995*6777b538SAndroid Build Coastguard Worker spdy::Http2HeaderBlock headers(
5996*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructGetHeaderBlock(request_origin));
5997*6777b538SAndroid Build Coastguard Worker
5998*6777b538SAndroid Build Coastguard Worker spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
5999*6777b538SAndroid Build Coastguard Worker
6000*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6001*6777b538SAndroid Build Coastguard Worker
6002*6777b538SAndroid Build Coastguard Worker const url::SchemeHostPort session_origin("https", test_url_.host(),
6003*6777b538SAndroid Build Coastguard Worker test_url_.EffectiveIntPort());
6004*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_session_pool_->http_server_properties()
6005*6777b538SAndroid Build Coastguard Worker ->GetAlternativeServiceInfos(session_origin,
6006*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey())
6007*6777b538SAndroid Build Coastguard Worker .empty());
6008*6777b538SAndroid Build Coastguard Worker
6009*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_session_pool_->http_server_properties()
6010*6777b538SAndroid Build Coastguard Worker ->GetAlternativeServiceInfos(
6011*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(GURL(request_origin)),
6012*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey())
6013*6777b538SAndroid Build Coastguard Worker .empty());
6014*6777b538SAndroid Build Coastguard Worker }
6015*6777b538SAndroid Build Coastguard Worker
TEST_F(AltSvcFrameTest,DoNotProcessAltSvcFrameOnNonExistentStream)6016*6777b538SAndroid Build Coastguard Worker TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameOnNonExistentStream) {
6017*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
6018*6777b538SAndroid Build Coastguard Worker altsvc_ir.add_altsvc(alternative_service_);
6019*6777b538SAndroid Build Coastguard Worker AddSocketData(altsvc_ir);
6020*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
6021*6777b538SAndroid Build Coastguard Worker
6022*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
6023*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
6024*6777b538SAndroid Build Coastguard Worker
6025*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6026*6777b538SAndroid Build Coastguard Worker
6027*6777b538SAndroid Build Coastguard Worker const url::SchemeHostPort session_origin("https", test_url_.host(),
6028*6777b538SAndroid Build Coastguard Worker test_url_.EffectiveIntPort());
6029*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(spdy_session_pool_->http_server_properties()
6030*6777b538SAndroid Build Coastguard Worker ->GetAlternativeServiceInfos(session_origin,
6031*6777b538SAndroid Build Coastguard Worker NetworkAnonymizationKey())
6032*6777b538SAndroid Build Coastguard Worker .empty());
6033*6777b538SAndroid Build Coastguard Worker }
6034*6777b538SAndroid Build Coastguard Worker
6035*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/810404.
TEST_F(AltSvcFrameTest,InvalidOrigin)6036*6777b538SAndroid Build Coastguard Worker TEST_F(AltSvcFrameTest, InvalidOrigin) {
6037*6777b538SAndroid Build Coastguard Worker // This origin parses to an invalid GURL with https scheme.
6038*6777b538SAndroid Build Coastguard Worker const std::string origin("https:?");
6039*6777b538SAndroid Build Coastguard Worker const GURL origin_gurl(origin);
6040*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(origin_gurl.is_valid());
6041*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(origin_gurl.host().empty());
6042*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(origin_gurl.SchemeIs(url::kHttpsScheme));
6043*6777b538SAndroid Build Coastguard Worker
6044*6777b538SAndroid Build Coastguard Worker spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
6045*6777b538SAndroid Build Coastguard Worker altsvc_ir.add_altsvc(alternative_service_);
6046*6777b538SAndroid Build Coastguard Worker altsvc_ir.set_origin(origin);
6047*6777b538SAndroid Build Coastguard Worker AddSocketData(altsvc_ir);
6048*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
6049*6777b538SAndroid Build Coastguard Worker
6050*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
6051*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
6052*6777b538SAndroid Build Coastguard Worker
6053*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6054*6777b538SAndroid Build Coastguard Worker
6055*6777b538SAndroid Build Coastguard Worker const url::SchemeHostPort session_origin("https", test_url_.host(),
6056*6777b538SAndroid Build Coastguard Worker test_url_.EffectiveIntPort());
6057*6777b538SAndroid Build Coastguard Worker AlternativeServiceInfoVector altsvc_info_vector =
6058*6777b538SAndroid Build Coastguard Worker spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
6059*6777b538SAndroid Build Coastguard Worker session_origin, NetworkAnonymizationKey());
6060*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(altsvc_info_vector.empty());
6061*6777b538SAndroid Build Coastguard Worker }
6062*6777b538SAndroid Build Coastguard Worker
TEST(MapFramerErrorToProtocolError,MapsValues)6063*6777b538SAndroid Build Coastguard Worker TEST(MapFramerErrorToProtocolError, MapsValues) {
6064*6777b538SAndroid Build Coastguard Worker CHECK_EQ(SPDY_ERROR_INVALID_CONTROL_FRAME,
6065*6777b538SAndroid Build Coastguard Worker MapFramerErrorToProtocolError(
6066*6777b538SAndroid Build Coastguard Worker http2::Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME));
6067*6777b538SAndroid Build Coastguard Worker CHECK_EQ(SPDY_ERROR_INVALID_DATA_FRAME_FLAGS,
6068*6777b538SAndroid Build Coastguard Worker MapFramerErrorToProtocolError(
6069*6777b538SAndroid Build Coastguard Worker http2::Http2DecoderAdapter::SPDY_INVALID_DATA_FRAME_FLAGS));
6070*6777b538SAndroid Build Coastguard Worker CHECK_EQ(SPDY_ERROR_HPACK_NAME_HUFFMAN_ERROR,
6071*6777b538SAndroid Build Coastguard Worker MapFramerErrorToProtocolError(
6072*6777b538SAndroid Build Coastguard Worker http2::Http2DecoderAdapter::SPDY_HPACK_NAME_HUFFMAN_ERROR));
6073*6777b538SAndroid Build Coastguard Worker CHECK_EQ(SPDY_ERROR_UNEXPECTED_FRAME,
6074*6777b538SAndroid Build Coastguard Worker MapFramerErrorToProtocolError(
6075*6777b538SAndroid Build Coastguard Worker http2::Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME));
6076*6777b538SAndroid Build Coastguard Worker }
6077*6777b538SAndroid Build Coastguard Worker
TEST(MapFramerErrorToNetError,MapsValue)6078*6777b538SAndroid Build Coastguard Worker TEST(MapFramerErrorToNetError, MapsValue) {
6079*6777b538SAndroid Build Coastguard Worker CHECK_EQ(ERR_HTTP2_PROTOCOL_ERROR,
6080*6777b538SAndroid Build Coastguard Worker MapFramerErrorToNetError(
6081*6777b538SAndroid Build Coastguard Worker http2::Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME));
6082*6777b538SAndroid Build Coastguard Worker CHECK_EQ(ERR_HTTP2_COMPRESSION_ERROR,
6083*6777b538SAndroid Build Coastguard Worker MapFramerErrorToNetError(
6084*6777b538SAndroid Build Coastguard Worker http2::Http2DecoderAdapter::SPDY_DECOMPRESS_FAILURE));
6085*6777b538SAndroid Build Coastguard Worker CHECK_EQ(ERR_HTTP2_FRAME_SIZE_ERROR,
6086*6777b538SAndroid Build Coastguard Worker MapFramerErrorToNetError(
6087*6777b538SAndroid Build Coastguard Worker http2::Http2DecoderAdapter::SPDY_CONTROL_PAYLOAD_TOO_LARGE));
6088*6777b538SAndroid Build Coastguard Worker CHECK_EQ(ERR_HTTP2_FRAME_SIZE_ERROR,
6089*6777b538SAndroid Build Coastguard Worker MapFramerErrorToNetError(
6090*6777b538SAndroid Build Coastguard Worker http2::Http2DecoderAdapter::SPDY_OVERSIZED_PAYLOAD));
6091*6777b538SAndroid Build Coastguard Worker }
6092*6777b538SAndroid Build Coastguard Worker
TEST(MapRstStreamStatusToProtocolError,MapsValues)6093*6777b538SAndroid Build Coastguard Worker TEST(MapRstStreamStatusToProtocolError, MapsValues) {
6094*6777b538SAndroid Build Coastguard Worker CHECK_EQ(STATUS_CODE_PROTOCOL_ERROR,
6095*6777b538SAndroid Build Coastguard Worker MapRstStreamStatusToProtocolError(spdy::ERROR_CODE_PROTOCOL_ERROR));
6096*6777b538SAndroid Build Coastguard Worker CHECK_EQ(
6097*6777b538SAndroid Build Coastguard Worker STATUS_CODE_FRAME_SIZE_ERROR,
6098*6777b538SAndroid Build Coastguard Worker MapRstStreamStatusToProtocolError(spdy::ERROR_CODE_FRAME_SIZE_ERROR));
6099*6777b538SAndroid Build Coastguard Worker CHECK_EQ(
6100*6777b538SAndroid Build Coastguard Worker STATUS_CODE_ENHANCE_YOUR_CALM,
6101*6777b538SAndroid Build Coastguard Worker MapRstStreamStatusToProtocolError(spdy::ERROR_CODE_ENHANCE_YOUR_CALM));
6102*6777b538SAndroid Build Coastguard Worker CHECK_EQ(
6103*6777b538SAndroid Build Coastguard Worker STATUS_CODE_INADEQUATE_SECURITY,
6104*6777b538SAndroid Build Coastguard Worker MapRstStreamStatusToProtocolError(spdy::ERROR_CODE_INADEQUATE_SECURITY));
6105*6777b538SAndroid Build Coastguard Worker CHECK_EQ(
6106*6777b538SAndroid Build Coastguard Worker STATUS_CODE_HTTP_1_1_REQUIRED,
6107*6777b538SAndroid Build Coastguard Worker MapRstStreamStatusToProtocolError(spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
6108*6777b538SAndroid Build Coastguard Worker }
6109*6777b538SAndroid Build Coastguard Worker
TEST(MapNetErrorToGoAwayStatus,MapsValue)6110*6777b538SAndroid Build Coastguard Worker TEST(MapNetErrorToGoAwayStatus, MapsValue) {
6111*6777b538SAndroid Build Coastguard Worker CHECK_EQ(spdy::ERROR_CODE_INADEQUATE_SECURITY,
6112*6777b538SAndroid Build Coastguard Worker MapNetErrorToGoAwayStatus(ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY));
6113*6777b538SAndroid Build Coastguard Worker CHECK_EQ(spdy::ERROR_CODE_FLOW_CONTROL_ERROR,
6114*6777b538SAndroid Build Coastguard Worker MapNetErrorToGoAwayStatus(ERR_HTTP2_FLOW_CONTROL_ERROR));
6115*6777b538SAndroid Build Coastguard Worker CHECK_EQ(spdy::ERROR_CODE_PROTOCOL_ERROR,
6116*6777b538SAndroid Build Coastguard Worker MapNetErrorToGoAwayStatus(ERR_HTTP2_PROTOCOL_ERROR));
6117*6777b538SAndroid Build Coastguard Worker CHECK_EQ(spdy::ERROR_CODE_COMPRESSION_ERROR,
6118*6777b538SAndroid Build Coastguard Worker MapNetErrorToGoAwayStatus(ERR_HTTP2_COMPRESSION_ERROR));
6119*6777b538SAndroid Build Coastguard Worker CHECK_EQ(spdy::ERROR_CODE_FRAME_SIZE_ERROR,
6120*6777b538SAndroid Build Coastguard Worker MapNetErrorToGoAwayStatus(ERR_HTTP2_FRAME_SIZE_ERROR));
6121*6777b538SAndroid Build Coastguard Worker CHECK_EQ(spdy::ERROR_CODE_PROTOCOL_ERROR,
6122*6777b538SAndroid Build Coastguard Worker MapNetErrorToGoAwayStatus(ERR_UNEXPECTED));
6123*6777b538SAndroid Build Coastguard Worker }
6124*6777b538SAndroid Build Coastguard Worker
6125*6777b538SAndroid Build Coastguard Worker namespace {
6126*6777b538SAndroid Build Coastguard Worker
6127*6777b538SAndroid Build Coastguard Worker class TestSSLConfigService : public SSLConfigService {
6128*6777b538SAndroid Build Coastguard Worker public:
6129*6777b538SAndroid Build Coastguard Worker TestSSLConfigService() = default;
6130*6777b538SAndroid Build Coastguard Worker ~TestSSLConfigService() override = default;
6131*6777b538SAndroid Build Coastguard Worker
GetSSLContextConfig()6132*6777b538SAndroid Build Coastguard Worker SSLContextConfig GetSSLContextConfig() override { return config_; }
6133*6777b538SAndroid Build Coastguard Worker
6134*6777b538SAndroid Build Coastguard Worker // Returns true if |hostname| is in domains_for_pooling_. This is a simpler
6135*6777b538SAndroid Build Coastguard Worker // implementation than the production implementation in SSLConfigServiceMojo.
CanShareConnectionWithClientCerts(std::string_view hostname) const6136*6777b538SAndroid Build Coastguard Worker bool CanShareConnectionWithClientCerts(
6137*6777b538SAndroid Build Coastguard Worker std::string_view hostname) const override {
6138*6777b538SAndroid Build Coastguard Worker return base::Contains(domains_for_pooling_, hostname);
6139*6777b538SAndroid Build Coastguard Worker }
6140*6777b538SAndroid Build Coastguard Worker
SetDomainsForPooling(const std::vector<std::string> & domains)6141*6777b538SAndroid Build Coastguard Worker void SetDomainsForPooling(const std::vector<std::string>& domains) {
6142*6777b538SAndroid Build Coastguard Worker domains_for_pooling_ = domains;
6143*6777b538SAndroid Build Coastguard Worker }
6144*6777b538SAndroid Build Coastguard Worker
6145*6777b538SAndroid Build Coastguard Worker private:
6146*6777b538SAndroid Build Coastguard Worker SSLContextConfig config_;
6147*6777b538SAndroid Build Coastguard Worker std::vector<std::string> domains_for_pooling_;
6148*6777b538SAndroid Build Coastguard Worker };
6149*6777b538SAndroid Build Coastguard Worker
6150*6777b538SAndroid Build Coastguard Worker } // namespace
6151*6777b538SAndroid Build Coastguard Worker
TEST(CanPoolTest,CanPool)6152*6777b538SAndroid Build Coastguard Worker TEST(CanPoolTest, CanPool) {
6153*6777b538SAndroid Build Coastguard Worker // Load a cert that is valid for:
6154*6777b538SAndroid Build Coastguard Worker // www.example.org
6155*6777b538SAndroid Build Coastguard Worker // mail.example.org
6156*6777b538SAndroid Build Coastguard Worker // mail.example.com
6157*6777b538SAndroid Build Coastguard Worker
6158*6777b538SAndroid Build Coastguard Worker TransportSecurityState tss;
6159*6777b538SAndroid Build Coastguard Worker TestSSLConfigService ssl_config_service;
6160*6777b538SAndroid Build Coastguard Worker SSLInfo ssl_info;
6161*6777b538SAndroid Build Coastguard Worker ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
6162*6777b538SAndroid Build Coastguard Worker "spdy_pooling.pem");
6163*6777b538SAndroid Build Coastguard Worker
6164*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6165*6777b538SAndroid Build Coastguard Worker "www.example.org", "www.example.org"));
6166*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6167*6777b538SAndroid Build Coastguard Worker "www.example.org", "mail.example.org"));
6168*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6169*6777b538SAndroid Build Coastguard Worker "www.example.org", "mail.example.com"));
6170*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6171*6777b538SAndroid Build Coastguard Worker "www.example.org", "mail.google.com"));
6172*6777b538SAndroid Build Coastguard Worker }
6173*6777b538SAndroid Build Coastguard Worker
TEST(CanPoolTest,CanNotPoolWithCertErrors)6174*6777b538SAndroid Build Coastguard Worker TEST(CanPoolTest, CanNotPoolWithCertErrors) {
6175*6777b538SAndroid Build Coastguard Worker // Load a cert that is valid for:
6176*6777b538SAndroid Build Coastguard Worker // www.example.org
6177*6777b538SAndroid Build Coastguard Worker // mail.example.org
6178*6777b538SAndroid Build Coastguard Worker // mail.example.com
6179*6777b538SAndroid Build Coastguard Worker
6180*6777b538SAndroid Build Coastguard Worker TransportSecurityState tss;
6181*6777b538SAndroid Build Coastguard Worker TestSSLConfigService ssl_config_service;
6182*6777b538SAndroid Build Coastguard Worker SSLInfo ssl_info;
6183*6777b538SAndroid Build Coastguard Worker ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
6184*6777b538SAndroid Build Coastguard Worker "spdy_pooling.pem");
6185*6777b538SAndroid Build Coastguard Worker ssl_info.cert_status = CERT_STATUS_REVOKED;
6186*6777b538SAndroid Build Coastguard Worker
6187*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6188*6777b538SAndroid Build Coastguard Worker "www.example.org", "mail.example.org"));
6189*6777b538SAndroid Build Coastguard Worker }
6190*6777b538SAndroid Build Coastguard Worker
TEST(CanPoolTest,CanNotPoolWithClientCerts)6191*6777b538SAndroid Build Coastguard Worker TEST(CanPoolTest, CanNotPoolWithClientCerts) {
6192*6777b538SAndroid Build Coastguard Worker // Load a cert that is valid for:
6193*6777b538SAndroid Build Coastguard Worker // www.example.org
6194*6777b538SAndroid Build Coastguard Worker // mail.example.org
6195*6777b538SAndroid Build Coastguard Worker // mail.example.com
6196*6777b538SAndroid Build Coastguard Worker
6197*6777b538SAndroid Build Coastguard Worker TransportSecurityState tss;
6198*6777b538SAndroid Build Coastguard Worker TestSSLConfigService ssl_config_service;
6199*6777b538SAndroid Build Coastguard Worker SSLInfo ssl_info;
6200*6777b538SAndroid Build Coastguard Worker ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
6201*6777b538SAndroid Build Coastguard Worker "spdy_pooling.pem");
6202*6777b538SAndroid Build Coastguard Worker ssl_info.client_cert_sent = true;
6203*6777b538SAndroid Build Coastguard Worker
6204*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6205*6777b538SAndroid Build Coastguard Worker "www.example.org", "mail.example.org"));
6206*6777b538SAndroid Build Coastguard Worker }
6207*6777b538SAndroid Build Coastguard Worker
TEST(CanPoolTest,CanNotPoolWithBadPins)6208*6777b538SAndroid Build Coastguard Worker TEST(CanPoolTest, CanNotPoolWithBadPins) {
6209*6777b538SAndroid Build Coastguard Worker base::test::ScopedFeatureList scoped_feature_list_;
6210*6777b538SAndroid Build Coastguard Worker scoped_feature_list_.InitAndEnableFeature(
6211*6777b538SAndroid Build Coastguard Worker net::features::kStaticKeyPinningEnforcement);
6212*6777b538SAndroid Build Coastguard Worker TransportSecurityState tss;
6213*6777b538SAndroid Build Coastguard Worker tss.EnableStaticPinsForTesting();
6214*6777b538SAndroid Build Coastguard Worker tss.SetPinningListAlwaysTimelyForTesting(true);
6215*6777b538SAndroid Build Coastguard Worker ScopedTransportSecurityStateSource scoped_security_state_source;
6216*6777b538SAndroid Build Coastguard Worker
6217*6777b538SAndroid Build Coastguard Worker TestSSLConfigService ssl_config_service;
6218*6777b538SAndroid Build Coastguard Worker SSLInfo ssl_info;
6219*6777b538SAndroid Build Coastguard Worker ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
6220*6777b538SAndroid Build Coastguard Worker "spdy_pooling.pem");
6221*6777b538SAndroid Build Coastguard Worker ssl_info.is_issued_by_known_root = true;
6222*6777b538SAndroid Build Coastguard Worker uint8_t bad_pin = 3;
6223*6777b538SAndroid Build Coastguard Worker ssl_info.public_key_hashes.push_back(test::GetTestHashValue(bad_pin));
6224*6777b538SAndroid Build Coastguard Worker
6225*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6226*6777b538SAndroid Build Coastguard Worker "www.example.org", "example.test"));
6227*6777b538SAndroid Build Coastguard Worker }
6228*6777b538SAndroid Build Coastguard Worker
TEST(CanPoolTest,CanNotPoolWithBadCTWhenCTRequired)6229*6777b538SAndroid Build Coastguard Worker TEST(CanPoolTest, CanNotPoolWithBadCTWhenCTRequired) {
6230*6777b538SAndroid Build Coastguard Worker using testing::Return;
6231*6777b538SAndroid Build Coastguard Worker using CTRequirementLevel =
6232*6777b538SAndroid Build Coastguard Worker TransportSecurityState::RequireCTDelegate::CTRequirementLevel;
6233*6777b538SAndroid Build Coastguard Worker
6234*6777b538SAndroid Build Coastguard Worker TestSSLConfigService ssl_config_service;
6235*6777b538SAndroid Build Coastguard Worker SSLInfo ssl_info;
6236*6777b538SAndroid Build Coastguard Worker ssl_info.cert =
6237*6777b538SAndroid Build Coastguard Worker ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
6238*6777b538SAndroid Build Coastguard Worker ssl_info.is_issued_by_known_root = true;
6239*6777b538SAndroid Build Coastguard Worker ssl_info.public_key_hashes.push_back(test::GetTestHashValue(1));
6240*6777b538SAndroid Build Coastguard Worker ssl_info.ct_policy_compliance =
6241*6777b538SAndroid Build Coastguard Worker ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
6242*6777b538SAndroid Build Coastguard Worker
6243*6777b538SAndroid Build Coastguard Worker MockRequireCTDelegate require_ct_delegate;
6244*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("www.example.org", _, _))
6245*6777b538SAndroid Build Coastguard Worker .WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
6246*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(require_ct_delegate,
6247*6777b538SAndroid Build Coastguard Worker IsCTRequiredForHost("mail.example.org", _, _))
6248*6777b538SAndroid Build Coastguard Worker .WillRepeatedly(Return(CTRequirementLevel::REQUIRED));
6249*6777b538SAndroid Build Coastguard Worker
6250*6777b538SAndroid Build Coastguard Worker TransportSecurityState tss;
6251*6777b538SAndroid Build Coastguard Worker tss.SetRequireCTDelegate(&require_ct_delegate);
6252*6777b538SAndroid Build Coastguard Worker
6253*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6254*6777b538SAndroid Build Coastguard Worker "www.example.org", "mail.example.org"));
6255*6777b538SAndroid Build Coastguard Worker }
6256*6777b538SAndroid Build Coastguard Worker
TEST(CanPoolTest,CanPoolWithBadCTWhenCTNotRequired)6257*6777b538SAndroid Build Coastguard Worker TEST(CanPoolTest, CanPoolWithBadCTWhenCTNotRequired) {
6258*6777b538SAndroid Build Coastguard Worker using testing::Return;
6259*6777b538SAndroid Build Coastguard Worker using CTRequirementLevel =
6260*6777b538SAndroid Build Coastguard Worker TransportSecurityState::RequireCTDelegate::CTRequirementLevel;
6261*6777b538SAndroid Build Coastguard Worker
6262*6777b538SAndroid Build Coastguard Worker TestSSLConfigService ssl_config_service;
6263*6777b538SAndroid Build Coastguard Worker SSLInfo ssl_info;
6264*6777b538SAndroid Build Coastguard Worker ssl_info.cert =
6265*6777b538SAndroid Build Coastguard Worker ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
6266*6777b538SAndroid Build Coastguard Worker ssl_info.is_issued_by_known_root = true;
6267*6777b538SAndroid Build Coastguard Worker ssl_info.public_key_hashes.push_back(test::GetTestHashValue(1));
6268*6777b538SAndroid Build Coastguard Worker ssl_info.ct_policy_compliance =
6269*6777b538SAndroid Build Coastguard Worker ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
6270*6777b538SAndroid Build Coastguard Worker
6271*6777b538SAndroid Build Coastguard Worker MockRequireCTDelegate require_ct_delegate;
6272*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("www.example.org", _, _))
6273*6777b538SAndroid Build Coastguard Worker .WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
6274*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(require_ct_delegate,
6275*6777b538SAndroid Build Coastguard Worker IsCTRequiredForHost("mail.example.org", _, _))
6276*6777b538SAndroid Build Coastguard Worker .WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
6277*6777b538SAndroid Build Coastguard Worker
6278*6777b538SAndroid Build Coastguard Worker TransportSecurityState tss;
6279*6777b538SAndroid Build Coastguard Worker tss.SetRequireCTDelegate(&require_ct_delegate);
6280*6777b538SAndroid Build Coastguard Worker
6281*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6282*6777b538SAndroid Build Coastguard Worker "www.example.org", "mail.example.org"));
6283*6777b538SAndroid Build Coastguard Worker }
6284*6777b538SAndroid Build Coastguard Worker
TEST(CanPoolTest,CanPoolWithGoodCTWhenCTRequired)6285*6777b538SAndroid Build Coastguard Worker TEST(CanPoolTest, CanPoolWithGoodCTWhenCTRequired) {
6286*6777b538SAndroid Build Coastguard Worker using testing::Return;
6287*6777b538SAndroid Build Coastguard Worker using CTRequirementLevel =
6288*6777b538SAndroid Build Coastguard Worker TransportSecurityState::RequireCTDelegate::CTRequirementLevel;
6289*6777b538SAndroid Build Coastguard Worker
6290*6777b538SAndroid Build Coastguard Worker TestSSLConfigService ssl_config_service;
6291*6777b538SAndroid Build Coastguard Worker SSLInfo ssl_info;
6292*6777b538SAndroid Build Coastguard Worker ssl_info.cert =
6293*6777b538SAndroid Build Coastguard Worker ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
6294*6777b538SAndroid Build Coastguard Worker ssl_info.is_issued_by_known_root = true;
6295*6777b538SAndroid Build Coastguard Worker ssl_info.public_key_hashes.push_back(test::GetTestHashValue(1));
6296*6777b538SAndroid Build Coastguard Worker ssl_info.ct_policy_compliance =
6297*6777b538SAndroid Build Coastguard Worker ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS;
6298*6777b538SAndroid Build Coastguard Worker
6299*6777b538SAndroid Build Coastguard Worker MockRequireCTDelegate require_ct_delegate;
6300*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("www.example.org", _, _))
6301*6777b538SAndroid Build Coastguard Worker .WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
6302*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(require_ct_delegate,
6303*6777b538SAndroid Build Coastguard Worker IsCTRequiredForHost("mail.example.org", _, _))
6304*6777b538SAndroid Build Coastguard Worker .WillRepeatedly(Return(CTRequirementLevel::REQUIRED));
6305*6777b538SAndroid Build Coastguard Worker
6306*6777b538SAndroid Build Coastguard Worker TransportSecurityState tss;
6307*6777b538SAndroid Build Coastguard Worker tss.SetRequireCTDelegate(&require_ct_delegate);
6308*6777b538SAndroid Build Coastguard Worker
6309*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6310*6777b538SAndroid Build Coastguard Worker "www.example.org", "mail.example.org"));
6311*6777b538SAndroid Build Coastguard Worker }
6312*6777b538SAndroid Build Coastguard Worker
TEST(CanPoolTest,CanPoolWithAcceptablePins)6313*6777b538SAndroid Build Coastguard Worker TEST(CanPoolTest, CanPoolWithAcceptablePins) {
6314*6777b538SAndroid Build Coastguard Worker TransportSecurityState tss;
6315*6777b538SAndroid Build Coastguard Worker tss.EnableStaticPinsForTesting();
6316*6777b538SAndroid Build Coastguard Worker tss.SetPinningListAlwaysTimelyForTesting(true);
6317*6777b538SAndroid Build Coastguard Worker ScopedTransportSecurityStateSource scoped_security_state_source;
6318*6777b538SAndroid Build Coastguard Worker
6319*6777b538SAndroid Build Coastguard Worker TestSSLConfigService ssl_config_service;
6320*6777b538SAndroid Build Coastguard Worker SSLInfo ssl_info;
6321*6777b538SAndroid Build Coastguard Worker ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
6322*6777b538SAndroid Build Coastguard Worker "spdy_pooling.pem");
6323*6777b538SAndroid Build Coastguard Worker ssl_info.is_issued_by_known_root = true;
6324*6777b538SAndroid Build Coastguard Worker HashValue hash;
6325*6777b538SAndroid Build Coastguard Worker // The expected value of GoodPin1 used by |scoped_security_state_source|.
6326*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(
6327*6777b538SAndroid Build Coastguard Worker hash.FromString("sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
6328*6777b538SAndroid Build Coastguard Worker ssl_info.public_key_hashes.push_back(hash);
6329*6777b538SAndroid Build Coastguard Worker
6330*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6331*6777b538SAndroid Build Coastguard Worker "www.example.org", "mail.example.org"));
6332*6777b538SAndroid Build Coastguard Worker }
6333*6777b538SAndroid Build Coastguard Worker
TEST(CanPoolTest,CanPoolWithClientCertsAndPolicy)6334*6777b538SAndroid Build Coastguard Worker TEST(CanPoolTest, CanPoolWithClientCertsAndPolicy) {
6335*6777b538SAndroid Build Coastguard Worker TransportSecurityState tss;
6336*6777b538SAndroid Build Coastguard Worker SSLInfo ssl_info;
6337*6777b538SAndroid Build Coastguard Worker ssl_info.cert =
6338*6777b538SAndroid Build Coastguard Worker ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
6339*6777b538SAndroid Build Coastguard Worker ssl_info.client_cert_sent = true;
6340*6777b538SAndroid Build Coastguard Worker
6341*6777b538SAndroid Build Coastguard Worker // Configure ssl_config_service so that CanShareConnectionWithClientCerts
6342*6777b538SAndroid Build Coastguard Worker // returns true for www.example.org and mail.example.org.
6343*6777b538SAndroid Build Coastguard Worker TestSSLConfigService ssl_config_service;
6344*6777b538SAndroid Build Coastguard Worker ssl_config_service.SetDomainsForPooling(
6345*6777b538SAndroid Build Coastguard Worker {"www.example.org", "mail.example.org"});
6346*6777b538SAndroid Build Coastguard Worker
6347*6777b538SAndroid Build Coastguard Worker // Test that CanPool returns true when client certs are enabled and
6348*6777b538SAndroid Build Coastguard Worker // CanShareConnectionWithClientCerts returns true for both hostnames, but not
6349*6777b538SAndroid Build Coastguard Worker // just one hostname.
6350*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6351*6777b538SAndroid Build Coastguard Worker "www.example.org", "mail.example.org"));
6352*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6353*6777b538SAndroid Build Coastguard Worker "www.example.org", "mail.example.com"));
6354*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
6355*6777b538SAndroid Build Coastguard Worker "mail.example.com", "www.example.org"));
6356*6777b538SAndroid Build Coastguard Worker }
6357*6777b538SAndroid Build Coastguard Worker
6358*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/1115492.
TEST_F(SpdySessionTest,UpdateHeaderTableSize)6359*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, UpdateHeaderTableSize) {
6360*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings;
6361*6777b538SAndroid Build Coastguard Worker settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = 12345;
6362*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_frame(
6363*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(settings));
6364*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {CreateMockRead(settings_frame, 0),
6365*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
6366*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3)};
6367*6777b538SAndroid Build Coastguard Worker
6368*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
6369*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(settings_ack, 1)};
6370*6777b538SAndroid Build Coastguard Worker
6371*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
6372*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
6373*6777b538SAndroid Build Coastguard Worker
6374*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
6375*6777b538SAndroid Build Coastguard Worker
6376*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
6377*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
6378*6777b538SAndroid Build Coastguard Worker
6379*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(spdy::kDefaultHeaderTableSizeSetting, header_encoder_table_size());
6380*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6381*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(12345u, header_encoder_table_size());
6382*6777b538SAndroid Build Coastguard Worker
6383*6777b538SAndroid Build Coastguard Worker data.Resume();
6384*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6385*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
6386*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
6387*6777b538SAndroid Build Coastguard Worker }
6388*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,PriorityUpdateDisabled)6389*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, PriorityUpdateDisabled) {
6390*6777b538SAndroid Build Coastguard Worker session_deps_.enable_priority_update = false;
6391*6777b538SAndroid Build Coastguard Worker
6392*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings;
6393*6777b538SAndroid Build Coastguard Worker settings[spdy::SETTINGS_DEPRECATE_HTTP2_PRIORITIES] = 1;
6394*6777b538SAndroid Build Coastguard Worker auto settings_frame = spdy_util_.ConstructSpdySettings(settings);
6395*6777b538SAndroid Build Coastguard Worker auto settings_ack = spdy_util_.ConstructSpdySettingsAck();
6396*6777b538SAndroid Build Coastguard Worker
6397*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {CreateMockRead(settings_frame, 0),
6398*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
6399*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3)};
6400*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(settings_ack, 1)};
6401*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
6402*6777b538SAndroid Build Coastguard Worker
6403*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
6404*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
6405*6777b538SAndroid Build Coastguard Worker
6406*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
6407*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
6408*6777b538SAndroid Build Coastguard Worker
6409*6777b538SAndroid Build Coastguard Worker // HTTP/2 priorities enabled by default.
6410*6777b538SAndroid Build Coastguard Worker // PRIORITY_UPDATE is disabled by |enable_priority_update| = false.
6411*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->ShouldSendHttp2Priority());
6412*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->ShouldSendPriorityUpdate());
6413*6777b538SAndroid Build Coastguard Worker
6414*6777b538SAndroid Build Coastguard Worker // Receive SETTINGS frame.
6415*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6416*6777b538SAndroid Build Coastguard Worker
6417*6777b538SAndroid Build Coastguard Worker // Since |enable_priority_update| = false,
6418*6777b538SAndroid Build Coastguard Worker // SETTINGS_DEPRECATE_HTTP2_PRIORITIES has no effect.
6419*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->ShouldSendHttp2Priority());
6420*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->ShouldSendPriorityUpdate());
6421*6777b538SAndroid Build Coastguard Worker
6422*6777b538SAndroid Build Coastguard Worker data.Resume();
6423*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6424*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
6425*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
6426*6777b538SAndroid Build Coastguard Worker }
6427*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,PriorityUpdateEnabledHttp2PrioritiesDeprecated)6428*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, PriorityUpdateEnabledHttp2PrioritiesDeprecated) {
6429*6777b538SAndroid Build Coastguard Worker session_deps_.enable_priority_update = true;
6430*6777b538SAndroid Build Coastguard Worker
6431*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings;
6432*6777b538SAndroid Build Coastguard Worker settings[spdy::SETTINGS_DEPRECATE_HTTP2_PRIORITIES] = 1;
6433*6777b538SAndroid Build Coastguard Worker auto settings_frame = spdy_util_.ConstructSpdySettings(settings);
6434*6777b538SAndroid Build Coastguard Worker auto settings_ack = spdy_util_.ConstructSpdySettingsAck();
6435*6777b538SAndroid Build Coastguard Worker
6436*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {CreateMockRead(settings_frame, 0),
6437*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
6438*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3)};
6439*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(settings_ack, 1)};
6440*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
6441*6777b538SAndroid Build Coastguard Worker
6442*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
6443*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
6444*6777b538SAndroid Build Coastguard Worker
6445*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
6446*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
6447*6777b538SAndroid Build Coastguard Worker
6448*6777b538SAndroid Build Coastguard Worker // Both priority schemes are enabled until SETTINGS frame is received.
6449*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->ShouldSendHttp2Priority());
6450*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->ShouldSendPriorityUpdate());
6451*6777b538SAndroid Build Coastguard Worker
6452*6777b538SAndroid Build Coastguard Worker // Receive SETTINGS frame.
6453*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6454*6777b538SAndroid Build Coastguard Worker
6455*6777b538SAndroid Build Coastguard Worker // SETTINGS_DEPRECATE_HTTP2_PRIORITIES = 1 disables HTTP/2 priorities.
6456*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->ShouldSendHttp2Priority());
6457*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->ShouldSendPriorityUpdate());
6458*6777b538SAndroid Build Coastguard Worker
6459*6777b538SAndroid Build Coastguard Worker data.Resume();
6460*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6461*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
6462*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
6463*6777b538SAndroid Build Coastguard Worker }
6464*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,PriorityUpdateEnabledHttp2PrioritiesNotDeprecated)6465*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, PriorityUpdateEnabledHttp2PrioritiesNotDeprecated) {
6466*6777b538SAndroid Build Coastguard Worker session_deps_.enable_priority_update = true;
6467*6777b538SAndroid Build Coastguard Worker
6468*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings;
6469*6777b538SAndroid Build Coastguard Worker settings[spdy::SETTINGS_DEPRECATE_HTTP2_PRIORITIES] = 0;
6470*6777b538SAndroid Build Coastguard Worker auto settings_frame = spdy_util_.ConstructSpdySettings(settings);
6471*6777b538SAndroid Build Coastguard Worker auto settings_ack = spdy_util_.ConstructSpdySettingsAck();
6472*6777b538SAndroid Build Coastguard Worker
6473*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {CreateMockRead(settings_frame, 0),
6474*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, ERR_IO_PENDING, 2),
6475*6777b538SAndroid Build Coastguard Worker MockRead(ASYNC, 0, 3)};
6476*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {CreateMockWrite(settings_ack, 1)};
6477*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
6478*6777b538SAndroid Build Coastguard Worker
6479*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
6480*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
6481*6777b538SAndroid Build Coastguard Worker
6482*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
6483*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
6484*6777b538SAndroid Build Coastguard Worker
6485*6777b538SAndroid Build Coastguard Worker // Both priority schemes are enabled until SETTINGS frame is received.
6486*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->ShouldSendHttp2Priority());
6487*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->ShouldSendPriorityUpdate());
6488*6777b538SAndroid Build Coastguard Worker
6489*6777b538SAndroid Build Coastguard Worker // Receive SETTINGS frame.
6490*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6491*6777b538SAndroid Build Coastguard Worker
6492*6777b538SAndroid Build Coastguard Worker // SETTINGS_DEPRECATE_HTTP2_PRIORITIES = 0 disables PRIORITY_UPDATE.
6493*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->ShouldSendHttp2Priority());
6494*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(session_->ShouldSendPriorityUpdate());
6495*6777b538SAndroid Build Coastguard Worker
6496*6777b538SAndroid Build Coastguard Worker data.Resume();
6497*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6498*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
6499*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
6500*6777b538SAndroid Build Coastguard Worker }
6501*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,SettingsDeprecateHttp2PrioritiesValueMustNotChange)6502*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, SettingsDeprecateHttp2PrioritiesValueMustNotChange) {
6503*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings0;
6504*6777b538SAndroid Build Coastguard Worker settings0[spdy::SETTINGS_DEPRECATE_HTTP2_PRIORITIES] = 0;
6505*6777b538SAndroid Build Coastguard Worker auto settings_frame0 = spdy_util_.ConstructSpdySettings(settings0);
6506*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings1;
6507*6777b538SAndroid Build Coastguard Worker settings1[spdy::SETTINGS_DEPRECATE_HTTP2_PRIORITIES] = 1;
6508*6777b538SAndroid Build Coastguard Worker auto settings_frame1 = spdy_util_.ConstructSpdySettings(settings1);
6509*6777b538SAndroid Build Coastguard Worker MockRead reads[] = {
6510*6777b538SAndroid Build Coastguard Worker CreateMockRead(settings_frame1, 0), MockRead(ASYNC, ERR_IO_PENDING, 2),
6511*6777b538SAndroid Build Coastguard Worker CreateMockRead(settings_frame1, 3), MockRead(ASYNC, ERR_IO_PENDING, 5),
6512*6777b538SAndroid Build Coastguard Worker CreateMockRead(settings_frame0, 6)};
6513*6777b538SAndroid Build Coastguard Worker
6514*6777b538SAndroid Build Coastguard Worker auto settings_ack = spdy_util_.ConstructSpdySettingsAck();
6515*6777b538SAndroid Build Coastguard Worker auto goaway = spdy_util_.ConstructSpdyGoAway(
6516*6777b538SAndroid Build Coastguard Worker 0, spdy::ERROR_CODE_PROTOCOL_ERROR,
6517*6777b538SAndroid Build Coastguard Worker "spdy::SETTINGS_DEPRECATE_HTTP2_PRIORITIES value changed after first "
6518*6777b538SAndroid Build Coastguard Worker "SETTINGS frame.");
6519*6777b538SAndroid Build Coastguard Worker MockWrite writes[] = {
6520*6777b538SAndroid Build Coastguard Worker CreateMockWrite(settings_ack, 1), CreateMockWrite(settings_ack, 4),
6521*6777b538SAndroid Build Coastguard Worker CreateMockWrite(settings_ack, 7), CreateMockWrite(goaway, 8)};
6522*6777b538SAndroid Build Coastguard Worker
6523*6777b538SAndroid Build Coastguard Worker SequencedSocketData data(reads, writes);
6524*6777b538SAndroid Build Coastguard Worker
6525*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
6526*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
6527*6777b538SAndroid Build Coastguard Worker
6528*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
6529*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
6530*6777b538SAndroid Build Coastguard Worker
6531*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6532*6777b538SAndroid Build Coastguard Worker data.Resume();
6533*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6534*6777b538SAndroid Build Coastguard Worker data.Resume();
6535*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
6536*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllWriteDataConsumed());
6537*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(data.AllReadDataConsumed());
6538*6777b538SAndroid Build Coastguard Worker }
6539*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,AlpsEmpty)6540*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, AlpsEmpty) {
6541*6777b538SAndroid Build Coastguard Worker base::HistogramTester histogram_tester;
6542*6777b538SAndroid Build Coastguard Worker
6543*6777b538SAndroid Build Coastguard Worker ssl_.peer_application_settings = "";
6544*6777b538SAndroid Build Coastguard Worker
6545*6777b538SAndroid Build Coastguard Worker SequencedSocketData data;
6546*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
6547*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
6548*6777b538SAndroid Build Coastguard Worker
6549*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
6550*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
6551*6777b538SAndroid Build Coastguard Worker
6552*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectUniqueSample(
6553*6777b538SAndroid Build Coastguard Worker "Net.SpdySession.AlpsDecoderStatus",
6554*6777b538SAndroid Build Coastguard Worker static_cast<int>(AlpsDecoder::Error::kNoError), 1);
6555*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectUniqueSample(
6556*6777b538SAndroid Build Coastguard Worker "Net.SpdySession.AlpsSettingParameterCount", 0, 1);
6557*6777b538SAndroid Build Coastguard Worker const int kNoEntries = 0;
6558*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectUniqueSample("Net.SpdySession.AlpsAcceptChEntries",
6559*6777b538SAndroid Build Coastguard Worker kNoEntries, 1);
6560*6777b538SAndroid Build Coastguard Worker
6561*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectTotalCount("Net.SpdySession.AcceptChForOrigin", 0);
6562*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("", session_->GetAcceptChViaAlps(
6563*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(GURL("https://www.example.org"))));
6564*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectUniqueSample("Net.SpdySession.AcceptChForOrigin",
6565*6777b538SAndroid Build Coastguard Worker false, 1);
6566*6777b538SAndroid Build Coastguard Worker }
6567*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,AlpsSettings)6568*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, AlpsSettings) {
6569*6777b538SAndroid Build Coastguard Worker base::HistogramTester histogram_tester;
6570*6777b538SAndroid Build Coastguard Worker
6571*6777b538SAndroid Build Coastguard Worker spdy::SettingsMap settings;
6572*6777b538SAndroid Build Coastguard Worker settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = 12345;
6573*6777b538SAndroid Build Coastguard Worker spdy::SpdySerializedFrame settings_frame(
6574*6777b538SAndroid Build Coastguard Worker spdy_util_.ConstructSpdySettings(settings));
6575*6777b538SAndroid Build Coastguard Worker ssl_.peer_application_settings =
6576*6777b538SAndroid Build Coastguard Worker std::string(settings_frame.data(), settings_frame.size());
6577*6777b538SAndroid Build Coastguard Worker
6578*6777b538SAndroid Build Coastguard Worker SequencedSocketData data;
6579*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
6580*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
6581*6777b538SAndroid Build Coastguard Worker
6582*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
6583*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
6584*6777b538SAndroid Build Coastguard Worker
6585*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(12345u, header_encoder_table_size());
6586*6777b538SAndroid Build Coastguard Worker
6587*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectUniqueSample(
6588*6777b538SAndroid Build Coastguard Worker "Net.SpdySession.AlpsDecoderStatus",
6589*6777b538SAndroid Build Coastguard Worker static_cast<int>(AlpsDecoder::Error::kNoError), 1);
6590*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectUniqueSample(
6591*6777b538SAndroid Build Coastguard Worker "Net.SpdySession.AlpsSettingParameterCount", 1, 1);
6592*6777b538SAndroid Build Coastguard Worker }
6593*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,AlpsAcceptCh)6594*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, AlpsAcceptCh) {
6595*6777b538SAndroid Build Coastguard Worker base::HistogramTester histogram_tester;
6596*6777b538SAndroid Build Coastguard Worker
6597*6777b538SAndroid Build Coastguard Worker ssl_.peer_application_settings = HexDecode(
6598*6777b538SAndroid Build Coastguard Worker "00001e" // length
6599*6777b538SAndroid Build Coastguard Worker "89" // type ACCEPT_CH
6600*6777b538SAndroid Build Coastguard Worker "00" // flags
6601*6777b538SAndroid Build Coastguard Worker "00000000" // stream ID
6602*6777b538SAndroid Build Coastguard Worker "0017" // origin length
6603*6777b538SAndroid Build Coastguard Worker "68747470733a2f2f7777772e" //
6604*6777b538SAndroid Build Coastguard Worker "6578616d706c652e636f6d" // origin "https://www.example.com"
6605*6777b538SAndroid Build Coastguard Worker "0003" // value length
6606*6777b538SAndroid Build Coastguard Worker "666f6f"); // value "foo"
6607*6777b538SAndroid Build Coastguard Worker
6608*6777b538SAndroid Build Coastguard Worker SequencedSocketData data;
6609*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
6610*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
6611*6777b538SAndroid Build Coastguard Worker
6612*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
6613*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
6614*6777b538SAndroid Build Coastguard Worker
6615*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectUniqueSample(
6616*6777b538SAndroid Build Coastguard Worker "Net.SpdySession.AlpsDecoderStatus",
6617*6777b538SAndroid Build Coastguard Worker static_cast<int>(AlpsDecoder::Error::kNoError), 1);
6618*6777b538SAndroid Build Coastguard Worker const int kOnlyValidEntries = 1;
6619*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectUniqueSample("Net.SpdySession.AlpsAcceptChEntries",
6620*6777b538SAndroid Build Coastguard Worker kOnlyValidEntries, 1);
6621*6777b538SAndroid Build Coastguard Worker
6622*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectTotalCount("Net.SpdySession.AcceptChForOrigin", 0);
6623*6777b538SAndroid Build Coastguard Worker
6624*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("foo", session_->GetAcceptChViaAlps(
6625*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(GURL("https://www.example.com"))));
6626*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectUniqueSample("Net.SpdySession.AcceptChForOrigin", true,
6627*6777b538SAndroid Build Coastguard Worker 1);
6628*6777b538SAndroid Build Coastguard Worker
6629*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("", session_->GetAcceptChViaAlps(
6630*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort(GURL("https://www.example.org"))));
6631*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectTotalCount("Net.SpdySession.AcceptChForOrigin", 2);
6632*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectBucketCount("Net.SpdySession.AcceptChForOrigin", true,
6633*6777b538SAndroid Build Coastguard Worker 1);
6634*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectBucketCount("Net.SpdySession.AcceptChForOrigin", false,
6635*6777b538SAndroid Build Coastguard Worker 1);
6636*6777b538SAndroid Build Coastguard Worker }
6637*6777b538SAndroid Build Coastguard Worker
TEST_F(SpdySessionTest,AlpsAcceptChInvalidOrigin)6638*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, AlpsAcceptChInvalidOrigin) {
6639*6777b538SAndroid Build Coastguard Worker base::HistogramTester histogram_tester;
6640*6777b538SAndroid Build Coastguard Worker
6641*6777b538SAndroid Build Coastguard Worker // "www.example.com" is not a valid origin, because it does not have a scheme.
6642*6777b538SAndroid Build Coastguard Worker ssl_.peer_application_settings = HexDecode(
6643*6777b538SAndroid Build Coastguard Worker "000017" // length
6644*6777b538SAndroid Build Coastguard Worker "89" // type ACCEPT_CH
6645*6777b538SAndroid Build Coastguard Worker "00" // flags
6646*6777b538SAndroid Build Coastguard Worker "00000000" // stream ID
6647*6777b538SAndroid Build Coastguard Worker "0010" // origin length
6648*6777b538SAndroid Build Coastguard Worker "2f7777772e6578616d706c652e636f6d" // origin "www.example.com"
6649*6777b538SAndroid Build Coastguard Worker "0003" // value length
6650*6777b538SAndroid Build Coastguard Worker "666f6f"); // value "foo"
6651*6777b538SAndroid Build Coastguard Worker
6652*6777b538SAndroid Build Coastguard Worker SequencedSocketData data;
6653*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
6654*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
6655*6777b538SAndroid Build Coastguard Worker
6656*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
6657*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
6658*6777b538SAndroid Build Coastguard Worker
6659*6777b538SAndroid Build Coastguard Worker // Invalid origin error is not considered fatal for the connection.
6660*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(session_->IsAvailable());
6661*6777b538SAndroid Build Coastguard Worker
6662*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectUniqueSample(
6663*6777b538SAndroid Build Coastguard Worker "Net.SpdySession.AlpsDecoderStatus",
6664*6777b538SAndroid Build Coastguard Worker static_cast<int>(AlpsDecoder::Error::kNoError), 1);
6665*6777b538SAndroid Build Coastguard Worker const int kOnlyInvalidEntries = 2;
6666*6777b538SAndroid Build Coastguard Worker histogram_tester.ExpectUniqueSample("Net.SpdySession.AlpsAcceptChEntries",
6667*6777b538SAndroid Build Coastguard Worker kOnlyInvalidEntries, 1);
6668*6777b538SAndroid Build Coastguard Worker }
6669*6777b538SAndroid Build Coastguard Worker
6670*6777b538SAndroid Build Coastguard Worker // Test that ConfirmHandshake() correctly handles the client aborting the
6671*6777b538SAndroid Build Coastguard Worker // connection. See https://crbug.com/1211639.
TEST_F(SpdySessionTest,ConfirmHandshakeAfterClose)6672*6777b538SAndroid Build Coastguard Worker TEST_F(SpdySessionTest, ConfirmHandshakeAfterClose) {
6673*6777b538SAndroid Build Coastguard Worker base::HistogramTester histogram_tester;
6674*6777b538SAndroid Build Coastguard Worker
6675*6777b538SAndroid Build Coastguard Worker session_deps_.enable_early_data = true;
6676*6777b538SAndroid Build Coastguard Worker // Arrange for StreamSocket::ConfirmHandshake() to hang.
6677*6777b538SAndroid Build Coastguard Worker ssl_.confirm = MockConfirm(SYNCHRONOUS, ERR_IO_PENDING);
6678*6777b538SAndroid Build Coastguard Worker SequencedSocketData data;
6679*6777b538SAndroid Build Coastguard Worker session_deps_.socket_factory->AddSocketDataProvider(&data);
6680*6777b538SAndroid Build Coastguard Worker AddSSLSocketData();
6681*6777b538SAndroid Build Coastguard Worker
6682*6777b538SAndroid Build Coastguard Worker CreateNetworkSession();
6683*6777b538SAndroid Build Coastguard Worker CreateSpdySession();
6684*6777b538SAndroid Build Coastguard Worker
6685*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback1;
6686*6777b538SAndroid Build Coastguard Worker int rv1 = session_->ConfirmHandshake(callback1.callback());
6687*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(rv1, IsError(ERR_IO_PENDING));
6688*6777b538SAndroid Build Coastguard Worker
6689*6777b538SAndroid Build Coastguard Worker // Abort the session. Although the underlying StreamSocket::ConfirmHandshake()
6690*6777b538SAndroid Build Coastguard Worker // operation never completes, SpdySession::ConfirmHandshake() is signaled when
6691*6777b538SAndroid Build Coastguard Worker // the session is discarded.
6692*6777b538SAndroid Build Coastguard Worker session_->CloseSessionOnError(ERR_ABORTED, "Aborting session");
6693*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(callback1.GetResult(rv1), IsError(ERR_ABORTED));
6694*6777b538SAndroid Build Coastguard Worker
6695*6777b538SAndroid Build Coastguard Worker // Subsequent calls to SpdySession::ConfirmHandshake() fail gracefully. This
6696*6777b538SAndroid Build Coastguard Worker // tests that SpdySession honors StreamSocket::ConfirmHandshake() invariants.
6697*6777b538SAndroid Build Coastguard Worker // (MockSSLClientSocket::ConfirmHandshake() checks it internally.)
6698*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback2;
6699*6777b538SAndroid Build Coastguard Worker int rv2 = session_->ConfirmHandshake(callback2.callback());
6700*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(rv2, IsError(ERR_CONNECTION_CLOSED));
6701*6777b538SAndroid Build Coastguard Worker }
6702*6777b538SAndroid Build Coastguard Worker
6703*6777b538SAndroid Build Coastguard Worker } // namespace net
6704