Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(392)

Side by Side Diff: net/spdy/spdy_session_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698