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