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