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 handles a chunked upload with no |
| 577 // payload. Unclear if this is a case worth supporting. |
| 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 |