OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/core/quic_spdy_stream.h" | 5 #include "net/quic/core/quic_spdy_stream.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 SupportedVersions(GetParam())); | 103 SupportedVersions(GetParam())); |
104 session_.reset(new testing::StrictMock<MockQuicSpdySession>(connection_)); | 104 session_.reset(new testing::StrictMock<MockQuicSpdySession>(connection_)); |
105 stream_ = new TestStream(kClientDataStreamId1, session_.get(), | 105 stream_ = new TestStream(kClientDataStreamId1, session_.get(), |
106 stream_should_process_data); | 106 stream_should_process_data); |
107 session_->ActivateStream(base::WrapUnique(stream_)); | 107 session_->ActivateStream(base::WrapUnique(stream_)); |
108 stream2_ = new TestStream(kClientDataStreamId2, session_.get(), | 108 stream2_ = new TestStream(kClientDataStreamId2, session_.get(), |
109 stream_should_process_data); | 109 stream_should_process_data); |
110 session_->ActivateStream(base::WrapUnique(stream2_)); | 110 session_->ActivateStream(base::WrapUnique(stream2_)); |
111 } | 111 } |
112 | 112 |
| 113 QuicHeaderList ProcessHeaders(bool fin, const SpdyHeaderBlock& headers) { |
| 114 QuicHeaderList h = AsHeaderList(headers); |
| 115 stream_->OnStreamHeaderList(fin, h.uncompressed_header_bytes(), h); |
| 116 return h; |
| 117 } |
| 118 |
113 protected: | 119 protected: |
114 QuicFlagSaver flags_; // Save/restore all QUIC flag values. | 120 QuicFlagSaver flags_; // Save/restore all QUIC flag values. |
115 MockQuicConnectionHelper helper_; | 121 MockQuicConnectionHelper helper_; |
116 MockAlarmFactory alarm_factory_; | 122 MockAlarmFactory alarm_factory_; |
117 MockQuicConnection* connection_; | 123 MockQuicConnection* connection_; |
118 std::unique_ptr<MockQuicSpdySession> session_; | 124 std::unique_ptr<MockQuicSpdySession> session_; |
119 | 125 |
120 // Owned by the |session_|. | 126 // Owned by the |session_|. |
121 TestStream* stream_; | 127 TestStream* stream_; |
122 TestStream* stream2_; | 128 TestStream* stream2_; |
123 | 129 |
124 SpdyHeaderBlock headers_; | 130 SpdyHeaderBlock headers_; |
125 }; | 131 }; |
126 | 132 |
127 INSTANTIATE_TEST_CASE_P(Tests, | 133 INSTANTIATE_TEST_CASE_P(Tests, |
128 QuicSpdyStreamTest, | 134 QuicSpdyStreamTest, |
129 ::testing::ValuesIn(AllSupportedVersions())); | 135 ::testing::ValuesIn(AllSupportedVersions())); |
130 | 136 |
131 TEST_P(QuicSpdyStreamTest, ProcessHeaders) { | |
132 Initialize(kShouldProcessData); | |
133 | |
134 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
135 stream_->OnStreamHeadersPriority(kV3HighestPriority); | |
136 stream_->OnStreamHeaders(headers); | |
137 EXPECT_EQ("", stream_->data()); | |
138 EXPECT_EQ(headers, stream_->decompressed_headers()); | |
139 stream_->OnStreamHeadersComplete(false, headers.size()); | |
140 EXPECT_EQ(kV3HighestPriority, stream_->priority()); | |
141 EXPECT_EQ("", stream_->data()); | |
142 EXPECT_EQ(headers, stream_->decompressed_headers()); | |
143 EXPECT_FALSE(stream_->IsDoneReading()); | |
144 } | |
145 | |
146 TEST_P(QuicSpdyStreamTest, ProcessHeaderList) { | 137 TEST_P(QuicSpdyStreamTest, ProcessHeaderList) { |
147 Initialize(kShouldProcessData); | 138 Initialize(kShouldProcessData); |
148 | 139 |
149 size_t total_bytes = 0; | |
150 QuicHeaderList headers; | |
151 for (auto p : headers_) { | |
152 headers.OnHeader(p.first, p.second); | |
153 total_bytes += p.first.size() + p.second.size(); | |
154 } | |
155 stream_->OnStreamHeadersPriority(kV3HighestPriority); | 140 stream_->OnStreamHeadersPriority(kV3HighestPriority); |
156 stream_->OnStreamHeaderList(false, total_bytes, headers); | 141 ProcessHeaders(false, headers_); |
157 EXPECT_EQ("", stream_->data()); | 142 EXPECT_EQ("", stream_->data()); |
158 EXPECT_FALSE(stream_->header_list().empty()); | 143 EXPECT_FALSE(stream_->header_list().empty()); |
159 EXPECT_FALSE(stream_->IsDoneReading()); | 144 EXPECT_FALSE(stream_->IsDoneReading()); |
160 } | 145 } |
161 | 146 |
162 TEST_P(QuicSpdyStreamTest, ProcessEmptyHeaderList) { | 147 TEST_P(QuicSpdyStreamTest, ProcessTooLargeHeaderList) { |
163 FLAGS_quic_limit_uncompressed_headers = true; | 148 FLAGS_quic_limit_uncompressed_headers = true; |
164 Initialize(kShouldProcessData); | 149 Initialize(kShouldProcessData); |
165 | 150 |
166 QuicHeaderList headers; | 151 QuicHeaderList headers; |
167 stream_->OnStreamHeadersPriority(kV3HighestPriority); | 152 stream_->OnStreamHeadersPriority(kV3HighestPriority); |
168 | 153 |
169 EXPECT_CALL(*session_, | 154 EXPECT_CALL(*session_, |
170 SendRstStream(stream_->id(), QUIC_HEADERS_TOO_LARGE, 0)); | 155 SendRstStream(stream_->id(), QUIC_HEADERS_TOO_LARGE, 0)); |
171 stream_->OnStreamHeaderList(false, 1 << 20, headers); | 156 stream_->OnStreamHeaderList(false, 1 << 20, headers); |
172 EXPECT_EQ(QUIC_HEADERS_TOO_LARGE, stream_->stream_error()); | 157 EXPECT_EQ(QUIC_HEADERS_TOO_LARGE, stream_->stream_error()); |
173 } | 158 } |
174 | 159 |
175 TEST_P(QuicSpdyStreamTest, ProcessHeadersWithFin) { | |
176 Initialize(kShouldProcessData); | |
177 | |
178 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
179 stream_->OnStreamHeadersPriority(kV3HighestPriority); | |
180 stream_->OnStreamHeaders(headers); | |
181 EXPECT_EQ("", stream_->data()); | |
182 EXPECT_EQ(headers, stream_->decompressed_headers()); | |
183 stream_->OnStreamHeadersComplete(true, headers.size()); | |
184 EXPECT_EQ(kV3HighestPriority, stream_->priority()); | |
185 EXPECT_EQ("", stream_->data()); | |
186 EXPECT_EQ(headers, stream_->decompressed_headers()); | |
187 EXPECT_FALSE(stream_->IsDoneReading()); | |
188 EXPECT_TRUE(stream_->HasFinalReceivedByteOffset()); | |
189 } | |
190 | |
191 TEST_P(QuicSpdyStreamTest, ProcessHeaderListWithFin) { | 160 TEST_P(QuicSpdyStreamTest, ProcessHeaderListWithFin) { |
192 Initialize(kShouldProcessData); | 161 Initialize(kShouldProcessData); |
193 | 162 |
194 size_t total_bytes = 0; | 163 size_t total_bytes = 0; |
195 QuicHeaderList headers; | 164 QuicHeaderList headers; |
196 for (auto p : headers_) { | 165 for (auto p : headers_) { |
197 headers.OnHeader(p.first, p.second); | 166 headers.OnHeader(p.first, p.second); |
198 total_bytes += p.first.size() + p.second.size(); | 167 total_bytes += p.first.size() + p.second.size(); |
199 } | 168 } |
200 stream_->OnStreamHeadersPriority(kV3HighestPriority); | 169 stream_->OnStreamHeadersPriority(kV3HighestPriority); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 headers_[":status"] = " 200 "; | 214 headers_[":status"] = " 200 "; |
246 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code)); | 215 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code)); |
247 | 216 |
248 headers_[":status"] = " "; | 217 headers_[":status"] = " "; |
249 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code)); | 218 EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code)); |
250 } | 219 } |
251 | 220 |
252 TEST_P(QuicSpdyStreamTest, MarkHeadersConsumed) { | 221 TEST_P(QuicSpdyStreamTest, MarkHeadersConsumed) { |
253 Initialize(kShouldProcessData); | 222 Initialize(kShouldProcessData); |
254 | 223 |
255 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
256 string body = "this is the body"; | 224 string body = "this is the body"; |
| 225 QuicHeaderList headers = ProcessHeaders(false, headers_); |
| 226 EXPECT_EQ(headers, stream_->header_list()); |
257 | 227 |
258 stream_->OnStreamHeaders(headers); | 228 stream_->ConsumeHeaderList(); |
259 stream_->OnStreamHeadersComplete(false, headers.size()); | 229 EXPECT_EQ(QuicHeaderList(), stream_->header_list()); |
260 EXPECT_EQ(headers, stream_->decompressed_headers()); | |
261 | |
262 headers.erase(0, 10); | |
263 stream_->MarkHeadersConsumed(10); | |
264 EXPECT_EQ(headers, stream_->decompressed_headers()); | |
265 | |
266 stream_->MarkHeadersConsumed(headers.length()); | |
267 EXPECT_EQ("", stream_->decompressed_headers()); | |
268 } | 230 } |
269 | 231 |
270 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) { | 232 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) { |
271 Initialize(kShouldProcessData); | 233 Initialize(kShouldProcessData); |
272 | 234 |
273 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
274 string body = "this is the body"; | 235 string body = "this is the body"; |
275 | 236 |
276 stream_->OnStreamHeaders(headers); | |
277 EXPECT_EQ("", stream_->data()); | 237 EXPECT_EQ("", stream_->data()); |
278 EXPECT_EQ(headers, stream_->decompressed_headers()); | 238 QuicHeaderList headers = ProcessHeaders(false, headers_); |
279 stream_->OnStreamHeadersComplete(false, headers.size()); | 239 EXPECT_EQ(headers, stream_->header_list()); |
280 EXPECT_EQ(headers, stream_->decompressed_headers()); | 240 stream_->ConsumeHeaderList(); |
281 stream_->MarkHeadersConsumed(headers.length()); | |
282 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 241 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
283 stream_->OnStreamFrame(frame); | 242 stream_->OnStreamFrame(frame); |
284 EXPECT_EQ("", stream_->decompressed_headers()); | 243 EXPECT_EQ(QuicHeaderList(), stream_->header_list()); |
285 EXPECT_EQ(body, stream_->data()); | 244 EXPECT_EQ(body, stream_->data()); |
286 } | 245 } |
287 | 246 |
288 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) { | 247 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) { |
289 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
290 string body = "this is the body"; | 248 string body = "this is the body"; |
291 | 249 |
292 for (size_t fragment_size = 1; fragment_size < body.size(); ++fragment_size) { | 250 for (size_t fragment_size = 1; fragment_size < body.size(); ++fragment_size) { |
293 Initialize(kShouldProcessData); | 251 Initialize(kShouldProcessData); |
294 for (size_t offset = 0; offset < headers.size(); offset += fragment_size) { | 252 QuicHeaderList headers = ProcessHeaders(false, headers_); |
295 size_t remaining_data = headers.size() - offset; | 253 ASSERT_EQ(headers, stream_->header_list()); |
296 StringPiece fragment(headers.data() + offset, | 254 stream_->ConsumeHeaderList(); |
297 min(fragment_size, remaining_data)); | |
298 stream_->OnStreamHeaders(fragment); | |
299 } | |
300 stream_->OnStreamHeadersComplete(false, headers.size()); | |
301 ASSERT_EQ(headers, stream_->decompressed_headers()) << "fragment_size: " | |
302 << fragment_size; | |
303 stream_->MarkHeadersConsumed(headers.length()); | |
304 for (size_t offset = 0; offset < body.size(); offset += fragment_size) { | 255 for (size_t offset = 0; offset < body.size(); offset += fragment_size) { |
305 size_t remaining_data = body.size() - offset; | 256 size_t remaining_data = body.size() - offset; |
306 StringPiece fragment(body.data() + offset, | 257 StringPiece fragment(body.data() + offset, |
307 min(fragment_size, remaining_data)); | 258 min(fragment_size, remaining_data)); |
308 QuicStreamFrame frame(kClientDataStreamId1, false, offset, | 259 QuicStreamFrame frame(kClientDataStreamId1, false, offset, |
309 StringPiece(fragment)); | 260 StringPiece(fragment)); |
310 stream_->OnStreamFrame(frame); | 261 stream_->OnStreamFrame(frame); |
311 } | 262 } |
312 ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size; | 263 ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size; |
313 } | 264 } |
314 } | 265 } |
315 | 266 |
316 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) { | 267 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) { |
317 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
318 string body = "this is the body"; | 268 string body = "this is the body"; |
319 | 269 |
320 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) { | 270 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) { |
321 Initialize(kShouldProcessData); | 271 Initialize(kShouldProcessData); |
322 StringPiece headers1(headers.data(), split_point); | 272 QuicHeaderList headers = ProcessHeaders(false, headers_); |
323 stream_->OnStreamHeaders(headers1); | 273 ASSERT_EQ(headers, stream_->header_list()); |
324 | 274 stream_->ConsumeHeaderList(); |
325 StringPiece headers2(headers.data() + split_point, | |
326 headers.size() - split_point); | |
327 stream_->OnStreamHeaders(headers2); | |
328 stream_->OnStreamHeadersComplete(false, headers.size()); | |
329 ASSERT_EQ(headers, stream_->decompressed_headers()) << "split_point: " | |
330 << split_point; | |
331 stream_->MarkHeadersConsumed(headers.length()); | |
332 | 275 |
333 StringPiece fragment1(body.data(), split_point); | 276 StringPiece fragment1(body.data(), split_point); |
334 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, | 277 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, |
335 StringPiece(fragment1)); | 278 StringPiece(fragment1)); |
336 stream_->OnStreamFrame(frame1); | 279 stream_->OnStreamFrame(frame1); |
337 | 280 |
338 StringPiece fragment2(body.data() + split_point, body.size() - split_point); | 281 StringPiece fragment2(body.data() + split_point, body.size() - split_point); |
339 QuicStreamFrame frame2(kClientDataStreamId1, false, split_point, | 282 QuicStreamFrame frame2(kClientDataStreamId1, false, split_point, |
340 StringPiece(fragment2)); | 283 StringPiece(fragment2)); |
341 stream_->OnStreamFrame(frame2); | 284 stream_->OnStreamFrame(frame2); |
342 | 285 |
343 ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point; | 286 ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point; |
344 } | 287 } |
345 } | 288 } |
346 | 289 |
347 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) { | 290 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) { |
348 Initialize(!kShouldProcessData); | 291 Initialize(!kShouldProcessData); |
349 | 292 |
350 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
351 string body = "this is the body"; | 293 string body = "this is the body"; |
352 | 294 |
353 stream_->OnStreamHeaders(headers); | 295 ProcessHeaders(false, headers_); |
354 stream_->OnStreamHeadersComplete(false, headers.size()); | |
355 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 296 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
356 stream_->OnStreamFrame(frame); | 297 stream_->OnStreamFrame(frame); |
357 stream_->MarkHeadersConsumed(headers.length()); | 298 stream_->ConsumeHeaderList(); |
358 | 299 |
359 char buffer[2048]; | 300 char buffer[2048]; |
360 ASSERT_LT(body.length(), arraysize(buffer)); | 301 ASSERT_LT(body.length(), arraysize(buffer)); |
361 struct iovec vec; | 302 struct iovec vec; |
362 vec.iov_base = buffer; | 303 vec.iov_base = buffer; |
363 vec.iov_len = arraysize(buffer); | 304 vec.iov_len = arraysize(buffer); |
364 | 305 |
365 size_t bytes_read = stream_->Readv(&vec, 1); | 306 size_t bytes_read = stream_->Readv(&vec, 1); |
366 EXPECT_EQ(body.length(), bytes_read); | 307 EXPECT_EQ(body.length(), bytes_read); |
367 EXPECT_EQ(body, string(buffer, bytes_read)); | 308 EXPECT_EQ(body, string(buffer, bytes_read)); |
368 } | 309 } |
369 | 310 |
370 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) { | 311 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) { |
371 Initialize(!kShouldProcessData); | 312 Initialize(!kShouldProcessData); |
372 | 313 |
373 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
374 string body = "this is the body"; | 314 string body = "this is the body"; |
375 | 315 |
376 stream_->OnStreamHeaders(headers); | 316 ProcessHeaders(false, headers_); |
377 stream_->OnStreamHeadersComplete(false, headers.size()); | |
378 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 317 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
379 stream_->OnStreamFrame(frame); | 318 stream_->OnStreamFrame(frame); |
380 stream_->MarkHeadersConsumed(headers.length()); | 319 stream_->ConsumeHeaderList(); |
381 | 320 |
382 struct iovec vec; | 321 struct iovec vec; |
383 | 322 |
384 EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1)); | 323 EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1)); |
385 EXPECT_EQ(body.length(), vec.iov_len); | 324 EXPECT_EQ(body.length(), vec.iov_len); |
386 EXPECT_EQ(body, string(static_cast<char*>(vec.iov_base), vec.iov_len)); | 325 EXPECT_EQ(body, string(static_cast<char*>(vec.iov_base), vec.iov_len)); |
387 | 326 |
388 stream_->MarkConsumed(body.length()); | 327 stream_->MarkConsumed(body.length()); |
389 EXPECT_EQ(body.length(), stream_->flow_controller()->bytes_consumed()); | 328 EXPECT_EQ(body.length(), stream_->flow_controller()->bytes_consumed()); |
390 } | 329 } |
391 | 330 |
392 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) { | 331 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) { |
393 Initialize(!kShouldProcessData); | 332 Initialize(!kShouldProcessData); |
394 | 333 |
395 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
396 string body = "this is the body"; | 334 string body = "this is the body"; |
397 stream_->OnStreamHeaders(headers); | 335 ProcessHeaders(false, headers_); |
398 stream_->OnStreamHeadersComplete(false, headers.size()); | |
399 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 336 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
400 stream_->OnStreamFrame(frame); | 337 stream_->OnStreamFrame(frame); |
401 stream_->MarkHeadersConsumed(headers.length()); | 338 stream_->ConsumeHeaderList(); |
402 | 339 |
403 char buffer[1]; | 340 char buffer[1]; |
404 struct iovec vec; | 341 struct iovec vec; |
405 vec.iov_base = buffer; | 342 vec.iov_base = buffer; |
406 vec.iov_len = arraysize(buffer); | 343 vec.iov_len = arraysize(buffer); |
407 | 344 |
408 for (size_t i = 0; i < body.length(); ++i) { | 345 for (size_t i = 0; i < body.length(); ++i) { |
409 size_t bytes_read = stream_->Readv(&vec, 1); | 346 size_t bytes_read = stream_->Readv(&vec, 1); |
410 ASSERT_EQ(1u, bytes_read); | 347 ASSERT_EQ(1u, bytes_read); |
411 EXPECT_EQ(body.data()[i], buffer[0]); | 348 EXPECT_EQ(body.data()[i], buffer[0]); |
412 } | 349 } |
413 } | 350 } |
414 | 351 |
415 TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { | 352 TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { |
416 Initialize(!kShouldProcessData); | 353 Initialize(!kShouldProcessData); |
417 | 354 |
418 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
419 string body = "this is the body"; | 355 string body = "this is the body"; |
420 stream_->OnStreamHeaders(headers); | 356 ProcessHeaders(false, headers_); |
421 stream_->OnStreamHeadersComplete(false, headers.size()); | |
422 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 357 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
423 stream_->OnStreamFrame(frame); | 358 stream_->OnStreamFrame(frame); |
424 stream_->MarkHeadersConsumed(headers.length()); | 359 stream_->ConsumeHeaderList(); |
425 | 360 |
426 char buffer1[1]; | 361 char buffer1[1]; |
427 char buffer2[1]; | 362 char buffer2[1]; |
428 struct iovec vec[2]; | 363 struct iovec vec[2]; |
429 vec[0].iov_base = buffer1; | 364 vec[0].iov_base = buffer1; |
430 vec[0].iov_len = arraysize(buffer1); | 365 vec[0].iov_len = arraysize(buffer1); |
431 vec[1].iov_base = buffer2; | 366 vec[1].iov_base = buffer2; |
432 vec[1].iov_len = arraysize(buffer2); | 367 vec[1].iov_len = arraysize(buffer2); |
433 | 368 |
434 for (size_t i = 0; i < body.length(); i += 2) { | 369 for (size_t i = 0; i < body.length(); i += 2) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 // Set a small flow control receive window. | 420 // Set a small flow control receive window. |
486 const uint64_t kWindow = 36; | 421 const uint64_t kWindow = 36; |
487 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 422 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
488 kWindow); | 423 kWindow); |
489 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), | 424 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), |
490 kWindow); | 425 kWindow); |
491 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( | 426 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( |
492 stream_->flow_controller())); | 427 stream_->flow_controller())); |
493 | 428 |
494 // Stream receives enough data to fill a fraction of the receive window. | 429 // Stream receives enough data to fill a fraction of the receive window. |
495 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
496 string body; | 430 string body; |
497 GenerateBody(&body, kWindow / 3); | 431 GenerateBody(&body, kWindow / 3); |
498 stream_->OnStreamHeaders(headers); | 432 ProcessHeaders(false, headers_); |
499 stream_->OnStreamHeadersComplete(false, headers.size()); | |
500 | 433 |
501 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, StringPiece(body)); | 434 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, StringPiece(body)); |
502 stream_->OnStreamFrame(frame1); | 435 stream_->OnStreamFrame(frame1); |
503 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( | 436 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( |
504 stream_->flow_controller())); | 437 stream_->flow_controller())); |
505 | 438 |
506 // Now receive another frame which results in the receive window being over | 439 // Now receive another frame which results in the receive window being over |
507 // half full. This should all be buffered, decreasing the receive window but | 440 // half full. This should all be buffered, decreasing the receive window but |
508 // not sending WINDOW_UPDATE. | 441 // not sending WINDOW_UPDATE. |
509 QuicStreamFrame frame2(kClientDataStreamId1, false, kWindow / 3, | 442 QuicStreamFrame frame2(kClientDataStreamId1, false, kWindow / 3, |
(...skipping 13 matching lines...) Expand all Loading... |
523 // Set a small flow control limit. | 456 // Set a small flow control limit. |
524 const uint64_t kWindow = 36; | 457 const uint64_t kWindow = 36; |
525 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 458 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
526 kWindow); | 459 kWindow); |
527 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), | 460 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), |
528 kWindow); | 461 kWindow); |
529 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( | 462 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( |
530 stream_->flow_controller())); | 463 stream_->flow_controller())); |
531 | 464 |
532 // Stream receives enough data to fill a fraction of the receive window. | 465 // Stream receives enough data to fill a fraction of the receive window. |
533 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
534 string body; | 466 string body; |
535 GenerateBody(&body, kWindow / 3); | 467 GenerateBody(&body, kWindow / 3); |
536 stream_->OnStreamHeaders(headers); | 468 ProcessHeaders(false, headers_); |
537 stream_->OnStreamHeadersComplete(false, headers.size()); | 469 stream_->ConsumeHeaderList(); |
538 stream_->MarkHeadersConsumed(headers.length()); | |
539 | 470 |
540 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, StringPiece(body)); | 471 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, StringPiece(body)); |
541 stream_->OnStreamFrame(frame1); | 472 stream_->OnStreamFrame(frame1); |
542 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( | 473 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( |
543 stream_->flow_controller())); | 474 stream_->flow_controller())); |
544 | 475 |
545 // Now receive another frame which results in the receive window being over | 476 // Now receive another frame which results in the receive window being over |
546 // half full. This will trigger the stream to increase its receive window | 477 // half full. This will trigger the stream to increase its receive window |
547 // offset and send a WINDOW_UPDATE. The result will be again an available | 478 // offset and send a WINDOW_UPDATE. The result will be again an available |
548 // window of kWindow bytes. | 479 // window of kWindow bytes. |
(...skipping 24 matching lines...) Expand all Loading... |
573 QuicFlowControllerPeer::SetReceiveWindowOffset(stream2_->flow_controller(), | 504 QuicFlowControllerPeer::SetReceiveWindowOffset(stream2_->flow_controller(), |
574 kWindow); | 505 kWindow); |
575 QuicFlowControllerPeer::SetMaxReceiveWindow(stream2_->flow_controller(), | 506 QuicFlowControllerPeer::SetMaxReceiveWindow(stream2_->flow_controller(), |
576 kWindow); | 507 kWindow); |
577 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), | 508 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), |
578 kWindow); | 509 kWindow); |
579 QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(), | 510 QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(), |
580 kWindow); | 511 kWindow); |
581 | 512 |
582 // Supply headers to both streams so that they are happy to receive data. | 513 // Supply headers to both streams so that they are happy to receive data. |
583 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 514 auto headers = AsHeaderList(headers_); |
584 stream_->OnStreamHeaders(headers); | 515 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), |
585 stream_->OnStreamHeadersComplete(false, headers.size()); | 516 headers); |
586 stream_->MarkHeadersConsumed(headers.length()); | 517 stream_->ConsumeHeaderList(); |
587 stream2_->OnStreamHeaders(headers); | 518 stream2_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), |
588 stream2_->OnStreamHeadersComplete(false, headers.size()); | 519 headers); |
589 stream2_->MarkHeadersConsumed(headers.length()); | 520 stream2_->ConsumeHeaderList(); |
590 | 521 |
591 // Each stream gets a quarter window of data. This should not trigger a | 522 // Each stream gets a quarter window of data. This should not trigger a |
592 // WINDOW_UPDATE for either stream, nor for the connection. | 523 // WINDOW_UPDATE for either stream, nor for the connection. |
593 string body; | 524 string body; |
594 GenerateBody(&body, kWindow / 4); | 525 GenerateBody(&body, kWindow / 4); |
595 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, StringPiece(body)); | 526 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, StringPiece(body)); |
596 stream_->OnStreamFrame(frame1); | 527 stream_->OnStreamFrame(frame1); |
597 QuicStreamFrame frame2(kClientDataStreamId2, false, 0, StringPiece(body)); | 528 QuicStreamFrame frame2(kClientDataStreamId2, false, 0, StringPiece(body)); |
598 stream2_->OnStreamFrame(frame2); | 529 stream2_->OnStreamFrame(frame2); |
599 | 530 |
(...skipping 17 matching lines...) Expand all Loading... |
617 | 548 |
618 // Stream should not process data, so that data gets buffered in the | 549 // Stream should not process data, so that data gets buffered in the |
619 // sequencer, triggering flow control limits. | 550 // sequencer, triggering flow control limits. |
620 Initialize(!kShouldProcessData); | 551 Initialize(!kShouldProcessData); |
621 | 552 |
622 // Set a small flow control limit. | 553 // Set a small flow control limit. |
623 const uint64_t kWindow = 50; | 554 const uint64_t kWindow = 50; |
624 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 555 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
625 kWindow); | 556 kWindow); |
626 | 557 |
627 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 558 ProcessHeaders(false, headers_); |
628 stream_->OnStreamHeaders(headers); | |
629 stream_->OnStreamHeadersComplete(false, headers.size()); | |
630 | 559 |
631 // Receive data to overflow the window, violating flow control. | 560 // Receive data to overflow the window, violating flow control. |
632 string body; | 561 string body; |
633 GenerateBody(&body, kWindow + 1); | 562 GenerateBody(&body, kWindow + 1); |
634 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 563 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
635 EXPECT_CALL(*connection_, | 564 EXPECT_CALL(*connection_, |
636 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)); | 565 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)); |
637 stream_->OnStreamFrame(frame); | 566 stream_->OnStreamFrame(frame); |
638 } | 567 } |
639 | 568 |
640 TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) { | 569 TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) { |
641 Initialize(kShouldProcessData); | 570 Initialize(kShouldProcessData); |
642 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 571 ProcessHeaders(false, headers_); |
643 stream_->OnStreamHeaders(headers); | |
644 stream_->OnStreamHeadersComplete(false, headers.size()); | |
645 | 572 |
646 stream_->OnStreamReset( | 573 stream_->OnStreamReset( |
647 QuicRstStreamFrame(stream_->id(), QUIC_STREAM_NO_ERROR, 0)); | 574 QuicRstStreamFrame(stream_->id(), QUIC_STREAM_NO_ERROR, 0)); |
648 EXPECT_TRUE(stream_->write_side_closed()); | 575 EXPECT_TRUE(stream_->write_side_closed()); |
649 EXPECT_FALSE(stream_->reading_stopped()); | 576 EXPECT_FALSE(stream_->reading_stopped()); |
650 } | 577 } |
651 | 578 |
652 TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) { | 579 TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) { |
653 // Tests that on if the peer sends too much data (i.e. violates the flow | 580 // Tests that on if the peer sends too much data (i.e. violates the flow |
654 // control protocol), at the connection level (rather than the stream level) | 581 // control protocol), at the connection level (rather than the stream level) |
655 // then we terminate the connection. | 582 // then we terminate the connection. |
656 | 583 |
657 // Stream should not process data, so that data gets buffered in the | 584 // Stream should not process data, so that data gets buffered in the |
658 // sequencer, triggering flow control limits. | 585 // sequencer, triggering flow control limits. |
659 Initialize(!kShouldProcessData); | 586 Initialize(!kShouldProcessData); |
660 | 587 |
661 // Set a small flow control window on streams, and connection. | 588 // Set a small flow control window on streams, and connection. |
662 const uint64_t kStreamWindow = 50; | 589 const uint64_t kStreamWindow = 50; |
663 const uint64_t kConnectionWindow = 10; | 590 const uint64_t kConnectionWindow = 10; |
664 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 591 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
665 kStreamWindow); | 592 kStreamWindow); |
666 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), | 593 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), |
667 kConnectionWindow); | 594 kConnectionWindow); |
668 | 595 |
669 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 596 ProcessHeaders(false, headers_); |
670 stream_->OnStreamHeaders(headers); | |
671 stream_->OnStreamHeadersComplete(false, headers.size()); | |
672 | 597 |
673 // Send enough data to overflow the connection level flow control window. | 598 // Send enough data to overflow the connection level flow control window. |
674 string body; | 599 string body; |
675 GenerateBody(&body, kConnectionWindow + 1); | 600 GenerateBody(&body, kConnectionWindow + 1); |
676 EXPECT_LT(body.size(), kStreamWindow); | 601 EXPECT_LT(body.size(), kStreamWindow); |
677 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 602 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
678 | 603 |
679 EXPECT_CALL(*connection_, | 604 EXPECT_CALL(*connection_, |
680 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)); | 605 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)); |
681 stream_->OnStreamFrame(frame); | 606 stream_->OnStreamFrame(frame); |
(...skipping 14 matching lines...) Expand all Loading... |
696 string body = ""; | 621 string body = ""; |
697 bool fin = true; | 622 bool fin = true; |
698 | 623 |
699 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)).Times(0); | 624 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)).Times(0); |
700 EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) | 625 EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) |
701 .WillOnce(Return(QuicConsumedData(0, fin))); | 626 .WillOnce(Return(QuicConsumedData(0, fin))); |
702 | 627 |
703 stream_->WriteOrBufferData(body, fin, nullptr); | 628 stream_->WriteOrBufferData(body, fin, nullptr); |
704 } | 629 } |
705 | 630 |
706 TEST_P(QuicSpdyStreamTest, ReceivingTrailers) { | 631 TEST_P(QuicSpdyStreamTest, ReceivingTrailersViaHeaderList) { |
707 // Test that receiving trailing headers from the peer works, and can be read | 632 // Test that receiving trailing headers from the peer via |
708 // from the stream and consumed. | 633 // OnStreamHeaderList() works, and can be read from the stream and consumed. |
709 Initialize(kShouldProcessData); | 634 Initialize(kShouldProcessData); |
710 | 635 |
711 // Receive initial headers. | 636 // Receive initial headers. |
712 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 637 size_t total_bytes = 0; |
713 stream_->OnStreamHeaders(headers); | 638 QuicHeaderList headers; |
714 stream_->OnStreamHeadersComplete(false, headers.size()); | 639 for (const auto& p : headers_) { |
715 stream_->MarkHeadersConsumed(stream_->decompressed_headers().size()); | 640 headers.OnHeader(p.first, p.second); |
| 641 total_bytes += p.first.size() + p.second.size(); |
| 642 } |
| 643 |
| 644 stream_->OnStreamHeadersPriority(kV3HighestPriority); |
| 645 stream_->OnStreamHeaderList(/*fin=*/false, total_bytes, headers); |
| 646 stream_->ConsumeHeaderList(); |
716 | 647 |
717 // Receive trailing headers. | 648 // Receive trailing headers. |
718 SpdyHeaderBlock trailers_block; | 649 SpdyHeaderBlock trailers_block; |
719 trailers_block["key1"] = "value1"; | 650 trailers_block["key1"] = "value1"; |
720 trailers_block["key2"] = "value2"; | 651 trailers_block["key2"] = "value2"; |
721 trailers_block["key3"] = "value3"; | 652 trailers_block["key3"] = "value3"; |
722 trailers_block[kFinalOffsetHeaderKey] = "0"; | 653 SpdyHeaderBlock trailers_block_with_final_offset = trailers_block.Clone(); |
723 string trailers = SpdyUtils::SerializeUncompressedHeaders(trailers_block); | 654 trailers_block_with_final_offset[kFinalOffsetHeaderKey] = "0"; |
724 stream_->OnStreamHeaders(trailers); | 655 total_bytes = 0; |
725 stream_->OnStreamHeadersComplete(/*fin=*/true, trailers.size()); | 656 QuicHeaderList trailers; |
| 657 for (const auto& p : trailers_block_with_final_offset) { |
| 658 trailers.OnHeader(p.first, p.second); |
| 659 total_bytes += p.first.size() + p.second.size(); |
| 660 } |
| 661 stream_->OnStreamHeaderList(/*fin=*/true, total_bytes, trailers); |
726 | 662 |
727 // The trailers should be decompressed, and readable from the stream. | 663 // The trailers should be decompressed, and readable from the stream. |
728 EXPECT_TRUE(stream_->trailers_decompressed()); | 664 EXPECT_TRUE(stream_->trailers_decompressed()); |
729 const string decompressed_trailers = stream_->decompressed_trailers(); | 665 EXPECT_EQ(trailers_block, stream_->received_trailers()); |
730 EXPECT_EQ(trailers, decompressed_trailers); | |
731 | 666 |
732 // Consuming the trailers erases them from the stream. | 667 // IsDoneReading() returns false until trailers marked consumed. |
733 stream_->MarkTrailersConsumed(decompressed_trailers.size()); | 668 EXPECT_FALSE(stream_->IsDoneReading()); |
734 EXPECT_EQ("", stream_->decompressed_trailers()); | 669 stream_->MarkTrailersConsumed(); |
| 670 EXPECT_TRUE(stream_->IsDoneReading()); |
735 } | 671 } |
736 | 672 |
737 TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) { | 673 TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) { |
738 // Test that receiving trailers without a final offset field is an error. | 674 // Test that receiving trailers without a final offset field is an error. |
739 Initialize(kShouldProcessData); | 675 Initialize(kShouldProcessData); |
740 | 676 |
741 // Receive initial headers. | 677 // Receive initial headers. |
742 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 678 auto headers = AsHeaderList(headers_); |
743 stream_->OnStreamHeaders(headers); | 679 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), |
744 stream_->OnStreamHeadersComplete(false, headers.size()); | 680 headers); |
745 stream_->MarkHeadersConsumed(stream_->decompressed_headers().size()); | 681 stream_->ConsumeHeaderList(); |
746 | 682 |
747 const string body = "this is the body"; | 683 const string body = "this is the body"; |
748 // Receive trailing headers, without kFinalOffsetHeaderKey. | 684 // Receive trailing headers, without kFinalOffsetHeaderKey. |
749 SpdyHeaderBlock trailers_block; | 685 SpdyHeaderBlock trailers_block; |
750 trailers_block["key1"] = "value1"; | 686 trailers_block["key1"] = "value1"; |
751 trailers_block["key2"] = "value2"; | 687 trailers_block["key2"] = "value2"; |
752 trailers_block["key3"] = "value3"; | 688 trailers_block["key3"] = "value3"; |
753 string trailers = SpdyUtils::SerializeUncompressedHeaders(trailers_block); | 689 auto trailers = AsHeaderList(trailers_block); |
754 stream_->OnStreamHeaders(trailers); | |
755 | 690 |
756 // Verify that the trailers block didn't contain a final offset. | 691 // Verify that the trailers block didn't contain a final offset. |
757 EXPECT_EQ("", trailers_block[kFinalOffsetHeaderKey].as_string()); | 692 EXPECT_EQ("", trailers_block[kFinalOffsetHeaderKey].as_string()); |
758 | 693 |
759 // Receipt of the malformed trailers will close the connection. | 694 // Receipt of the malformed trailers will close the connection. |
760 EXPECT_CALL(*connection_, | 695 EXPECT_CALL(*connection_, |
761 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _)) | 696 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _)) |
762 .Times(1); | 697 .Times(1); |
763 stream_->OnStreamHeadersComplete(/*fin=*/true, trailers.size()); | 698 stream_->OnStreamHeaderList(/*fin=*/true, |
| 699 trailers.uncompressed_header_bytes(), trailers); |
764 } | 700 } |
765 | 701 |
766 TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutFin) { | 702 TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutFin) { |
767 // Test that received Trailers must always have the FIN set. | 703 // Test that received Trailers must always have the FIN set. |
768 Initialize(kShouldProcessData); | 704 Initialize(kShouldProcessData); |
769 | 705 |
770 // Receive initial headers. | 706 // Receive initial headers. |
771 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 707 auto headers = AsHeaderList(headers_); |
772 stream_->OnStreamHeaders(headers); | 708 stream_->OnStreamHeaderList(/*fin=*/false, |
773 stream_->OnStreamHeadersComplete(false, headers.size()); | 709 headers.uncompressed_header_bytes(), headers); |
774 | 710 |
775 // Receive trailing headers with FIN deliberately set to false. | 711 // Receive trailing headers with FIN deliberately set to false. |
776 SpdyHeaderBlock trailers_block; | 712 SpdyHeaderBlock trailers_block; |
777 string trailers = SpdyUtils::SerializeUncompressedHeaders(trailers_block); | 713 auto trailers = AsHeaderList(trailers_block); |
778 stream_->OnStreamHeaders(trailers); | |
779 | 714 |
780 EXPECT_CALL(*connection_, | 715 EXPECT_CALL(*connection_, |
781 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _)) | 716 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _)) |
782 .Times(1); | 717 .Times(1); |
783 stream_->OnStreamHeadersComplete(/*fin=*/false, trailers.size()); | 718 stream_->OnStreamHeaderList(/*fin=*/false, |
| 719 trailers.uncompressed_header_bytes(), trailers); |
784 } | 720 } |
785 | 721 |
786 TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterFin) { | 722 TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterFin) { |
787 // If Trailers are sent, neither Headers nor Body should contain a FIN. | 723 // If Trailers are sent, neither Headers nor Body should contain a FIN. |
788 Initialize(kShouldProcessData); | 724 Initialize(kShouldProcessData); |
789 | 725 |
790 // Receive initial headers with FIN set. | 726 // Receive initial headers with FIN set. |
791 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 727 ProcessHeaders(true, headers_); |
792 stream_->OnStreamHeaders(headers); | |
793 stream_->OnStreamHeadersComplete(/*fin=*/true, headers.size()); | |
794 | 728 |
795 // Receive trailing headers after FIN already received. | 729 // Receive trailing headers after FIN already received. |
796 SpdyHeaderBlock trailers_block; | 730 SpdyHeaderBlock trailers_block; |
797 string trailers = SpdyUtils::SerializeUncompressedHeaders(trailers_block); | |
798 stream_->OnStreamHeaders(trailers); | |
799 | |
800 EXPECT_CALL(*connection_, | 731 EXPECT_CALL(*connection_, |
801 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _)) | 732 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _)) |
802 .Times(1); | 733 .Times(1); |
803 stream_->OnStreamHeadersComplete(/*fin=*/true, trailers.size()); | 734 ProcessHeaders(true, trailers_block); |
804 } | 735 } |
805 | 736 |
806 TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) { | 737 TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) { |
807 // If body data are received with a FIN, no trailers should then arrive. | 738 // If body data are received with a FIN, no trailers should then arrive. |
808 Initialize(kShouldProcessData); | 739 Initialize(kShouldProcessData); |
809 | 740 |
810 // Receive initial headers without FIN set. | 741 // Receive initial headers without FIN set. |
811 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 742 ProcessHeaders(false, headers_); |
812 stream_->OnStreamHeaders(headers); | |
813 stream_->OnStreamHeadersComplete(/*fin=*/false, headers.size()); | |
814 | 743 |
815 // Receive body data, with FIN. | 744 // Receive body data, with FIN. |
816 QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/true, 0, "body"); | 745 QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/true, 0, "body"); |
817 stream_->OnStreamFrame(frame); | 746 stream_->OnStreamFrame(frame); |
818 | 747 |
819 // Receive trailing headers after FIN already received. | 748 // Receive trailing headers after FIN already received. |
820 SpdyHeaderBlock trailers_block; | 749 SpdyHeaderBlock trailers_block; |
821 string trailers = SpdyUtils::SerializeUncompressedHeaders(trailers_block); | |
822 stream_->OnStreamHeaders(trailers); | |
823 | |
824 EXPECT_CALL(*connection_, | 750 EXPECT_CALL(*connection_, |
825 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _)) | 751 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _)) |
826 .Times(1); | 752 .Times(1); |
827 stream_->OnStreamHeadersComplete(/*fin=*/true, trailers.size()); | 753 ProcessHeaders(false, trailers_block); |
828 } | 754 } |
829 | 755 |
830 TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithOffset) { | 756 TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithOffset) { |
831 // Test that when receiving trailing headers with an offset before response | 757 // Test that when receiving trailing headers with an offset before response |
832 // body, stream is closed at the right offset. | 758 // body, stream is closed at the right offset. |
833 Initialize(kShouldProcessData); | 759 Initialize(kShouldProcessData); |
834 | 760 |
835 // Receive initial headers. | 761 // Receive initial headers. |
836 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 762 QuicHeaderList headers = ProcessHeaders(false, headers_); |
837 stream_->OnStreamHeaders(headers); | 763 stream_->ConsumeHeaderList(); |
838 stream_->OnStreamHeadersComplete(false, headers.size()); | |
839 stream_->MarkHeadersConsumed(stream_->decompressed_headers().size()); | |
840 | 764 |
841 const string body = "this is the body"; | 765 const string body = "this is the body"; |
842 // Receive trailing headers. | 766 // Receive trailing headers. |
843 SpdyHeaderBlock trailers_block; | 767 SpdyHeaderBlock trailers_block; |
844 trailers_block["key1"] = "value1"; | 768 trailers_block["key1"] = "value1"; |
845 trailers_block["key2"] = "value2"; | 769 trailers_block["key2"] = "value2"; |
846 trailers_block["key3"] = "value3"; | 770 trailers_block["key3"] = "value3"; |
847 trailers_block[kFinalOffsetHeaderKey] = base::IntToString(body.size()); | 771 trailers_block[kFinalOffsetHeaderKey] = base::IntToString(body.size()); |
848 string trailers = SpdyUtils::SerializeUncompressedHeaders(trailers_block); | 772 |
849 stream_->OnStreamHeaders(trailers); | 773 QuicHeaderList trailers = ProcessHeaders(true, trailers_block); |
850 stream_->OnStreamHeadersComplete(/*fin=*/true, trailers.size()); | |
851 | 774 |
852 // The trailers should be decompressed, and readable from the stream. | 775 // The trailers should be decompressed, and readable from the stream. |
853 EXPECT_TRUE(stream_->trailers_decompressed()); | 776 EXPECT_TRUE(stream_->trailers_decompressed()); |
854 const string decompressed_trailers = stream_->decompressed_trailers(); | 777 |
855 EXPECT_EQ(trailers, decompressed_trailers); | 778 // The final offset trailer will be consumed by QUIC. |
| 779 trailers_block.erase(kFinalOffsetHeaderKey); |
| 780 EXPECT_EQ(trailers_block, stream_->received_trailers()); |
| 781 |
856 // Consuming the trailers erases them from the stream. | 782 // Consuming the trailers erases them from the stream. |
857 stream_->MarkTrailersConsumed(decompressed_trailers.size()); | |
858 stream_->MarkTrailersConsumed(); | 783 stream_->MarkTrailersConsumed(); |
859 EXPECT_EQ("", stream_->decompressed_trailers()); | 784 EXPECT_TRUE(stream_->FinishedReadingTrailers()); |
860 | 785 |
861 EXPECT_FALSE(stream_->IsDoneReading()); | 786 EXPECT_FALSE(stream_->IsDoneReading()); |
862 // Receive and consume body. | 787 // Receive and consume body. |
863 QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/false, 0, body); | 788 QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/false, 0, body); |
864 stream_->OnStreamFrame(frame); | 789 stream_->OnStreamFrame(frame); |
865 EXPECT_EQ(body, stream_->data()); | 790 EXPECT_EQ(body, stream_->data()); |
866 EXPECT_TRUE(stream_->IsDoneReading()); | 791 EXPECT_TRUE(stream_->IsDoneReading()); |
867 } | 792 } |
868 | 793 |
869 TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) { | 794 TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) { |
870 // Verify that a stream receiving headers, body, and no trailers is correctly | 795 // Verify that a stream receiving headers, body, and no trailers is correctly |
871 // marked as done reading on consumption of headers and body. | 796 // marked as done reading on consumption of headers and body. |
872 Initialize(kShouldProcessData); | 797 Initialize(kShouldProcessData); |
873 | 798 |
874 // Receive and consume initial headers with FIN not set. | 799 // Receive and consume initial headers with FIN not set. |
875 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 800 auto h = AsHeaderList(headers_); |
876 stream_->OnStreamHeaders(headers); | 801 stream_->OnStreamHeaderList(/*fin=*/false, h.uncompressed_header_bytes(), h); |
877 stream_->OnStreamHeadersComplete(/*fin=*/false, headers.size()); | 802 stream_->ConsumeHeaderList(); |
878 stream_->MarkHeadersConsumed(headers.size()); | |
879 | 803 |
880 // Receive and consume body with FIN set, and no trailers. | 804 // Receive and consume body with FIN set, and no trailers. |
881 const string kBody = string(1024, 'x'); | 805 const string kBody = string(1024, 'x'); |
882 QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/true, 0, kBody); | 806 QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/true, 0, kBody); |
883 stream_->OnStreamFrame(frame); | 807 stream_->OnStreamFrame(frame); |
884 | 808 |
885 EXPECT_TRUE(stream_->IsDoneReading()); | 809 EXPECT_TRUE(stream_->IsDoneReading()); |
886 } | 810 } |
887 | 811 |
888 TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) { | 812 TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) { |
(...skipping 30 matching lines...) Expand all Loading... |
919 | 843 |
920 // Write non-zero body data to force a non-zero final offset. | 844 // Write non-zero body data to force a non-zero final offset. |
921 const int kBodySize = 1 * 1024; // 1 MB | 845 const int kBodySize = 1 * 1024; // 1 MB |
922 stream_->WriteOrBufferData(string(kBodySize, 'x'), false, nullptr); | 846 stream_->WriteOrBufferData(string(kBodySize, 'x'), false, nullptr); |
923 | 847 |
924 // The final offset field in the trailing headers is populated with the | 848 // The final offset field in the trailing headers is populated with the |
925 // number of body bytes written (including queued bytes). | 849 // number of body bytes written (including queued bytes). |
926 SpdyHeaderBlock trailers; | 850 SpdyHeaderBlock trailers; |
927 trailers["trailer key"] = "trailer value"; | 851 trailers["trailer key"] = "trailer value"; |
928 SpdyHeaderBlock trailers_with_offset(trailers.Clone()); | 852 SpdyHeaderBlock trailers_with_offset(trailers.Clone()); |
929 trailers_with_offset[kFinalOffsetHeaderKey] = base::IntToString(kBodySize); | 853 trailers_with_offset[kFinalOffsetHeaderKey] = base::Uint64ToString(kBodySize); |
930 EXPECT_CALL(*session_, WriteHeadersMock(_, _, true, _, _)); | 854 EXPECT_CALL(*session_, WriteHeadersMock(_, _, true, _, _)); |
931 stream_->WriteTrailers(std::move(trailers), nullptr); | 855 stream_->WriteTrailers(std::move(trailers), nullptr); |
932 EXPECT_EQ(trailers_with_offset, session_->GetWriteHeaders()); | 856 EXPECT_EQ(trailers_with_offset, session_->GetWriteHeaders()); |
933 } | 857 } |
934 | 858 |
935 TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) { | 859 TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) { |
936 // Test that if trailers are written after all other data has been written | 860 // Test that if trailers are written after all other data has been written |
937 // (headers and body), that this closes the stream for writing. | 861 // (headers and body), that this closes the stream for writing. |
938 Initialize(kShouldProcessData); | 862 Initialize(kShouldProcessData); |
939 EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) | 863 EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 | 931 |
1008 // Writing Trailers should fail, as the FIN has already been sent. | 932 // Writing Trailers should fail, as the FIN has already been sent. |
1009 // populated with the number of body bytes written. | 933 // populated with the number of body bytes written. |
1010 EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr), | 934 EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr), |
1011 "Trailers cannot be sent after a FIN"); | 935 "Trailers cannot be sent after a FIN"); |
1012 } | 936 } |
1013 | 937 |
1014 } // namespace | 938 } // namespace |
1015 } // namespace test | 939 } // namespace test |
1016 } // namespace net | 940 } // namespace net |
OLD | NEW |