Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/spdy/spdy_http_stream.h" | 5 #include "net/spdy/spdy_http_stream.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 478 EXPECT_EQ(kUploadData, std::string(buf3->data(), kUploadDataSize)); | 478 EXPECT_EQ(kUploadData, std::string(buf3->data(), kUploadDataSize)); |
| 479 | 479 |
| 480 // Finish reading the |EOF|. | 480 // Finish reading the |EOF|. |
| 481 deterministic_data()->RunFor(1); | 481 deterministic_data()->RunFor(1); |
| 482 ASSERT_TRUE(response.headers.get()); | 482 ASSERT_TRUE(response.headers.get()); |
| 483 ASSERT_EQ(200, response.headers->response_code()); | 483 ASSERT_EQ(200, response.headers->response_code()); |
| 484 EXPECT_TRUE(deterministic_data()->at_read_eof()); | 484 EXPECT_TRUE(deterministic_data()->at_read_eof()); |
| 485 EXPECT_TRUE(deterministic_data()->at_write_eof()); | 485 EXPECT_TRUE(deterministic_data()->at_write_eof()); |
| 486 } | 486 } |
| 487 | 487 |
| 488 // Test that the SpdyStream state machine can handle sending a final empty data | |
| 489 // frame when uploading a chunked data stream. | |
| 490 TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPostWithEmptyFinalDataFrame) { | |
| 491 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); | |
| 492 scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, false)); | |
| 493 scoped_ptr<SpdyFrame> chunk2( | |
| 494 spdy_util_.ConstructSpdyBodyFrame(1, "", 0, true)); | |
| 495 MockWrite writes[] = { | |
| 496 CreateMockWrite(*req.get(), 0), | |
| 497 CreateMockWrite(*chunk1, 1), // POST upload frames | |
| 498 CreateMockWrite(*chunk2, 2), | |
| 499 }; | |
| 500 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); | |
| 501 MockRead reads[] = { | |
| 502 CreateMockRead(*resp, 3), | |
| 503 CreateMockRead(*chunk1, 4), | |
| 504 CreateMockRead(*chunk2, 5), | |
| 505 MockRead(ASYNC, 0, 6) // EOF | |
| 506 }; | |
| 507 | |
| 508 HostPortPair host_port_pair("www.google.com", 80); | |
| 509 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), | |
| 510 PRIVACY_MODE_DISABLED); | |
| 511 InitSessionDeterministic(reads, arraysize(reads), | |
| 512 writes, arraysize(writes), | |
| 513 key); | |
| 514 | |
| 515 UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0); | |
| 516 | |
| 517 HttpRequestInfo request; | |
| 518 request.method = "POST"; | |
| 519 request.url = GURL("http://www.google.com/"); | |
| 520 request.upload_data_stream = &upload_stream; | |
| 521 | |
| 522 ASSERT_EQ(OK, upload_stream.Init(CompletionCallback())); | |
| 523 upload_stream.AppendChunk(kUploadData, kUploadDataSize, false); | |
| 524 | |
| 525 BoundNetLog net_log; | |
| 526 scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); | |
| 527 ASSERT_EQ(OK, http_stream->InitializeStream(&request, DEFAULT_PRIORITY, | |
| 528 net_log, CompletionCallback())); | |
| 529 | |
| 530 TestCompletionCallback callback; | |
| 531 HttpRequestHeaders headers; | |
| 532 HttpResponseInfo response; | |
| 533 // This will attempt to Write() the initial request and headers, which will | |
| 534 // complete asynchronously. | |
| 535 EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response, | |
| 536 callback.callback())); | |
| 537 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); | |
| 538 | |
| 539 // Complete the initial request write and the first chunk. | |
| 540 deterministic_data()->RunFor(2); | |
| 541 ASSERT_TRUE(callback.have_result()); | |
| 542 EXPECT_EQ(OK, callback.WaitForResult()); | |
| 543 | |
| 544 // Now end the stream with an empty data frame and the FIN set. | |
| 545 upload_stream.AppendChunk(NULL, 0, true); | |
| 546 | |
| 547 // Finish writing the final frame. | |
| 548 deterministic_data()->RunFor(1); | |
| 549 | |
| 550 // Read response headers. | |
| 551 deterministic_data()->RunFor(1); | |
| 552 ASSERT_EQ(OK, http_stream->ReadResponseHeaders(callback.callback())); | |
| 553 | |
| 554 // Read and check |chunk1| response. | |
| 555 deterministic_data()->RunFor(1); | |
| 556 scoped_refptr<IOBuffer> buf1(new IOBuffer(kUploadDataSize)); | |
| 557 ASSERT_EQ(kUploadDataSize, | |
| 558 http_stream->ReadResponseBody( | |
| 559 buf1.get(), kUploadDataSize, callback.callback())); | |
| 560 EXPECT_EQ(kUploadData, std::string(buf1->data(), kUploadDataSize)); | |
| 561 | |
| 562 // Read and check |chunk2| response. | |
| 563 deterministic_data()->RunFor(1); | |
| 564 ASSERT_EQ(0, | |
| 565 http_stream->ReadResponseBody( | |
| 566 buf1.get(), kUploadDataSize, callback.callback())); | |
| 567 | |
| 568 // Finish reading the |EOF|. | |
| 569 deterministic_data()->RunFor(1); | |
| 570 ASSERT_TRUE(response.headers.get()); | |
| 571 ASSERT_EQ(200, response.headers->response_code()); | |
| 572 EXPECT_TRUE(deterministic_data()->at_read_eof()); | |
| 573 EXPECT_TRUE(deterministic_data()->at_write_eof()); | |
| 574 } | |
| 575 | |
| 576 // Test that the SpdyStream state machine can an chunked upload with no payload. | |
|
Johnny
2014/08/21 16:16:58
"can an chunked" => "handles a chunked"?
mmenke
2014/08/21 16:22:04
Oops. Done.
| |
| 577 // Unclear if this is a case worth supporting. | |
|
mmenke
2014/08/21 15:40:24
Not sure if we should really bother with this test
Johnny
2014/08/21 16:16:58
It's allowed at the protocol level, and I can imag
| |
| 578 TEST_P(SpdyHttpStreamTest, ChunkedPostWithEmptyPayload) { | |
| 579 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); | |
| 580 scoped_ptr<SpdyFrame> chunk( | |
| 581 spdy_util_.ConstructSpdyBodyFrame(1, "", 0, true)); | |
| 582 MockWrite writes[] = { | |
| 583 CreateMockWrite(*req.get(), 0), | |
| 584 CreateMockWrite(*chunk, 1), | |
| 585 }; | |
| 586 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); | |
| 587 MockRead reads[] = { | |
| 588 CreateMockRead(*resp, 2), | |
| 589 CreateMockRead(*chunk, 3), | |
| 590 MockRead(ASYNC, 0, 4) // EOF | |
| 591 }; | |
| 592 | |
| 593 HostPortPair host_port_pair("www.google.com", 80); | |
| 594 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), | |
| 595 PRIVACY_MODE_DISABLED); | |
| 596 InitSessionDeterministic(reads, arraysize(reads), | |
| 597 writes, arraysize(writes), | |
| 598 key); | |
| 599 | |
| 600 UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0); | |
| 601 | |
| 602 HttpRequestInfo request; | |
| 603 request.method = "POST"; | |
| 604 request.url = GURL("http://www.google.com/"); | |
| 605 request.upload_data_stream = &upload_stream; | |
| 606 | |
| 607 ASSERT_EQ(OK, upload_stream.Init(CompletionCallback())); | |
| 608 upload_stream.AppendChunk("", 0, true); | |
| 609 | |
| 610 BoundNetLog net_log; | |
| 611 scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); | |
| 612 ASSERT_EQ(OK, http_stream->InitializeStream(&request, DEFAULT_PRIORITY, | |
| 613 net_log, CompletionCallback())); | |
| 614 | |
| 615 TestCompletionCallback callback; | |
| 616 HttpRequestHeaders headers; | |
| 617 HttpResponseInfo response; | |
| 618 // This will attempt to Write() the initial request and headers, which will | |
| 619 // complete asynchronously. | |
| 620 EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response, | |
| 621 callback.callback())); | |
| 622 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); | |
| 623 | |
| 624 // Complete writing request, followed by a FIN. | |
| 625 deterministic_data()->RunFor(2); | |
| 626 ASSERT_TRUE(callback.have_result()); | |
| 627 EXPECT_EQ(OK, callback.WaitForResult()); | |
| 628 | |
| 629 // Read response headers. | |
| 630 deterministic_data()->RunFor(1); | |
| 631 ASSERT_EQ(OK, http_stream->ReadResponseHeaders(callback.callback())); | |
| 632 | |
| 633 // Read and check |chunk| response. | |
| 634 deterministic_data()->RunFor(1); | |
| 635 scoped_refptr<IOBuffer> buf(new IOBuffer(1)); | |
| 636 ASSERT_EQ(0, | |
| 637 http_stream->ReadResponseBody( | |
| 638 buf.get(), 1, callback.callback())); | |
| 639 | |
| 640 // Finish reading the |EOF|. | |
| 641 deterministic_data()->RunFor(1); | |
| 642 ASSERT_TRUE(response.headers.get()); | |
| 643 ASSERT_EQ(200, response.headers->response_code()); | |
| 644 EXPECT_TRUE(deterministic_data()->at_read_eof()); | |
| 645 EXPECT_TRUE(deterministic_data()->at_write_eof()); | |
| 646 } | |
| 647 | |
| 488 // Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058 | 648 // Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058 |
| 489 TEST_P(SpdyHttpStreamTest, SpdyURLTest) { | 649 TEST_P(SpdyHttpStreamTest, SpdyURLTest) { |
| 490 const char * const full_url = "http://www.google.com/foo?query=what#anchor"; | 650 const char * const full_url = "http://www.google.com/foo?query=what#anchor"; |
| 491 const char * const base_url = "http://www.google.com/foo?query=what"; | 651 const char * const base_url = "http://www.google.com/foo?query=what"; |
| 492 scoped_ptr<SpdyFrame> req( | 652 scoped_ptr<SpdyFrame> req( |
| 493 spdy_util_.ConstructSpdyGet(base_url, false, 1, LOWEST)); | 653 spdy_util_.ConstructSpdyGet(base_url, false, 1, LOWEST)); |
| 494 MockWrite writes[] = { | 654 MockWrite writes[] = { |
| 495 CreateMockWrite(*req.get(), 1), | 655 CreateMockWrite(*req.get(), 1), |
| 496 }; | 656 }; |
| 497 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 657 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 626 ASSERT_TRUE(response.headers.get()); | 786 ASSERT_TRUE(response.headers.get()); |
| 627 ASSERT_EQ(200, response.headers->response_code()); | 787 ASSERT_EQ(200, response.headers->response_code()); |
| 628 EXPECT_TRUE(deterministic_data_->at_read_eof()); | 788 EXPECT_TRUE(deterministic_data_->at_read_eof()); |
| 629 EXPECT_TRUE(deterministic_data_->at_write_eof()); | 789 EXPECT_TRUE(deterministic_data_->at_write_eof()); |
| 630 } | 790 } |
| 631 | 791 |
| 632 // TODO(willchan): Write a longer test for SpdyStream that exercises all | 792 // TODO(willchan): Write a longer test for SpdyStream that exercises all |
| 633 // methods. | 793 // methods. |
| 634 | 794 |
| 635 } // namespace net | 795 } // namespace net |
| OLD | NEW |