OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/tools/quic/quic_simple_server_stream.h" | 5 #include "net/tools/quic/quic_simple_server_stream.h" |
6 | 6 |
| 7 #include <utility> |
| 8 |
7 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
8 #include "base/strings/string_piece.h" | 10 #include "base/strings/string_piece.h" |
9 #include "net/quic/quic_connection.h" | 11 #include "net/quic/quic_connection.h" |
10 #include "net/quic/quic_flags.h" | 12 #include "net/quic/quic_flags.h" |
11 #include "net/quic/quic_protocol.h" | 13 #include "net/quic/quic_protocol.h" |
12 #include "net/quic/quic_utils.h" | 14 #include "net/quic/quic_utils.h" |
13 #include "net/quic/spdy_utils.h" | 15 #include "net/quic/spdy_utils.h" |
14 #include "net/quic/test_tools/crypto_test_utils.h" | 16 #include "net/quic/test_tools/crypto_test_utils.h" |
15 #include "net/quic/test_tools/quic_test_utils.h" | 17 #include "net/quic/test_tools/quic_test_utils.h" |
16 #include "net/quic/test_tools/reliable_quic_stream_peer.h" | 18 #include "net/quic/test_tools/reliable_quic_stream_peer.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 QuicIOVector data, | 115 QuicIOVector data, |
114 QuicStreamOffset offset, | 116 QuicStreamOffset offset, |
115 bool fin, | 117 bool fin, |
116 QuicAckListenerInterface*)); | 118 QuicAckListenerInterface*)); |
117 MOCK_METHOD2(OnStreamHeaders, | 119 MOCK_METHOD2(OnStreamHeaders, |
118 void(QuicStreamId stream_id, StringPiece headers_data)); | 120 void(QuicStreamId stream_id, StringPiece headers_data)); |
119 MOCK_METHOD2(OnStreamHeadersPriority, | 121 MOCK_METHOD2(OnStreamHeadersPriority, |
120 void(QuicStreamId stream_id, SpdyPriority priority)); | 122 void(QuicStreamId stream_id, SpdyPriority priority)); |
121 MOCK_METHOD3(OnStreamHeadersComplete, | 123 MOCK_METHOD3(OnStreamHeadersComplete, |
122 void(QuicStreamId stream_id, bool fin, size_t frame_len)); | 124 void(QuicStreamId stream_id, bool fin, size_t frame_len)); |
123 MOCK_METHOD5(WriteHeaders, | 125 // Methods taking non-copyable types like SpdyHeaderBlock by value cannot be |
| 126 // mocked directly. |
| 127 size_t WriteHeaders( |
| 128 QuicStreamId id, |
| 129 SpdyHeaderBlock headers, |
| 130 bool fin, |
| 131 SpdyPriority priority, |
| 132 QuicAckListenerInterface* ack_notifier_delegate) override { |
| 133 return WriteHeadersMock(id, headers, fin, priority, ack_notifier_delegate); |
| 134 } |
| 135 MOCK_METHOD5(WriteHeadersMock, |
124 size_t(QuicStreamId id, | 136 size_t(QuicStreamId id, |
125 SpdyHeaderBlock headers, | 137 const SpdyHeaderBlock& headers, |
126 bool fin, | 138 bool fin, |
127 SpdyPriority priority, | 139 SpdyPriority priority, |
128 QuicAckListenerInterface* ack_notifier_delegate)); | 140 QuicAckListenerInterface* ack_notifier_delegate)); |
129 MOCK_METHOD3(SendRstStream, | 141 MOCK_METHOD3(SendRstStream, |
130 void(QuicStreamId stream_id, | 142 void(QuicStreamId stream_id, |
131 QuicRstStreamErrorCode error, | 143 QuicRstStreamErrorCode error, |
132 QuicStreamOffset bytes_written)); | 144 QuicStreamOffset bytes_written)); |
133 MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(QuicTime::Delta delta)); | 145 MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(QuicTime::Delta delta)); |
134 MOCK_METHOD4(PromisePushResources, | 146 // Matchers cannot be used on non-copyable types like SpdyHeaderBlock. |
| 147 void PromisePushResources( |
| 148 const string& request_url, |
| 149 const std::list<QuicInMemoryCache::ServerPushInfo>& resources, |
| 150 QuicStreamId original_stream_id, |
| 151 const SpdyHeaderBlock& original_request_headers) override { |
| 152 original_request_headers_ = original_request_headers.Clone(); |
| 153 PromisePushResourcesMock(request_url, resources, original_stream_id, |
| 154 original_request_headers); |
| 155 } |
| 156 MOCK_METHOD4(PromisePushResourcesMock, |
135 void(const string&, | 157 void(const string&, |
136 const std::list<QuicInMemoryCache::ServerPushInfo>&, | 158 const std::list<QuicInMemoryCache::ServerPushInfo>&, |
137 QuicStreamId, | 159 QuicStreamId, |
138 const SpdyHeaderBlock&)); | 160 const SpdyHeaderBlock&)); |
139 | 161 |
140 using QuicSession::ActivateStream; | 162 using QuicSession::ActivateStream; |
141 | 163 |
| 164 SpdyHeaderBlock original_request_headers_; |
| 165 |
142 private: | 166 private: |
143 DISALLOW_COPY_AND_ASSIGN(MockQuicSimpleServerSession); | 167 DISALLOW_COPY_AND_ASSIGN(MockQuicSimpleServerSession); |
144 }; | 168 }; |
145 | 169 |
146 namespace { | 170 namespace { |
147 | 171 |
148 class QuicSimpleServerStreamTest | 172 class QuicSimpleServerStreamTest |
149 : public ::testing::TestWithParam<QuicVersion> { | 173 : public ::testing::TestWithParam<QuicVersion> { |
150 public: | 174 public: |
151 QuicSimpleServerStreamTest() | 175 QuicSimpleServerStreamTest() |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 } else { | 291 } else { |
268 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 292 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
269 } | 293 } |
270 stream_->StopReading(); | 294 stream_->StopReading(); |
271 } | 295 } |
272 | 296 |
273 TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) { | 297 TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) { |
274 string large_body = "hello world!!!!!!"; | 298 string large_body = "hello world!!!!!!"; |
275 | 299 |
276 // We'll automatically write out an error (headers + body) | 300 // We'll automatically write out an error (headers + body) |
277 EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _)); | 301 EXPECT_CALL(session_, WriteHeadersMock(_, _, _, _, _)); |
278 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 302 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
279 .WillOnce(Invoke(MockQuicSession::ConsumeAllData)); | 303 .WillOnce(Invoke(MockQuicSession::ConsumeAllData)); |
280 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 304 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
281 | 305 |
282 stream_->OnStreamHeaders(headers_string_); | 306 stream_->OnStreamHeaders(headers_string_); |
283 stream_->OnStreamHeadersComplete(false, headers_string_.size()); | 307 stream_->OnStreamHeadersComplete(false, headers_string_.size()); |
284 stream_->OnStreamFrame( | 308 stream_->OnStreamFrame( |
285 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); | 309 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); |
286 // Content length is still 11. This will register as an error and we won't | 310 // Content length is still 11. This will register as an error and we won't |
287 // accept the bytes. | 311 // accept the bytes. |
(...skipping 10 matching lines...) Expand all Loading... |
298 (*request_headers)[":path"] = "/bar"; | 322 (*request_headers)[":path"] = "/bar"; |
299 (*request_headers)[":authority"] = "www.google.com"; | 323 (*request_headers)[":authority"] = "www.google.com"; |
300 (*request_headers)[":version"] = "HTTP/1.1"; | 324 (*request_headers)[":version"] = "HTTP/1.1"; |
301 (*request_headers)[":method"] = "GET"; | 325 (*request_headers)[":method"] = "GET"; |
302 | 326 |
303 response_headers_[":version"] = "HTTP/1.1"; | 327 response_headers_[":version"] = "HTTP/1.1"; |
304 // HTTP/2 only supports integer responsecode, so "200 OK" is illegal. | 328 // HTTP/2 only supports integer responsecode, so "200 OK" is illegal. |
305 response_headers_[":status"] = "200 OK"; | 329 response_headers_[":status"] = "200 OK"; |
306 response_headers_["content-length"] = "5"; | 330 response_headers_["content-length"] = "5"; |
307 string body = "Yummm"; | 331 string body = "Yummm"; |
308 QuicInMemoryCache::GetInstance()->AddResponse("www.google.com", "/bar", | 332 QuicInMemoryCache::GetInstance()->AddResponse( |
309 response_headers_, body); | 333 "www.google.com", "/bar", std::move(response_headers_), body); |
310 | 334 |
311 stream_->set_fin_received(true); | 335 stream_->set_fin_received(true); |
312 | 336 |
313 InSequence s; | 337 InSequence s; |
314 EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr)); | 338 EXPECT_CALL(session_, WriteHeadersMock(stream_->id(), _, false, _, nullptr)); |
315 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 339 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
316 .Times(1) | 340 .Times(1) |
317 .WillOnce(Return(QuicConsumedData( | 341 .WillOnce(Return(QuicConsumedData( |
318 strlen(QuicSimpleServerStream::kErrorResponseBody), true))); | 342 strlen(QuicSimpleServerStream::kErrorResponseBody), true))); |
319 | 343 |
320 QuicSimpleServerStreamPeer::SendResponse(stream_); | 344 QuicSimpleServerStreamPeer::SendResponse(stream_); |
321 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 345 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
322 EXPECT_TRUE(stream_->reading_stopped()); | 346 EXPECT_TRUE(stream_->reading_stopped()); |
323 EXPECT_TRUE(stream_->write_side_closed()); | 347 EXPECT_TRUE(stream_->write_side_closed()); |
324 } | 348 } |
325 | 349 |
326 TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus2) { | 350 TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus2) { |
327 // Send an illegal response with response status not supported by HTTP/2. | 351 // Send an illegal response with response status not supported by HTTP/2. |
328 SpdyHeaderBlock* request_headers = stream_->mutable_headers(); | 352 SpdyHeaderBlock* request_headers = stream_->mutable_headers(); |
329 (*request_headers)[":path"] = "/bar"; | 353 (*request_headers)[":path"] = "/bar"; |
330 (*request_headers)[":authority"] = "www.google.com"; | 354 (*request_headers)[":authority"] = "www.google.com"; |
331 (*request_headers)[":version"] = "HTTP/1.1"; | 355 (*request_headers)[":version"] = "HTTP/1.1"; |
332 (*request_headers)[":method"] = "GET"; | 356 (*request_headers)[":method"] = "GET"; |
333 | 357 |
334 response_headers_[":version"] = "HTTP/1.1"; | 358 response_headers_[":version"] = "HTTP/1.1"; |
335 // HTTP/2 only supports 3-digit-integer, so "+200" is illegal. | 359 // HTTP/2 only supports 3-digit-integer, so "+200" is illegal. |
336 response_headers_[":status"] = "+200"; | 360 response_headers_[":status"] = "+200"; |
337 response_headers_["content-length"] = "5"; | 361 response_headers_["content-length"] = "5"; |
338 string body = "Yummm"; | 362 string body = "Yummm"; |
339 QuicInMemoryCache::GetInstance()->AddResponse("www.google.com", "/bar", | 363 QuicInMemoryCache::GetInstance()->AddResponse( |
340 response_headers_, body); | 364 "www.google.com", "/bar", std::move(response_headers_), body); |
341 | 365 |
342 stream_->set_fin_received(true); | 366 stream_->set_fin_received(true); |
343 | 367 |
344 InSequence s; | 368 InSequence s; |
345 EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr)); | 369 EXPECT_CALL(session_, WriteHeadersMock(stream_->id(), _, false, _, nullptr)); |
346 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 370 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
347 .Times(1) | 371 .Times(1) |
348 .WillOnce(Return(QuicConsumedData( | 372 .WillOnce(Return(QuicConsumedData( |
349 strlen(QuicSimpleServerStream::kErrorResponseBody), true))); | 373 strlen(QuicSimpleServerStream::kErrorResponseBody), true))); |
350 | 374 |
351 QuicSimpleServerStreamPeer::SendResponse(stream_); | 375 QuicSimpleServerStreamPeer::SendResponse(stream_); |
352 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 376 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
353 EXPECT_TRUE(stream_->reading_stopped()); | 377 EXPECT_TRUE(stream_->reading_stopped()); |
354 EXPECT_TRUE(stream_->write_side_closed()); | 378 EXPECT_TRUE(stream_->write_side_closed()); |
355 } | 379 } |
356 | 380 |
357 TEST_P(QuicSimpleServerStreamTest, SendPushResponseWith404Response) { | 381 TEST_P(QuicSimpleServerStreamTest, SendPushResponseWith404Response) { |
358 // Create a new promised stream with even id(). | 382 // Create a new promised stream with even id(). |
359 QuicSimpleServerStreamPeer* promised_stream = | 383 QuicSimpleServerStreamPeer* promised_stream = |
360 new QuicSimpleServerStreamPeer(2, &session_); | 384 new QuicSimpleServerStreamPeer(2, &session_); |
361 session_.ActivateStream(promised_stream); | 385 session_.ActivateStream(promised_stream); |
362 | 386 |
363 // Send a push response with response status 404, which will be regarded as | 387 // Send a push response with response status 404, which will be regarded as |
364 // invalid server push response. | 388 // invalid server push response. |
365 SpdyHeaderBlock* request_headers = promised_stream->mutable_headers(); | 389 SpdyHeaderBlock* request_headers = promised_stream->mutable_headers(); |
366 (*request_headers)[":path"] = "/bar"; | 390 (*request_headers)[":path"] = "/bar"; |
367 (*request_headers)[":authority"] = "www.google.com"; | 391 (*request_headers)[":authority"] = "www.google.com"; |
368 (*request_headers)[":version"] = "HTTP/1.1"; | 392 (*request_headers)[":version"] = "HTTP/1.1"; |
369 (*request_headers)[":method"] = "GET"; | 393 (*request_headers)[":method"] = "GET"; |
370 | 394 |
371 response_headers_[":version"] = "HTTP/1.1"; | 395 response_headers_[":version"] = "HTTP/1.1"; |
372 response_headers_[":status"] = "404"; | 396 response_headers_[":status"] = "404"; |
373 response_headers_["content-length"] = "8"; | 397 response_headers_["content-length"] = "8"; |
374 string body = "NotFound"; | 398 string body = "NotFound"; |
375 QuicInMemoryCache::GetInstance()->AddResponse("www.google.com", "/bar", | 399 QuicInMemoryCache::GetInstance()->AddResponse( |
376 response_headers_, body); | 400 "www.google.com", "/bar", std::move(response_headers_), body); |
377 | 401 |
378 InSequence s; | 402 InSequence s; |
379 EXPECT_CALL(session_, | 403 EXPECT_CALL(session_, |
380 SendRstStream(promised_stream->id(), QUIC_STREAM_CANCELLED, 0)); | 404 SendRstStream(promised_stream->id(), QUIC_STREAM_CANCELLED, 0)); |
381 | 405 |
382 QuicSimpleServerStreamPeer::SendResponse(promised_stream); | 406 QuicSimpleServerStreamPeer::SendResponse(promised_stream); |
383 } | 407 } |
384 | 408 |
385 TEST_P(QuicSimpleServerStreamTest, SendResponseWithValidHeaders) { | 409 TEST_P(QuicSimpleServerStreamTest, SendResponseWithValidHeaders) { |
386 // Add a request and response with valid headers. | 410 // Add a request and response with valid headers. |
387 SpdyHeaderBlock* request_headers = stream_->mutable_headers(); | 411 SpdyHeaderBlock* request_headers = stream_->mutable_headers(); |
388 (*request_headers)[":path"] = "/bar"; | 412 (*request_headers)[":path"] = "/bar"; |
389 (*request_headers)[":authority"] = "www.google.com"; | 413 (*request_headers)[":authority"] = "www.google.com"; |
390 (*request_headers)[":version"] = "HTTP/1.1"; | 414 (*request_headers)[":version"] = "HTTP/1.1"; |
391 (*request_headers)[":method"] = "GET"; | 415 (*request_headers)[":method"] = "GET"; |
392 | 416 |
393 response_headers_[":version"] = "HTTP/1.1"; | 417 response_headers_[":version"] = "HTTP/1.1"; |
394 response_headers_[":status"] = "200"; | 418 response_headers_[":status"] = "200"; |
395 response_headers_["content-length"] = "5"; | 419 response_headers_["content-length"] = "5"; |
396 string body = "Yummm"; | 420 string body = "Yummm"; |
397 QuicInMemoryCache::GetInstance()->AddResponse("www.google.com", "/bar", | 421 QuicInMemoryCache::GetInstance()->AddResponse( |
398 response_headers_, body); | 422 "www.google.com", "/bar", std::move(response_headers_), body); |
399 stream_->set_fin_received(true); | 423 stream_->set_fin_received(true); |
400 | 424 |
401 InSequence s; | 425 InSequence s; |
402 EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr)); | 426 EXPECT_CALL(session_, WriteHeadersMock(stream_->id(), _, false, _, nullptr)); |
403 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 427 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
404 .Times(1) | 428 .Times(1) |
405 .WillOnce(Return(QuicConsumedData(body.length(), true))); | 429 .WillOnce(Return(QuicConsumedData(body.length(), true))); |
406 | 430 |
407 QuicSimpleServerStreamPeer::SendResponse(stream_); | 431 QuicSimpleServerStreamPeer::SendResponse(stream_); |
408 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 432 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
409 EXPECT_TRUE(stream_->reading_stopped()); | 433 EXPECT_TRUE(stream_->reading_stopped()); |
410 EXPECT_TRUE(stream_->write_side_closed()); | 434 EXPECT_TRUE(stream_->write_side_closed()); |
411 } | 435 } |
412 | 436 |
413 TEST_P(QuicSimpleServerStreamTest, SendReponseWithPushResources) { | 437 TEST_P(QuicSimpleServerStreamTest, SendReponseWithPushResources) { |
414 // Tests that if a reponse has push resources to be send, SendResponse() will | 438 // Tests that if a reponse has push resources to be send, SendResponse() will |
415 // call PromisePushResources() to handle these resources. | 439 // call PromisePushResources() to handle these resources. |
416 | 440 |
417 // Add a request and response with valid headers into cache. | 441 // Add a request and response with valid headers into cache. |
418 string host = "www.google.com"; | 442 string host = "www.google.com"; |
419 string request_path = "/foo"; | 443 string request_path = "/foo"; |
420 string body = "Yummm"; | 444 string body = "Yummm"; |
421 SpdyHeaderBlock response_headers; | |
422 string url = host + "/bar"; | 445 string url = host + "/bar"; |
423 QuicInMemoryCache::ServerPushInfo push_info(GURL(url), response_headers, | 446 QuicInMemoryCache::ServerPushInfo push_info(GURL(url), SpdyHeaderBlock(), |
424 kDefaultPriority, "Push body"); | 447 kDefaultPriority, "Push body"); |
425 std::list<QuicInMemoryCache::ServerPushInfo> push_resources; | 448 std::list<QuicInMemoryCache::ServerPushInfo> push_resources; |
426 push_resources.push_back(push_info); | 449 push_resources.push_back(push_info); |
427 QuicInMemoryCache::GetInstance()->AddSimpleResponseWithServerPushResources( | 450 QuicInMemoryCache::GetInstance()->AddSimpleResponseWithServerPushResources( |
428 host, request_path, 200, body, push_resources); | 451 host, request_path, 200, body, push_resources); |
429 | 452 |
430 SpdyHeaderBlock* request_headers = stream_->mutable_headers(); | 453 SpdyHeaderBlock* request_headers = stream_->mutable_headers(); |
431 (*request_headers)[":path"] = request_path; | 454 (*request_headers)[":path"] = request_path; |
432 (*request_headers)[":authority"] = host; | 455 (*request_headers)[":authority"] = host; |
433 (*request_headers)[":version"] = "HTTP/1.1"; | 456 (*request_headers)[":version"] = "HTTP/1.1"; |
434 (*request_headers)[":method"] = "GET"; | 457 (*request_headers)[":method"] = "GET"; |
435 | 458 |
436 stream_->set_fin_received(true); | 459 stream_->set_fin_received(true); |
437 InSequence s; | 460 InSequence s; |
438 EXPECT_CALL(session_, PromisePushResources(host + request_path, _, | 461 EXPECT_CALL(session_, |
439 ::net::test::kClientDataStreamId1, | 462 PromisePushResourcesMock(host + request_path, _, |
440 *request_headers)); | 463 ::net::test::kClientDataStreamId1, _)); |
441 EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr)); | 464 EXPECT_CALL(session_, WriteHeadersMock(stream_->id(), _, false, _, nullptr)); |
442 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 465 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
443 .Times(1) | 466 .Times(1) |
444 .WillOnce(Return(QuicConsumedData(body.length(), true))); | 467 .WillOnce(Return(QuicConsumedData(body.length(), true))); |
445 QuicSimpleServerStreamPeer::SendResponse(stream_); | 468 QuicSimpleServerStreamPeer::SendResponse(stream_); |
| 469 EXPECT_EQ(*request_headers, session_.original_request_headers_); |
446 } | 470 } |
447 | 471 |
448 TEST_P(QuicSimpleServerStreamTest, PushResponseOnClientInitiatedStream) { | 472 TEST_P(QuicSimpleServerStreamTest, PushResponseOnClientInitiatedStream) { |
449 // Calling PushResponse() on a client initialted stream is never supposed to | 473 // Calling PushResponse() on a client initialted stream is never supposed to |
450 // happen. | 474 // happen. |
451 SpdyHeaderBlock headers; | 475 EXPECT_DFATAL(stream_->PushResponse(SpdyHeaderBlock()), |
452 EXPECT_DFATAL(stream_->PushResponse(headers), | |
453 "Client initiated stream" | 476 "Client initiated stream" |
454 " shouldn't be used as promised stream."); | 477 " shouldn't be used as promised stream."); |
455 } | 478 } |
456 | 479 |
457 TEST_P(QuicSimpleServerStreamTest, PushResponseOnServerInitiatedStream) { | 480 TEST_P(QuicSimpleServerStreamTest, PushResponseOnServerInitiatedStream) { |
458 // Tests that PushResponse() should take the given headers as request headers | 481 // Tests that PushResponse() should take the given headers as request headers |
459 // and fetch response from cache, and send it out. | 482 // and fetch response from cache, and send it out. |
460 | 483 |
461 // Create a stream with even stream id and test against this stream. | 484 // Create a stream with even stream id and test against this stream. |
462 const QuicStreamId kServerInitiatedStreamId = 2; | 485 const QuicStreamId kServerInitiatedStreamId = 2; |
463 // Create a server initiated stream and pass it to session_. | 486 // Create a server initiated stream and pass it to session_. |
464 QuicSimpleServerStreamPeer* server_initiated_stream = | 487 QuicSimpleServerStreamPeer* server_initiated_stream = |
465 new QuicSimpleServerStreamPeer(kServerInitiatedStreamId, &session_); | 488 new QuicSimpleServerStreamPeer(kServerInitiatedStreamId, &session_); |
466 session_.ActivateStream(server_initiated_stream); | 489 session_.ActivateStream(server_initiated_stream); |
467 | 490 |
468 const string kHost = "www.foo.com"; | 491 const string kHost = "www.foo.com"; |
469 const string kPath = "/bar"; | 492 const string kPath = "/bar"; |
470 SpdyHeaderBlock headers; | 493 SpdyHeaderBlock headers; |
471 headers[":path"] = kPath; | 494 headers[":path"] = kPath; |
472 headers[":authority"] = kHost; | 495 headers[":authority"] = kHost; |
473 headers[":version"] = "HTTP/1.1"; | 496 headers[":version"] = "HTTP/1.1"; |
474 headers[":method"] = "GET"; | 497 headers[":method"] = "GET"; |
475 | 498 |
476 response_headers_[":version"] = "HTTP/1.1"; | 499 response_headers_[":version"] = "HTTP/1.1"; |
477 response_headers_[":status"] = "200"; | 500 response_headers_[":status"] = "200"; |
478 response_headers_["content-length"] = "5"; | 501 response_headers_["content-length"] = "5"; |
479 const string kBody = "Hello"; | 502 const string kBody = "Hello"; |
480 QuicInMemoryCache::GetInstance()->AddResponse(kHost, kPath, response_headers_, | 503 QuicInMemoryCache::GetInstance()->AddResponse( |
481 kBody); | 504 kHost, kPath, std::move(response_headers_), kBody); |
482 | 505 |
483 // Call PushResponse() should trigger stream to fetch response from cache | 506 // Call PushResponse() should trigger stream to fetch response from cache |
484 // and send it back. | 507 // and send it back. |
485 EXPECT_CALL(session_, | 508 EXPECT_CALL(session_, |
486 WriteHeaders(kServerInitiatedStreamId, _, false, | 509 WriteHeadersMock(kServerInitiatedStreamId, _, false, |
487 server_initiated_stream->priority(), nullptr)); | 510 server_initiated_stream->priority(), nullptr)); |
488 EXPECT_CALL(session_, WritevData(_, kServerInitiatedStreamId, _, _, _, _)) | 511 EXPECT_CALL(session_, WritevData(_, kServerInitiatedStreamId, _, _, _, _)) |
489 .Times(1) | 512 .Times(1) |
490 .WillOnce(Return(QuicConsumedData(kBody.size(), true))); | 513 .WillOnce(Return(QuicConsumedData(kBody.size(), true))); |
491 server_initiated_stream->PushResponse(headers); | 514 server_initiated_stream->PushResponse(std::move(headers)); |
492 EXPECT_EQ(kPath, QuicSimpleServerStreamPeer::headers( | 515 EXPECT_EQ(kPath, QuicSimpleServerStreamPeer::headers( |
493 server_initiated_stream)[":path"] | 516 server_initiated_stream)[":path"] |
494 .as_string()); | 517 .as_string()); |
495 EXPECT_EQ("GET", QuicSimpleServerStreamPeer::headers( | 518 EXPECT_EQ("GET", QuicSimpleServerStreamPeer::headers( |
496 server_initiated_stream)[":method"] | 519 server_initiated_stream)[":method"] |
497 .as_string()); | 520 .as_string()); |
498 } | 521 } |
499 | 522 |
500 TEST_P(QuicSimpleServerStreamTest, TestSendErrorResponse) { | 523 TEST_P(QuicSimpleServerStreamTest, TestSendErrorResponse) { |
501 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 524 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
502 | 525 |
503 response_headers_[":version"] = "HTTP/1.1"; | |
504 response_headers_[":status"] = "500 Server Error"; | |
505 response_headers_["content-length"] = "3"; | |
506 stream_->set_fin_received(true); | 526 stream_->set_fin_received(true); |
507 | 527 |
508 InSequence s; | 528 InSequence s; |
509 EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _)); | 529 EXPECT_CALL(session_, WriteHeadersMock(_, _, _, _, _)); |
510 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 530 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
511 .Times(1) | 531 .Times(1) |
512 .WillOnce(Return(QuicConsumedData(3, true))); | 532 .WillOnce(Return(QuicConsumedData(3, true))); |
513 | 533 |
514 QuicSimpleServerStreamPeer::SendErrorResponse(stream_); | 534 QuicSimpleServerStreamPeer::SendErrorResponse(stream_); |
515 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 535 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
516 EXPECT_TRUE(stream_->reading_stopped()); | 536 EXPECT_TRUE(stream_->reading_stopped()); |
517 EXPECT_TRUE(stream_->write_side_closed()); | 537 EXPECT_TRUE(stream_->write_side_closed()); |
518 } | 538 } |
519 | 539 |
520 TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) { | 540 TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) { |
521 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 541 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
522 | 542 |
523 SpdyHeaderBlock request_headers; | 543 SpdyHeaderBlock request_headers; |
524 // \000 is a way to write the null byte when followed by a literal digit. | 544 // \000 is a way to write the null byte when followed by a literal digit. |
525 request_headers["content-length"] = StringPiece("11\00012", 5); | 545 request_headers["content-length"] = StringPiece("11\00012", 5); |
526 | 546 |
527 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers); | 547 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers); |
528 | 548 |
529 EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _)); | 549 EXPECT_CALL(session_, WriteHeadersMock(_, _, _, _, _)); |
530 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 550 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
531 .Times(AnyNumber()) | 551 .Times(AnyNumber()) |
532 .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData)); | 552 .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData)); |
533 stream_->OnStreamHeaders(headers_string_); | 553 stream_->OnStreamHeaders(headers_string_); |
534 stream_->OnStreamHeadersComplete(true, headers_string_.size()); | 554 stream_->OnStreamHeadersComplete(true, headers_string_.size()); |
535 | 555 |
536 EXPECT_TRUE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 556 EXPECT_TRUE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
537 EXPECT_TRUE(stream_->reading_stopped()); | 557 EXPECT_TRUE(stream_->reading_stopped()); |
538 EXPECT_TRUE(stream_->write_side_closed()); | 558 EXPECT_TRUE(stream_->write_side_closed()); |
539 } | 559 } |
540 | 560 |
541 TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) { | 561 TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) { |
542 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 562 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
543 | 563 |
544 SpdyHeaderBlock request_headers; | 564 SpdyHeaderBlock request_headers; |
545 // \000 is a way to write the null byte when followed by a literal digit. | 565 // \000 is a way to write the null byte when followed by a literal digit. |
546 request_headers["content-length"] = StringPiece("\00012", 3); | 566 request_headers["content-length"] = StringPiece("\00012", 3); |
547 | 567 |
548 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers); | 568 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers); |
549 | 569 |
550 EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _)); | 570 EXPECT_CALL(session_, WriteHeadersMock(_, _, _, _, _)); |
551 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 571 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
552 .Times(AnyNumber()) | 572 .Times(AnyNumber()) |
553 .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData)); | 573 .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData)); |
554 stream_->OnStreamHeaders(headers_string_); | 574 stream_->OnStreamHeaders(headers_string_); |
555 stream_->OnStreamHeadersComplete(true, headers_string_.size()); | 575 stream_->OnStreamHeadersComplete(true, headers_string_.size()); |
556 | 576 |
557 EXPECT_TRUE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 577 EXPECT_TRUE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
558 EXPECT_TRUE(stream_->reading_stopped()); | 578 EXPECT_TRUE(stream_->reading_stopped()); |
559 EXPECT_TRUE(stream_->write_side_closed()); | 579 EXPECT_TRUE(stream_->write_side_closed()); |
560 } | 580 } |
561 | 581 |
562 TEST_P(QuicSimpleServerStreamTest, ValidMultipleContentLength) { | 582 TEST_P(QuicSimpleServerStreamTest, ValidMultipleContentLength) { |
563 SpdyHeaderBlock request_headers; | 583 SpdyHeaderBlock request_headers; |
564 // \000 is a way to write the null byte when followed by a literal digit. | 584 // \000 is a way to write the null byte when followed by a literal digit. |
565 request_headers["content-length"] = StringPiece("11\00011", 5); | 585 request_headers["content-length"] = StringPiece("11\00011", 5); |
566 | 586 |
567 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers); | 587 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers); |
568 | 588 |
569 stream_->OnStreamHeaders(headers_string_); | 589 stream_->OnStreamHeaders(headers_string_); |
570 stream_->OnStreamHeadersComplete(false, headers_string_.size()); | 590 stream_->OnStreamHeadersComplete(false, headers_string_.size()); |
571 | 591 |
572 EXPECT_EQ(11, QuicSimpleServerStreamPeer::content_length(stream_)); | 592 EXPECT_EQ(11, QuicSimpleServerStreamPeer::content_length(stream_)); |
573 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 593 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
574 EXPECT_FALSE(stream_->reading_stopped()); | 594 EXPECT_FALSE(stream_->reading_stopped()); |
575 EXPECT_FALSE(stream_->write_side_closed()); | 595 EXPECT_FALSE(stream_->write_side_closed()); |
576 } | 596 } |
577 | 597 |
578 TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorWithEarlyResponse) { | 598 TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorWithEarlyResponse) { |
579 response_headers_[":version"] = "HTTP/1.1"; | |
580 response_headers_[":status"] = "500 Server Error"; | |
581 response_headers_["content-length"] = "3"; | |
582 | |
583 InSequence s; | 599 InSequence s; |
584 EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, _, _, _)); | 600 EXPECT_CALL(session_, WriteHeadersMock(stream_->id(), _, false, _, nullptr)); |
585 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 601 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
586 .Times(1) | 602 .Times(1) |
587 .WillOnce(Return(QuicConsumedData(3, true))); | 603 .WillOnce(Return(QuicConsumedData(3, true))); |
588 if (GetParam() > QUIC_VERSION_28) { | 604 if (GetParam() > QUIC_VERSION_28) { |
589 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(1); | 605 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(1); |
590 } else { | 606 } else { |
591 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 607 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
592 } | 608 } |
593 EXPECT_FALSE(stream_->fin_received()); | 609 EXPECT_FALSE(stream_->fin_received()); |
594 QuicSimpleServerStreamPeer::SendErrorResponse(stream_); | 610 QuicSimpleServerStreamPeer::SendErrorResponse(stream_); |
595 EXPECT_TRUE(stream_->reading_stopped()); | 611 EXPECT_TRUE(stream_->reading_stopped()); |
596 EXPECT_TRUE(stream_->write_side_closed()); | 612 EXPECT_TRUE(stream_->write_side_closed()); |
597 } | 613 } |
598 | 614 |
599 TEST_P(QuicSimpleServerStreamTest, | 615 TEST_P(QuicSimpleServerStreamTest, |
600 DoNotSendQuicRstStreamNoErrorWithRstReceived) { | 616 DoNotSendQuicRstStreamNoErrorWithRstReceived) { |
601 response_headers_[":version"] = "HTTP/1.1"; | |
602 response_headers_[":status"] = "500 Server Error"; | |
603 response_headers_["content-length"] = "3"; | |
604 | |
605 InSequence s; | 617 InSequence s; |
606 EXPECT_FALSE(stream_->reading_stopped()); | 618 EXPECT_FALSE(stream_->reading_stopped()); |
607 | 619 |
608 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 620 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
609 EXPECT_CALL(session_, SendRstStream(_, QUIC_RST_ACKNOWLEDGEMENT, _)).Times(1); | 621 EXPECT_CALL(session_, SendRstStream(_, QUIC_RST_ACKNOWLEDGEMENT, _)).Times(1); |
610 QuicRstStreamFrame rst_frame(stream_->id(), QUIC_STREAM_CANCELLED, 1234); | 622 QuicRstStreamFrame rst_frame(stream_->id(), QUIC_STREAM_CANCELLED, 1234); |
611 stream_->OnStreamReset(rst_frame); | 623 stream_->OnStreamReset(rst_frame); |
612 | 624 |
613 EXPECT_TRUE(stream_->reading_stopped()); | 625 EXPECT_TRUE(stream_->reading_stopped()); |
614 EXPECT_TRUE(stream_->write_side_closed()); | 626 EXPECT_TRUE(stream_->write_side_closed()); |
(...skipping 25 matching lines...) Expand all Loading... |
640 }; | 652 }; |
641 StringPiece data(arr, arraysize(arr)); | 653 StringPiece data(arr, arraysize(arr)); |
642 QuicStreamFrame frame(stream_->id(), true, 0, data); | 654 QuicStreamFrame frame(stream_->id(), true, 0, data); |
643 // Verify that we don't crash when we get a invalid headers in stream frame. | 655 // Verify that we don't crash when we get a invalid headers in stream frame. |
644 stream_->OnStreamFrame(frame); | 656 stream_->OnStreamFrame(frame); |
645 } | 657 } |
646 | 658 |
647 } // namespace | 659 } // namespace |
648 } // namespace test | 660 } // namespace test |
649 } // namespace net | 661 } // namespace net |
OLD | NEW |