| 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 |