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