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