blob: eb9a0b3dbb2397c5d7c3dbbda3e5788647b45778 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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/third_party/quiche/src/quic/core/http/quic_spdy_stream.h"
6
7#include <memory>
vasilvv872e7a32019-03-12 16:42:44 -07008#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -05009#include <utility>
10
11#include "net/third_party/quiche/src/quic/core/http/http_encoder.h"
12#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
13#include "net/third_party/quiche/src/quic/core/quic_connection.h"
14#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h"
15#include "net/third_party/quiche/src/quic/core/quic_utils.h"
16#include "net/third_party/quiche/src/quic/core/quic_versions.h"
17#include "net/third_party/quiche/src/quic/core/quic_write_blocked_list.h"
18#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
19#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
20#include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h"
21#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050022#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
23#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
24#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
25#include "net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h"
26#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
27#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
28#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h"
29#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
30#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
31
32using spdy::kV3HighestPriority;
33using spdy::kV3LowestPriority;
34using spdy::SpdyHeaderBlock;
35using spdy::SpdyPriority;
36using testing::_;
37using testing::AtLeast;
38using testing::Invoke;
39using testing::Return;
40using testing::StrictMock;
41
42namespace quic {
43namespace test {
44namespace {
45
46const bool kShouldProcessData = true;
47
48class TestStream : public QuicSpdyStream {
49 public:
50 TestStream(QuicStreamId id,
51 QuicSpdySession* session,
52 bool should_process_data)
53 : QuicSpdyStream(id, session, BIDIRECTIONAL),
54 should_process_data_(should_process_data) {}
55 ~TestStream() override = default;
56
57 using QuicSpdyStream::set_ack_listener;
58 using QuicStream::CloseWriteSide;
59 using QuicStream::WriteOrBufferData;
60
61 void OnBodyAvailable() override {
62 if (!should_process_data_) {
63 return;
64 }
65 char buffer[2048];
66 struct iovec vec;
67 vec.iov_base = buffer;
68 vec.iov_len = QUIC_ARRAYSIZE(buffer);
69 size_t bytes_read = Readv(&vec, 1);
vasilvvc48c8712019-03-11 13:38:16 -070070 data_ += std::string(buffer, bytes_read);
QUICHE teama6ef0a62019-03-07 20:34:33 -050071 }
72
73 MOCK_METHOD1(WriteHeadersMock, void(bool fin));
74
75 size_t WriteHeadersImpl(spdy::SpdyHeaderBlock header_block,
76 bool fin,
77 QuicReferenceCountedPointer<QuicAckListenerInterface>
78 ack_listener) override {
79 saved_headers_ = std::move(header_block);
80 WriteHeadersMock(fin);
renjietang2abedac2019-05-20 14:04:50 -070081 if (VersionUsesQpack(transport_version())) {
82 // In this case, call QuicSpdyStream::WriteHeadersImpl() that does the
83 // actual work of closing the stream.
84 QuicSpdyStream::WriteHeadersImpl(saved_headers_.Clone(), fin, nullptr);
85 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050086 return 0;
87 }
88
vasilvvc48c8712019-03-11 13:38:16 -070089 const std::string& data() const { return data_; }
QUICHE teama6ef0a62019-03-07 20:34:33 -050090 const spdy::SpdyHeaderBlock& saved_headers() const { return saved_headers_; }
91
92 private:
93 bool should_process_data_;
94 spdy::SpdyHeaderBlock saved_headers_;
vasilvvc48c8712019-03-11 13:38:16 -070095 std::string data_;
QUICHE teama6ef0a62019-03-07 20:34:33 -050096};
97
98class TestMockUpdateStreamSession : public MockQuicSpdySession {
99 public:
100 explicit TestMockUpdateStreamSession(QuicConnection* connection)
101 : MockQuicSpdySession(connection) {}
102
103 void UpdateStreamPriority(QuicStreamId id, SpdyPriority priority) override {
104 EXPECT_EQ(id, expected_stream_->id());
105 EXPECT_EQ(expected_priority_, priority);
106 EXPECT_EQ(expected_priority_, expected_stream_->priority());
107 }
108
109 void SetExpectedStream(QuicSpdyStream* stream) { expected_stream_ = stream; }
110 void SetExpectedPriority(SpdyPriority priority) {
111 expected_priority_ = priority;
112 }
113
114 private:
115 QuicSpdyStream* expected_stream_;
116 SpdyPriority expected_priority_;
117};
118
119class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
120 public:
121 QuicSpdyStreamTest() {
122 headers_[":host"] = "www.google.com";
123 headers_[":path"] = "/index.hml";
124 headers_[":scheme"] = "https";
125 headers_["cookie"] =
126 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
127 "__utmc=160408618; "
128 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
129 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
130 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
131 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
132 "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
133 "1zFMi5vzcns38-8_Sns; "
134 "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
135 "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
136 "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
137 "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
138 "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
139 "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
140 "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
141 "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
142 "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
143 "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
144 "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
145 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
146 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
147 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
148 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
149 }
150
151 void Initialize(bool stream_should_process_data) {
152 connection_ = new StrictMock<MockQuicConnection>(
153 &helper_, &alarm_factory_, Perspective::IS_SERVER,
154 SupportedVersions(GetParam()));
155 session_ = QuicMakeUnique<StrictMock<MockQuicSpdySession>>(connection_);
156 session_->Initialize();
157 ON_CALL(*session_, WritevData(_, _, _, _, _))
158 .WillByDefault(Invoke(MockQuicSession::ConsumeData));
159
160 stream_ =
161 new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(0),
162 session_.get(), stream_should_process_data);
163 session_->ActivateStream(QuicWrapUnique(stream_));
164 stream2_ =
165 new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(1),
166 session_.get(), stream_should_process_data);
167 session_->ActivateStream(QuicWrapUnique(stream2_));
168 }
169
170 QuicHeaderList ProcessHeaders(bool fin, const SpdyHeaderBlock& headers) {
171 QuicHeaderList h = AsHeaderList(headers);
172 stream_->OnStreamHeaderList(fin, h.uncompressed_header_bytes(), h);
173 return h;
174 }
175
176 QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
177 return GetNthClientInitiatedBidirectionalStreamId(
178 connection_->transport_version(), n);
179 }
180
181 bool HasFrameHeader() const {
182 return VersionHasDataFrameHeader(connection_->transport_version());
183 }
184
185 protected:
186 MockQuicConnectionHelper helper_;
187 MockAlarmFactory alarm_factory_;
188 MockQuicConnection* connection_;
189 std::unique_ptr<MockQuicSpdySession> session_;
190
191 // Owned by the |session_|.
192 TestStream* stream_;
193 TestStream* stream2_;
194
195 SpdyHeaderBlock headers_;
196
197 HttpEncoder encoder_;
198};
199
vasilvvc48c8712019-03-11 13:38:16 -0700200INSTANTIATE_TEST_SUITE_P(Tests,
201 QuicSpdyStreamTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500202 ::testing::ValuesIn(AllSupportedVersions()));
203
204TEST_P(QuicSpdyStreamTest, ProcessHeaderList) {
205 Initialize(kShouldProcessData);
206
207 stream_->OnStreamHeadersPriority(kV3HighestPriority);
208 ProcessHeaders(false, headers_);
209 EXPECT_EQ("", stream_->data());
210 EXPECT_FALSE(stream_->header_list().empty());
211 EXPECT_FALSE(stream_->IsDoneReading());
212}
213
214TEST_P(QuicSpdyStreamTest, ProcessTooLargeHeaderList) {
215 Initialize(kShouldProcessData);
216
217 QuicHeaderList headers;
218 stream_->OnStreamHeadersPriority(kV3HighestPriority);
219
renjietang2abedac2019-05-20 14:04:50 -0700220 const bool version_uses_qpack =
221 VersionUsesQpack(connection_->transport_version());
222
223 if (version_uses_qpack) {
224 EXPECT_CALL(*connection_,
225 CloseConnection(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
226 "Too large headers received on stream 4", _));
227 } else {
228 EXPECT_CALL(*session_,
229 SendRstStream(stream_->id(), QUIC_HEADERS_TOO_LARGE, 0));
230 }
231
QUICHE teama6ef0a62019-03-07 20:34:33 -0500232 stream_->OnStreamHeaderList(false, 1 << 20, headers);
renjietang2abedac2019-05-20 14:04:50 -0700233
234 if (!version_uses_qpack) {
235 EXPECT_EQ(QUIC_HEADERS_TOO_LARGE, stream_->stream_error());
236 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500237}
238
239TEST_P(QuicSpdyStreamTest, ProcessHeaderListWithFin) {
240 Initialize(kShouldProcessData);
241
242 size_t total_bytes = 0;
243 QuicHeaderList headers;
244 for (auto p : headers_) {
245 headers.OnHeader(p.first, p.second);
246 total_bytes += p.first.size() + p.second.size();
247 }
248 stream_->OnStreamHeadersPriority(kV3HighestPriority);
249 stream_->OnStreamHeaderList(true, total_bytes, headers);
250 EXPECT_EQ("", stream_->data());
251 EXPECT_FALSE(stream_->header_list().empty());
252 EXPECT_FALSE(stream_->IsDoneReading());
253 EXPECT_TRUE(stream_->HasFinalReceivedByteOffset());
254}
255
256TEST_P(QuicSpdyStreamTest, ParseHeaderStatusCode) {
257 // A valid status code should be 3-digit integer. The first digit should be in
258 // the range of [1, 5]. All the others are invalid.
259 Initialize(kShouldProcessData);
260 int status_code = 0;
261
262 // Valid status codes.
263 headers_[":status"] = "404";
264 EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
265 EXPECT_EQ(404, status_code);
266
267 headers_[":status"] = "100";
268 EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
269 EXPECT_EQ(100, status_code);
270
271 headers_[":status"] = "599";
272 EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
273 EXPECT_EQ(599, status_code);
274
275 // Invalid status codes.
276 headers_[":status"] = "010";
277 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
278
279 headers_[":status"] = "600";
280 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
281
282 headers_[":status"] = "200 ok";
283 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
284
285 headers_[":status"] = "2000";
286 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
287
288 headers_[":status"] = "+200";
289 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
290
291 headers_[":status"] = "+20";
292 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
293
294 headers_[":status"] = "-10";
295 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
296
297 headers_[":status"] = "-100";
298 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
299
300 // Leading or trailing spaces are also invalid.
301 headers_[":status"] = " 200";
302 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
303
304 headers_[":status"] = "200 ";
305 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
306
307 headers_[":status"] = " 200 ";
308 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
309
310 headers_[":status"] = " ";
311 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
312}
313
314TEST_P(QuicSpdyStreamTest, MarkHeadersConsumed) {
315 Initialize(kShouldProcessData);
316
vasilvvc48c8712019-03-11 13:38:16 -0700317 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500318 QuicHeaderList headers = ProcessHeaders(false, headers_);
319 EXPECT_EQ(headers, stream_->header_list());
320
321 stream_->ConsumeHeaderList();
322 EXPECT_EQ(QuicHeaderList(), stream_->header_list());
323}
324
QUICHE team396d1092019-03-20 10:21:07 -0700325TEST_P(QuicSpdyStreamTest, ProcessWrongFramesOnSpdyStream) {
326 testing::InSequence s;
327 Initialize(kShouldProcessData);
328 if (!HasFrameHeader()) {
329 return;
330 }
331 connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
332 GoAwayFrame goaway;
333 goaway.stream_id = 0x1;
334 std::unique_ptr<char[]> buffer;
335 QuicByteCount header_length = encoder_.SerializeGoAwayFrame(goaway, &buffer);
336 std::string data = std::string(buffer.get(), header_length);
337
338 EXPECT_EQ("", stream_->data());
339 QuicHeaderList headers = ProcessHeaders(false, headers_);
340 EXPECT_EQ(headers, stream_->header_list());
341 stream_->ConsumeHeaderList();
342 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
343 QuicStringPiece(data));
344
345 EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_DECODER_ERROR, _, _))
346 .WillOnce(
347 (Invoke([this](QuicErrorCode error, const std::string& error_details,
348 ConnectionCloseBehavior connection_close_behavior) {
349 connection_->ReallyCloseConnection(error, error_details,
350 connection_close_behavior);
351 })));
ianswettdc1e7ab2019-05-03 16:10:44 -0700352 EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _));
QUICHE team396d1092019-03-20 10:21:07 -0700353 EXPECT_CALL(*session_, OnConnectionClosed(_, _, _))
354 .WillOnce(
355 Invoke([this](QuicErrorCode error, const std::string& error_details,
356 ConnectionCloseSource source) {
357 session_->ReallyOnConnectionClosed(error, error_details, source);
358 }));
359 EXPECT_CALL(*session_, SendRstStream(_, _, _));
360 EXPECT_CALL(*session_, SendRstStream(_, _, _));
361
362 stream_->OnStreamFrame(frame);
363}
364
QUICHE teama6ef0a62019-03-07 20:34:33 -0500365TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) {
366 Initialize(kShouldProcessData);
367
vasilvvc48c8712019-03-11 13:38:16 -0700368 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500369 std::unique_ptr<char[]> buffer;
370 QuicByteCount header_length =
371 encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700372 std::string header = std::string(buffer.get(), header_length);
373 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500374
375 EXPECT_EQ("", stream_->data());
376 QuicHeaderList headers = ProcessHeaders(false, headers_);
377 EXPECT_EQ(headers, stream_->header_list());
378 stream_->ConsumeHeaderList();
379 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
380 QuicStringPiece(data));
381 stream_->OnStreamFrame(frame);
382 EXPECT_EQ(QuicHeaderList(), stream_->header_list());
383 EXPECT_EQ(body, stream_->data());
384}
385
386TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) {
387 Initialize(kShouldProcessData);
vasilvvc48c8712019-03-11 13:38:16 -0700388 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500389 std::unique_ptr<char[]> buffer;
390 QuicByteCount header_length =
391 encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700392 std::string header = std::string(buffer.get(), header_length);
393 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500394
395 for (size_t fragment_size = 1; fragment_size < data.size(); ++fragment_size) {
396 Initialize(kShouldProcessData);
397 QuicHeaderList headers = ProcessHeaders(false, headers_);
398 ASSERT_EQ(headers, stream_->header_list());
399 stream_->ConsumeHeaderList();
400 for (size_t offset = 0; offset < data.size(); offset += fragment_size) {
401 size_t remaining_data = data.size() - offset;
402 QuicStringPiece fragment(data.data() + offset,
403 std::min(fragment_size, remaining_data));
404 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false,
405 offset, QuicStringPiece(fragment));
406 stream_->OnStreamFrame(frame);
407 }
408 ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size;
409 }
410}
411
412TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
413 Initialize(kShouldProcessData);
vasilvvc48c8712019-03-11 13:38:16 -0700414 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500415 std::unique_ptr<char[]> buffer;
416 QuicByteCount header_length =
417 encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700418 std::string header = std::string(buffer.get(), header_length);
419 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500420
421 for (size_t split_point = 1; split_point < data.size() - 1; ++split_point) {
422 Initialize(kShouldProcessData);
423 QuicHeaderList headers = ProcessHeaders(false, headers_);
424 ASSERT_EQ(headers, stream_->header_list());
425 stream_->ConsumeHeaderList();
426
427 QuicStringPiece fragment1(data.data(), split_point);
428 QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
429 QuicStringPiece(fragment1));
430 stream_->OnStreamFrame(frame1);
431
432 QuicStringPiece fragment2(data.data() + split_point,
433 data.size() - split_point);
434 QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
435 split_point, QuicStringPiece(fragment2));
436 stream_->OnStreamFrame(frame2);
437
438 ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point;
439 }
440}
441
442TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) {
443 Initialize(!kShouldProcessData);
444
vasilvvc48c8712019-03-11 13:38:16 -0700445 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500446 std::unique_ptr<char[]> buf;
447 QuicByteCount header_length =
448 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700449 std::string header = std::string(buf.get(), header_length);
450 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500451
452 ProcessHeaders(false, headers_);
453 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
454 QuicStringPiece(data));
455 stream_->OnStreamFrame(frame);
456 stream_->ConsumeHeaderList();
457
458 char buffer[2048];
459 ASSERT_LT(data.length(), QUIC_ARRAYSIZE(buffer));
460 struct iovec vec;
461 vec.iov_base = buffer;
462 vec.iov_len = QUIC_ARRAYSIZE(buffer);
463
464 size_t bytes_read = stream_->Readv(&vec, 1);
QUICHE team396d1092019-03-20 10:21:07 -0700465 QuicStreamPeer::CloseReadSide(stream_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500466 EXPECT_EQ(body.length(), bytes_read);
vasilvvc48c8712019-03-11 13:38:16 -0700467 EXPECT_EQ(body, std::string(buffer, bytes_read));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500468}
469
470TEST_P(QuicSpdyStreamTest, ProcessHeadersAndLargeBodySmallReadv) {
471 Initialize(kShouldProcessData);
vasilvvc48c8712019-03-11 13:38:16 -0700472 std::string body(12 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500473 std::unique_ptr<char[]> buf;
474 QuicByteCount header_length =
475 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700476 std::string header = std::string(buf.get(), header_length);
477 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500478 ProcessHeaders(false, headers_);
479 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
480 QuicStringPiece(data));
481 stream_->OnStreamFrame(frame);
482 stream_->ConsumeHeaderList();
483 char buffer[2048];
484 char buffer2[2048];
485 struct iovec vec[2];
486 vec[0].iov_base = buffer;
487 vec[0].iov_len = QUIC_ARRAYSIZE(buffer);
488 vec[1].iov_base = buffer2;
489 vec[1].iov_len = QUIC_ARRAYSIZE(buffer2);
490 size_t bytes_read = stream_->Readv(vec, 2);
491 EXPECT_EQ(2048u * 2, bytes_read);
vasilvvc48c8712019-03-11 13:38:16 -0700492 EXPECT_EQ(body.substr(0, 2048), std::string(buffer, 2048));
493 EXPECT_EQ(body.substr(2048, 2048), std::string(buffer2, 2048));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500494}
495
496TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) {
497 Initialize(!kShouldProcessData);
498
vasilvvc48c8712019-03-11 13:38:16 -0700499 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500500 std::unique_ptr<char[]> buf;
501 QuicByteCount header_length =
502 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700503 std::string header = std::string(buf.get(), header_length);
504 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500505
506 ProcessHeaders(false, headers_);
507 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
508 QuicStringPiece(data));
509 stream_->OnStreamFrame(frame);
510 stream_->ConsumeHeaderList();
511
512 struct iovec vec;
513
514 EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1));
515 EXPECT_EQ(body.length(), vec.iov_len);
vasilvvc48c8712019-03-11 13:38:16 -0700516 EXPECT_EQ(body, std::string(static_cast<char*>(vec.iov_base), vec.iov_len));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500517
518 stream_->MarkConsumed(body.length());
519 EXPECT_EQ(data.length(), stream_->flow_controller()->bytes_consumed());
520}
521
522TEST_P(QuicSpdyStreamTest, ProcessHeadersAndConsumeMultipleBody) {
523 Initialize(!kShouldProcessData);
vasilvvc48c8712019-03-11 13:38:16 -0700524 std::string body1 = "this is body 1";
525 std::string body2 = "body 2";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500526 std::unique_ptr<char[]> buf;
527 QuicByteCount header_length =
528 encoder_.SerializeDataFrameHeader(body1.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700529 std::string header = std::string(buf.get(), header_length);
530 std::string data1 = HasFrameHeader() ? header + body1 : body1;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500531 header_length = encoder_.SerializeDataFrameHeader(body2.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700532 std::string data2 = HasFrameHeader() ? header + body2 : body2;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500533
534 ProcessHeaders(false, headers_);
535 QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
536 QuicStringPiece(data1));
537 QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
538 data1.length(), QuicStringPiece(data2));
539 stream_->OnStreamFrame(frame1);
540 stream_->OnStreamFrame(frame2);
541 stream_->ConsumeHeaderList();
542
543 stream_->MarkConsumed(body1.length() + body2.length());
544 EXPECT_EQ(data1.length() + data2.length(),
545 stream_->flow_controller()->bytes_consumed());
546}
547
548TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
549 Initialize(!kShouldProcessData);
550
vasilvvc48c8712019-03-11 13:38:16 -0700551 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500552 std::unique_ptr<char[]> buf;
553 QuicByteCount header_length =
554 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700555 std::string header = std::string(buf.get(), header_length);
556 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500557
558 ProcessHeaders(false, headers_);
559 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
560 QuicStringPiece(data));
561 stream_->OnStreamFrame(frame);
562 stream_->ConsumeHeaderList();
563
564 char buffer[1];
565 struct iovec vec;
566 vec.iov_base = buffer;
567 vec.iov_len = QUIC_ARRAYSIZE(buffer);
568
569 for (size_t i = 0; i < body.length(); ++i) {
570 size_t bytes_read = stream_->Readv(&vec, 1);
571 ASSERT_EQ(1u, bytes_read);
572 EXPECT_EQ(body.data()[i], buffer[0]);
573 }
574}
575
576TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
577 Initialize(!kShouldProcessData);
578
vasilvvc48c8712019-03-11 13:38:16 -0700579 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500580 std::unique_ptr<char[]> buf;
581 QuicByteCount header_length =
582 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700583 std::string header = std::string(buf.get(), header_length);
584 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500585
586 ProcessHeaders(false, headers_);
587 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
588 QuicStringPiece(data));
589 stream_->OnStreamFrame(frame);
590 stream_->ConsumeHeaderList();
591
592 char buffer1[1];
593 char buffer2[1];
594 struct iovec vec[2];
595 vec[0].iov_base = buffer1;
596 vec[0].iov_len = QUIC_ARRAYSIZE(buffer1);
597 vec[1].iov_base = buffer2;
598 vec[1].iov_len = QUIC_ARRAYSIZE(buffer2);
599
600 for (size_t i = 0; i < body.length(); i += 2) {
601 size_t bytes_read = stream_->Readv(vec, 2);
602 ASSERT_EQ(2u, bytes_read) << i;
603 ASSERT_EQ(body.data()[i], buffer1[0]) << i;
604 ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i;
605 }
606}
607
608TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) {
609 testing::InSequence seq;
610 // Tests that we send a BLOCKED frame to the peer when we attempt to write,
611 // but are flow control blocked.
612 Initialize(kShouldProcessData);
613
614 // Set a small flow control limit.
615 const uint64_t kWindow = 36;
616 QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(),
617 kWindow);
618 EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset(
619 stream_->flow_controller()));
620
621 // Try to send more data than the flow control limit allows.
622 const uint64_t kOverflow = 15;
vasilvvc48c8712019-03-11 13:38:16 -0700623 std::string body(kWindow + kOverflow, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500624
625 const uint64_t kHeaderLength = HasFrameHeader() ? 2 : 0;
626 if (HasFrameHeader()) {
627 EXPECT_CALL(*session_, WritevData(_, _, kHeaderLength, _, NO_FIN));
628 }
629 EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
630 .WillOnce(Return(QuicConsumedData(kWindow - kHeaderLength, true)));
631 EXPECT_CALL(*connection_, SendControlFrame(_));
632 stream_->WriteOrBufferBody(body, false);
633
634 // Should have sent as much as possible, resulting in no send window left.
635 EXPECT_EQ(0u,
636 QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller()));
637
638 // And we should have queued the overflowed data.
bncc7d9e0c2019-04-16 10:22:15 -0700639 EXPECT_EQ(kOverflow + kHeaderLength, stream_->BufferedDataBytes());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500640}
641
642TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
643 // The flow control receive window decreases whenever we add new bytes to the
644 // sequencer, whether they are consumed immediately or buffered. However we
645 // only send WINDOW_UPDATE frames based on increasing number of bytes
646 // consumed.
647
648 // Don't process data - it will be buffered instead.
649 Initialize(!kShouldProcessData);
650
651 // Expect no WINDOW_UPDATE frames to be sent.
652 EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0);
653
654 // Set a small flow control receive window.
655 const uint64_t kWindow = 36;
656 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
657 kWindow);
658 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
659 kWindow);
660 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset(
661 stream_->flow_controller()));
662
663 // Stream receives enough data to fill a fraction of the receive window.
vasilvvc48c8712019-03-11 13:38:16 -0700664 std::string body(kWindow / 3, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500665 QuicByteCount header_length = 0;
vasilvvc48c8712019-03-11 13:38:16 -0700666 std::string data;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500667
668 if (HasFrameHeader()) {
669 std::unique_ptr<char[]> buffer;
670 header_length = encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700671 std::string header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500672 data = header + body;
673 } else {
674 data = body;
675 }
676
677 ProcessHeaders(false, headers_);
678
679 QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
680 QuicStringPiece(data));
681 stream_->OnStreamFrame(frame1);
682 EXPECT_EQ(
683 kWindow - (kWindow / 3) - header_length,
684 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller()));
685
686 // Now receive another frame which results in the receive window being over
687 // half full. This should all be buffered, decreasing the receive window but
688 // not sending WINDOW_UPDATE.
689 QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
690 kWindow / 3 + header_length, QuicStringPiece(data));
691 stream_->OnStreamFrame(frame2);
692 EXPECT_EQ(
693 kWindow - (2 * kWindow / 3) - 2 * header_length,
694 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller()));
695}
696
697TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) {
698 // Tests that on receipt of data, the stream updates its receive window offset
699 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops
700 // too low.
701 Initialize(kShouldProcessData);
702
703 // Set a small flow control limit.
704 const uint64_t kWindow = 36;
705 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
706 kWindow);
707 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
708 kWindow);
709 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset(
710 stream_->flow_controller()));
711
712 // Stream receives enough data to fill a fraction of the receive window.
vasilvvc48c8712019-03-11 13:38:16 -0700713 std::string body(kWindow / 3, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500714 QuicByteCount header_length = 0;
vasilvvc48c8712019-03-11 13:38:16 -0700715 std::string data;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500716
717 if (HasFrameHeader()) {
718 std::unique_ptr<char[]> buffer;
719 header_length = encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700720 std::string header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500721 data = header + body;
722 } else {
723 data = body;
724 }
725
726 ProcessHeaders(false, headers_);
727 stream_->ConsumeHeaderList();
728
729 QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
730 QuicStringPiece(data));
731 stream_->OnStreamFrame(frame1);
732 EXPECT_EQ(
733 kWindow - (kWindow / 3) - header_length,
734 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller()));
735
736 // Now receive another frame which results in the receive window being over
737 // half full. This will trigger the stream to increase its receive window
738 // offset and send a WINDOW_UPDATE. The result will be again an available
739 // window of kWindow bytes.
740 QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
741 kWindow / 3 + header_length, QuicStringPiece(data));
742 EXPECT_CALL(*connection_, SendControlFrame(_));
743 stream_->OnStreamFrame(frame2);
744 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize(
745 stream_->flow_controller()));
746}
747
748TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) {
749 // Tests that on receipt of data, the connection updates its receive window
750 // offset appropriately, and sends WINDOW_UPDATE frames when its receive
751 // window drops too low.
752 Initialize(kShouldProcessData);
753
754 // Set a small flow control limit for streams and connection.
755 const uint64_t kWindow = 36;
756 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
757 kWindow);
758 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
759 kWindow);
760 QuicFlowControllerPeer::SetReceiveWindowOffset(stream2_->flow_controller(),
761 kWindow);
762 QuicFlowControllerPeer::SetMaxReceiveWindow(stream2_->flow_controller(),
763 kWindow);
764 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
765 kWindow);
766 QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(),
767 kWindow);
768
769 // Supply headers to both streams so that they are happy to receive data.
770 auto headers = AsHeaderList(headers_);
771 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
772 headers);
773 stream_->ConsumeHeaderList();
774 stream2_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
775 headers);
776 stream2_->ConsumeHeaderList();
777
778 // Each stream gets a quarter window of data. This should not trigger a
779 // WINDOW_UPDATE for either stream, nor for the connection.
780 QuicByteCount header_length = 0;
vasilvvc48c8712019-03-11 13:38:16 -0700781 std::string body;
782 std::string data;
783 std::string data2;
784 std::string body2(1, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500785
786 if (HasFrameHeader()) {
vasilvvc48c8712019-03-11 13:38:16 -0700787 body = std::string(kWindow / 4 - 2, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500788 std::unique_ptr<char[]> buffer;
789 header_length = encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700790 std::string header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500791 data = header + body;
792 std::unique_ptr<char[]> buffer2;
793 QuicByteCount header_length2 =
794 encoder_.SerializeDataFrameHeader(body2.length(), &buffer2);
vasilvvc48c8712019-03-11 13:38:16 -0700795 std::string header2 = std::string(buffer2.get(), header_length2);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500796 data2 = header2 + body2;
797 } else {
vasilvvc48c8712019-03-11 13:38:16 -0700798 body = std::string(kWindow / 4, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500799 data = body;
800 data2 = body2;
801 }
802
803 QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
804 QuicStringPiece(data));
805 stream_->OnStreamFrame(frame1);
806 QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
807 QuicStringPiece(data));
808 stream2_->OnStreamFrame(frame2);
809
810 // Now receive a further single byte on one stream - again this does not
811 // trigger a stream WINDOW_UPDATE, but now the connection flow control window
812 // is over half full and thus a connection WINDOW_UPDATE is sent.
813 EXPECT_CALL(*connection_, SendControlFrame(_));
814 QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false,
815 body.length() + header_length, QuicStringPiece(data2));
816 stream_->OnStreamFrame(frame3);
817}
818
819TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) {
820 // Tests that on if the peer sends too much data (i.e. violates the flow
821 // control protocol), then we terminate the connection.
822
823 // Stream should not process data, so that data gets buffered in the
824 // sequencer, triggering flow control limits.
825 Initialize(!kShouldProcessData);
826
827 // Set a small flow control limit.
828 const uint64_t kWindow = 50;
829 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
830 kWindow);
831
832 ProcessHeaders(false, headers_);
833
834 // Receive data to overflow the window, violating flow control.
vasilvvc48c8712019-03-11 13:38:16 -0700835 std::string body(kWindow + 1, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500836 std::unique_ptr<char[]> buf;
837 QuicByteCount header_length =
838 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700839 std::string header = std::string(buf.get(), header_length);
840 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500841 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
842 QuicStringPiece(data));
843 EXPECT_CALL(*connection_,
844 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
845 stream_->OnStreamFrame(frame);
846}
847
848TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) {
849 Initialize(kShouldProcessData);
850 ProcessHeaders(false, headers_);
851
852 stream_->OnStreamReset(QuicRstStreamFrame(
853 kInvalidControlFrameId, stream_->id(), QUIC_STREAM_NO_ERROR, 0));
854 EXPECT_TRUE(stream_->write_side_closed());
855 EXPECT_FALSE(stream_->reading_stopped());
856}
857
858TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) {
859 // Tests that on if the peer sends too much data (i.e. violates the flow
860 // control protocol), at the connection level (rather than the stream level)
861 // then we terminate the connection.
862
863 // Stream should not process data, so that data gets buffered in the
864 // sequencer, triggering flow control limits.
865 Initialize(!kShouldProcessData);
866
867 // Set a small flow control window on streams, and connection.
868 const uint64_t kStreamWindow = 50;
869 const uint64_t kConnectionWindow = 10;
870 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
871 kStreamWindow);
872 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
873 kConnectionWindow);
874
875 ProcessHeaders(false, headers_);
876
877 // Send enough data to overflow the connection level flow control window.
vasilvvc48c8712019-03-11 13:38:16 -0700878 std::string body(kConnectionWindow + 1, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500879 std::unique_ptr<char[]> buf;
880 QuicByteCount header_length =
881 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700882 std::string header = std::string(buf.get(), header_length);
883 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500884
885 EXPECT_LT(data.size(), kStreamWindow);
886 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
887 QuicStringPiece(data));
888
889 EXPECT_CALL(*connection_,
890 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
891 stream_->OnStreamFrame(frame);
892}
893
894TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) {
895 // An attempt to write a FIN with no data should not be flow control blocked,
896 // even if the send window is 0.
897
898 Initialize(kShouldProcessData);
899
900 // Set a flow control limit of zero.
901 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0);
902 EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset(
903 stream_->flow_controller()));
904
905 // Send a frame with a FIN but no data. This should not be blocked.
vasilvvc48c8712019-03-11 13:38:16 -0700906 std::string body = "";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500907 bool fin = true;
908
909 EXPECT_CALL(*connection_,
910 SendBlocked(GetNthClientInitiatedBidirectionalId(0)))
911 .Times(0);
912 EXPECT_CALL(*session_, WritevData(_, _, 0, _, FIN));
913
914 stream_->WriteOrBufferBody(body, fin);
915}
916
917TEST_P(QuicSpdyStreamTest, ReceivingTrailersViaHeaderList) {
918 // Test that receiving trailing headers from the peer via
919 // OnStreamHeaderList() works, and can be read from the stream and consumed.
920 Initialize(kShouldProcessData);
921
922 // Receive initial headers.
923 size_t total_bytes = 0;
924 QuicHeaderList headers;
925 for (const auto& p : headers_) {
926 headers.OnHeader(p.first, p.second);
927 total_bytes += p.first.size() + p.second.size();
928 }
929
930 stream_->OnStreamHeadersPriority(kV3HighestPriority);
931 stream_->OnStreamHeaderList(/*fin=*/false, total_bytes, headers);
932 stream_->ConsumeHeaderList();
933
934 // Receive trailing headers.
935 SpdyHeaderBlock trailers_block;
936 trailers_block["key1"] = "value1";
937 trailers_block["key2"] = "value2";
938 trailers_block["key3"] = "value3";
939 SpdyHeaderBlock trailers_block_with_final_offset = trailers_block.Clone();
renjietang2abedac2019-05-20 14:04:50 -0700940 if (!VersionUsesQpack(GetParam().transport_version)) {
941 // :final-offset pseudo-header is only added if trailers are sent
942 // on the headers stream.
943 trailers_block_with_final_offset[kFinalOffsetHeaderKey] = "0";
944 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500945 total_bytes = 0;
946 QuicHeaderList trailers;
947 for (const auto& p : trailers_block_with_final_offset) {
948 trailers.OnHeader(p.first, p.second);
949 total_bytes += p.first.size() + p.second.size();
950 }
951 stream_->OnStreamHeaderList(/*fin=*/true, total_bytes, trailers);
952
953 // The trailers should be decompressed, and readable from the stream.
954 EXPECT_TRUE(stream_->trailers_decompressed());
955 EXPECT_EQ(trailers_block, stream_->received_trailers());
956
957 // IsDoneReading() returns false until trailers marked consumed.
958 EXPECT_FALSE(stream_->IsDoneReading());
959 stream_->MarkTrailersConsumed();
960 EXPECT_TRUE(stream_->IsDoneReading());
961}
962
963TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithOffset) {
964 // Test that when receiving trailing headers with an offset before response
965 // body, stream is closed at the right offset.
966 Initialize(kShouldProcessData);
967
renjietang2abedac2019-05-20 14:04:50 -0700968 // kFinalOffsetHeaderKey is not used when HEADERS are sent on the
969 // request/response stream.
970 if (VersionUsesQpack(GetParam().transport_version)) {
971 return;
972 }
973
QUICHE teama6ef0a62019-03-07 20:34:33 -0500974 // Receive initial headers.
975 QuicHeaderList headers = ProcessHeaders(false, headers_);
976 stream_->ConsumeHeaderList();
977
vasilvvc48c8712019-03-11 13:38:16 -0700978 const std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500979 std::unique_ptr<char[]> buf;
980 QuicByteCount header_length =
981 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700982 std::string header = std::string(buf.get(), header_length);
983 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500984
985 // Receive trailing headers.
986 SpdyHeaderBlock trailers_block;
987 trailers_block["key1"] = "value1";
988 trailers_block["key2"] = "value2";
989 trailers_block["key3"] = "value3";
990 trailers_block[kFinalOffsetHeaderKey] =
991 QuicTextUtils::Uint64ToString(data.size());
992
993 QuicHeaderList trailers = ProcessHeaders(true, trailers_block);
994
995 // The trailers should be decompressed, and readable from the stream.
996 EXPECT_TRUE(stream_->trailers_decompressed());
997
998 // The final offset trailer will be consumed by QUIC.
999 trailers_block.erase(kFinalOffsetHeaderKey);
1000 EXPECT_EQ(trailers_block, stream_->received_trailers());
1001
1002 // Consuming the trailers erases them from the stream.
1003 stream_->MarkTrailersConsumed();
1004 EXPECT_TRUE(stream_->FinishedReadingTrailers());
1005
1006 EXPECT_FALSE(stream_->IsDoneReading());
1007 // Receive and consume body.
1008 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/false,
1009 0, data);
1010 stream_->OnStreamFrame(frame);
1011 EXPECT_EQ(body, stream_->data());
1012 EXPECT_TRUE(stream_->IsDoneReading());
1013}
1014
1015TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) {
1016 // Test that receiving trailers without a final offset field is an error.
1017 Initialize(kShouldProcessData);
1018
renjietang2abedac2019-05-20 14:04:50 -07001019 // kFinalOffsetHeaderKey is not used when HEADERS are sent on the
1020 // request/response stream.
1021 if (VersionUsesQpack(GetParam().transport_version)) {
1022 return;
1023 }
1024
QUICHE teama6ef0a62019-03-07 20:34:33 -05001025 // Receive initial headers.
1026 ProcessHeaders(false, headers_);
1027 stream_->ConsumeHeaderList();
1028
1029 // Receive trailing headers, without kFinalOffsetHeaderKey.
1030 SpdyHeaderBlock trailers_block;
1031 trailers_block["key1"] = "value1";
1032 trailers_block["key2"] = "value2";
1033 trailers_block["key3"] = "value3";
1034 auto trailers = AsHeaderList(trailers_block);
1035
1036 // Verify that the trailers block didn't contain a final offset.
1037 EXPECT_EQ("", trailers_block[kFinalOffsetHeaderKey].as_string());
1038
1039 // Receipt of the malformed trailers will close the connection.
1040 EXPECT_CALL(*connection_,
1041 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
1042 .Times(1);
1043 stream_->OnStreamHeaderList(/*fin=*/true,
1044 trailers.uncompressed_header_bytes(), trailers);
1045}
1046
renjietang2abedac2019-05-20 14:04:50 -07001047TEST_P(QuicSpdyStreamTest, ReceivingTrailersOnRequestStream) {
1048 Initialize(kShouldProcessData);
1049
1050 if (!VersionUsesQpack(GetParam().transport_version)) {
1051 return;
1052 }
1053
1054 // Receive initial headers.
1055 QuicHeaderList headers = ProcessHeaders(false, headers_);
1056 stream_->ConsumeHeaderList();
1057
1058 const std::string body = "this is the body";
1059 std::unique_ptr<char[]> buf;
1060 QuicByteCount header_length =
1061 encoder_.SerializeDataFrameHeader(body.length(), &buf);
1062 std::string header = std::string(buf.get(), header_length);
1063 std::string data = HasFrameHeader() ? header + body : body;
1064
1065 // Receive trailing headers.
1066 SpdyHeaderBlock trailers_block;
1067 trailers_block["key1"] = "value1";
1068 trailers_block["key2"] = "value2";
1069 trailers_block["key3"] = "value3";
1070
1071 QuicHeaderList trailers = ProcessHeaders(true, trailers_block);
1072
1073 // The trailers should be decompressed, and readable from the stream.
1074 EXPECT_TRUE(stream_->trailers_decompressed());
1075
1076 EXPECT_EQ(trailers_block, stream_->received_trailers());
1077
1078 // Consuming the trailers erases them from the stream.
1079 stream_->MarkTrailersConsumed();
1080 EXPECT_TRUE(stream_->FinishedReadingTrailers());
1081 EXPECT_TRUE(stream_->IsDoneReading());
1082
1083 // Receive and consume body.
1084 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/false,
1085 0, data);
1086 stream_->OnStreamFrame(frame);
1087 EXPECT_EQ(body, stream_->data());
1088 EXPECT_TRUE(stream_->IsDoneReading());
1089}
1090
QUICHE teama6ef0a62019-03-07 20:34:33 -05001091TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutFin) {
1092 // Test that received Trailers must always have the FIN set.
1093 Initialize(kShouldProcessData);
1094
renjietang2abedac2019-05-20 14:04:50 -07001095 // In IETF QUIC, there is no such thing as FIN flag on HTTP/3 frames like the
1096 // HEADERS frame.
1097 if (VersionUsesQpack(GetParam().transport_version)) {
1098 return;
1099 }
1100
QUICHE teama6ef0a62019-03-07 20:34:33 -05001101 // Receive initial headers.
1102 auto headers = AsHeaderList(headers_);
1103 stream_->OnStreamHeaderList(/*fin=*/false,
1104 headers.uncompressed_header_bytes(), headers);
1105 stream_->ConsumeHeaderList();
1106
1107 // Receive trailing headers with FIN deliberately set to false.
1108 SpdyHeaderBlock trailers_block;
1109 trailers_block["foo"] = "bar";
1110 auto trailers = AsHeaderList(trailers_block);
1111
1112 EXPECT_CALL(*connection_,
1113 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
1114 .Times(1);
1115 stream_->OnStreamHeaderList(/*fin=*/false,
1116 trailers.uncompressed_header_bytes(), trailers);
1117}
1118
1119TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterHeadersWithFin) {
1120 // If headers are received with a FIN, no trailers should then arrive.
1121 Initialize(kShouldProcessData);
1122
1123 // Receive initial headers with FIN set.
1124 ProcessHeaders(true, headers_);
1125 stream_->ConsumeHeaderList();
1126
1127 // Receive trailing headers after FIN already received.
1128 SpdyHeaderBlock trailers_block;
1129 trailers_block["foo"] = "bar";
1130 EXPECT_CALL(*connection_,
1131 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
1132 .Times(1);
1133 ProcessHeaders(true, trailers_block);
1134}
1135
1136TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) {
1137 // If body data are received with a FIN, no trailers should then arrive.
1138 Initialize(kShouldProcessData);
1139
renjietang2abedac2019-05-20 14:04:50 -07001140 // If HEADERS frames are sent on the request/response stream,
1141 // then the sequencer will block them from reaching QuicSpdyStream
1142 // after the stream is closed.
1143 if (VersionUsesQpack(GetParam().transport_version)) {
1144 return;
1145 }
1146
QUICHE teama6ef0a62019-03-07 20:34:33 -05001147 // Receive initial headers without FIN set.
1148 ProcessHeaders(false, headers_);
1149 stream_->ConsumeHeaderList();
1150
1151 // Receive body data, with FIN.
1152 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
1153 0, "body");
1154 stream_->OnStreamFrame(frame);
1155
1156 // Receive trailing headers after FIN already received.
1157 SpdyHeaderBlock trailers_block;
1158 trailers_block["foo"] = "bar";
1159 EXPECT_CALL(*connection_,
1160 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
1161 .Times(1);
1162 ProcessHeaders(true, trailers_block);
1163}
1164
1165TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) {
1166 // Verify that a stream receiving headers, body, and no trailers is correctly
1167 // marked as done reading on consumption of headers and body.
1168 Initialize(kShouldProcessData);
1169
1170 // Receive and consume initial headers with FIN not set.
1171 auto h = AsHeaderList(headers_);
1172 stream_->OnStreamHeaderList(/*fin=*/false, h.uncompressed_header_bytes(), h);
1173 stream_->ConsumeHeaderList();
1174
1175 // Receive and consume body with FIN set, and no trailers.
vasilvvc48c8712019-03-11 13:38:16 -07001176 std::string body(1024, 'x');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001177 std::unique_ptr<char[]> buf;
1178 QuicByteCount header_length =
1179 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -07001180 std::string header = std::string(buf.get(), header_length);
1181 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001182
1183 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
1184 0, data);
1185 stream_->OnStreamFrame(frame);
1186
1187 EXPECT_TRUE(stream_->IsDoneReading());
1188}
1189
1190TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) {
1191 // Test that writing trailers will send a FIN, as Trailers are the last thing
1192 // to be sent on a stream.
1193 Initialize(kShouldProcessData);
1194
renjietang2abedac2019-05-20 14:04:50 -07001195 if (VersionUsesQpack(GetParam().transport_version)) {
1196 // In this case, TestStream::WriteHeadersImpl() does not prevent writes.
1197 EXPECT_CALL(*session_, WritevData(stream_, stream_->id(), _, _, _))
1198 .Times(AtLeast(1));
1199 }
1200
QUICHE teama6ef0a62019-03-07 20:34:33 -05001201 // Write the initial headers, without a FIN.
1202 EXPECT_CALL(*stream_, WriteHeadersMock(false));
1203 stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
1204
1205 // Writing trailers implicitly sends a FIN.
1206 SpdyHeaderBlock trailers;
1207 trailers["trailer key"] = "trailer value";
1208 EXPECT_CALL(*stream_, WriteHeadersMock(true));
1209 stream_->WriteTrailers(std::move(trailers), nullptr);
1210 EXPECT_TRUE(stream_->fin_sent());
1211}
1212
1213TEST_P(QuicSpdyStreamTest, WritingTrailersFinalOffset) {
1214 // Test that when writing trailers, the trailers that are actually sent to the
1215 // peer contain the final offset field indicating last byte of data.
1216 Initialize(kShouldProcessData);
1217
renjietang2abedac2019-05-20 14:04:50 -07001218 if (VersionUsesQpack(GetParam().transport_version)) {
1219 // In this case, TestStream::WriteHeadersImpl() does not prevent writes.
1220 EXPECT_CALL(*session_, WritevData(stream_, stream_->id(), _, _, _))
1221 .Times(AtLeast(1));
1222 }
1223
QUICHE teama6ef0a62019-03-07 20:34:33 -05001224 // Write the initial headers.
1225 EXPECT_CALL(*stream_, WriteHeadersMock(false));
1226 stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
1227
1228 // Write non-zero body data to force a non-zero final offset.
1229 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
vasilvvc48c8712019-03-11 13:38:16 -07001230 std::string body(1024, 'x'); // 1 kB
QUICHE teama6ef0a62019-03-07 20:34:33 -05001231 QuicByteCount header_length = 0;
1232 if (HasFrameHeader()) {
1233 std::unique_ptr<char[]> buf;
1234 header_length = encoder_.SerializeDataFrameHeader(body.length(), &buf);
1235 }
1236
1237 stream_->WriteOrBufferBody(body, false);
1238
1239 // The final offset field in the trailing headers is populated with the
1240 // number of body bytes written (including queued bytes).
1241 SpdyHeaderBlock trailers;
1242 trailers["trailer key"] = "trailer value";
renjietang2abedac2019-05-20 14:04:50 -07001243
1244 SpdyHeaderBlock expected_trailers(trailers.Clone());
1245 // :final-offset pseudo-header is only added if trailers are sent
1246 // on the headers stream.
1247 if (!VersionUsesQpack(GetParam().transport_version)) {
1248 expected_trailers[kFinalOffsetHeaderKey] =
1249 QuicTextUtils::Uint64ToString(body.length() + header_length);
1250 }
1251
QUICHE teama6ef0a62019-03-07 20:34:33 -05001252 EXPECT_CALL(*stream_, WriteHeadersMock(true));
1253 stream_->WriteTrailers(std::move(trailers), nullptr);
renjietang2abedac2019-05-20 14:04:50 -07001254 EXPECT_EQ(expected_trailers, stream_->saved_headers());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001255}
1256
1257TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) {
1258 // Test that if trailers are written after all other data has been written
1259 // (headers and body), that this closes the stream for writing.
1260 Initialize(kShouldProcessData);
1261
renjietang2abedac2019-05-20 14:04:50 -07001262 // Expect data being written on the stream. In addition to that, headers are
1263 // also written on the stream in case of IETF QUIC.
1264 EXPECT_CALL(*session_, WritevData(stream_, stream_->id(), _, _, _))
1265 .Times(AtLeast(1));
1266
QUICHE teama6ef0a62019-03-07 20:34:33 -05001267 // Write the initial headers.
1268 EXPECT_CALL(*stream_, WriteHeadersMock(false));
1269 stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
1270
1271 // Write non-zero body data.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001272 const int kBodySize = 1 * 1024; // 1 kB
vasilvvc48c8712019-03-11 13:38:16 -07001273 stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001274 EXPECT_EQ(0u, stream_->BufferedDataBytes());
1275
1276 // Headers and body have been fully written, there is no queued data. Writing
1277 // trailers marks the end of this stream, and thus the write side is closed.
1278 EXPECT_CALL(*stream_, WriteHeadersMock(true));
1279 stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
1280 EXPECT_TRUE(stream_->write_side_closed());
1281}
1282
1283TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
renjietang2abedac2019-05-20 14:04:50 -07001284 // This test exercises sending trailers on the headers stream while data is
1285 // still queued on the response/request stream. In IETF QUIC, data and
1286 // trailers are sent on the same stream, so this test does not apply.
1287 if (VersionUsesQpack(GetParam().transport_version)) {
1288 return;
1289 }
1290
QUICHE teama6ef0a62019-03-07 20:34:33 -05001291 // Test that the stream is not closed for writing when trailers are sent
1292 // while there are still body bytes queued.
1293 testing::InSequence seq;
1294 Initialize(kShouldProcessData);
1295
1296 // Write the initial headers.
1297 EXPECT_CALL(*stream_, WriteHeadersMock(false));
1298 stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
1299
1300 // Write non-zero body data, but only consume partially, ensuring queueing.
1301 const int kBodySize = 1 * 1024; // 1 kB
1302 if (HasFrameHeader()) {
1303 EXPECT_CALL(*session_, WritevData(_, _, 3, _, NO_FIN));
1304 }
1305 EXPECT_CALL(*session_, WritevData(_, _, kBodySize, _, NO_FIN))
1306 .WillOnce(Return(QuicConsumedData(kBodySize - 1, false)));
vasilvvc48c8712019-03-11 13:38:16 -07001307 stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001308 EXPECT_EQ(1u, stream_->BufferedDataBytes());
1309
1310 // Writing trailers will send a FIN, but not close the write side of the
1311 // stream as there are queued bytes.
1312 EXPECT_CALL(*stream_, WriteHeadersMock(true));
1313 stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
1314 EXPECT_TRUE(stream_->fin_sent());
1315 EXPECT_FALSE(stream_->write_side_closed());
1316
1317 // Writing the queued bytes will close the write side of the stream.
1318 EXPECT_CALL(*session_, WritevData(_, _, 1, _, NO_FIN));
1319 stream_->OnCanWrite();
1320 EXPECT_TRUE(stream_->write_side_closed());
1321}
1322
1323TEST_P(QuicSpdyStreamTest, WritingTrailersAfterFIN) {
1324 // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
renjietang2abedac2019-05-20 14:04:50 -07001325 // In IETF QUIC, there is no such thing as FIN flag on HTTP/3 frames like the
1326 // HEADERS frame. That is version 99, which is element 0 of the array, so
1327 // pick another element.
1328 if (GetParam() != AllSupportedVersions()[1]) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001329 return;
1330 }
1331
1332 // Test that it is not possible to write Trailers after a FIN has been sent.
1333 Initialize(kShouldProcessData);
1334
1335 // Write the initial headers, with a FIN.
1336 EXPECT_CALL(*stream_, WriteHeadersMock(true));
1337 stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr);
1338 EXPECT_TRUE(stream_->fin_sent());
1339
1340 // Writing Trailers should fail, as the FIN has already been sent.
1341 // populated with the number of body bytes written.
1342 EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr),
1343 "Trailers cannot be sent after a FIN");
1344}
1345
1346TEST_P(QuicSpdyStreamTest, HeaderStreamNotiferCorrespondingSpdyStream) {
1347 Initialize(kShouldProcessData);
1348 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1349 testing::InSequence s;
1350 QuicReferenceCountedPointer<MockAckListener> ack_listener1(
1351 new MockAckListener());
1352 QuicReferenceCountedPointer<MockAckListener> ack_listener2(
1353 new MockAckListener());
1354 stream_->set_ack_listener(ack_listener1);
1355 stream2_->set_ack_listener(ack_listener2);
1356
1357 session_->headers_stream()->WriteOrBufferData("Header1", false,
1358 ack_listener1);
1359 stream_->WriteOrBufferBody("Test1", true);
1360
1361 session_->headers_stream()->WriteOrBufferData("Header2", false,
1362 ack_listener2);
1363 stream2_->WriteOrBufferBody("Test2", false);
1364
1365 QuicStreamFrame frame1(
1366 QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 0,
1367 "Header1");
vasilvvc48c8712019-03-11 13:38:16 -07001368 std::string header = "";
QUICHE teama6ef0a62019-03-07 20:34:33 -05001369 if (HasFrameHeader()) {
1370 std::unique_ptr<char[]> buffer;
1371 QuicByteCount header_length = encoder_.SerializeDataFrameHeader(5, &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001372 header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001373 }
1374 QuicStreamFrame frame2(stream_->id(), true, 0, header + "Test1");
1375 QuicStreamFrame frame3(
1376 QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 7,
1377 "Header2");
1378 QuicStreamFrame frame4(stream2_->id(), false, 0, header + "Test2");
1379
1380 EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(7));
1381 session_->OnStreamFrameRetransmitted(frame1);
1382
1383 EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
1384 EXPECT_TRUE(
1385 session_->OnFrameAcked(QuicFrame(frame1), QuicTime::Delta::Zero()));
1386 EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
1387 EXPECT_TRUE(
1388 session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero()));
1389 EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
1390 EXPECT_TRUE(
1391 session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero()));
1392 EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
1393 EXPECT_TRUE(
1394 session_->OnFrameAcked(QuicFrame(frame4), QuicTime::Delta::Zero()));
1395}
1396
1397TEST_P(QuicSpdyStreamTest, StreamBecomesZombieWithWriteThatCloses) {
1398 Initialize(kShouldProcessData);
1399 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1400 QuicStreamPeer::CloseReadSide(stream_);
1401 // This write causes stream to be closed.
1402 stream_->WriteOrBufferBody("Test1", true);
1403 // stream_ has unacked data and should become zombie.
1404 EXPECT_TRUE(QuicContainsKey(QuicSessionPeer::zombie_streams(session_.get()),
1405 stream_->id()));
1406 EXPECT_TRUE(QuicSessionPeer::closed_streams(session_.get()).empty());
1407}
1408
1409TEST_P(QuicSpdyStreamTest, OnPriorityFrame) {
1410 Initialize(kShouldProcessData);
1411 stream_->OnPriorityFrame(kV3HighestPriority);
1412 EXPECT_EQ(kV3HighestPriority, stream_->priority());
1413}
1414
1415TEST_P(QuicSpdyStreamTest, OnPriorityFrameAfterSendingData) {
1416 testing::InSequence seq;
1417 Initialize(kShouldProcessData);
1418
1419 if (HasFrameHeader()) {
1420 EXPECT_CALL(*session_, WritevData(_, _, 2, _, NO_FIN));
1421 }
1422 EXPECT_CALL(*session_, WritevData(_, _, 4, _, FIN));
1423 stream_->WriteOrBufferBody("data", true);
1424 stream_->OnPriorityFrame(kV3HighestPriority);
1425 EXPECT_EQ(kV3HighestPriority, stream_->priority());
1426}
1427
1428TEST_P(QuicSpdyStreamTest, SetPriorityBeforeUpdateStreamPriority) {
1429 MockQuicConnection* connection = new StrictMock<MockQuicConnection>(
1430 &helper_, &alarm_factory_, Perspective::IS_SERVER,
1431 SupportedVersions(GetParam()));
1432 std::unique_ptr<TestMockUpdateStreamSession> session(
1433 new StrictMock<TestMockUpdateStreamSession>(connection));
1434 auto stream = new StrictMock<TestStream>(
1435 GetNthClientInitiatedBidirectionalStreamId(
1436 session->connection()->transport_version(), 0),
1437 session.get(),
1438 /*should_process_data=*/true);
1439 session->ActivateStream(QuicWrapUnique(stream));
1440
1441 // QuicSpdyStream::SetPriority() should eventually call UpdateStreamPriority()
1442 // on the session. Make sure stream->priority() returns the updated priority
1443 // if called within UpdateStreamPriority(). This expectation is enforced in
1444 // TestMockUpdateStreamSession::UpdateStreamPriority().
1445 session->SetExpectedStream(stream);
1446 session->SetExpectedPriority(kV3HighestPriority);
1447 stream->SetPriority(kV3HighestPriority);
1448
1449 session->SetExpectedPriority(kV3LowestPriority);
1450 stream->SetPriority(kV3LowestPriority);
1451}
1452
1453TEST_P(QuicSpdyStreamTest, StreamWaitsForAcks) {
1454 Initialize(kShouldProcessData);
1455 QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
1456 new StrictMock<MockAckListener>);
1457 stream_->set_ack_listener(mock_ack_listener);
1458 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1459 // Stream is not waiting for acks initially.
1460 EXPECT_FALSE(stream_->IsWaitingForAcks());
1461 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1462
1463 // Send kData1.
1464 stream_->WriteOrBufferData("FooAndBar", false, nullptr);
1465 EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1466 EXPECT_TRUE(stream_->IsWaitingForAcks());
1467 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
1468 QuicByteCount newly_acked_length = 0;
1469 EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
1470 &newly_acked_length));
1471 // Stream is not waiting for acks as all sent data is acked.
1472 EXPECT_FALSE(stream_->IsWaitingForAcks());
1473 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1474
1475 // Send kData2.
1476 stream_->WriteOrBufferData("FooAndBar", false, nullptr);
1477 EXPECT_TRUE(stream_->IsWaitingForAcks());
1478 EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1479 // Send FIN.
1480 stream_->WriteOrBufferData("", true, nullptr);
1481 // Fin only frame is not stored in send buffer.
1482 EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1483
1484 // kData2 is retransmitted.
1485 EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(9));
1486 stream_->OnStreamFrameRetransmitted(9, 9, false);
1487
1488 // kData2 is acked.
1489 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
1490 EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
1491 &newly_acked_length));
1492 // Stream is waiting for acks as FIN is not acked.
1493 EXPECT_TRUE(stream_->IsWaitingForAcks());
1494 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1495
1496 // FIN is acked.
1497 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
1498 EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 0, true, QuicTime::Delta::Zero(),
1499 &newly_acked_length));
1500 EXPECT_FALSE(stream_->IsWaitingForAcks());
1501 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1502}
1503
1504TEST_P(QuicSpdyStreamTest, StreamDataGetAckedMultipleTimes) {
1505 Initialize(kShouldProcessData);
1506 QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
1507 new StrictMock<MockAckListener>);
1508 stream_->set_ack_listener(mock_ack_listener);
1509 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1510 // Send [0, 27) and fin.
1511 stream_->WriteOrBufferData("FooAndBar", false, nullptr);
1512 stream_->WriteOrBufferData("FooAndBar", false, nullptr);
1513 stream_->WriteOrBufferData("FooAndBar", true, nullptr);
1514
1515 // Ack [0, 9), [5, 22) and [18, 26)
1516 // Verify [0, 9) 9 bytes are acked.
1517 QuicByteCount newly_acked_length = 0;
1518 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
1519 EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
1520 &newly_acked_length));
1521 EXPECT_EQ(2u, QuicStreamPeer::SendBuffer(stream_).size());
1522 // Verify [9, 22) 13 bytes are acked.
1523 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(13, _));
1524 EXPECT_TRUE(stream_->OnStreamFrameAcked(5, 17, false, QuicTime::Delta::Zero(),
1525 &newly_acked_length));
1526 EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1527 // Verify [22, 26) 4 bytes are acked.
1528 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(4, _));
1529 EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 8, false, QuicTime::Delta::Zero(),
1530 &newly_acked_length));
1531 EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1532 EXPECT_TRUE(stream_->IsWaitingForAcks());
1533
1534 // Ack [0, 27).
1535 // Verify [26, 27) 1 byte is acked.
1536 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(1, _));
1537 EXPECT_TRUE(stream_->OnStreamFrameAcked(26, 1, false, QuicTime::Delta::Zero(),
1538 &newly_acked_length));
1539 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1540 EXPECT_TRUE(stream_->IsWaitingForAcks());
1541
1542 // Ack Fin. Verify OnPacketAcked is called.
1543 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
1544 EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
1545 &newly_acked_length));
1546 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1547 EXPECT_FALSE(stream_->IsWaitingForAcks());
1548
1549 // Ack [10, 27) and fin.
1550 // No new data is acked, verify OnPacketAcked is not called.
1551 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(_, _)).Times(0);
1552 EXPECT_FALSE(stream_->OnStreamFrameAcked(
1553 10, 17, true, QuicTime::Delta::Zero(), &newly_acked_length));
1554 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1555 EXPECT_FALSE(stream_->IsWaitingForAcks());
1556}
1557
1558// HTTP/3 only.
1559TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteOrBufferBody) {
1560 Initialize(kShouldProcessData);
1561 if (!HasFrameHeader()) {
1562 return;
1563 }
1564 QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
1565 new StrictMock<MockAckListener>);
1566 stream_->set_ack_listener(mock_ack_listener);
vasilvvc48c8712019-03-11 13:38:16 -07001567 std::string body = "Test1";
1568 std::string body2(100, 'x');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001569
1570 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1571 stream_->WriteOrBufferBody(body, false);
1572 stream_->WriteOrBufferBody(body2, true);
1573
1574 std::unique_ptr<char[]> buffer;
1575 QuicByteCount header_length =
1576 encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001577 std::string header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001578
1579 header_length = encoder_.SerializeDataFrameHeader(body2.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001580 std::string header2 = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001581
1582 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body.length(), _));
1583 QuicStreamFrame frame(stream_->id(), false, 0, header + body);
1584 EXPECT_TRUE(
1585 session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero()));
1586
1587 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
1588 QuicStreamFrame frame2(stream_->id(), false, (header + body).length(),
1589 header2);
1590 EXPECT_TRUE(
1591 session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero()));
1592
1593 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body2.length(), _));
1594 QuicStreamFrame frame3(stream_->id(), true,
1595 (header + body).length() + header2.length(), body2);
1596 EXPECT_TRUE(
1597 session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero()));
1598
1599 EXPECT_TRUE(
1600 QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
1601}
1602
1603// HTTP/3 only.
1604TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteBodySlices) {
1605 Initialize(kShouldProcessData);
1606 if (!HasFrameHeader()) {
1607 return;
1608 }
1609 QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
1610 new StrictMock<MockAckListener>);
1611 stream_->set_ack_listener(mock_ack_listener);
vasilvvc48c8712019-03-11 13:38:16 -07001612 std::string body = "Test1";
1613 std::string body2(100, 'x');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001614 struct iovec body1_iov = {const_cast<char*>(body.data()), body.length()};
1615 struct iovec body2_iov = {const_cast<char*>(body2.data()), body2.length()};
1616 QuicMemSliceStorage storage(&body1_iov, 1,
1617 helper_.GetStreamSendBufferAllocator(), 1024);
1618 QuicMemSliceStorage storage2(&body2_iov, 1,
1619 helper_.GetStreamSendBufferAllocator(), 1024);
1620 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1621 stream_->WriteBodySlices(storage.ToSpan(), false);
1622 stream_->WriteBodySlices(storage2.ToSpan(), true);
1623
1624 std::unique_ptr<char[]> buffer;
1625 QuicByteCount header_length =
1626 encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001627 std::string header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001628
1629 header_length = encoder_.SerializeDataFrameHeader(body2.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001630 std::string header2 = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001631
1632 EXPECT_CALL(*mock_ack_listener,
1633 OnPacketAcked(body.length() + body2.length(), _));
1634 QuicStreamFrame frame(stream_->id(), true, 0,
1635 header + body + header2 + body2);
1636 EXPECT_TRUE(
1637 session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero()));
1638
1639 EXPECT_TRUE(
1640 QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
1641}
1642
1643// HTTP/3 only.
1644TEST_P(QuicSpdyStreamTest, HeaderBytesNotReportedOnRetransmission) {
1645 Initialize(kShouldProcessData);
1646 if (!HasFrameHeader()) {
1647 return;
1648 }
1649 QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
1650 new StrictMock<MockAckListener>);
1651 stream_->set_ack_listener(mock_ack_listener);
vasilvvc48c8712019-03-11 13:38:16 -07001652 std::string body = "Test1";
1653 std::string body2(100, 'x');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001654
1655 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1656 stream_->WriteOrBufferBody(body, false);
1657 stream_->WriteOrBufferBody(body2, true);
1658
1659 std::unique_ptr<char[]> buffer;
1660 QuicByteCount header_length =
1661 encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001662 std::string header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001663
1664 header_length = encoder_.SerializeDataFrameHeader(body2.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001665 std::string header2 = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001666
1667 EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body.length()));
1668 QuicStreamFrame frame(stream_->id(), false, 0, header + body);
1669 session_->OnStreamFrameRetransmitted(frame);
1670
1671 EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body2.length()));
1672 QuicStreamFrame frame2(stream_->id(), true, (header + body).length(),
1673 header2 + body2);
1674 session_->OnStreamFrameRetransmitted(frame2);
1675
1676 EXPECT_FALSE(
1677 QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
1678}
1679
renjietang2abedac2019-05-20 14:04:50 -07001680TEST_P(QuicSpdyStreamTest, HeadersFrameOnRequestStream) {
1681 if (!VersionUsesQpack(GetParam().transport_version)) {
1682 return;
1683 }
1684
1685 Initialize(kShouldProcessData);
1686
1687 // QPACK encoded header block with single header field "foo: bar".
1688 std::string headers_frame_payload =
1689 QuicTextUtils::HexDecode("00002a94e703626172");
1690 std::unique_ptr<char[]> headers_buffer;
1691 QuicByteCount headers_frame_header_length =
1692 encoder_.SerializeHeadersFrameHeader(headers_frame_payload.length(),
1693 &headers_buffer);
1694 QuicStringPiece headers_frame_header(headers_buffer.get(),
1695 headers_frame_header_length);
1696
1697 std::string data_frame_payload = "some data";
1698 std::unique_ptr<char[]> data_buffer;
1699 QuicByteCount data_frame_header_length = encoder_.SerializeDataFrameHeader(
1700 data_frame_payload.length(), &data_buffer);
1701 QuicStringPiece data_frame_header(data_buffer.get(),
1702 data_frame_header_length);
1703
1704 // QPACK encoded header block with single header field
1705 // "custom-key: custom-value".
1706 std::string trailers_frame_payload =
1707 QuicTextUtils::HexDecode("00002f0125a849e95ba97d7f8925a849e95bb8e8b4bf");
1708 std::unique_ptr<char[]> trailers_buffer;
1709 QuicByteCount trailers_frame_header_length =
1710 encoder_.SerializeHeadersFrameHeader(trailers_frame_payload.length(),
1711 &trailers_buffer);
1712 QuicStringPiece trailers_frame_header(trailers_buffer.get(),
1713 trailers_frame_header_length);
1714
1715 std::string stream_frame_payload = QuicStrCat(
1716 headers_frame_header, headers_frame_payload, data_frame_header,
1717 data_frame_payload, trailers_frame_header, trailers_frame_payload);
1718 QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
1719 stream_->OnStreamFrame(frame);
1720
1721 auto it = stream_->header_list().begin();
1722 ASSERT_TRUE(it != stream_->header_list().end());
1723 EXPECT_EQ("foo", it->first);
1724 EXPECT_EQ("bar", it->second);
1725 ++it;
1726 EXPECT_TRUE(it == stream_->header_list().end());
1727
1728 // QuicSpdyStream only calls OnBodyAvailable()
1729 // after the header list has been consumed.
1730 EXPECT_EQ("", stream_->data());
1731 stream_->ConsumeHeaderList();
1732 EXPECT_EQ("some data", stream_->data());
1733
1734 const spdy::SpdyHeaderBlock& trailers = stream_->received_trailers();
1735 EXPECT_THAT(trailers, testing::ElementsAre(
1736 testing::Pair("custom-key", "custom-value")));
1737}
1738
QUICHE teama6ef0a62019-03-07 20:34:33 -05001739} // namespace
1740} // namespace test
1741} // namespace quic