xref: /aosp_15_r20/external/cronet/net/spdy/spdy_stream_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_stream.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <algorithm>
10*6777b538SAndroid Build Coastguard Worker #include <cstddef>
11*6777b538SAndroid Build Coastguard Worker #include <limits>
12*6777b538SAndroid Build Coastguard Worker #include <memory>
13*6777b538SAndroid Build Coastguard Worker #include <string>
14*6777b538SAndroid Build Coastguard Worker #include <string_view>
15*6777b538SAndroid Build Coastguard Worker #include <utility>
16*6777b538SAndroid Build Coastguard Worker #include <vector>
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
22*6777b538SAndroid Build Coastguard Worker #include "net/base/request_priority.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/base/session_usage.h"
24*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/secure_dns_policy.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/http/http_request_info.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_event_type.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log.h"
28*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log_util.h"
29*6777b538SAndroid Build Coastguard Worker #include "net/socket/socket_tag.h"
30*6777b538SAndroid Build Coastguard Worker #include "net/socket/socket_test_util.h"
31*6777b538SAndroid Build Coastguard Worker #include "net/spdy/buffered_spdy_framer.h"
32*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_http_utils.h"
33*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_session.h"
34*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_session_pool.h"
35*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_stream_test_util.h"
36*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_test_util_common.h"
37*6777b538SAndroid Build Coastguard Worker #include "net/test/cert_test_util.h"
38*6777b538SAndroid Build Coastguard Worker #include "net/test/gtest_util.h"
39*6777b538SAndroid Build Coastguard Worker #include "net/test/test_data_directory.h"
40*6777b538SAndroid Build Coastguard Worker #include "net/test/test_with_task_environment.h"
41*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
42*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
43*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker // TODO(ukai): factor out common part with spdy_http_stream_unittest.cc
46*6777b538SAndroid Build Coastguard Worker //
47*6777b538SAndroid Build Coastguard Worker namespace net::test {
48*6777b538SAndroid Build Coastguard Worker 
49*6777b538SAndroid Build Coastguard Worker namespace {
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker const char kPostBody[] = "\0hello!\xff";
52*6777b538SAndroid Build Coastguard Worker const size_t kPostBodyLength = std::size(kPostBody);
53*6777b538SAndroid Build Coastguard Worker const std::string_view kPostBodyStringPiece(kPostBody, kPostBodyLength);
54*6777b538SAndroid Build Coastguard Worker 
55*6777b538SAndroid Build Coastguard Worker // Creates a MockRead from the given serialized frame except for the last byte.
ReadFrameExceptForLastByte(const spdy::SpdySerializedFrame & frame)56*6777b538SAndroid Build Coastguard Worker MockRead ReadFrameExceptForLastByte(const spdy::SpdySerializedFrame& frame) {
57*6777b538SAndroid Build Coastguard Worker   CHECK_GE(frame.size(), 2u);
58*6777b538SAndroid Build Coastguard Worker   return MockRead(ASYNC, frame.data(), frame.size() - 1);
59*6777b538SAndroid Build Coastguard Worker }
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker // Creates a MockRead from the last byte of the given serialized frame.
LastByteOfReadFrame(const spdy::SpdySerializedFrame & frame)62*6777b538SAndroid Build Coastguard Worker MockRead LastByteOfReadFrame(const spdy::SpdySerializedFrame& frame) {
63*6777b538SAndroid Build Coastguard Worker   CHECK_GE(frame.size(), 2u);
64*6777b538SAndroid Build Coastguard Worker   return MockRead(ASYNC, frame.data() + frame.size() - 1, 1);
65*6777b538SAndroid Build Coastguard Worker }
66*6777b538SAndroid Build Coastguard Worker 
67*6777b538SAndroid Build Coastguard Worker }  // namespace
68*6777b538SAndroid Build Coastguard Worker 
69*6777b538SAndroid Build Coastguard Worker class SpdyStreamTest : public ::testing::Test, public WithTaskEnvironment {
70*6777b538SAndroid Build Coastguard Worker  protected:
71*6777b538SAndroid Build Coastguard Worker   // A function that takes a SpdyStream and the number of bytes which
72*6777b538SAndroid Build Coastguard Worker   // will unstall the next frame completely.
73*6777b538SAndroid Build Coastguard Worker   typedef base::OnceCallback<void(const base::WeakPtr<SpdyStream>&, int32_t)>
74*6777b538SAndroid Build Coastguard Worker       UnstallFunction;
75*6777b538SAndroid Build Coastguard Worker 
SpdyStreamTest(base::test::TaskEnvironment::TimeSource time_source=base::test::TaskEnvironment::TimeSource::DEFAULT)76*6777b538SAndroid Build Coastguard Worker   explicit SpdyStreamTest(base::test::TaskEnvironment::TimeSource time_source =
77*6777b538SAndroid Build Coastguard Worker                               base::test::TaskEnvironment::TimeSource::DEFAULT)
78*6777b538SAndroid Build Coastguard Worker       : WithTaskEnvironment(time_source),
79*6777b538SAndroid Build Coastguard Worker         url_(kDefaultUrl),
80*6777b538SAndroid Build Coastguard Worker         session_(SpdySessionDependencies::SpdyCreateSession(&session_deps_)),
81*6777b538SAndroid Build Coastguard Worker         ssl_(SYNCHRONOUS, OK) {}
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker   ~SpdyStreamTest() override = default;
84*6777b538SAndroid Build Coastguard Worker 
CreateDefaultSpdySession()85*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> CreateDefaultSpdySession() {
86*6777b538SAndroid Build Coastguard Worker     SpdySessionKey key(HostPortPair::FromURL(url_), PRIVACY_MODE_DISABLED,
87*6777b538SAndroid Build Coastguard Worker                        ProxyChain::Direct(), SessionUsage::kDestination,
88*6777b538SAndroid Build Coastguard Worker                        SocketTag(), NetworkAnonymizationKey(),
89*6777b538SAndroid Build Coastguard Worker                        SecureDnsPolicy::kAllow,
90*6777b538SAndroid Build Coastguard Worker                        /*disable_cert_verification_network_fetches=*/false);
91*6777b538SAndroid Build Coastguard Worker     return CreateSpdySession(session_.get(), key, NetLogWithSource());
92*6777b538SAndroid Build Coastguard Worker   }
93*6777b538SAndroid Build Coastguard Worker 
TearDown()94*6777b538SAndroid Build Coastguard Worker   void TearDown() override { base::RunLoop().RunUntilIdle(); }
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker   void RunResumeAfterUnstallRequestResponseTest(
97*6777b538SAndroid Build Coastguard Worker       UnstallFunction unstall_function);
98*6777b538SAndroid Build Coastguard Worker 
99*6777b538SAndroid Build Coastguard Worker   void RunResumeAfterUnstallBidirectionalTest(UnstallFunction unstall_function);
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker   // Add{Read,Write}() populates lists that are eventually passed to a
102*6777b538SAndroid Build Coastguard Worker   // SocketData class. |frame| must live for the whole test.
103*6777b538SAndroid Build Coastguard Worker 
AddRead(const spdy::SpdySerializedFrame & frame)104*6777b538SAndroid Build Coastguard Worker   void AddRead(const spdy::SpdySerializedFrame& frame) {
105*6777b538SAndroid Build Coastguard Worker     reads_.push_back(CreateMockRead(frame, offset_++));
106*6777b538SAndroid Build Coastguard Worker   }
107*6777b538SAndroid Build Coastguard Worker 
AddWrite(const spdy::SpdySerializedFrame & frame)108*6777b538SAndroid Build Coastguard Worker   void AddWrite(const spdy::SpdySerializedFrame& frame) {
109*6777b538SAndroid Build Coastguard Worker     writes_.push_back(CreateMockWrite(frame, offset_++));
110*6777b538SAndroid Build Coastguard Worker   }
111*6777b538SAndroid Build Coastguard Worker 
AddMockRead(MockRead read)112*6777b538SAndroid Build Coastguard Worker   void AddMockRead(MockRead read) {
113*6777b538SAndroid Build Coastguard Worker     read.sequence_number = offset_++;
114*6777b538SAndroid Build Coastguard Worker     reads_.push_back(std::move(read));
115*6777b538SAndroid Build Coastguard Worker   }
116*6777b538SAndroid Build Coastguard Worker 
AddReadEOF()117*6777b538SAndroid Build Coastguard Worker   void AddReadEOF() { reads_.emplace_back(ASYNC, 0, offset_++); }
118*6777b538SAndroid Build Coastguard Worker 
AddWritePause()119*6777b538SAndroid Build Coastguard Worker   void AddWritePause() {
120*6777b538SAndroid Build Coastguard Worker     writes_.emplace_back(ASYNC, ERR_IO_PENDING, offset_++);
121*6777b538SAndroid Build Coastguard Worker   }
122*6777b538SAndroid Build Coastguard Worker 
AddReadPause()123*6777b538SAndroid Build Coastguard Worker   void AddReadPause() { reads_.emplace_back(ASYNC, ERR_IO_PENDING, offset_++); }
124*6777b538SAndroid Build Coastguard Worker 
GetReads()125*6777b538SAndroid Build Coastguard Worker   base::span<const MockRead> GetReads() { return reads_; }
GetWrites()126*6777b538SAndroid Build Coastguard Worker   base::span<const MockWrite> GetWrites() { return writes_; }
127*6777b538SAndroid Build Coastguard Worker 
ActivatePushStream(SpdySession * session,SpdyStream * stream)128*6777b538SAndroid Build Coastguard Worker   void ActivatePushStream(SpdySession* session, SpdyStream* stream) {
129*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<SpdyStream> activated =
130*6777b538SAndroid Build Coastguard Worker         session->ActivateCreatedStream(stream);
131*6777b538SAndroid Build Coastguard Worker     activated->set_stream_id(2);
132*6777b538SAndroid Build Coastguard Worker     session->InsertActivatedStream(std::move(activated));
133*6777b538SAndroid Build Coastguard Worker   }
134*6777b538SAndroid Build Coastguard Worker 
AddSSLSocketData()135*6777b538SAndroid Build Coastguard Worker   void AddSSLSocketData() {
136*6777b538SAndroid Build Coastguard Worker     // Load a cert that is valid for
137*6777b538SAndroid Build Coastguard Worker     // www.example.org, mail.example.org, and mail.example.com.
138*6777b538SAndroid Build Coastguard Worker     ssl_.ssl_info.cert =
139*6777b538SAndroid Build Coastguard Worker         ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
140*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(ssl_.ssl_info.cert);
141*6777b538SAndroid Build Coastguard Worker     session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
142*6777b538SAndroid Build Coastguard Worker   }
143*6777b538SAndroid Build Coastguard Worker 
unacked_recv_window_bytes(base::WeakPtr<SpdyStream> stream)144*6777b538SAndroid Build Coastguard Worker   int32_t unacked_recv_window_bytes(base::WeakPtr<SpdyStream> stream) {
145*6777b538SAndroid Build Coastguard Worker     return stream->unacked_recv_window_bytes_;
146*6777b538SAndroid Build Coastguard Worker   }
147*6777b538SAndroid Build Coastguard Worker 
spdy_session_pool(base::WeakPtr<SpdySession> session)148*6777b538SAndroid Build Coastguard Worker   static SpdySessionPool* spdy_session_pool(
149*6777b538SAndroid Build Coastguard Worker       base::WeakPtr<SpdySession> session) {
150*6777b538SAndroid Build Coastguard Worker     return session->pool_;
151*6777b538SAndroid Build Coastguard Worker   }
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker   const GURL url_;
154*6777b538SAndroid Build Coastguard Worker   SpdyTestUtil spdy_util_;
155*6777b538SAndroid Build Coastguard Worker   SpdySessionDependencies session_deps_;
156*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpNetworkSession> session_;
157*6777b538SAndroid Build Coastguard Worker 
158*6777b538SAndroid Build Coastguard Worker  private:
159*6777b538SAndroid Build Coastguard Worker   // Used by Add{Read,Write}() above.
160*6777b538SAndroid Build Coastguard Worker   std::vector<MockWrite> writes_;
161*6777b538SAndroid Build Coastguard Worker   std::vector<MockRead> reads_;
162*6777b538SAndroid Build Coastguard Worker   int offset_ = 0;
163*6777b538SAndroid Build Coastguard Worker   SSLSocketDataProvider ssl_;
164*6777b538SAndroid Build Coastguard Worker };
165*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,SendDataAfterOpen)166*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, SendDataAfterOpen) {
167*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
168*6777b538SAndroid Build Coastguard Worker       kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
169*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
170*6777b538SAndroid Build Coastguard Worker 
171*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
172*6777b538SAndroid Build Coastguard Worker   AddRead(resp);
173*6777b538SAndroid Build Coastguard Worker 
174*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame msg(
175*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
176*6777b538SAndroid Build Coastguard Worker   AddWrite(msg);
177*6777b538SAndroid Build Coastguard Worker 
178*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame echo(
179*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
180*6777b538SAndroid Build Coastguard Worker   AddRead(echo);
181*6777b538SAndroid Build Coastguard Worker 
182*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
183*6777b538SAndroid Build Coastguard Worker 
184*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
185*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
186*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
187*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
188*6777b538SAndroid Build Coastguard Worker 
189*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
190*6777b538SAndroid Build Coastguard Worker 
191*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
192*6777b538SAndroid Build Coastguard Worker 
193*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
194*6777b538SAndroid Build Coastguard Worker       SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
195*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
196*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
197*6777b538SAndroid Build Coastguard Worker 
198*6777b538SAndroid Build Coastguard Worker   StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
199*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
200*6777b538SAndroid Build Coastguard Worker 
201*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
202*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
203*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
204*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
205*6777b538SAndroid Build Coastguard Worker 
206*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
207*6777b538SAndroid Build Coastguard Worker 
208*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(delegate.send_headers_completed());
209*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
210*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
211*6777b538SAndroid Build Coastguard Worker             delegate.TakeReceivedData());
212*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
213*6777b538SAndroid Build Coastguard Worker }
214*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,BrokenConnectionDetectionSuccessfulRequest)215*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, BrokenConnectionDetectionSuccessfulRequest) {
216*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
217*6777b538SAndroid Build Coastguard Worker       kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
218*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
219*6777b538SAndroid Build Coastguard Worker 
220*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
221*6777b538SAndroid Build Coastguard Worker   AddRead(resp);
222*6777b538SAndroid Build Coastguard Worker 
223*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame msg(
224*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
225*6777b538SAndroid Build Coastguard Worker   AddWrite(msg);
226*6777b538SAndroid Build Coastguard Worker 
227*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame echo(
228*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
229*6777b538SAndroid Build Coastguard Worker   AddRead(echo);
230*6777b538SAndroid Build Coastguard Worker 
231*6777b538SAndroid Build Coastguard Worker   AddReadPause();
232*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
233*6777b538SAndroid Build Coastguard Worker 
234*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
235*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
236*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
237*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
238*6777b538SAndroid Build Coastguard Worker 
239*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
240*6777b538SAndroid Build Coastguard Worker 
241*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
242*6777b538SAndroid Build Coastguard Worker 
243*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(session->IsBrokenConnectionDetectionEnabled());
244*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
245*6777b538SAndroid Build Coastguard Worker       SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource(),
246*6777b538SAndroid Build Coastguard Worker       true, base::Seconds(10));
247*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
248*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(session->IsBrokenConnectionDetectionEnabled());
249*6777b538SAndroid Build Coastguard Worker   StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
250*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
251*6777b538SAndroid Build Coastguard Worker 
252*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
253*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
254*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
255*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
256*6777b538SAndroid Build Coastguard Worker 
257*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
258*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(session->IsBrokenConnectionDetectionEnabled());
259*6777b538SAndroid Build Coastguard Worker 
260*6777b538SAndroid Build Coastguard Worker   data.Resume();
261*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
262*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(session->IsBrokenConnectionDetectionEnabled());
263*6777b538SAndroid Build Coastguard Worker }
264*6777b538SAndroid Build Coastguard Worker 
265*6777b538SAndroid Build Coastguard Worker // Delegate that receives trailers.
266*6777b538SAndroid Build Coastguard Worker class StreamDelegateWithTrailers : public test::StreamDelegateWithBody {
267*6777b538SAndroid Build Coastguard Worker  public:
StreamDelegateWithTrailers(const base::WeakPtr<SpdyStream> & stream,std::string_view data)268*6777b538SAndroid Build Coastguard Worker   StreamDelegateWithTrailers(const base::WeakPtr<SpdyStream>& stream,
269*6777b538SAndroid Build Coastguard Worker                              std::string_view data)
270*6777b538SAndroid Build Coastguard Worker       : StreamDelegateWithBody(stream, data) {}
271*6777b538SAndroid Build Coastguard Worker 
272*6777b538SAndroid Build Coastguard Worker   ~StreamDelegateWithTrailers() override = default;
273*6777b538SAndroid Build Coastguard Worker 
OnTrailers(const spdy::Http2HeaderBlock & trailers)274*6777b538SAndroid Build Coastguard Worker   void OnTrailers(const spdy::Http2HeaderBlock& trailers) override {
275*6777b538SAndroid Build Coastguard Worker     trailers_ = trailers.Clone();
276*6777b538SAndroid Build Coastguard Worker   }
277*6777b538SAndroid Build Coastguard Worker 
trailers() const278*6777b538SAndroid Build Coastguard Worker   const spdy::Http2HeaderBlock& trailers() const { return trailers_; }
279*6777b538SAndroid Build Coastguard Worker 
280*6777b538SAndroid Build Coastguard Worker  private:
281*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock trailers_;
282*6777b538SAndroid Build Coastguard Worker };
283*6777b538SAndroid Build Coastguard Worker 
284*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/481033.
TEST_F(SpdyStreamTest,Trailers)285*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, Trailers) {
286*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
287*6777b538SAndroid Build Coastguard Worker       kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
288*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
289*6777b538SAndroid Build Coastguard Worker 
290*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame msg(
291*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
292*6777b538SAndroid Build Coastguard Worker   AddWrite(msg);
293*6777b538SAndroid Build Coastguard Worker 
294*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
295*6777b538SAndroid Build Coastguard Worker   AddRead(resp);
296*6777b538SAndroid Build Coastguard Worker 
297*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame echo(
298*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
299*6777b538SAndroid Build Coastguard Worker   AddRead(echo);
300*6777b538SAndroid Build Coastguard Worker 
301*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock late_headers;
302*6777b538SAndroid Build Coastguard Worker   late_headers["foo"] = "bar";
303*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame trailers(spdy_util_.ConstructSpdyResponseHeaders(
304*6777b538SAndroid Build Coastguard Worker       1, std::move(late_headers), false));
305*6777b538SAndroid Build Coastguard Worker   AddRead(trailers);
306*6777b538SAndroid Build Coastguard Worker 
307*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
308*6777b538SAndroid Build Coastguard Worker 
309*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
310*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
311*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
312*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
313*6777b538SAndroid Build Coastguard Worker 
314*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
315*6777b538SAndroid Build Coastguard Worker 
316*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
317*6777b538SAndroid Build Coastguard Worker 
318*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
319*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
320*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
321*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
322*6777b538SAndroid Build Coastguard Worker 
323*6777b538SAndroid Build Coastguard Worker   StreamDelegateWithTrailers delegate(stream, kPostBodyStringPiece);
324*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
325*6777b538SAndroid Build Coastguard Worker 
326*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
327*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
328*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
329*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
330*6777b538SAndroid Build Coastguard Worker 
331*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
332*6777b538SAndroid Build Coastguard Worker 
333*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(delegate.send_headers_completed());
334*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
335*6777b538SAndroid Build Coastguard Worker   const spdy::Http2HeaderBlock& received_trailers = delegate.trailers();
336*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock::const_iterator it = received_trailers.find("foo");
337*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("bar", it->second);
338*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
339*6777b538SAndroid Build Coastguard Worker             delegate.TakeReceivedData());
340*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
341*6777b538SAndroid Build Coastguard Worker }
342*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,StreamError)343*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, StreamError) {
344*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
345*6777b538SAndroid Build Coastguard Worker       kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
346*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
347*6777b538SAndroid Build Coastguard Worker 
348*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame resp(
349*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
350*6777b538SAndroid Build Coastguard Worker   AddRead(resp);
351*6777b538SAndroid Build Coastguard Worker 
352*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame msg(
353*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
354*6777b538SAndroid Build Coastguard Worker   AddWrite(msg);
355*6777b538SAndroid Build Coastguard Worker 
356*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame echo(
357*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
358*6777b538SAndroid Build Coastguard Worker   AddRead(echo);
359*6777b538SAndroid Build Coastguard Worker 
360*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
361*6777b538SAndroid Build Coastguard Worker 
362*6777b538SAndroid Build Coastguard Worker   RecordingNetLogObserver net_log_observer;
363*6777b538SAndroid Build Coastguard Worker 
364*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
365*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
366*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
367*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
368*6777b538SAndroid Build Coastguard Worker 
369*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
370*6777b538SAndroid Build Coastguard Worker 
371*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
372*6777b538SAndroid Build Coastguard Worker 
373*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
374*6777b538SAndroid Build Coastguard Worker       SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST,
375*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE));
376*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
377*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
378*6777b538SAndroid Build Coastguard Worker 
379*6777b538SAndroid Build Coastguard Worker   StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
380*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
381*6777b538SAndroid Build Coastguard Worker 
382*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
383*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
384*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
385*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
386*6777b538SAndroid Build Coastguard Worker 
387*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
388*6777b538SAndroid Build Coastguard Worker 
389*6777b538SAndroid Build Coastguard Worker   const spdy::SpdyStreamId stream_id = delegate.stream_id();
390*6777b538SAndroid Build Coastguard Worker 
391*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(delegate.send_headers_completed());
392*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
393*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
394*6777b538SAndroid Build Coastguard Worker             delegate.TakeReceivedData());
395*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
396*6777b538SAndroid Build Coastguard Worker 
397*6777b538SAndroid Build Coastguard Worker   // Check that the NetLog was filled reasonably.
398*6777b538SAndroid Build Coastguard Worker   auto entries = net_log_observer.GetEntries();
399*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(0u, entries.size());
400*6777b538SAndroid Build Coastguard Worker 
401*6777b538SAndroid Build Coastguard Worker   // Check that we logged SPDY_STREAM_ERROR correctly.
402*6777b538SAndroid Build Coastguard Worker   int pos = ExpectLogContainsSomewhere(
403*6777b538SAndroid Build Coastguard Worker       entries, 0, NetLogEventType::HTTP2_STREAM_ERROR, NetLogEventPhase::NONE);
404*6777b538SAndroid Build Coastguard Worker 
405*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(stream_id),
406*6777b538SAndroid Build Coastguard Worker             GetIntegerValueFromParams(entries[pos], "stream_id"));
407*6777b538SAndroid Build Coastguard Worker }
408*6777b538SAndroid Build Coastguard Worker 
409*6777b538SAndroid Build Coastguard Worker // Make sure that large blocks of data are properly split up into frame-sized
410*6777b538SAndroid Build Coastguard Worker // chunks for a request/response (i.e., an HTTP-like) stream.
TEST_F(SpdyStreamTest,SendLargeDataAfterOpenRequestResponse)411*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) {
412*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
413*6777b538SAndroid Build Coastguard Worker       kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
414*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
415*6777b538SAndroid Build Coastguard Worker 
416*6777b538SAndroid Build Coastguard Worker   std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
417*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame chunk(
418*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, chunk_data, false));
419*6777b538SAndroid Build Coastguard Worker   AddWrite(chunk);
420*6777b538SAndroid Build Coastguard Worker   AddWrite(chunk);
421*6777b538SAndroid Build Coastguard Worker 
422*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame last_chunk(
423*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, chunk_data, true));
424*6777b538SAndroid Build Coastguard Worker   AddWrite(last_chunk);
425*6777b538SAndroid Build Coastguard Worker 
426*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
427*6777b538SAndroid Build Coastguard Worker   AddRead(resp);
428*6777b538SAndroid Build Coastguard Worker 
429*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
430*6777b538SAndroid Build Coastguard Worker 
431*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
432*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
433*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
434*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
435*6777b538SAndroid Build Coastguard Worker 
436*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
437*6777b538SAndroid Build Coastguard Worker 
438*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
439*6777b538SAndroid Build Coastguard Worker 
440*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
441*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
442*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
443*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
444*6777b538SAndroid Build Coastguard Worker 
445*6777b538SAndroid Build Coastguard Worker   std::string body_data(3 * kMaxSpdyFrameChunkSize, 'x');
446*6777b538SAndroid Build Coastguard Worker   StreamDelegateWithBody delegate(stream, body_data);
447*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
448*6777b538SAndroid Build Coastguard Worker 
449*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
450*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
451*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
452*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
453*6777b538SAndroid Build Coastguard Worker 
454*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
455*6777b538SAndroid Build Coastguard Worker 
456*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(delegate.send_headers_completed());
457*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
458*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(), delegate.TakeReceivedData());
459*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
460*6777b538SAndroid Build Coastguard Worker }
461*6777b538SAndroid Build Coastguard Worker 
462*6777b538SAndroid Build Coastguard Worker // Make sure that large blocks of data are properly split up into frame-sized
463*6777b538SAndroid Build Coastguard Worker // chunks for a bidirectional (i.e., non-HTTP-like) stream.
TEST_F(SpdyStreamTest,SendLargeDataAfterOpenBidirectional)464*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) {
465*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
466*6777b538SAndroid Build Coastguard Worker       kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
467*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
468*6777b538SAndroid Build Coastguard Worker 
469*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
470*6777b538SAndroid Build Coastguard Worker   AddRead(resp);
471*6777b538SAndroid Build Coastguard Worker 
472*6777b538SAndroid Build Coastguard Worker   std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
473*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame chunk(
474*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, chunk_data, false));
475*6777b538SAndroid Build Coastguard Worker   AddWrite(chunk);
476*6777b538SAndroid Build Coastguard Worker   AddWrite(chunk);
477*6777b538SAndroid Build Coastguard Worker   AddWrite(chunk);
478*6777b538SAndroid Build Coastguard Worker 
479*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
480*6777b538SAndroid Build Coastguard Worker 
481*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
482*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
483*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
484*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
485*6777b538SAndroid Build Coastguard Worker 
486*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
487*6777b538SAndroid Build Coastguard Worker 
488*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
489*6777b538SAndroid Build Coastguard Worker 
490*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
491*6777b538SAndroid Build Coastguard Worker       SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
492*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
493*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
494*6777b538SAndroid Build Coastguard Worker 
495*6777b538SAndroid Build Coastguard Worker   std::string body_data(3 * kMaxSpdyFrameChunkSize, 'x');
496*6777b538SAndroid Build Coastguard Worker   StreamDelegateSendImmediate delegate(stream, body_data);
497*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
498*6777b538SAndroid Build Coastguard Worker 
499*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
500*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
501*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
502*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
503*6777b538SAndroid Build Coastguard Worker 
504*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
505*6777b538SAndroid Build Coastguard Worker 
506*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(delegate.send_headers_completed());
507*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
508*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(), delegate.TakeReceivedData());
509*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
510*6777b538SAndroid Build Coastguard Worker }
511*6777b538SAndroid Build Coastguard Worker 
512*6777b538SAndroid Build Coastguard Worker // Receiving a header with uppercase ASCII should result in a protocol error.
TEST_F(SpdyStreamTest,UpperCaseHeaders)513*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, UpperCaseHeaders) {
514*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(
515*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
516*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
517*6777b538SAndroid Build Coastguard Worker 
518*6777b538SAndroid Build Coastguard Worker   const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
519*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(
520*6777b538SAndroid Build Coastguard Worker       kExtraHeaders, std::size(kExtraHeaders) / 2, 1));
521*6777b538SAndroid Build Coastguard Worker   AddRead(reply);
522*6777b538SAndroid Build Coastguard Worker 
523*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame rst(
524*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
525*6777b538SAndroid Build Coastguard Worker   AddWrite(rst);
526*6777b538SAndroid Build Coastguard Worker 
527*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
528*6777b538SAndroid Build Coastguard Worker 
529*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
530*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
531*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
532*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
533*6777b538SAndroid Build Coastguard Worker 
534*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
535*6777b538SAndroid Build Coastguard Worker 
536*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
537*6777b538SAndroid Build Coastguard Worker 
538*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
539*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
540*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
541*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
542*6777b538SAndroid Build Coastguard Worker 
543*6777b538SAndroid Build Coastguard Worker   StreamDelegateDoNothing delegate(stream);
544*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
545*6777b538SAndroid Build Coastguard Worker 
546*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
547*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
548*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
549*6777b538SAndroid Build Coastguard Worker       stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
550*6777b538SAndroid Build Coastguard Worker       IsError(ERR_IO_PENDING));
551*6777b538SAndroid Build Coastguard Worker 
552*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
553*6777b538SAndroid Build Coastguard Worker 
554*6777b538SAndroid Build Coastguard Worker   // Finish async network reads and writes.
555*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
556*6777b538SAndroid Build Coastguard Worker 
557*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
558*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllReadDataConsumed());
559*6777b538SAndroid Build Coastguard Worker }
560*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,HeadersMustHaveStatus)561*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, HeadersMustHaveStatus) {
562*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(
563*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
564*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
565*6777b538SAndroid Build Coastguard Worker 
566*6777b538SAndroid Build Coastguard Worker   // Response headers without ":status" header field: protocol error.
567*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock header_block_without_status;
568*6777b538SAndroid Build Coastguard Worker   header_block_without_status[spdy::kHttp2MethodHeader] = "GET";
569*6777b538SAndroid Build Coastguard Worker   header_block_without_status[spdy::kHttp2AuthorityHeader] = "www.example.org";
570*6777b538SAndroid Build Coastguard Worker   header_block_without_status[spdy::kHttp2SchemeHeader] = "https";
571*6777b538SAndroid Build Coastguard Worker   header_block_without_status[spdy::kHttp2PathHeader] = "/";
572*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame reply(
573*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyReply(1, std::move(header_block_without_status)));
574*6777b538SAndroid Build Coastguard Worker   AddRead(reply);
575*6777b538SAndroid Build Coastguard Worker 
576*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame rst(
577*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
578*6777b538SAndroid Build Coastguard Worker   AddWrite(rst);
579*6777b538SAndroid Build Coastguard Worker 
580*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
581*6777b538SAndroid Build Coastguard Worker 
582*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
583*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
584*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
585*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
586*6777b538SAndroid Build Coastguard Worker 
587*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
588*6777b538SAndroid Build Coastguard Worker 
589*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
590*6777b538SAndroid Build Coastguard Worker 
591*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
592*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
593*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
594*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
595*6777b538SAndroid Build Coastguard Worker 
596*6777b538SAndroid Build Coastguard Worker   StreamDelegateDoNothing delegate(stream);
597*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
598*6777b538SAndroid Build Coastguard Worker 
599*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
600*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
601*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
602*6777b538SAndroid Build Coastguard Worker                                                        NO_MORE_DATA_TO_SEND));
603*6777b538SAndroid Build Coastguard Worker 
604*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
605*6777b538SAndroid Build Coastguard Worker 
606*6777b538SAndroid Build Coastguard Worker   // Finish async network reads and writes.
607*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
608*6777b538SAndroid Build Coastguard Worker 
609*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
610*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllReadDataConsumed());
611*6777b538SAndroid Build Coastguard Worker }
612*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,TrailersMustNotFollowTrailers)613*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, TrailersMustNotFollowTrailers) {
614*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(
615*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
616*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
617*6777b538SAndroid Build Coastguard Worker 
618*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame reply(
619*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
620*6777b538SAndroid Build Coastguard Worker   AddRead(reply);
621*6777b538SAndroid Build Coastguard Worker 
622*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame body(
623*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
624*6777b538SAndroid Build Coastguard Worker   AddRead(body);
625*6777b538SAndroid Build Coastguard Worker 
626*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock trailers_block;
627*6777b538SAndroid Build Coastguard Worker   trailers_block["foo"] = "bar";
628*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame first_trailers(
629*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers_block),
630*6777b538SAndroid Build Coastguard Worker                                               false));
631*6777b538SAndroid Build Coastguard Worker   AddRead(first_trailers);
632*6777b538SAndroid Build Coastguard Worker 
633*6777b538SAndroid Build Coastguard Worker   // Trailers following trailers: procotol error.
634*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame second_trailers(
635*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers_block),
636*6777b538SAndroid Build Coastguard Worker                                               true));
637*6777b538SAndroid Build Coastguard Worker   AddRead(second_trailers);
638*6777b538SAndroid Build Coastguard Worker 
639*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame rst(
640*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
641*6777b538SAndroid Build Coastguard Worker   AddWrite(rst);
642*6777b538SAndroid Build Coastguard Worker 
643*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
644*6777b538SAndroid Build Coastguard Worker 
645*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
646*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
647*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
648*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
649*6777b538SAndroid Build Coastguard Worker 
650*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
651*6777b538SAndroid Build Coastguard Worker 
652*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
653*6777b538SAndroid Build Coastguard Worker 
654*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
655*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
656*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
657*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
658*6777b538SAndroid Build Coastguard Worker 
659*6777b538SAndroid Build Coastguard Worker   StreamDelegateDoNothing delegate(stream);
660*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
661*6777b538SAndroid Build Coastguard Worker 
662*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
663*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
664*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
665*6777b538SAndroid Build Coastguard Worker                                                        NO_MORE_DATA_TO_SEND));
666*6777b538SAndroid Build Coastguard Worker 
667*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
668*6777b538SAndroid Build Coastguard Worker 
669*6777b538SAndroid Build Coastguard Worker   // Finish async network reads and writes.
670*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
671*6777b538SAndroid Build Coastguard Worker 
672*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
673*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllReadDataConsumed());
674*6777b538SAndroid Build Coastguard Worker }
675*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,DataMustNotFollowTrailers)676*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, DataMustNotFollowTrailers) {
677*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(
678*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
679*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
680*6777b538SAndroid Build Coastguard Worker 
681*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame reply(
682*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
683*6777b538SAndroid Build Coastguard Worker   AddRead(reply);
684*6777b538SAndroid Build Coastguard Worker 
685*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame body(
686*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
687*6777b538SAndroid Build Coastguard Worker   AddRead(body);
688*6777b538SAndroid Build Coastguard Worker 
689*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock trailers_block;
690*6777b538SAndroid Build Coastguard Worker   trailers_block["foo"] = "bar";
691*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame trailers(spdy_util_.ConstructSpdyResponseHeaders(
692*6777b538SAndroid Build Coastguard Worker       1, std::move(trailers_block), false));
693*6777b538SAndroid Build Coastguard Worker   AddRead(trailers);
694*6777b538SAndroid Build Coastguard Worker 
695*6777b538SAndroid Build Coastguard Worker   // DATA frame following trailers: protocol error.
696*6777b538SAndroid Build Coastguard Worker   AddRead(body);
697*6777b538SAndroid Build Coastguard Worker 
698*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame rst(
699*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
700*6777b538SAndroid Build Coastguard Worker   AddWrite(rst);
701*6777b538SAndroid Build Coastguard Worker 
702*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
703*6777b538SAndroid Build Coastguard Worker 
704*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
705*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
706*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
707*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
708*6777b538SAndroid Build Coastguard Worker 
709*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
710*6777b538SAndroid Build Coastguard Worker 
711*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
712*6777b538SAndroid Build Coastguard Worker 
713*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
714*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
715*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
716*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
717*6777b538SAndroid Build Coastguard Worker 
718*6777b538SAndroid Build Coastguard Worker   StreamDelegateDoNothing delegate(stream);
719*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
720*6777b538SAndroid Build Coastguard Worker 
721*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
722*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
723*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
724*6777b538SAndroid Build Coastguard Worker                                                        NO_MORE_DATA_TO_SEND));
725*6777b538SAndroid Build Coastguard Worker 
726*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
727*6777b538SAndroid Build Coastguard Worker 
728*6777b538SAndroid Build Coastguard Worker   // Finish async network reads and writes.
729*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
730*6777b538SAndroid Build Coastguard Worker 
731*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
732*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllReadDataConsumed());
733*6777b538SAndroid Build Coastguard Worker }
734*6777b538SAndroid Build Coastguard Worker 
735*6777b538SAndroid Build Coastguard Worker class SpdyStreamTestWithMockClock : public SpdyStreamTest {
736*6777b538SAndroid Build Coastguard Worker  public:
SpdyStreamTestWithMockClock()737*6777b538SAndroid Build Coastguard Worker   SpdyStreamTestWithMockClock()
738*6777b538SAndroid Build Coastguard Worker       : SpdyStreamTest(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
739*6777b538SAndroid Build Coastguard Worker 
Initialize()740*6777b538SAndroid Build Coastguard Worker   void Initialize() {
741*6777b538SAndroid Build Coastguard Worker     // Set up the sequenced socket data.
742*6777b538SAndroid Build Coastguard Worker     data_ = std::make_unique<SequencedSocketData>(GetReads(), GetWrites());
743*6777b538SAndroid Build Coastguard Worker     MockConnect connect_data(SYNCHRONOUS, OK);
744*6777b538SAndroid Build Coastguard Worker     data_->set_connect_data(connect_data);
745*6777b538SAndroid Build Coastguard Worker     session_deps_.socket_factory->AddSocketDataProvider(data_.get());
746*6777b538SAndroid Build Coastguard Worker 
747*6777b538SAndroid Build Coastguard Worker     AddSSLSocketData();
748*6777b538SAndroid Build Coastguard Worker 
749*6777b538SAndroid Build Coastguard Worker     // Set up the SPDY stream.
750*6777b538SAndroid Build Coastguard Worker     base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
751*6777b538SAndroid Build Coastguard Worker     stream_ = CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session,
752*6777b538SAndroid Build Coastguard Worker                                         url_, LOWEST, NetLogWithSource());
753*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(stream_);
754*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kDefaultUrl, stream_->url().spec());
755*6777b538SAndroid Build Coastguard Worker 
756*6777b538SAndroid Build Coastguard Worker     DCHECK(!delegate_);
757*6777b538SAndroid Build Coastguard Worker     delegate_ = std::make_unique<StreamDelegateDoNothing>(stream_);
758*6777b538SAndroid Build Coastguard Worker     stream_->SetDelegate(delegate_.get());
759*6777b538SAndroid Build Coastguard Worker   }
760*6777b538SAndroid Build Coastguard Worker 
RunUntilNextPause()761*6777b538SAndroid Build Coastguard Worker   void RunUntilNextPause() {
762*6777b538SAndroid Build Coastguard Worker     if (data_->IsPaused())
763*6777b538SAndroid Build Coastguard Worker       data_->Resume();
764*6777b538SAndroid Build Coastguard Worker     data_->RunUntilPaused();
765*6777b538SAndroid Build Coastguard Worker   }
766*6777b538SAndroid Build Coastguard Worker 
RunUntilClose()767*6777b538SAndroid Build Coastguard Worker   int RunUntilClose() {
768*6777b538SAndroid Build Coastguard Worker     if (data_->IsPaused())
769*6777b538SAndroid Build Coastguard Worker       data_->Resume();
770*6777b538SAndroid Build Coastguard Worker     return delegate_->WaitForClose();
771*6777b538SAndroid Build Coastguard Worker   }
772*6777b538SAndroid Build Coastguard Worker 
data()773*6777b538SAndroid Build Coastguard Worker   SequencedSocketData& data() { return *data_; }
stream()774*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream() { return stream_; }
delegate()775*6777b538SAndroid Build Coastguard Worker   StreamDelegateDoNothing& delegate() { return *delegate_; }
776*6777b538SAndroid Build Coastguard Worker 
777*6777b538SAndroid Build Coastguard Worker  private:
778*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<SequencedSocketData> data_;
779*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream_;
780*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<StreamDelegateDoNothing> delegate_;
781*6777b538SAndroid Build Coastguard Worker };
782*6777b538SAndroid Build Coastguard Worker 
783*6777b538SAndroid Build Coastguard Worker // Test that the response start time is recorded for non-informational response.
TEST_F(SpdyStreamTestWithMockClock,NonInformationalResponseStart)784*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTestWithMockClock, NonInformationalResponseStart) {
785*6777b538SAndroid Build Coastguard Worker   // Set up the request.
786*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(
787*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
788*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
789*6777b538SAndroid Build Coastguard Worker 
790*6777b538SAndroid Build Coastguard Worker   // Set up the response headers.
791*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame reply(
792*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
793*6777b538SAndroid Build Coastguard Worker   // Separate the headers into 2 fragments and add pauses between the fragments
794*6777b538SAndroid Build Coastguard Worker   // so that the test runner can advance the mock clock to test timing
795*6777b538SAndroid Build Coastguard Worker   // information.
796*6777b538SAndroid Build Coastguard Worker   AddMockRead(ReadFrameExceptForLastByte(reply));
797*6777b538SAndroid Build Coastguard Worker   AddReadPause();
798*6777b538SAndroid Build Coastguard Worker   AddMockRead(LastByteOfReadFrame(reply));
799*6777b538SAndroid Build Coastguard Worker   AddReadPause();
800*6777b538SAndroid Build Coastguard Worker 
801*6777b538SAndroid Build Coastguard Worker   // Set up the response body.
802*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame body(
803*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
804*6777b538SAndroid Build Coastguard Worker   AddRead(body);
805*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
806*6777b538SAndroid Build Coastguard Worker 
807*6777b538SAndroid Build Coastguard Worker   // Set up the sequenced socket data and the spdy stream.
808*6777b538SAndroid Build Coastguard Worker   Initialize();
809*6777b538SAndroid Build Coastguard Worker 
810*6777b538SAndroid Build Coastguard Worker   // Send a request.
811*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
812*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
813*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING, stream()->SendRequestHeaders(std::move(headers),
814*6777b538SAndroid Build Coastguard Worker                                                          NO_MORE_DATA_TO_SEND));
815*6777b538SAndroid Build Coastguard Worker   AdvanceClock(base::Seconds(1));
816*6777b538SAndroid Build Coastguard Worker 
817*6777b538SAndroid Build Coastguard Worker   // The receive headers start time should be captured at this time.
818*6777b538SAndroid Build Coastguard Worker   base::TimeTicks expected_receive_headers_start_time = base::TimeTicks::Now();
819*6777b538SAndroid Build Coastguard Worker 
820*6777b538SAndroid Build Coastguard Worker   // Read the first header fragment.
821*6777b538SAndroid Build Coastguard Worker   RunUntilNextPause();
822*6777b538SAndroid Build Coastguard Worker   AdvanceClock(base::Seconds(1));
823*6777b538SAndroid Build Coastguard Worker   // Read the second header fragment.
824*6777b538SAndroid Build Coastguard Worker   RunUntilNextPause();
825*6777b538SAndroid Build Coastguard Worker   AdvanceClock(base::Seconds(1));
826*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("200", delegate().GetResponseHeaderValue(spdy::kHttp2StatusHeader));
827*6777b538SAndroid Build Coastguard Worker 
828*6777b538SAndroid Build Coastguard Worker   // Read the response body.
829*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(RunUntilClose(), IsOk());
830*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
831*6777b538SAndroid Build Coastguard Worker             delegate().TakeReceivedData());
832*6777b538SAndroid Build Coastguard Worker 
833*6777b538SAndroid Build Coastguard Worker   // Finish async network reads and writes.
834*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
835*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data().AllWriteDataConsumed());
836*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data().AllReadDataConsumed());
837*6777b538SAndroid Build Coastguard Worker 
838*6777b538SAndroid Build Coastguard Worker   // No informational responses were served. The response start time should be
839*6777b538SAndroid Build Coastguard Worker   // equal to the non-informational response start time.
840*6777b538SAndroid Build Coastguard Worker   const LoadTimingInfo& load_timing_info = delegate().GetLoadTimingInfo();
841*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(load_timing_info.receive_headers_start,
842*6777b538SAndroid Build Coastguard Worker             expected_receive_headers_start_time);
843*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(load_timing_info.receive_non_informational_headers_start,
844*6777b538SAndroid Build Coastguard Worker             expected_receive_headers_start_time);
845*6777b538SAndroid Build Coastguard Worker }
846*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTestWithMockClock,InformationalHeaders)847*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTestWithMockClock, InformationalHeaders) {
848*6777b538SAndroid Build Coastguard Worker   // Set up the request.
849*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(
850*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
851*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
852*6777b538SAndroid Build Coastguard Worker 
853*6777b538SAndroid Build Coastguard Worker   // Set up the informational response headers.
854*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock informational_headers;
855*6777b538SAndroid Build Coastguard Worker   informational_headers[":status"] = "100";
856*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame informational_response(
857*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyResponseHeaders(
858*6777b538SAndroid Build Coastguard Worker           1, std::move(informational_headers), false));
859*6777b538SAndroid Build Coastguard Worker   // Separate the headers into 2 fragments and add pauses between the fragments
860*6777b538SAndroid Build Coastguard Worker   // so that the test runner can advance the mock clock to test timing
861*6777b538SAndroid Build Coastguard Worker   // information.
862*6777b538SAndroid Build Coastguard Worker   AddMockRead(ReadFrameExceptForLastByte(informational_response));
863*6777b538SAndroid Build Coastguard Worker   AddReadPause();
864*6777b538SAndroid Build Coastguard Worker   AddMockRead(LastByteOfReadFrame(informational_response));
865*6777b538SAndroid Build Coastguard Worker   AddReadPause();
866*6777b538SAndroid Build Coastguard Worker 
867*6777b538SAndroid Build Coastguard Worker   // Set up the non-informational response headers and body.
868*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame reply(
869*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
870*6777b538SAndroid Build Coastguard Worker   AddRead(reply);
871*6777b538SAndroid Build Coastguard Worker   AddReadPause();
872*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame body(
873*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
874*6777b538SAndroid Build Coastguard Worker   AddRead(body);
875*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
876*6777b538SAndroid Build Coastguard Worker 
877*6777b538SAndroid Build Coastguard Worker   // Set up the sequenced socket data and the spdy stream.
878*6777b538SAndroid Build Coastguard Worker   Initialize();
879*6777b538SAndroid Build Coastguard Worker 
880*6777b538SAndroid Build Coastguard Worker   // Send a request.
881*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
882*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
883*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING, stream()->SendRequestHeaders(std::move(headers),
884*6777b538SAndroid Build Coastguard Worker                                                          NO_MORE_DATA_TO_SEND));
885*6777b538SAndroid Build Coastguard Worker   AdvanceClock(base::Seconds(1));
886*6777b538SAndroid Build Coastguard Worker 
887*6777b538SAndroid Build Coastguard Worker   // The receive headers start time should be captured at this time.
888*6777b538SAndroid Build Coastguard Worker   base::TimeTicks expected_receive_headers_start_time = base::TimeTicks::Now();
889*6777b538SAndroid Build Coastguard Worker 
890*6777b538SAndroid Build Coastguard Worker   // Read the first header fragment of the informational response.
891*6777b538SAndroid Build Coastguard Worker   RunUntilNextPause();
892*6777b538SAndroid Build Coastguard Worker   AdvanceClock(base::Seconds(1));
893*6777b538SAndroid Build Coastguard Worker   // Read the second header fragment of the informational response.
894*6777b538SAndroid Build Coastguard Worker   RunUntilNextPause();
895*6777b538SAndroid Build Coastguard Worker   AdvanceClock(base::Seconds(1));
896*6777b538SAndroid Build Coastguard Worker   // We don't check the status code of the informational headers here because
897*6777b538SAndroid Build Coastguard Worker   // SpdyStream doesn't propagate it to the delegate.
898*6777b538SAndroid Build Coastguard Worker 
899*6777b538SAndroid Build Coastguard Worker   // The receive non-informational headers start time should be captured at this
900*6777b538SAndroid Build Coastguard Worker   // time.
901*6777b538SAndroid Build Coastguard Worker   base::TimeTicks expected_receive_non_informational_headers_start_time =
902*6777b538SAndroid Build Coastguard Worker       base::TimeTicks::Now();
903*6777b538SAndroid Build Coastguard Worker 
904*6777b538SAndroid Build Coastguard Worker   // Read the non-informational response headers.
905*6777b538SAndroid Build Coastguard Worker   RunUntilNextPause();
906*6777b538SAndroid Build Coastguard Worker   AdvanceClock(base::Seconds(1));
907*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("200", delegate().GetResponseHeaderValue(spdy::kHttp2StatusHeader));
908*6777b538SAndroid Build Coastguard Worker 
909*6777b538SAndroid Build Coastguard Worker   // Read the response body.
910*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(RunUntilClose(), IsOk());
911*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
912*6777b538SAndroid Build Coastguard Worker             delegate().TakeReceivedData());
913*6777b538SAndroid Build Coastguard Worker 
914*6777b538SAndroid Build Coastguard Worker   // Finish async network reads and writes.
915*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
916*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data().AllWriteDataConsumed());
917*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data().AllReadDataConsumed());
918*6777b538SAndroid Build Coastguard Worker 
919*6777b538SAndroid Build Coastguard Worker   const LoadTimingInfo& load_timing_info = delegate().GetLoadTimingInfo();
920*6777b538SAndroid Build Coastguard Worker   // The response start time should be captured at the time the first header
921*6777b538SAndroid Build Coastguard Worker   // fragment of the informational response is received.
922*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(load_timing_info.receive_headers_start,
923*6777b538SAndroid Build Coastguard Worker             expected_receive_headers_start_time);
924*6777b538SAndroid Build Coastguard Worker   // The non-informational response start time should be captured at the time
925*6777b538SAndroid Build Coastguard Worker   // the first header fragment of the non-informational response is received.
926*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(load_timing_info.receive_non_informational_headers_start,
927*6777b538SAndroid Build Coastguard Worker             expected_receive_non_informational_headers_start_time);
928*6777b538SAndroid Build Coastguard Worker   // The first response start time should be earlier than the non-informational
929*6777b538SAndroid Build Coastguard Worker   // response start time.
930*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(load_timing_info.receive_headers_start,
931*6777b538SAndroid Build Coastguard Worker             load_timing_info.receive_non_informational_headers_start);
932*6777b538SAndroid Build Coastguard Worker }
933*6777b538SAndroid Build Coastguard Worker 
934*6777b538SAndroid Build Coastguard Worker // Tests that timing information of 103 Eary Hints responses are collected and
935*6777b538SAndroid Build Coastguard Worker // callbacks are called as expected.
TEST_F(SpdyStreamTestWithMockClock,EarlyHints)936*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTestWithMockClock, EarlyHints) {
937*6777b538SAndroid Build Coastguard Worker   // Set up the request.
938*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(
939*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
940*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
941*6777b538SAndroid Build Coastguard Worker 
942*6777b538SAndroid Build Coastguard Worker   // Set up two early hints response headers.
943*6777b538SAndroid Build Coastguard Worker   const char kLinkHeaderValue1[] = "</image.jpg>; rel=preload; as=image";
944*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock informational_headers1;
945*6777b538SAndroid Build Coastguard Worker   informational_headers1[":status"] = "103";
946*6777b538SAndroid Build Coastguard Worker   informational_headers1["link"] = kLinkHeaderValue1;
947*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame informational_response1(
948*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyResponseHeaders(
949*6777b538SAndroid Build Coastguard Worker           1, std::move(informational_headers1), false));
950*6777b538SAndroid Build Coastguard Worker 
951*6777b538SAndroid Build Coastguard Worker   const char kLinkHeaderValue2[] = "</style.css>; rel=preload; as=stylesheet";
952*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock informational_headers2;
953*6777b538SAndroid Build Coastguard Worker   informational_headers2[":status"] = "103";
954*6777b538SAndroid Build Coastguard Worker   informational_headers2["link"] = kLinkHeaderValue2;
955*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame informational_response2(
956*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyResponseHeaders(
957*6777b538SAndroid Build Coastguard Worker           1, std::move(informational_headers2), false));
958*6777b538SAndroid Build Coastguard Worker 
959*6777b538SAndroid Build Coastguard Worker   // Add the headers to make sure that multiple informational responses don't
960*6777b538SAndroid Build Coastguard Worker   // confuse the timing information.
961*6777b538SAndroid Build Coastguard Worker   const int kNumberOfInformationalResponses = 2;
962*6777b538SAndroid Build Coastguard Worker   // Separate the headers into 2 fragments and add pauses between the
963*6777b538SAndroid Build Coastguard Worker   // fragments so that the test runner can advance the mock clock to test
964*6777b538SAndroid Build Coastguard Worker   // timing information.
965*6777b538SAndroid Build Coastguard Worker   AddMockRead(ReadFrameExceptForLastByte(informational_response1));
966*6777b538SAndroid Build Coastguard Worker   AddReadPause();
967*6777b538SAndroid Build Coastguard Worker   AddMockRead(LastByteOfReadFrame(informational_response1));
968*6777b538SAndroid Build Coastguard Worker   AddReadPause();
969*6777b538SAndroid Build Coastguard Worker 
970*6777b538SAndroid Build Coastguard Worker   AddMockRead(ReadFrameExceptForLastByte(informational_response2));
971*6777b538SAndroid Build Coastguard Worker   AddReadPause();
972*6777b538SAndroid Build Coastguard Worker   AddMockRead(LastByteOfReadFrame(informational_response2));
973*6777b538SAndroid Build Coastguard Worker   AddReadPause();
974*6777b538SAndroid Build Coastguard Worker 
975*6777b538SAndroid Build Coastguard Worker   // Set up the non-informational response headers and body.
976*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame reply(
977*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
978*6777b538SAndroid Build Coastguard Worker   AddRead(reply);
979*6777b538SAndroid Build Coastguard Worker   AddReadPause();
980*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame body(
981*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
982*6777b538SAndroid Build Coastguard Worker   AddRead(body);
983*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
984*6777b538SAndroid Build Coastguard Worker 
985*6777b538SAndroid Build Coastguard Worker   // Set up the sequenced socket data and the spdy stream.
986*6777b538SAndroid Build Coastguard Worker   Initialize();
987*6777b538SAndroid Build Coastguard Worker 
988*6777b538SAndroid Build Coastguard Worker   // Send a request.
989*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
990*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
991*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING, stream()->SendRequestHeaders(std::move(headers),
992*6777b538SAndroid Build Coastguard Worker                                                          NO_MORE_DATA_TO_SEND));
993*6777b538SAndroid Build Coastguard Worker   AdvanceClock(base::Seconds(1));
994*6777b538SAndroid Build Coastguard Worker 
995*6777b538SAndroid Build Coastguard Worker   // The receive headers start time should be captured at this time.
996*6777b538SAndroid Build Coastguard Worker   base::TimeTicks expected_receive_headers_start_time = base::TimeTicks::Now();
997*6777b538SAndroid Build Coastguard Worker 
998*6777b538SAndroid Build Coastguard Worker   // Read the header fragments of the informational responses.
999*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumberOfInformationalResponses; ++i) {
1000*6777b538SAndroid Build Coastguard Worker     RunUntilNextPause();
1001*6777b538SAndroid Build Coastguard Worker     AdvanceClock(base::Seconds(1));
1002*6777b538SAndroid Build Coastguard Worker     RunUntilNextPause();
1003*6777b538SAndroid Build Coastguard Worker     AdvanceClock(base::Seconds(1));
1004*6777b538SAndroid Build Coastguard Worker   }
1005*6777b538SAndroid Build Coastguard Worker 
1006*6777b538SAndroid Build Coastguard Worker   // Check the callback was called twice with 103 status code.
1007*6777b538SAndroid Build Coastguard Worker   const std::vector<spdy::Http2HeaderBlock>& early_hints =
1008*6777b538SAndroid Build Coastguard Worker       delegate().early_hints();
1009*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(early_hints.size(),
1010*6777b538SAndroid Build Coastguard Worker             static_cast<size_t>(kNumberOfInformationalResponses));
1011*6777b538SAndroid Build Coastguard Worker   {
1012*6777b538SAndroid Build Coastguard Worker     const spdy::Http2HeaderBlock& hint = delegate().early_hints()[0];
1013*6777b538SAndroid Build Coastguard Worker     spdy::Http2HeaderBlock::const_iterator status_iterator =
1014*6777b538SAndroid Build Coastguard Worker         hint.find(spdy::kHttp2StatusHeader);
1015*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(status_iterator != hint.end());
1016*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(status_iterator->second, "103");
1017*6777b538SAndroid Build Coastguard Worker 
1018*6777b538SAndroid Build Coastguard Worker     spdy::Http2HeaderBlock::const_iterator link_header_iterator =
1019*6777b538SAndroid Build Coastguard Worker         hint.find("link");
1020*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(link_header_iterator != hint.end());
1021*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(link_header_iterator->second, kLinkHeaderValue1);
1022*6777b538SAndroid Build Coastguard Worker   }
1023*6777b538SAndroid Build Coastguard Worker   {
1024*6777b538SAndroid Build Coastguard Worker     const spdy::Http2HeaderBlock& hint = delegate().early_hints()[1];
1025*6777b538SAndroid Build Coastguard Worker     spdy::Http2HeaderBlock::const_iterator status_iterator =
1026*6777b538SAndroid Build Coastguard Worker         hint.find(spdy::kHttp2StatusHeader);
1027*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(status_iterator != hint.end());
1028*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(status_iterator->second, "103");
1029*6777b538SAndroid Build Coastguard Worker 
1030*6777b538SAndroid Build Coastguard Worker     spdy::Http2HeaderBlock::const_iterator link_header_iterator =
1031*6777b538SAndroid Build Coastguard Worker         hint.find("link");
1032*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(link_header_iterator != hint.end());
1033*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(link_header_iterator->second, kLinkHeaderValue2);
1034*6777b538SAndroid Build Coastguard Worker   }
1035*6777b538SAndroid Build Coastguard Worker 
1036*6777b538SAndroid Build Coastguard Worker   // The receive non-informational headers start time should be captured at this
1037*6777b538SAndroid Build Coastguard Worker   // time.
1038*6777b538SAndroid Build Coastguard Worker   base::TimeTicks expected_receive_non_informational_headers_start_time =
1039*6777b538SAndroid Build Coastguard Worker       base::TimeTicks::Now();
1040*6777b538SAndroid Build Coastguard Worker 
1041*6777b538SAndroid Build Coastguard Worker   // Read the non-informational response headers.
1042*6777b538SAndroid Build Coastguard Worker   RunUntilNextPause();
1043*6777b538SAndroid Build Coastguard Worker   AdvanceClock(base::Seconds(1));
1044*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("200", delegate().GetResponseHeaderValue(spdy::kHttp2StatusHeader));
1045*6777b538SAndroid Build Coastguard Worker 
1046*6777b538SAndroid Build Coastguard Worker   // Read the response body.
1047*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(RunUntilClose(), IsOk());
1048*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
1049*6777b538SAndroid Build Coastguard Worker             delegate().TakeReceivedData());
1050*6777b538SAndroid Build Coastguard Worker 
1051*6777b538SAndroid Build Coastguard Worker   // Finish async network reads and writes.
1052*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1053*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data().AllWriteDataConsumed());
1054*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data().AllReadDataConsumed());
1055*6777b538SAndroid Build Coastguard Worker 
1056*6777b538SAndroid Build Coastguard Worker   const LoadTimingInfo& load_timing_info = delegate().GetLoadTimingInfo();
1057*6777b538SAndroid Build Coastguard Worker   // The response start time should be captured at the time the first header
1058*6777b538SAndroid Build Coastguard Worker   // fragment of the first informational response is received.
1059*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(load_timing_info.receive_headers_start,
1060*6777b538SAndroid Build Coastguard Worker             expected_receive_headers_start_time);
1061*6777b538SAndroid Build Coastguard Worker   // The first early hints time should be recorded as well.
1062*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(load_timing_info.first_early_hints_time,
1063*6777b538SAndroid Build Coastguard Worker             expected_receive_headers_start_time);
1064*6777b538SAndroid Build Coastguard Worker   // The non-informational response start time should be captured at the time
1065*6777b538SAndroid Build Coastguard Worker   // the first header fragment of the non-informational response is received.
1066*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(load_timing_info.receive_non_informational_headers_start,
1067*6777b538SAndroid Build Coastguard Worker             expected_receive_non_informational_headers_start_time);
1068*6777b538SAndroid Build Coastguard Worker   // The response start time should be earlier than the non-informational
1069*6777b538SAndroid Build Coastguard Worker   // response start time.
1070*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(load_timing_info.receive_headers_start,
1071*6777b538SAndroid Build Coastguard Worker             load_timing_info.receive_non_informational_headers_start);
1072*6777b538SAndroid Build Coastguard Worker }
1073*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,StatusMustBeNumber)1074*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, StatusMustBeNumber) {
1075*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(
1076*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
1077*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
1078*6777b538SAndroid Build Coastguard Worker 
1079*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock incorrect_headers;
1080*6777b538SAndroid Build Coastguard Worker   incorrect_headers[":status"] = "nan";
1081*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
1082*6777b538SAndroid Build Coastguard Worker       1, std::move(incorrect_headers), false));
1083*6777b538SAndroid Build Coastguard Worker   AddRead(reply);
1084*6777b538SAndroid Build Coastguard Worker 
1085*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame rst(
1086*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
1087*6777b538SAndroid Build Coastguard Worker   AddWrite(rst);
1088*6777b538SAndroid Build Coastguard Worker 
1089*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
1090*6777b538SAndroid Build Coastguard Worker 
1091*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
1092*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
1093*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
1094*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
1095*6777b538SAndroid Build Coastguard Worker 
1096*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
1097*6777b538SAndroid Build Coastguard Worker 
1098*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1099*6777b538SAndroid Build Coastguard Worker 
1100*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1101*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1102*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
1103*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
1104*6777b538SAndroid Build Coastguard Worker 
1105*6777b538SAndroid Build Coastguard Worker   StreamDelegateDoNothing delegate(stream);
1106*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
1107*6777b538SAndroid Build Coastguard Worker 
1108*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
1109*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
1110*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1111*6777b538SAndroid Build Coastguard Worker                                                        NO_MORE_DATA_TO_SEND));
1112*6777b538SAndroid Build Coastguard Worker 
1113*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
1114*6777b538SAndroid Build Coastguard Worker 
1115*6777b538SAndroid Build Coastguard Worker   // Finish async network reads and writes.
1116*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1117*6777b538SAndroid Build Coastguard Worker 
1118*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
1119*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllReadDataConsumed());
1120*6777b538SAndroid Build Coastguard Worker }
1121*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,StatusCannotHaveExtraText)1122*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, StatusCannotHaveExtraText) {
1123*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(
1124*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
1125*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
1126*6777b538SAndroid Build Coastguard Worker 
1127*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers_with_status_text;
1128*6777b538SAndroid Build Coastguard Worker   headers_with_status_text[":status"] =
1129*6777b538SAndroid Build Coastguard Worker       "200 Some random extra text describing status";
1130*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
1131*6777b538SAndroid Build Coastguard Worker       1, std::move(headers_with_status_text), false));
1132*6777b538SAndroid Build Coastguard Worker   AddRead(reply);
1133*6777b538SAndroid Build Coastguard Worker 
1134*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame body(
1135*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
1136*6777b538SAndroid Build Coastguard Worker   AddRead(body);
1137*6777b538SAndroid Build Coastguard Worker 
1138*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame rst(
1139*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
1140*6777b538SAndroid Build Coastguard Worker   AddWrite(rst);
1141*6777b538SAndroid Build Coastguard Worker 
1142*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
1143*6777b538SAndroid Build Coastguard Worker 
1144*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
1145*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
1146*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
1147*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
1148*6777b538SAndroid Build Coastguard Worker 
1149*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
1150*6777b538SAndroid Build Coastguard Worker 
1151*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1152*6777b538SAndroid Build Coastguard Worker 
1153*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1154*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1155*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
1156*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
1157*6777b538SAndroid Build Coastguard Worker 
1158*6777b538SAndroid Build Coastguard Worker   StreamDelegateDoNothing delegate(stream);
1159*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
1160*6777b538SAndroid Build Coastguard Worker 
1161*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
1162*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
1163*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1164*6777b538SAndroid Build Coastguard Worker                                                        NO_MORE_DATA_TO_SEND));
1165*6777b538SAndroid Build Coastguard Worker 
1166*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
1167*6777b538SAndroid Build Coastguard Worker 
1168*6777b538SAndroid Build Coastguard Worker   // Finish async network reads and writes.
1169*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1170*6777b538SAndroid Build Coastguard Worker 
1171*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
1172*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllReadDataConsumed());
1173*6777b538SAndroid Build Coastguard Worker }
1174*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,StatusMustBePresent)1175*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, StatusMustBePresent) {
1176*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(
1177*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
1178*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
1179*6777b538SAndroid Build Coastguard Worker 
1180*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers_without_status;
1181*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
1182*6777b538SAndroid Build Coastguard Worker       1, std::move(headers_without_status), false));
1183*6777b538SAndroid Build Coastguard Worker   AddRead(reply);
1184*6777b538SAndroid Build Coastguard Worker 
1185*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame body(
1186*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
1187*6777b538SAndroid Build Coastguard Worker   AddRead(body);
1188*6777b538SAndroid Build Coastguard Worker 
1189*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame rst(
1190*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
1191*6777b538SAndroid Build Coastguard Worker   AddWrite(rst);
1192*6777b538SAndroid Build Coastguard Worker 
1193*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
1194*6777b538SAndroid Build Coastguard Worker 
1195*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
1196*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
1197*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
1198*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
1199*6777b538SAndroid Build Coastguard Worker 
1200*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
1201*6777b538SAndroid Build Coastguard Worker 
1202*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1203*6777b538SAndroid Build Coastguard Worker 
1204*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1205*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1206*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
1207*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
1208*6777b538SAndroid Build Coastguard Worker 
1209*6777b538SAndroid Build Coastguard Worker   StreamDelegateDoNothing delegate(stream);
1210*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
1211*6777b538SAndroid Build Coastguard Worker 
1212*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
1213*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
1214*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1215*6777b538SAndroid Build Coastguard Worker                                                        NO_MORE_DATA_TO_SEND));
1216*6777b538SAndroid Build Coastguard Worker 
1217*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
1218*6777b538SAndroid Build Coastguard Worker 
1219*6777b538SAndroid Build Coastguard Worker   // Finish async network reads and writes.
1220*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1221*6777b538SAndroid Build Coastguard Worker 
1222*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
1223*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllReadDataConsumed());
1224*6777b538SAndroid Build Coastguard Worker }
1225*6777b538SAndroid Build Coastguard Worker 
1226*6777b538SAndroid Build Coastguard Worker // Call IncreaseSendWindowSize on a stream with a large enough delta to overflow
1227*6777b538SAndroid Build Coastguard Worker // an int32_t. The SpdyStream should handle that case gracefully.
TEST_F(SpdyStreamTest,IncreaseSendWindowSizeOverflow)1228*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, IncreaseSendWindowSizeOverflow) {
1229*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
1230*6777b538SAndroid Build Coastguard Worker       kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
1231*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
1232*6777b538SAndroid Build Coastguard Worker 
1233*6777b538SAndroid Build Coastguard Worker   AddReadPause();
1234*6777b538SAndroid Build Coastguard Worker 
1235*6777b538SAndroid Build Coastguard Worker   // Triggered by the overflowing call to IncreaseSendWindowSize
1236*6777b538SAndroid Build Coastguard Worker   // below.
1237*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
1238*6777b538SAndroid Build Coastguard Worker       1, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
1239*6777b538SAndroid Build Coastguard Worker   AddWrite(rst);
1240*6777b538SAndroid Build Coastguard Worker 
1241*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
1242*6777b538SAndroid Build Coastguard Worker 
1243*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
1244*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
1245*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
1246*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
1247*6777b538SAndroid Build Coastguard Worker 
1248*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
1249*6777b538SAndroid Build Coastguard Worker 
1250*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1251*6777b538SAndroid Build Coastguard Worker 
1252*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1253*6777b538SAndroid Build Coastguard Worker       SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST,
1254*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE));
1255*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
1256*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
1257*6777b538SAndroid Build Coastguard Worker 
1258*6777b538SAndroid Build Coastguard Worker   StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
1259*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
1260*6777b538SAndroid Build Coastguard Worker 
1261*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
1262*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1263*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1264*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
1265*6777b538SAndroid Build Coastguard Worker 
1266*6777b538SAndroid Build Coastguard Worker   data.RunUntilPaused();
1267*6777b538SAndroid Build Coastguard Worker 
1268*6777b538SAndroid Build Coastguard Worker   int32_t old_send_window_size = stream->send_window_size();
1269*6777b538SAndroid Build Coastguard Worker   ASSERT_GT(old_send_window_size, 0);
1270*6777b538SAndroid Build Coastguard Worker   int32_t delta_window_size =
1271*6777b538SAndroid Build Coastguard Worker       std::numeric_limits<int32_t>::max() - old_send_window_size + 1;
1272*6777b538SAndroid Build Coastguard Worker   stream->IncreaseSendWindowSize(delta_window_size);
1273*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(stream);
1274*6777b538SAndroid Build Coastguard Worker 
1275*6777b538SAndroid Build Coastguard Worker   data.Resume();
1276*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1277*6777b538SAndroid Build Coastguard Worker 
1278*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_FLOW_CONTROL_ERROR));
1279*6777b538SAndroid Build Coastguard Worker }
1280*6777b538SAndroid Build Coastguard Worker 
1281*6777b538SAndroid Build Coastguard Worker // Functions used with
1282*6777b538SAndroid Build Coastguard Worker // RunResumeAfterUnstall{RequestResponse,Bidirectional}Test().
1283*6777b538SAndroid Build Coastguard Worker 
StallStream(const base::WeakPtr<SpdyStream> & stream)1284*6777b538SAndroid Build Coastguard Worker void StallStream(const base::WeakPtr<SpdyStream>& stream) {
1285*6777b538SAndroid Build Coastguard Worker   // Reduce the send window size to 0 to stall.
1286*6777b538SAndroid Build Coastguard Worker   while (stream->send_window_size() > 0) {
1287*6777b538SAndroid Build Coastguard Worker     stream->DecreaseSendWindowSize(
1288*6777b538SAndroid Build Coastguard Worker         std::min(kMaxSpdyFrameChunkSize, stream->send_window_size()));
1289*6777b538SAndroid Build Coastguard Worker   }
1290*6777b538SAndroid Build Coastguard Worker }
1291*6777b538SAndroid Build Coastguard Worker 
IncreaseStreamSendWindowSize(const base::WeakPtr<SpdyStream> & stream,int32_t delta_window_size)1292*6777b538SAndroid Build Coastguard Worker void IncreaseStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream,
1293*6777b538SAndroid Build Coastguard Worker                                   int32_t delta_window_size) {
1294*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stream->send_stalled_by_flow_control());
1295*6777b538SAndroid Build Coastguard Worker   stream->IncreaseSendWindowSize(delta_window_size);
1296*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(stream->send_stalled_by_flow_control());
1297*6777b538SAndroid Build Coastguard Worker }
1298*6777b538SAndroid Build Coastguard Worker 
AdjustStreamSendWindowSize(const base::WeakPtr<SpdyStream> & stream,int32_t delta_window_size)1299*6777b538SAndroid Build Coastguard Worker void AdjustStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream,
1300*6777b538SAndroid Build Coastguard Worker                                 int32_t delta_window_size) {
1301*6777b538SAndroid Build Coastguard Worker   // Make sure that negative adjustments are handled properly.
1302*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stream->send_stalled_by_flow_control());
1303*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stream->AdjustSendWindowSize(-delta_window_size));
1304*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stream->send_stalled_by_flow_control());
1305*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stream->AdjustSendWindowSize(+delta_window_size));
1306*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stream->send_stalled_by_flow_control());
1307*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stream->AdjustSendWindowSize(+delta_window_size));
1308*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(stream->send_stalled_by_flow_control());
1309*6777b538SAndroid Build Coastguard Worker }
1310*6777b538SAndroid Build Coastguard Worker 
1311*6777b538SAndroid Build Coastguard Worker // Given an unstall function, runs a test to make sure that a
1312*6777b538SAndroid Build Coastguard Worker // request/response (i.e., an HTTP-like) stream resumes after a stall
1313*6777b538SAndroid Build Coastguard Worker // and unstall.
RunResumeAfterUnstallRequestResponseTest(UnstallFunction unstall_function)1314*6777b538SAndroid Build Coastguard Worker void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest(
1315*6777b538SAndroid Build Coastguard Worker     UnstallFunction unstall_function) {
1316*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
1317*6777b538SAndroid Build Coastguard Worker       kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
1318*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
1319*6777b538SAndroid Build Coastguard Worker 
1320*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame body(
1321*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
1322*6777b538SAndroid Build Coastguard Worker   AddWrite(body);
1323*6777b538SAndroid Build Coastguard Worker 
1324*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame resp(
1325*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1326*6777b538SAndroid Build Coastguard Worker   AddRead(resp);
1327*6777b538SAndroid Build Coastguard Worker 
1328*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
1329*6777b538SAndroid Build Coastguard Worker 
1330*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
1331*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
1332*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
1333*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
1334*6777b538SAndroid Build Coastguard Worker 
1335*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
1336*6777b538SAndroid Build Coastguard Worker 
1337*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1338*6777b538SAndroid Build Coastguard Worker 
1339*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1340*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1341*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
1342*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
1343*6777b538SAndroid Build Coastguard Worker 
1344*6777b538SAndroid Build Coastguard Worker   StreamDelegateWithBody delegate(stream, kPostBodyStringPiece);
1345*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
1346*6777b538SAndroid Build Coastguard Worker 
1347*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(stream->send_stalled_by_flow_control());
1348*6777b538SAndroid Build Coastguard Worker 
1349*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
1350*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1351*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1352*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
1353*6777b538SAndroid Build Coastguard Worker 
1354*6777b538SAndroid Build Coastguard Worker   StallStream(stream);
1355*6777b538SAndroid Build Coastguard Worker 
1356*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1357*6777b538SAndroid Build Coastguard Worker 
1358*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stream->send_stalled_by_flow_control());
1359*6777b538SAndroid Build Coastguard Worker 
1360*6777b538SAndroid Build Coastguard Worker   std::move(unstall_function).Run(stream, kPostBodyLength);
1361*6777b538SAndroid Build Coastguard Worker 
1362*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(stream->send_stalled_by_flow_control());
1363*6777b538SAndroid Build Coastguard Worker 
1364*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
1365*6777b538SAndroid Build Coastguard Worker 
1366*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(delegate.send_headers_completed());
1367*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
1368*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(), delegate.TakeReceivedData());
1369*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
1370*6777b538SAndroid Build Coastguard Worker }
1371*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,ResumeAfterSendWindowSizeIncreaseRequestResponse)1372*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseRequestResponse) {
1373*6777b538SAndroid Build Coastguard Worker   RunResumeAfterUnstallRequestResponseTest(
1374*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&IncreaseStreamSendWindowSize));
1375*6777b538SAndroid Build Coastguard Worker }
1376*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,ResumeAfterSendWindowSizeAdjustRequestResponse)1377*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustRequestResponse) {
1378*6777b538SAndroid Build Coastguard Worker   RunResumeAfterUnstallRequestResponseTest(
1379*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&AdjustStreamSendWindowSize));
1380*6777b538SAndroid Build Coastguard Worker }
1381*6777b538SAndroid Build Coastguard Worker 
1382*6777b538SAndroid Build Coastguard Worker // Given an unstall function, runs a test to make sure that a bidirectional
1383*6777b538SAndroid Build Coastguard Worker // (i.e., non-HTTP-like) stream resumes after a stall and unstall.
RunResumeAfterUnstallBidirectionalTest(UnstallFunction unstall_function)1384*6777b538SAndroid Build Coastguard Worker void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest(
1385*6777b538SAndroid Build Coastguard Worker     UnstallFunction unstall_function) {
1386*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
1387*6777b538SAndroid Build Coastguard Worker       kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
1388*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
1389*6777b538SAndroid Build Coastguard Worker 
1390*6777b538SAndroid Build Coastguard Worker   AddReadPause();
1391*6777b538SAndroid Build Coastguard Worker 
1392*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame resp(
1393*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1394*6777b538SAndroid Build Coastguard Worker   AddRead(resp);
1395*6777b538SAndroid Build Coastguard Worker 
1396*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame msg(
1397*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
1398*6777b538SAndroid Build Coastguard Worker   AddWrite(msg);
1399*6777b538SAndroid Build Coastguard Worker 
1400*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame echo(
1401*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
1402*6777b538SAndroid Build Coastguard Worker   AddRead(echo);
1403*6777b538SAndroid Build Coastguard Worker 
1404*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
1405*6777b538SAndroid Build Coastguard Worker 
1406*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
1407*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
1408*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
1409*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
1410*6777b538SAndroid Build Coastguard Worker 
1411*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
1412*6777b538SAndroid Build Coastguard Worker 
1413*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1414*6777b538SAndroid Build Coastguard Worker 
1415*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1416*6777b538SAndroid Build Coastguard Worker       SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
1417*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
1418*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
1419*6777b538SAndroid Build Coastguard Worker 
1420*6777b538SAndroid Build Coastguard Worker   StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
1421*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
1422*6777b538SAndroid Build Coastguard Worker 
1423*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
1424*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1425*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1426*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
1427*6777b538SAndroid Build Coastguard Worker 
1428*6777b538SAndroid Build Coastguard Worker   data.RunUntilPaused();
1429*6777b538SAndroid Build Coastguard Worker 
1430*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(stream->send_stalled_by_flow_control());
1431*6777b538SAndroid Build Coastguard Worker 
1432*6777b538SAndroid Build Coastguard Worker   StallStream(stream);
1433*6777b538SAndroid Build Coastguard Worker 
1434*6777b538SAndroid Build Coastguard Worker   data.Resume();
1435*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1436*6777b538SAndroid Build Coastguard Worker 
1437*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stream->send_stalled_by_flow_control());
1438*6777b538SAndroid Build Coastguard Worker 
1439*6777b538SAndroid Build Coastguard Worker   std::move(unstall_function).Run(stream, kPostBodyLength);
1440*6777b538SAndroid Build Coastguard Worker 
1441*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(stream->send_stalled_by_flow_control());
1442*6777b538SAndroid Build Coastguard Worker 
1443*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
1444*6777b538SAndroid Build Coastguard Worker 
1445*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(delegate.send_headers_completed());
1446*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
1447*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
1448*6777b538SAndroid Build Coastguard Worker             delegate.TakeReceivedData());
1449*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
1450*6777b538SAndroid Build Coastguard Worker }
1451*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,ResumeAfterSendWindowSizeIncreaseBidirectional)1452*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseBidirectional) {
1453*6777b538SAndroid Build Coastguard Worker   RunResumeAfterUnstallBidirectionalTest(
1454*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&IncreaseStreamSendWindowSize));
1455*6777b538SAndroid Build Coastguard Worker }
1456*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,ResumeAfterSendWindowSizeAdjustBidirectional)1457*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustBidirectional) {
1458*6777b538SAndroid Build Coastguard Worker   RunResumeAfterUnstallBidirectionalTest(
1459*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&AdjustStreamSendWindowSize));
1460*6777b538SAndroid Build Coastguard Worker }
1461*6777b538SAndroid Build Coastguard Worker 
1462*6777b538SAndroid Build Coastguard Worker // Test calculation of amount of bytes received from network.
TEST_F(SpdyStreamTest,ReceivedBytes)1463*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, ReceivedBytes) {
1464*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(
1465*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
1466*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
1467*6777b538SAndroid Build Coastguard Worker 
1468*6777b538SAndroid Build Coastguard Worker   AddReadPause();
1469*6777b538SAndroid Build Coastguard Worker 
1470*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame reply(
1471*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1472*6777b538SAndroid Build Coastguard Worker   AddRead(reply);
1473*6777b538SAndroid Build Coastguard Worker 
1474*6777b538SAndroid Build Coastguard Worker   AddReadPause();
1475*6777b538SAndroid Build Coastguard Worker 
1476*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame msg(
1477*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
1478*6777b538SAndroid Build Coastguard Worker   AddRead(msg);
1479*6777b538SAndroid Build Coastguard Worker 
1480*6777b538SAndroid Build Coastguard Worker   AddReadPause();
1481*6777b538SAndroid Build Coastguard Worker 
1482*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
1483*6777b538SAndroid Build Coastguard Worker 
1484*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
1485*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
1486*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
1487*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
1488*6777b538SAndroid Build Coastguard Worker 
1489*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
1490*6777b538SAndroid Build Coastguard Worker 
1491*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1492*6777b538SAndroid Build Coastguard Worker 
1493*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1494*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1495*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
1496*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
1497*6777b538SAndroid Build Coastguard Worker 
1498*6777b538SAndroid Build Coastguard Worker   StreamDelegateDoNothing delegate(stream);
1499*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
1500*6777b538SAndroid Build Coastguard Worker 
1501*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
1502*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
1503*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
1504*6777b538SAndroid Build Coastguard Worker       stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
1505*6777b538SAndroid Build Coastguard Worker       IsError(ERR_IO_PENDING));
1506*6777b538SAndroid Build Coastguard Worker 
1507*6777b538SAndroid Build Coastguard Worker   int64_t reply_frame_len = reply.size();
1508*6777b538SAndroid Build Coastguard Worker   int64_t data_header_len = spdy::kDataFrameMinimumSize;
1509*6777b538SAndroid Build Coastguard Worker   int64_t data_frame_len = data_header_len + kPostBodyLength;
1510*6777b538SAndroid Build Coastguard Worker   int64_t response_len = reply_frame_len + data_frame_len;
1511*6777b538SAndroid Build Coastguard Worker 
1512*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, stream->raw_received_bytes());
1513*6777b538SAndroid Build Coastguard Worker 
1514*6777b538SAndroid Build Coastguard Worker   // REQUEST
1515*6777b538SAndroid Build Coastguard Worker   data.RunUntilPaused();
1516*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, stream->raw_received_bytes());
1517*6777b538SAndroid Build Coastguard Worker 
1518*6777b538SAndroid Build Coastguard Worker   // REPLY
1519*6777b538SAndroid Build Coastguard Worker   data.Resume();
1520*6777b538SAndroid Build Coastguard Worker   data.RunUntilPaused();
1521*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(reply_frame_len, stream->raw_received_bytes());
1522*6777b538SAndroid Build Coastguard Worker 
1523*6777b538SAndroid Build Coastguard Worker   // DATA
1524*6777b538SAndroid Build Coastguard Worker   data.Resume();
1525*6777b538SAndroid Build Coastguard Worker   data.RunUntilPaused();
1526*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(response_len, stream->raw_received_bytes());
1527*6777b538SAndroid Build Coastguard Worker 
1528*6777b538SAndroid Build Coastguard Worker   // FIN
1529*6777b538SAndroid Build Coastguard Worker   data.Resume();
1530*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
1531*6777b538SAndroid Build Coastguard Worker }
1532*6777b538SAndroid Build Coastguard Worker 
1533*6777b538SAndroid Build Coastguard Worker // Regression test for https://crbug.com/810763.
TEST_F(SpdyStreamTest,DataOnHalfClosedRemoveStream)1534*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, DataOnHalfClosedRemoveStream) {
1535*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
1536*6777b538SAndroid Build Coastguard Worker       kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
1537*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
1538*6777b538SAndroid Build Coastguard Worker 
1539*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock response_headers;
1540*6777b538SAndroid Build Coastguard Worker   response_headers[spdy::kHttp2StatusHeader] = "200";
1541*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
1542*6777b538SAndroid Build Coastguard Worker       1, std::move(response_headers), /* fin = */ true));
1543*6777b538SAndroid Build Coastguard Worker   AddRead(resp);
1544*6777b538SAndroid Build Coastguard Worker 
1545*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame data_frame(
1546*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
1547*6777b538SAndroid Build Coastguard Worker   AddRead(data_frame);
1548*6777b538SAndroid Build Coastguard Worker 
1549*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame rst(
1550*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_STREAM_CLOSED));
1551*6777b538SAndroid Build Coastguard Worker   AddWrite(rst);
1552*6777b538SAndroid Build Coastguard Worker 
1553*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
1554*6777b538SAndroid Build Coastguard Worker 
1555*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
1556*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
1557*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
1558*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
1559*6777b538SAndroid Build Coastguard Worker 
1560*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
1561*6777b538SAndroid Build Coastguard Worker 
1562*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1563*6777b538SAndroid Build Coastguard Worker 
1564*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1565*6777b538SAndroid Build Coastguard Worker       SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
1566*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
1567*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
1568*6777b538SAndroid Build Coastguard Worker 
1569*6777b538SAndroid Build Coastguard Worker   StreamDelegateDoNothing delegate(stream);
1570*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
1571*6777b538SAndroid Build Coastguard Worker 
1572*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
1573*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1574*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1575*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
1576*6777b538SAndroid Build Coastguard Worker 
1577*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_STREAM_CLOSED));
1578*6777b538SAndroid Build Coastguard Worker 
1579*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1580*6777b538SAndroid Build Coastguard Worker 
1581*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllReadDataConsumed());
1582*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
1583*6777b538SAndroid Build Coastguard Worker }
1584*6777b538SAndroid Build Coastguard Worker 
TEST_F(SpdyStreamTest,DelegateIsInformedOfEOF)1585*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTest, DelegateIsInformedOfEOF) {
1586*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
1587*6777b538SAndroid Build Coastguard Worker       kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
1588*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
1589*6777b538SAndroid Build Coastguard Worker 
1590*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock response_headers;
1591*6777b538SAndroid Build Coastguard Worker   response_headers[spdy::kHttp2StatusHeader] = "200";
1592*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
1593*6777b538SAndroid Build Coastguard Worker       1, std::move(response_headers), /* fin = */ true));
1594*6777b538SAndroid Build Coastguard Worker   AddRead(resp);
1595*6777b538SAndroid Build Coastguard Worker 
1596*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame data_frame(
1597*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
1598*6777b538SAndroid Build Coastguard Worker   AddRead(data_frame);
1599*6777b538SAndroid Build Coastguard Worker 
1600*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame rst(
1601*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_STREAM_CLOSED));
1602*6777b538SAndroid Build Coastguard Worker   AddWrite(rst);
1603*6777b538SAndroid Build Coastguard Worker 
1604*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
1605*6777b538SAndroid Build Coastguard Worker 
1606*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
1607*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
1608*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
1609*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
1610*6777b538SAndroid Build Coastguard Worker 
1611*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
1612*6777b538SAndroid Build Coastguard Worker 
1613*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1614*6777b538SAndroid Build Coastguard Worker 
1615*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1616*6777b538SAndroid Build Coastguard Worker       SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
1617*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
1618*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
1619*6777b538SAndroid Build Coastguard Worker 
1620*6777b538SAndroid Build Coastguard Worker   StreamDelegateDetectEOF delegate(stream);
1621*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
1622*6777b538SAndroid Build Coastguard Worker 
1623*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
1624*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1625*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1626*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
1627*6777b538SAndroid Build Coastguard Worker 
1628*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1629*6777b538SAndroid Build Coastguard Worker 
1630*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(delegate.eof_detected());
1631*6777b538SAndroid Build Coastguard Worker 
1632*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllReadDataConsumed());
1633*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data.AllWriteDataConsumed());
1634*6777b538SAndroid Build Coastguard Worker }
1635*6777b538SAndroid Build Coastguard Worker 
1636*6777b538SAndroid Build Coastguard Worker // A small read should trigger sending a receive window update and dropping the
1637*6777b538SAndroid Build Coastguard Worker // count of unacknowledged bytes to zero only after
1638*6777b538SAndroid Build Coastguard Worker // kDefaultTimeToBufferSmallWindowUpdates time has passed.
TEST_F(SpdyStreamTestWithMockClock,FlowControlSlowReads)1639*6777b538SAndroid Build Coastguard Worker TEST_F(SpdyStreamTestWithMockClock, FlowControlSlowReads) {
1640*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame req(
1641*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
1642*6777b538SAndroid Build Coastguard Worker   AddWrite(req);
1643*6777b538SAndroid Build Coastguard Worker 
1644*6777b538SAndroid Build Coastguard Worker   AddReadPause();
1645*6777b538SAndroid Build Coastguard Worker 
1646*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame reply(
1647*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1648*6777b538SAndroid Build Coastguard Worker   AddRead(reply);
1649*6777b538SAndroid Build Coastguard Worker 
1650*6777b538SAndroid Build Coastguard Worker   AddReadPause();
1651*6777b538SAndroid Build Coastguard Worker 
1652*6777b538SAndroid Build Coastguard Worker   spdy::SpdySerializedFrame msg(
1653*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
1654*6777b538SAndroid Build Coastguard Worker   AddRead(msg);
1655*6777b538SAndroid Build Coastguard Worker 
1656*6777b538SAndroid Build Coastguard Worker   AddReadPause();
1657*6777b538SAndroid Build Coastguard Worker 
1658*6777b538SAndroid Build Coastguard Worker   AddReadEOF();
1659*6777b538SAndroid Build Coastguard Worker 
1660*6777b538SAndroid Build Coastguard Worker   SequencedSocketData data(GetReads(), GetWrites());
1661*6777b538SAndroid Build Coastguard Worker   MockConnect connect_data(SYNCHRONOUS, OK);
1662*6777b538SAndroid Build Coastguard Worker   data.set_connect_data(connect_data);
1663*6777b538SAndroid Build Coastguard Worker   session_deps_.socket_factory->AddSocketDataProvider(&data);
1664*6777b538SAndroid Build Coastguard Worker 
1665*6777b538SAndroid Build Coastguard Worker   AddSSLSocketData();
1666*6777b538SAndroid Build Coastguard Worker 
1667*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1668*6777b538SAndroid Build Coastguard Worker   session->SetTimeToBufferSmallWindowUpdates(
1669*6777b538SAndroid Build Coastguard Worker       kDefaultTimeToBufferSmallWindowUpdates);
1670*6777b538SAndroid Build Coastguard Worker 
1671*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1672*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1673*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(stream);
1674*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDefaultUrl, stream->url().spec());
1675*6777b538SAndroid Build Coastguard Worker 
1676*6777b538SAndroid Build Coastguard Worker   StreamDelegateConsumeData delegate(stream);
1677*6777b538SAndroid Build Coastguard Worker   stream->SetDelegate(&delegate);
1678*6777b538SAndroid Build Coastguard Worker 
1679*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, unacked_recv_window_bytes(stream));
1680*6777b538SAndroid Build Coastguard Worker 
1681*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers(
1682*6777b538SAndroid Build Coastguard Worker       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
1683*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
1684*6777b538SAndroid Build Coastguard Worker       stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
1685*6777b538SAndroid Build Coastguard Worker       IsError(ERR_IO_PENDING));
1686*6777b538SAndroid Build Coastguard Worker 
1687*6777b538SAndroid Build Coastguard Worker   // REQUEST
1688*6777b538SAndroid Build Coastguard Worker   data.RunUntilPaused();
1689*6777b538SAndroid Build Coastguard Worker 
1690*6777b538SAndroid Build Coastguard Worker   // REPLY
1691*6777b538SAndroid Build Coastguard Worker   data.Resume();
1692*6777b538SAndroid Build Coastguard Worker   data.RunUntilPaused();
1693*6777b538SAndroid Build Coastguard Worker 
1694*6777b538SAndroid Build Coastguard Worker   // Delay long enough for the receive window to send an update on read,
1695*6777b538SAndroid Build Coastguard Worker   // draining the unacked_recv_window_bytes back to zero.
1696*6777b538SAndroid Build Coastguard Worker   AdvanceClock(kDefaultTimeToBufferSmallWindowUpdates);
1697*6777b538SAndroid Build Coastguard Worker 
1698*6777b538SAndroid Build Coastguard Worker   // DATA
1699*6777b538SAndroid Build Coastguard Worker   data.Resume();
1700*6777b538SAndroid Build Coastguard Worker   data.RunUntilPaused();
1701*6777b538SAndroid Build Coastguard Worker 
1702*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, unacked_recv_window_bytes(stream));
1703*6777b538SAndroid Build Coastguard Worker 
1704*6777b538SAndroid Build Coastguard Worker   // FIN
1705*6777b538SAndroid Build Coastguard Worker   data.Resume();
1706*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
1707*6777b538SAndroid Build Coastguard Worker }
1708*6777b538SAndroid Build Coastguard Worker 
1709*6777b538SAndroid Build Coastguard Worker }  // namespace net::test
1710