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