blob: d61d197be97c5c910031c92bcd8db6a451a69906 [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>
8#include <utility>
9
10#include "net/third_party/quiche/src/quic/core/http/http_encoder.h"
11#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
12#include "net/third_party/quiche/src/quic/core/quic_connection.h"
13#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h"
14#include "net/third_party/quiche/src/quic/core/quic_utils.h"
15#include "net/third_party/quiche/src/quic/core/quic_versions.h"
16#include "net/third_party/quiche/src/quic/core/quic_write_blocked_list.h"
17#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
18#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
19#include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h"
20#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
21#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
22#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);
81 return 0;
82 }
83
vasilvvc48c8712019-03-11 13:38:16 -070084 const std::string& data() const { return data_; }
QUICHE teama6ef0a62019-03-07 20:34:33 -050085 const spdy::SpdyHeaderBlock& saved_headers() const { return saved_headers_; }
86
87 private:
88 bool should_process_data_;
89 spdy::SpdyHeaderBlock saved_headers_;
vasilvvc48c8712019-03-11 13:38:16 -070090 std::string data_;
QUICHE teama6ef0a62019-03-07 20:34:33 -050091};
92
93class TestMockUpdateStreamSession : public MockQuicSpdySession {
94 public:
95 explicit TestMockUpdateStreamSession(QuicConnection* connection)
96 : MockQuicSpdySession(connection) {}
97
98 void UpdateStreamPriority(QuicStreamId id, SpdyPriority priority) override {
99 EXPECT_EQ(id, expected_stream_->id());
100 EXPECT_EQ(expected_priority_, priority);
101 EXPECT_EQ(expected_priority_, expected_stream_->priority());
102 }
103
104 void SetExpectedStream(QuicSpdyStream* stream) { expected_stream_ = stream; }
105 void SetExpectedPriority(SpdyPriority priority) {
106 expected_priority_ = priority;
107 }
108
109 private:
110 QuicSpdyStream* expected_stream_;
111 SpdyPriority expected_priority_;
112};
113
114class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
115 public:
116 QuicSpdyStreamTest() {
117 headers_[":host"] = "www.google.com";
118 headers_[":path"] = "/index.hml";
119 headers_[":scheme"] = "https";
120 headers_["cookie"] =
121 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
122 "__utmc=160408618; "
123 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
124 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
125 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
126 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
127 "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
128 "1zFMi5vzcns38-8_Sns; "
129 "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
130 "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
131 "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
132 "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
133 "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
134 "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
135 "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
136 "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
137 "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
138 "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
139 "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
140 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
141 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
142 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
143 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
144 }
145
146 void Initialize(bool stream_should_process_data) {
147 connection_ = new StrictMock<MockQuicConnection>(
148 &helper_, &alarm_factory_, Perspective::IS_SERVER,
149 SupportedVersions(GetParam()));
150 session_ = QuicMakeUnique<StrictMock<MockQuicSpdySession>>(connection_);
151 session_->Initialize();
152 ON_CALL(*session_, WritevData(_, _, _, _, _))
153 .WillByDefault(Invoke(MockQuicSession::ConsumeData));
154
155 stream_ =
156 new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(0),
157 session_.get(), stream_should_process_data);
158 session_->ActivateStream(QuicWrapUnique(stream_));
159 stream2_ =
160 new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(1),
161 session_.get(), stream_should_process_data);
162 session_->ActivateStream(QuicWrapUnique(stream2_));
163 }
164
165 QuicHeaderList ProcessHeaders(bool fin, const SpdyHeaderBlock& headers) {
166 QuicHeaderList h = AsHeaderList(headers);
167 stream_->OnStreamHeaderList(fin, h.uncompressed_header_bytes(), h);
168 return h;
169 }
170
171 QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
172 return GetNthClientInitiatedBidirectionalStreamId(
173 connection_->transport_version(), n);
174 }
175
176 bool HasFrameHeader() const {
177 return VersionHasDataFrameHeader(connection_->transport_version());
178 }
179
180 protected:
181 MockQuicConnectionHelper helper_;
182 MockAlarmFactory alarm_factory_;
183 MockQuicConnection* connection_;
184 std::unique_ptr<MockQuicSpdySession> session_;
185
186 // Owned by the |session_|.
187 TestStream* stream_;
188 TestStream* stream2_;
189
190 SpdyHeaderBlock headers_;
191
192 HttpEncoder encoder_;
193};
194
vasilvvc48c8712019-03-11 13:38:16 -0700195INSTANTIATE_TEST_SUITE_P(Tests,
196 QuicSpdyStreamTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500197 ::testing::ValuesIn(AllSupportedVersions()));
198
199TEST_P(QuicSpdyStreamTest, ProcessHeaderList) {
200 Initialize(kShouldProcessData);
201
202 stream_->OnStreamHeadersPriority(kV3HighestPriority);
203 ProcessHeaders(false, headers_);
204 EXPECT_EQ("", stream_->data());
205 EXPECT_FALSE(stream_->header_list().empty());
206 EXPECT_FALSE(stream_->IsDoneReading());
207}
208
209TEST_P(QuicSpdyStreamTest, ProcessTooLargeHeaderList) {
210 Initialize(kShouldProcessData);
211
212 QuicHeaderList headers;
213 stream_->OnStreamHeadersPriority(kV3HighestPriority);
214
215 EXPECT_CALL(*session_,
216 SendRstStream(stream_->id(), QUIC_HEADERS_TOO_LARGE, 0));
217 stream_->OnStreamHeaderList(false, 1 << 20, headers);
218 EXPECT_EQ(QUIC_HEADERS_TOO_LARGE, stream_->stream_error());
219}
220
221TEST_P(QuicSpdyStreamTest, ProcessHeaderListWithFin) {
222 Initialize(kShouldProcessData);
223
224 size_t total_bytes = 0;
225 QuicHeaderList headers;
226 for (auto p : headers_) {
227 headers.OnHeader(p.first, p.second);
228 total_bytes += p.first.size() + p.second.size();
229 }
230 stream_->OnStreamHeadersPriority(kV3HighestPriority);
231 stream_->OnStreamHeaderList(true, total_bytes, headers);
232 EXPECT_EQ("", stream_->data());
233 EXPECT_FALSE(stream_->header_list().empty());
234 EXPECT_FALSE(stream_->IsDoneReading());
235 EXPECT_TRUE(stream_->HasFinalReceivedByteOffset());
236}
237
238TEST_P(QuicSpdyStreamTest, ParseHeaderStatusCode) {
239 // A valid status code should be 3-digit integer. The first digit should be in
240 // the range of [1, 5]. All the others are invalid.
241 Initialize(kShouldProcessData);
242 int status_code = 0;
243
244 // Valid status codes.
245 headers_[":status"] = "404";
246 EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
247 EXPECT_EQ(404, status_code);
248
249 headers_[":status"] = "100";
250 EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
251 EXPECT_EQ(100, status_code);
252
253 headers_[":status"] = "599";
254 EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
255 EXPECT_EQ(599, status_code);
256
257 // Invalid status codes.
258 headers_[":status"] = "010";
259 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
260
261 headers_[":status"] = "600";
262 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
263
264 headers_[":status"] = "200 ok";
265 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
266
267 headers_[":status"] = "2000";
268 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
269
270 headers_[":status"] = "+200";
271 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
272
273 headers_[":status"] = "+20";
274 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
275
276 headers_[":status"] = "-10";
277 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
278
279 headers_[":status"] = "-100";
280 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
281
282 // Leading or trailing spaces are also invalid.
283 headers_[":status"] = " 200";
284 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
285
286 headers_[":status"] = "200 ";
287 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
288
289 headers_[":status"] = " 200 ";
290 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
291
292 headers_[":status"] = " ";
293 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
294}
295
296TEST_P(QuicSpdyStreamTest, MarkHeadersConsumed) {
297 Initialize(kShouldProcessData);
298
vasilvvc48c8712019-03-11 13:38:16 -0700299 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500300 QuicHeaderList headers = ProcessHeaders(false, headers_);
301 EXPECT_EQ(headers, stream_->header_list());
302
303 stream_->ConsumeHeaderList();
304 EXPECT_EQ(QuicHeaderList(), stream_->header_list());
305}
306
307TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) {
308 Initialize(kShouldProcessData);
309
vasilvvc48c8712019-03-11 13:38:16 -0700310 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500311 std::unique_ptr<char[]> buffer;
312 QuicByteCount header_length =
313 encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700314 std::string header = std::string(buffer.get(), header_length);
315 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500316
317 EXPECT_EQ("", stream_->data());
318 QuicHeaderList headers = ProcessHeaders(false, headers_);
319 EXPECT_EQ(headers, stream_->header_list());
320 stream_->ConsumeHeaderList();
321 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
322 QuicStringPiece(data));
323 stream_->OnStreamFrame(frame);
324 EXPECT_EQ(QuicHeaderList(), stream_->header_list());
325 EXPECT_EQ(body, stream_->data());
326}
327
328TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) {
329 Initialize(kShouldProcessData);
vasilvvc48c8712019-03-11 13:38:16 -0700330 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500331 std::unique_ptr<char[]> buffer;
332 QuicByteCount header_length =
333 encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700334 std::string header = std::string(buffer.get(), header_length);
335 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500336
337 for (size_t fragment_size = 1; fragment_size < data.size(); ++fragment_size) {
338 Initialize(kShouldProcessData);
339 QuicHeaderList headers = ProcessHeaders(false, headers_);
340 ASSERT_EQ(headers, stream_->header_list());
341 stream_->ConsumeHeaderList();
342 for (size_t offset = 0; offset < data.size(); offset += fragment_size) {
343 size_t remaining_data = data.size() - offset;
344 QuicStringPiece fragment(data.data() + offset,
345 std::min(fragment_size, remaining_data));
346 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false,
347 offset, QuicStringPiece(fragment));
348 stream_->OnStreamFrame(frame);
349 }
350 ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size;
351 }
352}
353
354TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
355 Initialize(kShouldProcessData);
vasilvvc48c8712019-03-11 13:38:16 -0700356 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500357 std::unique_ptr<char[]> buffer;
358 QuicByteCount header_length =
359 encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700360 std::string header = std::string(buffer.get(), header_length);
361 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500362
363 for (size_t split_point = 1; split_point < data.size() - 1; ++split_point) {
364 Initialize(kShouldProcessData);
365 QuicHeaderList headers = ProcessHeaders(false, headers_);
366 ASSERT_EQ(headers, stream_->header_list());
367 stream_->ConsumeHeaderList();
368
369 QuicStringPiece fragment1(data.data(), split_point);
370 QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
371 QuicStringPiece(fragment1));
372 stream_->OnStreamFrame(frame1);
373
374 QuicStringPiece fragment2(data.data() + split_point,
375 data.size() - split_point);
376 QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
377 split_point, QuicStringPiece(fragment2));
378 stream_->OnStreamFrame(frame2);
379
380 ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point;
381 }
382}
383
384TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) {
385 Initialize(!kShouldProcessData);
386
vasilvvc48c8712019-03-11 13:38:16 -0700387 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500388 std::unique_ptr<char[]> buf;
389 QuicByteCount header_length =
390 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700391 std::string header = std::string(buf.get(), header_length);
392 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500393
394 ProcessHeaders(false, headers_);
395 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
396 QuicStringPiece(data));
397 stream_->OnStreamFrame(frame);
398 stream_->ConsumeHeaderList();
399
400 char buffer[2048];
401 ASSERT_LT(data.length(), QUIC_ARRAYSIZE(buffer));
402 struct iovec vec;
403 vec.iov_base = buffer;
404 vec.iov_len = QUIC_ARRAYSIZE(buffer);
405
406 size_t bytes_read = stream_->Readv(&vec, 1);
407 EXPECT_EQ(body.length(), bytes_read);
vasilvvc48c8712019-03-11 13:38:16 -0700408 EXPECT_EQ(body, std::string(buffer, bytes_read));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500409}
410
411TEST_P(QuicSpdyStreamTest, ProcessHeadersAndLargeBodySmallReadv) {
412 Initialize(kShouldProcessData);
vasilvvc48c8712019-03-11 13:38:16 -0700413 std::string body(12 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500414 std::unique_ptr<char[]> buf;
415 QuicByteCount header_length =
416 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700417 std::string header = std::string(buf.get(), header_length);
418 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500419 ProcessHeaders(false, headers_);
420 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
421 QuicStringPiece(data));
422 stream_->OnStreamFrame(frame);
423 stream_->ConsumeHeaderList();
424 char buffer[2048];
425 char buffer2[2048];
426 struct iovec vec[2];
427 vec[0].iov_base = buffer;
428 vec[0].iov_len = QUIC_ARRAYSIZE(buffer);
429 vec[1].iov_base = buffer2;
430 vec[1].iov_len = QUIC_ARRAYSIZE(buffer2);
431 size_t bytes_read = stream_->Readv(vec, 2);
432 EXPECT_EQ(2048u * 2, bytes_read);
vasilvvc48c8712019-03-11 13:38:16 -0700433 EXPECT_EQ(body.substr(0, 2048), std::string(buffer, 2048));
434 EXPECT_EQ(body.substr(2048, 2048), std::string(buffer2, 2048));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500435}
436
437TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) {
438 Initialize(!kShouldProcessData);
439
vasilvvc48c8712019-03-11 13:38:16 -0700440 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500441 std::unique_ptr<char[]> buf;
442 QuicByteCount header_length =
443 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700444 std::string header = std::string(buf.get(), header_length);
445 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500446
447 ProcessHeaders(false, headers_);
448 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
449 QuicStringPiece(data));
450 stream_->OnStreamFrame(frame);
451 stream_->ConsumeHeaderList();
452
453 struct iovec vec;
454
455 EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1));
456 EXPECT_EQ(body.length(), vec.iov_len);
vasilvvc48c8712019-03-11 13:38:16 -0700457 EXPECT_EQ(body, std::string(static_cast<char*>(vec.iov_base), vec.iov_len));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500458
459 stream_->MarkConsumed(body.length());
460 EXPECT_EQ(data.length(), stream_->flow_controller()->bytes_consumed());
461}
462
463TEST_P(QuicSpdyStreamTest, ProcessHeadersAndConsumeMultipleBody) {
464 Initialize(!kShouldProcessData);
vasilvvc48c8712019-03-11 13:38:16 -0700465 std::string body1 = "this is body 1";
466 std::string body2 = "body 2";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500467 std::unique_ptr<char[]> buf;
468 QuicByteCount header_length =
469 encoder_.SerializeDataFrameHeader(body1.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700470 std::string header = std::string(buf.get(), header_length);
471 std::string data1 = HasFrameHeader() ? header + body1 : body1;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500472 header_length = encoder_.SerializeDataFrameHeader(body2.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700473 std::string data2 = HasFrameHeader() ? header + body2 : body2;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500474
475 ProcessHeaders(false, headers_);
476 QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
477 QuicStringPiece(data1));
478 QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
479 data1.length(), QuicStringPiece(data2));
480 stream_->OnStreamFrame(frame1);
481 stream_->OnStreamFrame(frame2);
482 stream_->ConsumeHeaderList();
483
484 stream_->MarkConsumed(body1.length() + body2.length());
485 EXPECT_EQ(data1.length() + data2.length(),
486 stream_->flow_controller()->bytes_consumed());
487}
488
489TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
490 Initialize(!kShouldProcessData);
491
vasilvvc48c8712019-03-11 13:38:16 -0700492 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500493 std::unique_ptr<char[]> buf;
494 QuicByteCount header_length =
495 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700496 std::string header = std::string(buf.get(), header_length);
497 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500498
499 ProcessHeaders(false, headers_);
500 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
501 QuicStringPiece(data));
502 stream_->OnStreamFrame(frame);
503 stream_->ConsumeHeaderList();
504
505 char buffer[1];
506 struct iovec vec;
507 vec.iov_base = buffer;
508 vec.iov_len = QUIC_ARRAYSIZE(buffer);
509
510 for (size_t i = 0; i < body.length(); ++i) {
511 size_t bytes_read = stream_->Readv(&vec, 1);
512 ASSERT_EQ(1u, bytes_read);
513 EXPECT_EQ(body.data()[i], buffer[0]);
514 }
515}
516
517TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
518 Initialize(!kShouldProcessData);
519
vasilvvc48c8712019-03-11 13:38:16 -0700520 std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500521 std::unique_ptr<char[]> buf;
522 QuicByteCount header_length =
523 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700524 std::string header = std::string(buf.get(), header_length);
525 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500526
527 ProcessHeaders(false, headers_);
528 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
529 QuicStringPiece(data));
530 stream_->OnStreamFrame(frame);
531 stream_->ConsumeHeaderList();
532
533 char buffer1[1];
534 char buffer2[1];
535 struct iovec vec[2];
536 vec[0].iov_base = buffer1;
537 vec[0].iov_len = QUIC_ARRAYSIZE(buffer1);
538 vec[1].iov_base = buffer2;
539 vec[1].iov_len = QUIC_ARRAYSIZE(buffer2);
540
541 for (size_t i = 0; i < body.length(); i += 2) {
542 size_t bytes_read = stream_->Readv(vec, 2);
543 ASSERT_EQ(2u, bytes_read) << i;
544 ASSERT_EQ(body.data()[i], buffer1[0]) << i;
545 ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i;
546 }
547}
548
549TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) {
550 testing::InSequence seq;
551 // Tests that we send a BLOCKED frame to the peer when we attempt to write,
552 // but are flow control blocked.
553 Initialize(kShouldProcessData);
554
555 // Set a small flow control limit.
556 const uint64_t kWindow = 36;
557 QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(),
558 kWindow);
559 EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset(
560 stream_->flow_controller()));
561
562 // Try to send more data than the flow control limit allows.
563 const uint64_t kOverflow = 15;
vasilvvc48c8712019-03-11 13:38:16 -0700564 std::string body(kWindow + kOverflow, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500565
566 const uint64_t kHeaderLength = HasFrameHeader() ? 2 : 0;
567 if (HasFrameHeader()) {
568 EXPECT_CALL(*session_, WritevData(_, _, kHeaderLength, _, NO_FIN));
569 }
570 EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
571 .WillOnce(Return(QuicConsumedData(kWindow - kHeaderLength, true)));
572 EXPECT_CALL(*connection_, SendControlFrame(_));
573 stream_->WriteOrBufferBody(body, false);
574
575 // Should have sent as much as possible, resulting in no send window left.
576 EXPECT_EQ(0u,
577 QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller()));
578
579 // And we should have queued the overflowed data.
580 EXPECT_EQ(kOverflow + kHeaderLength,
581 QuicStreamPeer::SizeOfQueuedData(stream_));
582}
583
584TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
585 // The flow control receive window decreases whenever we add new bytes to the
586 // sequencer, whether they are consumed immediately or buffered. However we
587 // only send WINDOW_UPDATE frames based on increasing number of bytes
588 // consumed.
589
590 // Don't process data - it will be buffered instead.
591 Initialize(!kShouldProcessData);
592
593 // Expect no WINDOW_UPDATE frames to be sent.
594 EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0);
595
596 // Set a small flow control receive window.
597 const uint64_t kWindow = 36;
598 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
599 kWindow);
600 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
601 kWindow);
602 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset(
603 stream_->flow_controller()));
604
605 // Stream receives enough data to fill a fraction of the receive window.
vasilvvc48c8712019-03-11 13:38:16 -0700606 std::string body(kWindow / 3, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500607 QuicByteCount header_length = 0;
vasilvvc48c8712019-03-11 13:38:16 -0700608 std::string data;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500609
610 if (HasFrameHeader()) {
611 std::unique_ptr<char[]> buffer;
612 header_length = encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700613 std::string header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500614 data = header + body;
615 } else {
616 data = body;
617 }
618
619 ProcessHeaders(false, headers_);
620
621 QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
622 QuicStringPiece(data));
623 stream_->OnStreamFrame(frame1);
624 EXPECT_EQ(
625 kWindow - (kWindow / 3) - header_length,
626 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller()));
627
628 // Now receive another frame which results in the receive window being over
629 // half full. This should all be buffered, decreasing the receive window but
630 // not sending WINDOW_UPDATE.
631 QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
632 kWindow / 3 + header_length, QuicStringPiece(data));
633 stream_->OnStreamFrame(frame2);
634 EXPECT_EQ(
635 kWindow - (2 * kWindow / 3) - 2 * header_length,
636 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller()));
637}
638
639TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) {
640 // Tests that on receipt of data, the stream updates its receive window offset
641 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops
642 // too low.
643 Initialize(kShouldProcessData);
644
645 // Set a small flow control limit.
646 const uint64_t kWindow = 36;
647 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
648 kWindow);
649 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
650 kWindow);
651 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset(
652 stream_->flow_controller()));
653
654 // Stream receives enough data to fill a fraction of the receive window.
vasilvvc48c8712019-03-11 13:38:16 -0700655 std::string body(kWindow / 3, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500656 QuicByteCount header_length = 0;
vasilvvc48c8712019-03-11 13:38:16 -0700657 std::string data;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500658
659 if (HasFrameHeader()) {
660 std::unique_ptr<char[]> buffer;
661 header_length = encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700662 std::string header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500663 data = header + body;
664 } else {
665 data = body;
666 }
667
668 ProcessHeaders(false, headers_);
669 stream_->ConsumeHeaderList();
670
671 QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
672 QuicStringPiece(data));
673 stream_->OnStreamFrame(frame1);
674 EXPECT_EQ(
675 kWindow - (kWindow / 3) - header_length,
676 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller()));
677
678 // Now receive another frame which results in the receive window being over
679 // half full. This will trigger the stream to increase its receive window
680 // offset and send a WINDOW_UPDATE. The result will be again an available
681 // window of kWindow bytes.
682 QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
683 kWindow / 3 + header_length, QuicStringPiece(data));
684 EXPECT_CALL(*connection_, SendControlFrame(_));
685 stream_->OnStreamFrame(frame2);
686 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize(
687 stream_->flow_controller()));
688}
689
690TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) {
691 // Tests that on receipt of data, the connection updates its receive window
692 // offset appropriately, and sends WINDOW_UPDATE frames when its receive
693 // window drops too low.
694 Initialize(kShouldProcessData);
695
696 // Set a small flow control limit for streams and connection.
697 const uint64_t kWindow = 36;
698 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
699 kWindow);
700 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
701 kWindow);
702 QuicFlowControllerPeer::SetReceiveWindowOffset(stream2_->flow_controller(),
703 kWindow);
704 QuicFlowControllerPeer::SetMaxReceiveWindow(stream2_->flow_controller(),
705 kWindow);
706 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
707 kWindow);
708 QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(),
709 kWindow);
710
711 // Supply headers to both streams so that they are happy to receive data.
712 auto headers = AsHeaderList(headers_);
713 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
714 headers);
715 stream_->ConsumeHeaderList();
716 stream2_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
717 headers);
718 stream2_->ConsumeHeaderList();
719
720 // Each stream gets a quarter window of data. This should not trigger a
721 // WINDOW_UPDATE for either stream, nor for the connection.
722 QuicByteCount header_length = 0;
vasilvvc48c8712019-03-11 13:38:16 -0700723 std::string body;
724 std::string data;
725 std::string data2;
726 std::string body2(1, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500727
728 if (HasFrameHeader()) {
vasilvvc48c8712019-03-11 13:38:16 -0700729 body = std::string(kWindow / 4 - 2, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500730 std::unique_ptr<char[]> buffer;
731 header_length = encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700732 std::string header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500733 data = header + body;
734 std::unique_ptr<char[]> buffer2;
735 QuicByteCount header_length2 =
736 encoder_.SerializeDataFrameHeader(body2.length(), &buffer2);
vasilvvc48c8712019-03-11 13:38:16 -0700737 std::string header2 = std::string(buffer2.get(), header_length2);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500738 data2 = header2 + body2;
739 } else {
vasilvvc48c8712019-03-11 13:38:16 -0700740 body = std::string(kWindow / 4, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500741 data = body;
742 data2 = body2;
743 }
744
745 QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
746 QuicStringPiece(data));
747 stream_->OnStreamFrame(frame1);
748 QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
749 QuicStringPiece(data));
750 stream2_->OnStreamFrame(frame2);
751
752 // Now receive a further single byte on one stream - again this does not
753 // trigger a stream WINDOW_UPDATE, but now the connection flow control window
754 // is over half full and thus a connection WINDOW_UPDATE is sent.
755 EXPECT_CALL(*connection_, SendControlFrame(_));
756 QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false,
757 body.length() + header_length, QuicStringPiece(data2));
758 stream_->OnStreamFrame(frame3);
759}
760
761TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) {
762 // Tests that on if the peer sends too much data (i.e. violates the flow
763 // control protocol), then we terminate the connection.
764
765 // Stream should not process data, so that data gets buffered in the
766 // sequencer, triggering flow control limits.
767 Initialize(!kShouldProcessData);
768
769 // Set a small flow control limit.
770 const uint64_t kWindow = 50;
771 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
772 kWindow);
773
774 ProcessHeaders(false, headers_);
775
776 // Receive data to overflow the window, violating flow control.
vasilvvc48c8712019-03-11 13:38:16 -0700777 std::string body(kWindow + 1, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500778 std::unique_ptr<char[]> buf;
779 QuicByteCount header_length =
780 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700781 std::string header = std::string(buf.get(), header_length);
782 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500783 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
784 QuicStringPiece(data));
785 EXPECT_CALL(*connection_,
786 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
787 stream_->OnStreamFrame(frame);
788}
789
790TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) {
791 Initialize(kShouldProcessData);
792 ProcessHeaders(false, headers_);
793
794 stream_->OnStreamReset(QuicRstStreamFrame(
795 kInvalidControlFrameId, stream_->id(), QUIC_STREAM_NO_ERROR, 0));
796 EXPECT_TRUE(stream_->write_side_closed());
797 EXPECT_FALSE(stream_->reading_stopped());
798}
799
800TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) {
801 // Tests that on if the peer sends too much data (i.e. violates the flow
802 // control protocol), at the connection level (rather than the stream level)
803 // then we terminate the connection.
804
805 // Stream should not process data, so that data gets buffered in the
806 // sequencer, triggering flow control limits.
807 Initialize(!kShouldProcessData);
808
809 // Set a small flow control window on streams, and connection.
810 const uint64_t kStreamWindow = 50;
811 const uint64_t kConnectionWindow = 10;
812 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
813 kStreamWindow);
814 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
815 kConnectionWindow);
816
817 ProcessHeaders(false, headers_);
818
819 // Send enough data to overflow the connection level flow control window.
vasilvvc48c8712019-03-11 13:38:16 -0700820 std::string body(kConnectionWindow + 1, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500821 std::unique_ptr<char[]> buf;
822 QuicByteCount header_length =
823 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700824 std::string header = std::string(buf.get(), header_length);
825 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500826
827 EXPECT_LT(data.size(), kStreamWindow);
828 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
829 QuicStringPiece(data));
830
831 EXPECT_CALL(*connection_,
832 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
833 stream_->OnStreamFrame(frame);
834}
835
836TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) {
837 // An attempt to write a FIN with no data should not be flow control blocked,
838 // even if the send window is 0.
839
840 Initialize(kShouldProcessData);
841
842 // Set a flow control limit of zero.
843 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0);
844 EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset(
845 stream_->flow_controller()));
846
847 // Send a frame with a FIN but no data. This should not be blocked.
vasilvvc48c8712019-03-11 13:38:16 -0700848 std::string body = "";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500849 bool fin = true;
850
851 EXPECT_CALL(*connection_,
852 SendBlocked(GetNthClientInitiatedBidirectionalId(0)))
853 .Times(0);
854 EXPECT_CALL(*session_, WritevData(_, _, 0, _, FIN));
855
856 stream_->WriteOrBufferBody(body, fin);
857}
858
859TEST_P(QuicSpdyStreamTest, ReceivingTrailersViaHeaderList) {
860 // Test that receiving trailing headers from the peer via
861 // OnStreamHeaderList() works, and can be read from the stream and consumed.
862 Initialize(kShouldProcessData);
863
864 // Receive initial headers.
865 size_t total_bytes = 0;
866 QuicHeaderList headers;
867 for (const auto& p : headers_) {
868 headers.OnHeader(p.first, p.second);
869 total_bytes += p.first.size() + p.second.size();
870 }
871
872 stream_->OnStreamHeadersPriority(kV3HighestPriority);
873 stream_->OnStreamHeaderList(/*fin=*/false, total_bytes, headers);
874 stream_->ConsumeHeaderList();
875
876 // Receive trailing headers.
877 SpdyHeaderBlock trailers_block;
878 trailers_block["key1"] = "value1";
879 trailers_block["key2"] = "value2";
880 trailers_block["key3"] = "value3";
881 SpdyHeaderBlock trailers_block_with_final_offset = trailers_block.Clone();
882 trailers_block_with_final_offset[kFinalOffsetHeaderKey] = "0";
883 total_bytes = 0;
884 QuicHeaderList trailers;
885 for (const auto& p : trailers_block_with_final_offset) {
886 trailers.OnHeader(p.first, p.second);
887 total_bytes += p.first.size() + p.second.size();
888 }
889 stream_->OnStreamHeaderList(/*fin=*/true, total_bytes, trailers);
890
891 // The trailers should be decompressed, and readable from the stream.
892 EXPECT_TRUE(stream_->trailers_decompressed());
893 EXPECT_EQ(trailers_block, stream_->received_trailers());
894
895 // IsDoneReading() returns false until trailers marked consumed.
896 EXPECT_FALSE(stream_->IsDoneReading());
897 stream_->MarkTrailersConsumed();
898 EXPECT_TRUE(stream_->IsDoneReading());
899}
900
901TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithOffset) {
902 // Test that when receiving trailing headers with an offset before response
903 // body, stream is closed at the right offset.
904 Initialize(kShouldProcessData);
905
906 // Receive initial headers.
907 QuicHeaderList headers = ProcessHeaders(false, headers_);
908 stream_->ConsumeHeaderList();
909
vasilvvc48c8712019-03-11 13:38:16 -0700910 const std::string body = "this is the body";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500911 std::unique_ptr<char[]> buf;
912 QuicByteCount header_length =
913 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -0700914 std::string header = std::string(buf.get(), header_length);
915 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500916
917 // Receive trailing headers.
918 SpdyHeaderBlock trailers_block;
919 trailers_block["key1"] = "value1";
920 trailers_block["key2"] = "value2";
921 trailers_block["key3"] = "value3";
922 trailers_block[kFinalOffsetHeaderKey] =
923 QuicTextUtils::Uint64ToString(data.size());
924
925 QuicHeaderList trailers = ProcessHeaders(true, trailers_block);
926
927 // The trailers should be decompressed, and readable from the stream.
928 EXPECT_TRUE(stream_->trailers_decompressed());
929
930 // The final offset trailer will be consumed by QUIC.
931 trailers_block.erase(kFinalOffsetHeaderKey);
932 EXPECT_EQ(trailers_block, stream_->received_trailers());
933
934 // Consuming the trailers erases them from the stream.
935 stream_->MarkTrailersConsumed();
936 EXPECT_TRUE(stream_->FinishedReadingTrailers());
937
938 EXPECT_FALSE(stream_->IsDoneReading());
939 // Receive and consume body.
940 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/false,
941 0, data);
942 stream_->OnStreamFrame(frame);
943 EXPECT_EQ(body, stream_->data());
944 EXPECT_TRUE(stream_->IsDoneReading());
945}
946
947TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) {
948 // Test that receiving trailers without a final offset field is an error.
949 Initialize(kShouldProcessData);
950
951 // Receive initial headers.
952 ProcessHeaders(false, headers_);
953 stream_->ConsumeHeaderList();
954
955 // Receive trailing headers, without kFinalOffsetHeaderKey.
956 SpdyHeaderBlock trailers_block;
957 trailers_block["key1"] = "value1";
958 trailers_block["key2"] = "value2";
959 trailers_block["key3"] = "value3";
960 auto trailers = AsHeaderList(trailers_block);
961
962 // Verify that the trailers block didn't contain a final offset.
963 EXPECT_EQ("", trailers_block[kFinalOffsetHeaderKey].as_string());
964
965 // Receipt of the malformed trailers will close the connection.
966 EXPECT_CALL(*connection_,
967 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
968 .Times(1);
969 stream_->OnStreamHeaderList(/*fin=*/true,
970 trailers.uncompressed_header_bytes(), trailers);
971}
972
973TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutFin) {
974 // Test that received Trailers must always have the FIN set.
975 Initialize(kShouldProcessData);
976
977 // Receive initial headers.
978 auto headers = AsHeaderList(headers_);
979 stream_->OnStreamHeaderList(/*fin=*/false,
980 headers.uncompressed_header_bytes(), headers);
981 stream_->ConsumeHeaderList();
982
983 // Receive trailing headers with FIN deliberately set to false.
984 SpdyHeaderBlock trailers_block;
985 trailers_block["foo"] = "bar";
986 auto trailers = AsHeaderList(trailers_block);
987
988 EXPECT_CALL(*connection_,
989 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
990 .Times(1);
991 stream_->OnStreamHeaderList(/*fin=*/false,
992 trailers.uncompressed_header_bytes(), trailers);
993}
994
995TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterHeadersWithFin) {
996 // If headers are received with a FIN, no trailers should then arrive.
997 Initialize(kShouldProcessData);
998
999 // Receive initial headers with FIN set.
1000 ProcessHeaders(true, headers_);
1001 stream_->ConsumeHeaderList();
1002
1003 // Receive trailing headers after FIN already received.
1004 SpdyHeaderBlock trailers_block;
1005 trailers_block["foo"] = "bar";
1006 EXPECT_CALL(*connection_,
1007 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
1008 .Times(1);
1009 ProcessHeaders(true, trailers_block);
1010}
1011
1012TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) {
1013 // If body data are received with a FIN, no trailers should then arrive.
1014 Initialize(kShouldProcessData);
1015
1016 // Receive initial headers without FIN set.
1017 ProcessHeaders(false, headers_);
1018 stream_->ConsumeHeaderList();
1019
1020 // Receive body data, with FIN.
1021 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
1022 0, "body");
1023 stream_->OnStreamFrame(frame);
1024
1025 // Receive trailing headers after FIN already received.
1026 SpdyHeaderBlock trailers_block;
1027 trailers_block["foo"] = "bar";
1028 EXPECT_CALL(*connection_,
1029 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
1030 .Times(1);
1031 ProcessHeaders(true, trailers_block);
1032}
1033
1034TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) {
1035 // Verify that a stream receiving headers, body, and no trailers is correctly
1036 // marked as done reading on consumption of headers and body.
1037 Initialize(kShouldProcessData);
1038
1039 // Receive and consume initial headers with FIN not set.
1040 auto h = AsHeaderList(headers_);
1041 stream_->OnStreamHeaderList(/*fin=*/false, h.uncompressed_header_bytes(), h);
1042 stream_->ConsumeHeaderList();
1043
1044 // Receive and consume body with FIN set, and no trailers.
vasilvvc48c8712019-03-11 13:38:16 -07001045 std::string body(1024, 'x');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001046 std::unique_ptr<char[]> buf;
1047 QuicByteCount header_length =
1048 encoder_.SerializeDataFrameHeader(body.length(), &buf);
vasilvvc48c8712019-03-11 13:38:16 -07001049 std::string header = std::string(buf.get(), header_length);
1050 std::string data = HasFrameHeader() ? header + body : body;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001051
1052 QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
1053 0, data);
1054 stream_->OnStreamFrame(frame);
1055
1056 EXPECT_TRUE(stream_->IsDoneReading());
1057}
1058
1059TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) {
1060 // Test that writing trailers will send a FIN, as Trailers are the last thing
1061 // to be sent on a stream.
1062 Initialize(kShouldProcessData);
1063
1064 // Write the initial headers, without a FIN.
1065 EXPECT_CALL(*stream_, WriteHeadersMock(false));
1066 stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
1067
1068 // Writing trailers implicitly sends a FIN.
1069 SpdyHeaderBlock trailers;
1070 trailers["trailer key"] = "trailer value";
1071 EXPECT_CALL(*stream_, WriteHeadersMock(true));
1072 stream_->WriteTrailers(std::move(trailers), nullptr);
1073 EXPECT_TRUE(stream_->fin_sent());
1074}
1075
1076TEST_P(QuicSpdyStreamTest, WritingTrailersFinalOffset) {
1077 // Test that when writing trailers, the trailers that are actually sent to the
1078 // peer contain the final offset field indicating last byte of data.
1079 Initialize(kShouldProcessData);
1080
1081 // Write the initial headers.
1082 EXPECT_CALL(*stream_, WriteHeadersMock(false));
1083 stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
1084
1085 // Write non-zero body data to force a non-zero final offset.
1086 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
vasilvvc48c8712019-03-11 13:38:16 -07001087 std::string body(1024, 'x'); // 1 kB
QUICHE teama6ef0a62019-03-07 20:34:33 -05001088 QuicByteCount header_length = 0;
1089 if (HasFrameHeader()) {
1090 std::unique_ptr<char[]> buf;
1091 header_length = encoder_.SerializeDataFrameHeader(body.length(), &buf);
1092 }
1093
1094 stream_->WriteOrBufferBody(body, false);
1095
1096 // The final offset field in the trailing headers is populated with the
1097 // number of body bytes written (including queued bytes).
1098 SpdyHeaderBlock trailers;
1099 trailers["trailer key"] = "trailer value";
1100 SpdyHeaderBlock trailers_with_offset(trailers.Clone());
1101 trailers_with_offset[kFinalOffsetHeaderKey] =
1102 QuicTextUtils::Uint64ToString(body.length() + header_length);
1103 EXPECT_CALL(*stream_, WriteHeadersMock(true));
1104 stream_->WriteTrailers(std::move(trailers), nullptr);
1105 EXPECT_EQ(trailers_with_offset, stream_->saved_headers());
1106}
1107
1108TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) {
1109 // Test that if trailers are written after all other data has been written
1110 // (headers and body), that this closes the stream for writing.
1111 Initialize(kShouldProcessData);
1112
1113 // Write the initial headers.
1114 EXPECT_CALL(*stream_, WriteHeadersMock(false));
1115 stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
1116
1117 // Write non-zero body data.
1118 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1119 const int kBodySize = 1 * 1024; // 1 kB
vasilvvc48c8712019-03-11 13:38:16 -07001120 stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001121 EXPECT_EQ(0u, stream_->BufferedDataBytes());
1122
1123 // Headers and body have been fully written, there is no queued data. Writing
1124 // trailers marks the end of this stream, and thus the write side is closed.
1125 EXPECT_CALL(*stream_, WriteHeadersMock(true));
1126 stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
1127 EXPECT_TRUE(stream_->write_side_closed());
1128}
1129
1130TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
1131 // Test that the stream is not closed for writing when trailers are sent
1132 // while there are still body bytes queued.
1133 testing::InSequence seq;
1134 Initialize(kShouldProcessData);
1135
1136 // Write the initial headers.
1137 EXPECT_CALL(*stream_, WriteHeadersMock(false));
1138 stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
1139
1140 // Write non-zero body data, but only consume partially, ensuring queueing.
1141 const int kBodySize = 1 * 1024; // 1 kB
1142 if (HasFrameHeader()) {
1143 EXPECT_CALL(*session_, WritevData(_, _, 3, _, NO_FIN));
1144 }
1145 EXPECT_CALL(*session_, WritevData(_, _, kBodySize, _, NO_FIN))
1146 .WillOnce(Return(QuicConsumedData(kBodySize - 1, false)));
vasilvvc48c8712019-03-11 13:38:16 -07001147 stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001148 EXPECT_EQ(1u, stream_->BufferedDataBytes());
1149
1150 // Writing trailers will send a FIN, but not close the write side of the
1151 // stream as there are queued bytes.
1152 EXPECT_CALL(*stream_, WriteHeadersMock(true));
1153 stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
1154 EXPECT_TRUE(stream_->fin_sent());
1155 EXPECT_FALSE(stream_->write_side_closed());
1156
1157 // Writing the queued bytes will close the write side of the stream.
1158 EXPECT_CALL(*session_, WritevData(_, _, 1, _, NO_FIN));
1159 stream_->OnCanWrite();
1160 EXPECT_TRUE(stream_->write_side_closed());
1161}
1162
1163TEST_P(QuicSpdyStreamTest, WritingTrailersAfterFIN) {
1164 // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
1165 if (GetParam() != AllSupportedVersions()[0]) {
1166 return;
1167 }
1168
1169 // Test that it is not possible to write Trailers after a FIN has been sent.
1170 Initialize(kShouldProcessData);
1171
1172 // Write the initial headers, with a FIN.
1173 EXPECT_CALL(*stream_, WriteHeadersMock(true));
1174 stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr);
1175 EXPECT_TRUE(stream_->fin_sent());
1176
1177 // Writing Trailers should fail, as the FIN has already been sent.
1178 // populated with the number of body bytes written.
1179 EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr),
1180 "Trailers cannot be sent after a FIN");
1181}
1182
1183TEST_P(QuicSpdyStreamTest, HeaderStreamNotiferCorrespondingSpdyStream) {
1184 Initialize(kShouldProcessData);
1185 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1186 testing::InSequence s;
1187 QuicReferenceCountedPointer<MockAckListener> ack_listener1(
1188 new MockAckListener());
1189 QuicReferenceCountedPointer<MockAckListener> ack_listener2(
1190 new MockAckListener());
1191 stream_->set_ack_listener(ack_listener1);
1192 stream2_->set_ack_listener(ack_listener2);
1193
1194 session_->headers_stream()->WriteOrBufferData("Header1", false,
1195 ack_listener1);
1196 stream_->WriteOrBufferBody("Test1", true);
1197
1198 session_->headers_stream()->WriteOrBufferData("Header2", false,
1199 ack_listener2);
1200 stream2_->WriteOrBufferBody("Test2", false);
1201
1202 QuicStreamFrame frame1(
1203 QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 0,
1204 "Header1");
vasilvvc48c8712019-03-11 13:38:16 -07001205 std::string header = "";
QUICHE teama6ef0a62019-03-07 20:34:33 -05001206 if (HasFrameHeader()) {
1207 std::unique_ptr<char[]> buffer;
1208 QuicByteCount header_length = encoder_.SerializeDataFrameHeader(5, &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001209 header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001210 }
1211 QuicStreamFrame frame2(stream_->id(), true, 0, header + "Test1");
1212 QuicStreamFrame frame3(
1213 QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 7,
1214 "Header2");
1215 QuicStreamFrame frame4(stream2_->id(), false, 0, header + "Test2");
1216
1217 EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(7));
1218 session_->OnStreamFrameRetransmitted(frame1);
1219
1220 EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
1221 EXPECT_TRUE(
1222 session_->OnFrameAcked(QuicFrame(frame1), QuicTime::Delta::Zero()));
1223 EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
1224 EXPECT_TRUE(
1225 session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero()));
1226 EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
1227 EXPECT_TRUE(
1228 session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero()));
1229 EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
1230 EXPECT_TRUE(
1231 session_->OnFrameAcked(QuicFrame(frame4), QuicTime::Delta::Zero()));
1232}
1233
1234TEST_P(QuicSpdyStreamTest, StreamBecomesZombieWithWriteThatCloses) {
1235 Initialize(kShouldProcessData);
1236 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1237 QuicStreamPeer::CloseReadSide(stream_);
1238 // This write causes stream to be closed.
1239 stream_->WriteOrBufferBody("Test1", true);
1240 // stream_ has unacked data and should become zombie.
1241 EXPECT_TRUE(QuicContainsKey(QuicSessionPeer::zombie_streams(session_.get()),
1242 stream_->id()));
1243 EXPECT_TRUE(QuicSessionPeer::closed_streams(session_.get()).empty());
1244}
1245
1246TEST_P(QuicSpdyStreamTest, OnPriorityFrame) {
1247 Initialize(kShouldProcessData);
1248 stream_->OnPriorityFrame(kV3HighestPriority);
1249 EXPECT_EQ(kV3HighestPriority, stream_->priority());
1250}
1251
1252TEST_P(QuicSpdyStreamTest, OnPriorityFrameAfterSendingData) {
1253 testing::InSequence seq;
1254 Initialize(kShouldProcessData);
1255
1256 if (HasFrameHeader()) {
1257 EXPECT_CALL(*session_, WritevData(_, _, 2, _, NO_FIN));
1258 }
1259 EXPECT_CALL(*session_, WritevData(_, _, 4, _, FIN));
1260 stream_->WriteOrBufferBody("data", true);
1261 stream_->OnPriorityFrame(kV3HighestPriority);
1262 EXPECT_EQ(kV3HighestPriority, stream_->priority());
1263}
1264
1265TEST_P(QuicSpdyStreamTest, SetPriorityBeforeUpdateStreamPriority) {
1266 MockQuicConnection* connection = new StrictMock<MockQuicConnection>(
1267 &helper_, &alarm_factory_, Perspective::IS_SERVER,
1268 SupportedVersions(GetParam()));
1269 std::unique_ptr<TestMockUpdateStreamSession> session(
1270 new StrictMock<TestMockUpdateStreamSession>(connection));
1271 auto stream = new StrictMock<TestStream>(
1272 GetNthClientInitiatedBidirectionalStreamId(
1273 session->connection()->transport_version(), 0),
1274 session.get(),
1275 /*should_process_data=*/true);
1276 session->ActivateStream(QuicWrapUnique(stream));
1277
1278 // QuicSpdyStream::SetPriority() should eventually call UpdateStreamPriority()
1279 // on the session. Make sure stream->priority() returns the updated priority
1280 // if called within UpdateStreamPriority(). This expectation is enforced in
1281 // TestMockUpdateStreamSession::UpdateStreamPriority().
1282 session->SetExpectedStream(stream);
1283 session->SetExpectedPriority(kV3HighestPriority);
1284 stream->SetPriority(kV3HighestPriority);
1285
1286 session->SetExpectedPriority(kV3LowestPriority);
1287 stream->SetPriority(kV3LowestPriority);
1288}
1289
1290TEST_P(QuicSpdyStreamTest, StreamWaitsForAcks) {
1291 Initialize(kShouldProcessData);
1292 QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
1293 new StrictMock<MockAckListener>);
1294 stream_->set_ack_listener(mock_ack_listener);
1295 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1296 // Stream is not waiting for acks initially.
1297 EXPECT_FALSE(stream_->IsWaitingForAcks());
1298 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1299
1300 // Send kData1.
1301 stream_->WriteOrBufferData("FooAndBar", false, nullptr);
1302 EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1303 EXPECT_TRUE(stream_->IsWaitingForAcks());
1304 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
1305 QuicByteCount newly_acked_length = 0;
1306 EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
1307 &newly_acked_length));
1308 // Stream is not waiting for acks as all sent data is acked.
1309 EXPECT_FALSE(stream_->IsWaitingForAcks());
1310 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1311
1312 // Send kData2.
1313 stream_->WriteOrBufferData("FooAndBar", false, nullptr);
1314 EXPECT_TRUE(stream_->IsWaitingForAcks());
1315 EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1316 // Send FIN.
1317 stream_->WriteOrBufferData("", true, nullptr);
1318 // Fin only frame is not stored in send buffer.
1319 EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1320
1321 // kData2 is retransmitted.
1322 EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(9));
1323 stream_->OnStreamFrameRetransmitted(9, 9, false);
1324
1325 // kData2 is acked.
1326 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
1327 EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
1328 &newly_acked_length));
1329 // Stream is waiting for acks as FIN is not acked.
1330 EXPECT_TRUE(stream_->IsWaitingForAcks());
1331 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1332
1333 // FIN is acked.
1334 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
1335 EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 0, true, QuicTime::Delta::Zero(),
1336 &newly_acked_length));
1337 EXPECT_FALSE(stream_->IsWaitingForAcks());
1338 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1339}
1340
1341TEST_P(QuicSpdyStreamTest, StreamDataGetAckedMultipleTimes) {
1342 Initialize(kShouldProcessData);
1343 QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
1344 new StrictMock<MockAckListener>);
1345 stream_->set_ack_listener(mock_ack_listener);
1346 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1347 // Send [0, 27) and fin.
1348 stream_->WriteOrBufferData("FooAndBar", false, nullptr);
1349 stream_->WriteOrBufferData("FooAndBar", false, nullptr);
1350 stream_->WriteOrBufferData("FooAndBar", true, nullptr);
1351
1352 // Ack [0, 9), [5, 22) and [18, 26)
1353 // Verify [0, 9) 9 bytes are acked.
1354 QuicByteCount newly_acked_length = 0;
1355 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
1356 EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
1357 &newly_acked_length));
1358 EXPECT_EQ(2u, QuicStreamPeer::SendBuffer(stream_).size());
1359 // Verify [9, 22) 13 bytes are acked.
1360 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(13, _));
1361 EXPECT_TRUE(stream_->OnStreamFrameAcked(5, 17, false, QuicTime::Delta::Zero(),
1362 &newly_acked_length));
1363 EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1364 // Verify [22, 26) 4 bytes are acked.
1365 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(4, _));
1366 EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 8, false, QuicTime::Delta::Zero(),
1367 &newly_acked_length));
1368 EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1369 EXPECT_TRUE(stream_->IsWaitingForAcks());
1370
1371 // Ack [0, 27).
1372 // Verify [26, 27) 1 byte is acked.
1373 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(1, _));
1374 EXPECT_TRUE(stream_->OnStreamFrameAcked(26, 1, false, QuicTime::Delta::Zero(),
1375 &newly_acked_length));
1376 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1377 EXPECT_TRUE(stream_->IsWaitingForAcks());
1378
1379 // Ack Fin. Verify OnPacketAcked is called.
1380 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
1381 EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
1382 &newly_acked_length));
1383 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1384 EXPECT_FALSE(stream_->IsWaitingForAcks());
1385
1386 // Ack [10, 27) and fin.
1387 // No new data is acked, verify OnPacketAcked is not called.
1388 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(_, _)).Times(0);
1389 EXPECT_FALSE(stream_->OnStreamFrameAcked(
1390 10, 17, true, QuicTime::Delta::Zero(), &newly_acked_length));
1391 EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1392 EXPECT_FALSE(stream_->IsWaitingForAcks());
1393}
1394
1395// HTTP/3 only.
1396TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteOrBufferBody) {
1397 Initialize(kShouldProcessData);
1398 if (!HasFrameHeader()) {
1399 return;
1400 }
1401 QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
1402 new StrictMock<MockAckListener>);
1403 stream_->set_ack_listener(mock_ack_listener);
vasilvvc48c8712019-03-11 13:38:16 -07001404 std::string body = "Test1";
1405 std::string body2(100, 'x');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001406
1407 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1408 stream_->WriteOrBufferBody(body, false);
1409 stream_->WriteOrBufferBody(body2, true);
1410
1411 std::unique_ptr<char[]> buffer;
1412 QuicByteCount header_length =
1413 encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001414 std::string header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001415
1416 header_length = encoder_.SerializeDataFrameHeader(body2.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001417 std::string header2 = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001418
1419 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body.length(), _));
1420 QuicStreamFrame frame(stream_->id(), false, 0, header + body);
1421 EXPECT_TRUE(
1422 session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero()));
1423
1424 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
1425 QuicStreamFrame frame2(stream_->id(), false, (header + body).length(),
1426 header2);
1427 EXPECT_TRUE(
1428 session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero()));
1429
1430 EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body2.length(), _));
1431 QuicStreamFrame frame3(stream_->id(), true,
1432 (header + body).length() + header2.length(), body2);
1433 EXPECT_TRUE(
1434 session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero()));
1435
1436 EXPECT_TRUE(
1437 QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
1438}
1439
1440// HTTP/3 only.
1441TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteBodySlices) {
1442 Initialize(kShouldProcessData);
1443 if (!HasFrameHeader()) {
1444 return;
1445 }
1446 QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
1447 new StrictMock<MockAckListener>);
1448 stream_->set_ack_listener(mock_ack_listener);
vasilvvc48c8712019-03-11 13:38:16 -07001449 std::string body = "Test1";
1450 std::string body2(100, 'x');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001451 struct iovec body1_iov = {const_cast<char*>(body.data()), body.length()};
1452 struct iovec body2_iov = {const_cast<char*>(body2.data()), body2.length()};
1453 QuicMemSliceStorage storage(&body1_iov, 1,
1454 helper_.GetStreamSendBufferAllocator(), 1024);
1455 QuicMemSliceStorage storage2(&body2_iov, 1,
1456 helper_.GetStreamSendBufferAllocator(), 1024);
1457 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1458 stream_->WriteBodySlices(storage.ToSpan(), false);
1459 stream_->WriteBodySlices(storage2.ToSpan(), true);
1460
1461 std::unique_ptr<char[]> buffer;
1462 QuicByteCount header_length =
1463 encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001464 std::string header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001465
1466 header_length = encoder_.SerializeDataFrameHeader(body2.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001467 std::string header2 = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001468
1469 EXPECT_CALL(*mock_ack_listener,
1470 OnPacketAcked(body.length() + body2.length(), _));
1471 QuicStreamFrame frame(stream_->id(), true, 0,
1472 header + body + header2 + body2);
1473 EXPECT_TRUE(
1474 session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero()));
1475
1476 EXPECT_TRUE(
1477 QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
1478}
1479
1480// HTTP/3 only.
1481TEST_P(QuicSpdyStreamTest, HeaderBytesNotReportedOnRetransmission) {
1482 Initialize(kShouldProcessData);
1483 if (!HasFrameHeader()) {
1484 return;
1485 }
1486 QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
1487 new StrictMock<MockAckListener>);
1488 stream_->set_ack_listener(mock_ack_listener);
vasilvvc48c8712019-03-11 13:38:16 -07001489 std::string body = "Test1";
1490 std::string body2(100, 'x');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001491
1492 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
1493 stream_->WriteOrBufferBody(body, false);
1494 stream_->WriteOrBufferBody(body2, true);
1495
1496 std::unique_ptr<char[]> buffer;
1497 QuicByteCount header_length =
1498 encoder_.SerializeDataFrameHeader(body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001499 std::string header = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001500
1501 header_length = encoder_.SerializeDataFrameHeader(body2.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -07001502 std::string header2 = std::string(buffer.get(), header_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001503
1504 EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body.length()));
1505 QuicStreamFrame frame(stream_->id(), false, 0, header + body);
1506 session_->OnStreamFrameRetransmitted(frame);
1507
1508 EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body2.length()));
1509 QuicStreamFrame frame2(stream_->id(), true, (header + body).length(),
1510 header2 + body2);
1511 session_->OnStreamFrameRetransmitted(frame2);
1512
1513 EXPECT_FALSE(
1514 QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
1515}
1516
1517} // namespace
1518} // namespace test
1519} // namespace quic