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