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