Index: net/quic/quic_http_stream_test.cc |
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc |
deleted file mode 100644 |
index 5b69e469bf04ebb897149a9178d8f5a210483f27..0000000000000000000000000000000000000000 |
--- a/net/quic/quic_http_stream_test.cc |
+++ /dev/null |
@@ -1,766 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "net/quic/quic_http_stream.h" |
- |
-#include <vector> |
- |
-#include "net/base/chunked_upload_data_stream.h" |
-#include "net/base/elements_upload_data_stream.h" |
-#include "net/base/net_errors.h" |
-#include "net/base/test_completion_callback.h" |
-#include "net/base/upload_bytes_element_reader.h" |
-#include "net/http/http_response_headers.h" |
-#include "net/http/transport_security_state.h" |
-#include "net/quic/congestion_control/send_algorithm_interface.h" |
-#include "net/quic/crypto/crypto_protocol.h" |
-#include "net/quic/crypto/quic_decrypter.h" |
-#include "net/quic/crypto/quic_encrypter.h" |
-#include "net/quic/crypto/quic_server_info.h" |
-#include "net/quic/quic_client_session.h" |
-#include "net/quic/quic_connection.h" |
-#include "net/quic/quic_connection_helper.h" |
-#include "net/quic/quic_default_packet_writer.h" |
-#include "net/quic/quic_http_utils.h" |
-#include "net/quic/quic_reliable_client_stream.h" |
-#include "net/quic/quic_write_blocked_list.h" |
-#include "net/quic/spdy_utils.h" |
-#include "net/quic/test_tools/mock_clock.h" |
-#include "net/quic/test_tools/mock_crypto_client_stream_factory.h" |
-#include "net/quic/test_tools/mock_random.h" |
-#include "net/quic/test_tools/quic_connection_peer.h" |
-#include "net/quic/test_tools/quic_test_packet_maker.h" |
-#include "net/quic/test_tools/quic_test_utils.h" |
-#include "net/quic/test_tools/test_task_runner.h" |
-#include "net/socket/socket_test_util.h" |
-#include "net/spdy/spdy_frame_builder.h" |
-#include "net/spdy/spdy_framer.h" |
-#include "net/spdy/spdy_http_utils.h" |
-#include "net/spdy/spdy_protocol.h" |
-#include "testing/gmock/include/gmock/gmock.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-using testing::_; |
-using testing::AnyNumber; |
-using testing::Return; |
- |
-namespace net { |
-namespace test { |
-namespace { |
- |
-const char kUploadData[] = "Really nifty data!"; |
-const char kServerHostname[] = "www.google.com"; |
-const uint16 kServerPort = 80; |
- |
-class TestQuicConnection : public QuicConnection { |
- public: |
- TestQuicConnection(const QuicVersionVector& versions, |
- QuicConnectionId connection_id, |
- IPEndPoint address, |
- QuicConnectionHelper* helper, |
- const QuicConnection::PacketWriterFactory& writer_factory) |
- : QuicConnection(connection_id, |
- address, |
- helper, |
- writer_factory, |
- true /* owns_writer */, |
- false /* is_server */, |
- false /* is_secure */, |
- versions) { |
- } |
- |
- void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { |
- QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm); |
- } |
-}; |
- |
-// Subclass of QuicHttpStream that closes itself when the first piece of data |
-// is received. |
-class AutoClosingStream : public QuicHttpStream { |
- public: |
- explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session) |
- : QuicHttpStream(session) { |
- } |
- |
- int OnDataReceived(const char* data, int length) override { |
- Close(false); |
- return OK; |
- } |
-}; |
- |
-class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory { |
- public: |
- explicit TestPacketWriterFactory(DatagramClientSocket* socket) |
- : socket_(socket) {} |
- ~TestPacketWriterFactory() override {} |
- |
- QuicPacketWriter* Create(QuicConnection* connection) const override { |
- return new QuicDefaultPacketWriter(socket_); |
- } |
- |
- private: |
- DatagramClientSocket* socket_; |
-}; |
- |
-} // namespace |
- |
-class QuicHttpStreamPeer { |
- public: |
- static QuicReliableClientStream* GetQuicReliableClientStream( |
- QuicHttpStream* stream) { |
- return stream->stream_; |
- } |
-}; |
- |
-class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> { |
- protected: |
- static const bool kFin = true; |
- static const bool kIncludeVersion = true; |
- static const bool kIncludeCongestionFeedback = true; |
- |
- // Holds a packet to be written to the wire, and the IO mode that should |
- // be used by the mock socket when performing the write. |
- struct PacketToWrite { |
- PacketToWrite(IoMode mode, QuicEncryptedPacket* packet) |
- : mode(mode), |
- packet(packet) { |
- } |
- IoMode mode; |
- QuicEncryptedPacket* packet; |
- }; |
- |
- QuicHttpStreamTest() |
- : net_log_(BoundNetLog()), |
- use_closing_stream_(false), |
- read_buffer_(new IOBufferWithSize(4096)), |
- connection_id_(2), |
- stream_id_(kClientDataStreamId1), |
- maker_(GetParam(), connection_id_, &clock_), |
- random_generator_(0) { |
- IPAddressNumber ip; |
- CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); |
- peer_addr_ = IPEndPoint(ip, 443); |
- self_addr_ = IPEndPoint(ip, 8435); |
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20)); |
- } |
- |
- ~QuicHttpStreamTest() { |
- session_->CloseSessionOnError(ERR_ABORTED); |
- for (size_t i = 0; i < writes_.size(); i++) { |
- delete writes_[i].packet; |
- } |
- } |
- |
- // Adds a packet to the list of expected writes. |
- void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) { |
- writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release())); |
- } |
- |
- // Returns the packet to be written at position |pos|. |
- QuicEncryptedPacket* GetWrite(size_t pos) { |
- return writes_[pos].packet; |
- } |
- |
- bool AtEof() { |
- return socket_data_->at_read_eof() && socket_data_->at_write_eof(); |
- } |
- |
- void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) { |
- connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet); |
- } |
- |
- // Configures the test fixture to use the list of expected writes. |
- void Initialize() { |
- mock_writes_.reset(new MockWrite[writes_.size()]); |
- for (size_t i = 0; i < writes_.size(); i++) { |
- mock_writes_[i] = MockWrite(writes_[i].mode, |
- writes_[i].packet->data(), |
- writes_[i].packet->length()); |
- }; |
- |
- socket_data_.reset(new StaticSocketDataProvider( |
- nullptr, 0, mock_writes_.get(), writes_.size())); |
- |
- MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(), |
- net_log_.net_log()); |
- socket->Connect(peer_addr_); |
- runner_ = new TestTaskRunner(&clock_); |
- send_algorithm_ = new MockSendAlgorithm(); |
- EXPECT_CALL(*send_algorithm_, |
- OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true)); |
- EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( |
- Return(QuicTime::Delta::Zero())); |
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly( |
- Return(kMaxPacketSize)); |
- EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)). |
- WillRepeatedly(Return(QuicTime::Delta::Zero())); |
- EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly( |
- Return(QuicBandwidth::Zero())); |
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _)).Times(AnyNumber()); |
- helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_, |
- &random_generator_)); |
- TestPacketWriterFactory writer_factory(socket); |
- connection_ = new TestQuicConnection(SupportedVersions(GetParam()), |
- connection_id_, peer_addr_, |
- helper_.get(), writer_factory); |
- connection_->set_visitor(&visitor_); |
- connection_->SetSendAlgorithm(send_algorithm_); |
- session_.reset( |
- new QuicClientSession(connection_, |
- scoped_ptr<DatagramClientSocket>(socket), |
- nullptr, |
- &transport_security_state_, |
- make_scoped_ptr((QuicServerInfo*)nullptr), |
- DefaultQuicConfig(), |
- base::MessageLoop::current()-> |
- message_loop_proxy().get(), |
- nullptr)); |
- session_->InitializeSession(QuicServerId(kServerHostname, kServerPort, |
- /*is_secure=*/false, |
- PRIVACY_MODE_DISABLED), |
- &crypto_config_, |
- &crypto_client_stream_factory_); |
- session_->GetCryptoStream()->CryptoConnect(); |
- EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed()); |
- stream_.reset(use_closing_stream_ ? |
- new AutoClosingStream(session_->GetWeakPtr()) : |
- new QuicHttpStream(session_->GetWeakPtr())); |
- } |
- |
- void SetRequest(const std::string& method, |
- const std::string& path, |
- RequestPriority priority) { |
- request_headers_ = maker_.GetRequestHeaders(method, "http", path); |
- } |
- |
- void SetResponse(const std::string& status, const std::string& body) { |
- response_headers_ = maker_.GetResponseHeaders(status); |
- response_data_ = body; |
- } |
- |
- scoped_ptr<QuicEncryptedPacket> ConstructDataPacket( |
- QuicPacketSequenceNumber sequence_number, |
- bool should_include_version, |
- bool fin, |
- QuicStreamOffset offset, |
- base::StringPiece data) { |
- return maker_.MakeDataPacket(sequence_number, stream_id_, |
- should_include_version, fin, offset, data); |
- } |
- |
- scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket( |
- QuicPacketSequenceNumber sequence_number, |
- bool fin, |
- RequestPriority request_priority) { |
- QuicPriority priority = |
- ConvertRequestPriorityToQuicPriority(request_priority); |
- return maker_.MakeRequestHeadersPacket(sequence_number, stream_id_, |
- kIncludeVersion, fin, priority, |
- request_headers_); |
- } |
- |
- scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket( |
- QuicPacketSequenceNumber sequence_number, |
- bool fin) { |
- return maker_.MakeResponseHeadersPacket( |
- sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_); |
- } |
- |
- scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket( |
- QuicPacketSequenceNumber sequence_number) { |
- return maker_.MakeRstPacket( |
- sequence_number, true, stream_id_, |
- AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam())); |
- } |
- |
- scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket( |
- QuicPacketSequenceNumber sequence_number) { |
- return maker_.MakeAckAndRstPacket( |
- sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED, |
- 2, 1, !kIncludeCongestionFeedback); |
- } |
- |
- scoped_ptr<QuicEncryptedPacket> ConstructAckPacket( |
- QuicPacketSequenceNumber sequence_number, |
- QuicPacketSequenceNumber largest_received, |
- QuicPacketSequenceNumber least_unacked) { |
- return maker_.MakeAckPacket(sequence_number, largest_received, |
- least_unacked, !kIncludeCongestionFeedback); |
- } |
- |
- BoundNetLog net_log_; |
- bool use_closing_stream_; |
- MockSendAlgorithm* send_algorithm_; |
- scoped_refptr<TestTaskRunner> runner_; |
- scoped_ptr<MockWrite[]> mock_writes_; |
- MockClock clock_; |
- TestQuicConnection* connection_; |
- scoped_ptr<QuicConnectionHelper> helper_; |
- testing::StrictMock<MockConnectionVisitor> visitor_; |
- scoped_ptr<QuicHttpStream> stream_; |
- TransportSecurityState transport_security_state_; |
- scoped_ptr<QuicClientSession> session_; |
- QuicCryptoClientConfig crypto_config_; |
- TestCompletionCallback callback_; |
- HttpRequestInfo request_; |
- HttpRequestHeaders headers_; |
- HttpResponseInfo response_; |
- scoped_refptr<IOBufferWithSize> read_buffer_; |
- SpdyHeaderBlock request_headers_; |
- SpdyHeaderBlock response_headers_; |
- std::string request_data_; |
- std::string response_data_; |
- |
- private: |
- const QuicConnectionId connection_id_; |
- const QuicStreamId stream_id_; |
- QuicTestPacketMaker maker_; |
- IPEndPoint self_addr_; |
- IPEndPoint peer_addr_; |
- MockRandom random_generator_; |
- MockCryptoClientStreamFactory crypto_client_stream_factory_; |
- scoped_ptr<StaticSocketDataProvider> socket_data_; |
- std::vector<PacketToWrite> writes_; |
-}; |
- |
-INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest, |
- ::testing::ValuesIn(QuicSupportedVersions())); |
- |
-TEST_P(QuicHttpStreamTest, RenewStreamForAuth) { |
- Initialize(); |
- EXPECT_EQ(nullptr, stream_->RenewStreamForAuth()); |
-} |
- |
-TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) { |
- Initialize(); |
- EXPECT_TRUE(stream_->CanFindEndOfResponse()); |
-} |
- |
-TEST_P(QuicHttpStreamTest, IsConnectionReusable) { |
- Initialize(); |
- EXPECT_FALSE(stream_->IsConnectionReusable()); |
-} |
- |
-TEST_P(QuicHttpStreamTest, GetRequest) { |
- SetRequest("GET", "/", DEFAULT_PRIORITY); |
- AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY)); |
- Initialize(); |
- |
- request_.method = "GET"; |
- request_.url = GURL("http://www.google.com/"); |
- |
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
- net_log_, callback_.callback())); |
- EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
- callback_.callback())); |
- |
- // Ack the request. |
- ProcessPacket(ConstructAckPacket(1, 0, 0)); |
- |
- EXPECT_EQ(ERR_IO_PENDING, |
- stream_->ReadResponseHeaders(callback_.callback())); |
- |
- SetResponse("404 Not Found", std::string()); |
- ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); |
- |
- // Now that the headers have been processed, the callback will return. |
- EXPECT_EQ(OK, callback_.WaitForResult()); |
- ASSERT_TRUE(response_.headers.get()); |
- EXPECT_EQ(404, response_.headers->response_code()); |
- EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
- EXPECT_FALSE(response_.response_time.is_null()); |
- EXPECT_FALSE(response_.request_time.is_null()); |
- |
- // There is no body, so this should return immediately. |
- EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), |
- read_buffer_->size(), |
- callback_.callback())); |
- EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
- EXPECT_TRUE(AtEof()); |
-} |
- |
-// Regression test for http://crbug.com/288128 |
-TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) { |
- SetRequest("GET", "/", DEFAULT_PRIORITY); |
- AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY)); |
- Initialize(); |
- |
- request_.method = "GET"; |
- request_.url = GURL("http://www.google.com/"); |
- |
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
- net_log_, callback_.callback())); |
- EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
- callback_.callback())); |
- |
- // Ack the request. |
- ProcessPacket(ConstructAckPacket(1, 0, 0)); |
- |
- EXPECT_EQ(ERR_IO_PENDING, |
- stream_->ReadResponseHeaders(callback_.callback())); |
- |
- SpdyHeaderBlock headers; |
- headers[":status"] = "200 OK"; |
- headers[":version"] = "HTTP/1.1"; |
- headers["content-type"] = "text/plain"; |
- headers["big6"] = std::string(10000, 'x'); // Lots of x's. |
- |
- std::string response = SpdyUtils::SerializeUncompressedHeaders(headers); |
- EXPECT_LT(4096u, response.length()); |
- stream_->OnDataReceived(response.data(), response.length()); |
- stream_->OnClose(QUIC_NO_ERROR); |
- |
- // Now that the headers have been processed, the callback will return. |
- EXPECT_EQ(OK, callback_.WaitForResult()); |
- ASSERT_TRUE(response_.headers.get()); |
- EXPECT_EQ(200, response_.headers->response_code()); |
- EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
- |
- // There is no body, so this should return immediately. |
- EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), |
- read_buffer_->size(), |
- callback_.callback())); |
- EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
- EXPECT_TRUE(AtEof()); |
-} |
- |
-// Regression test for http://crbug.com/409101 |
-TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) { |
- SetRequest("GET", "/", DEFAULT_PRIORITY); |
- Initialize(); |
- |
- request_.method = "GET"; |
- request_.url = GURL("http://www.google.com/"); |
- |
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
- net_log_, callback_.callback())); |
- |
- session_->connection()->CloseConnection(QUIC_NO_ERROR, true); |
- |
- EXPECT_EQ(ERR_CONNECTION_CLOSED, |
- stream_->SendRequest(headers_, &response_, |
- callback_.callback())); |
-} |
- |
-// Regression test for http://crbug.com/409871 |
-TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) { |
- SetRequest("GET", "/", DEFAULT_PRIORITY); |
- AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY)); |
- Initialize(); |
- |
- request_.method = "GET"; |
- request_.url = GURL("http://www.google.com/"); |
- |
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
- net_log_, callback_.callback())); |
- |
- EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
- callback_.callback())); |
- |
- session_->connection()->CloseConnection(QUIC_NO_ERROR, true); |
- |
- EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback())); |
-} |
- |
-TEST_P(QuicHttpStreamTest, SendPostRequest) { |
- SetRequest("POST", "/", DEFAULT_PRIORITY); |
- AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY)); |
- AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData)); |
- AddWrite(ConstructAckPacket(3, 3, 1)); |
- |
- Initialize(); |
- |
- ScopedVector<UploadElementReader> element_readers; |
- element_readers.push_back( |
- new UploadBytesElementReader(kUploadData, strlen(kUploadData))); |
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0); |
- request_.method = "POST"; |
- request_.url = GURL("http://www.google.com/"); |
- request_.upload_data_stream = &upload_data_stream; |
- ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); |
- |
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
- net_log_, callback_.callback())); |
- EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
- callback_.callback())); |
- |
- // Ack both packets in the request. |
- ProcessPacket(ConstructAckPacket(1, 0, 0)); |
- |
- // Send the response headers (but not the body). |
- SetResponse("200 OK", std::string()); |
- ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); |
- |
- // Since the headers have already arrived, this should return immediately. |
- EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); |
- ASSERT_TRUE(response_.headers.get()); |
- EXPECT_EQ(200, response_.headers->response_code()); |
- EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
- |
- // Send the response body. |
- const char kResponseBody[] = "Hello world!"; |
- ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody)); |
- // Since the body has already arrived, this should return immediately. |
- EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), |
- stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), |
- callback_.callback())); |
- |
- EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
- EXPECT_TRUE(AtEof()); |
-} |
- |
-TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) { |
- SetRequest("POST", "/", DEFAULT_PRIORITY); |
- size_t chunk_size = strlen(kUploadData); |
- AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY)); |
- AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData)); |
- AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, |
- kUploadData)); |
- AddWrite(ConstructAckPacket(4, 3, 1)); |
- Initialize(); |
- |
- ChunkedUploadDataStream upload_data_stream(0); |
- upload_data_stream.AppendData(kUploadData, chunk_size, false); |
- |
- request_.method = "POST"; |
- request_.url = GURL("http://www.google.com/"); |
- request_.upload_data_stream = &upload_data_stream; |
- ASSERT_EQ(OK, request_.upload_data_stream->Init( |
- TestCompletionCallback().callback())); |
- |
- ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
- net_log_, callback_.callback())); |
- ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, |
- callback_.callback())); |
- |
- upload_data_stream.AppendData(kUploadData, chunk_size, true); |
- |
- // Ack both packets in the request. |
- ProcessPacket(ConstructAckPacket(1, 0, 0)); |
- |
- // Send the response headers (but not the body). |
- SetResponse("200 OK", std::string()); |
- ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); |
- |
- // Since the headers have already arrived, this should return immediately. |
- ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); |
- ASSERT_TRUE(response_.headers.get()); |
- EXPECT_EQ(200, response_.headers->response_code()); |
- EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
- |
- // Send the response body. |
- const char kResponseBody[] = "Hello world!"; |
- ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(), |
- kResponseBody)); |
- |
- // Since the body has already arrived, this should return immediately. |
- ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), |
- stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), |
- callback_.callback())); |
- |
- EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
- EXPECT_TRUE(AtEof()); |
-} |
- |
-TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) { |
- SetRequest("POST", "/", DEFAULT_PRIORITY); |
- size_t chunk_size = strlen(kUploadData); |
- AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY)); |
- AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData)); |
- AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, "")); |
- AddWrite(ConstructAckPacket(4, 3, 1)); |
- Initialize(); |
- |
- ChunkedUploadDataStream upload_data_stream(0); |
- upload_data_stream.AppendData(kUploadData, chunk_size, false); |
- |
- request_.method = "POST"; |
- request_.url = GURL("http://www.google.com/"); |
- request_.upload_data_stream = &upload_data_stream; |
- ASSERT_EQ(OK, request_.upload_data_stream->Init( |
- TestCompletionCallback().callback())); |
- |
- ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
- net_log_, callback_.callback())); |
- ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, |
- callback_.callback())); |
- |
- upload_data_stream.AppendData(nullptr, 0, true); |
- |
- ProcessPacket(ConstructAckPacket(1, 0, 0)); |
- |
- // Send the response headers (but not the body). |
- SetResponse("200 OK", std::string()); |
- ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); |
- |
- // Since the headers have already arrived, this should return immediately. |
- ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); |
- ASSERT_TRUE(response_.headers.get()); |
- EXPECT_EQ(200, response_.headers->response_code()); |
- EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
- |
- // Send the response body. |
- const char kResponseBody[] = "Hello world!"; |
- ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(), |
- kResponseBody)); |
- |
- // Since the body has already arrived, this should return immediately. |
- ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), |
- stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), |
- callback_.callback())); |
- |
- EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
- EXPECT_TRUE(AtEof()); |
-} |
- |
-TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) { |
- SetRequest("POST", "/", DEFAULT_PRIORITY); |
- AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY)); |
- AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, "")); |
- AddWrite(ConstructAckPacket(3, 3, 1)); |
- Initialize(); |
- |
- ChunkedUploadDataStream upload_data_stream(0); |
- |
- request_.method = "POST"; |
- request_.url = GURL("http://www.google.com/"); |
- request_.upload_data_stream = &upload_data_stream; |
- ASSERT_EQ(OK, request_.upload_data_stream->Init( |
- TestCompletionCallback().callback())); |
- |
- ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
- net_log_, callback_.callback())); |
- ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, |
- callback_.callback())); |
- |
- upload_data_stream.AppendData(nullptr, 0, true); |
- |
- ProcessPacket(ConstructAckPacket(1, 0, 0)); |
- |
- // Send the response headers (but not the body). |
- SetResponse("200 OK", std::string()); |
- ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); |
- |
- // Since the headers have already arrived, this should return immediately. |
- ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); |
- ASSERT_TRUE(response_.headers.get()); |
- EXPECT_EQ(200, response_.headers->response_code()); |
- EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
- |
- // Send the response body. |
- const char kResponseBody[] = "Hello world!"; |
- ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(), |
- kResponseBody)); |
- |
- // Since the body has already arrived, this should return immediately. |
- ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), |
- stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), |
- callback_.callback())); |
- |
- EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
- EXPECT_TRUE(AtEof()); |
-} |
- |
-TEST_P(QuicHttpStreamTest, DestroyedEarly) { |
- SetRequest("GET", "/", DEFAULT_PRIORITY); |
- AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY)); |
- AddWrite(ConstructAckAndRstStreamPacket(2)); |
- use_closing_stream_ = true; |
- Initialize(); |
- |
- request_.method = "GET"; |
- request_.url = GURL("http://www.google.com/"); |
- |
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
- net_log_, callback_.callback())); |
- EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
- callback_.callback())); |
- |
- // Ack the request. |
- ProcessPacket(ConstructAckPacket(1, 0, 0)); |
- EXPECT_EQ(ERR_IO_PENDING, |
- stream_->ReadResponseHeaders(callback_.callback())); |
- |
- // Send the response with a body. |
- SetResponse("404 OK", "hello world!"); |
- // In the course of processing this packet, the QuicHttpStream close itself. |
- ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); |
- |
- EXPECT_TRUE(AtEof()); |
-} |
- |
-TEST_P(QuicHttpStreamTest, Priority) { |
- SetRequest("GET", "/", MEDIUM); |
- AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM)); |
- AddWrite(ConstructAckAndRstStreamPacket(2)); |
- use_closing_stream_ = true; |
- Initialize(); |
- |
- request_.method = "GET"; |
- request_.url = GURL("http://www.google.com/"); |
- |
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, |
- net_log_, callback_.callback())); |
- |
- // Check that priority is highest. |
- QuicReliableClientStream* reliable_stream = |
- QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); |
- DCHECK(reliable_stream); |
- DCHECK_EQ(QuicWriteBlockedList::kHighestPriority, |
- reliable_stream->EffectivePriority()); |
- |
- EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
- callback_.callback())); |
- |
- // Check that priority has now dropped back to MEDIUM. |
- DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority( |
- reliable_stream->EffectivePriority())); |
- |
- // Ack the request. |
- ProcessPacket(ConstructAckPacket(1, 0, 0)); |
- EXPECT_EQ(ERR_IO_PENDING, |
- stream_->ReadResponseHeaders(callback_.callback())); |
- |
- // Send the response with a body. |
- SetResponse("404 OK", "hello world!"); |
- // In the course of processing this packet, the QuicHttpStream close itself. |
- ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); |
- |
- EXPECT_TRUE(AtEof()); |
-} |
- |
-// Regression test for http://crbug.com/294870 |
-TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) { |
- SetRequest("GET", "/", MEDIUM); |
- use_closing_stream_ = true; |
- |
- AddWrite(ConstructRstStreamPacket(1)); |
- |
- Initialize(); |
- |
- request_.method = "GET"; |
- request_.url = GURL("http://www.google.com/"); |
- |
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, |
- net_log_, callback_.callback())); |
- |
- // Check that priority is highest. |
- QuicReliableClientStream* reliable_stream = |
- QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); |
- DCHECK(reliable_stream); |
- QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate(); |
- DCHECK(delegate); |
- DCHECK_EQ(QuicWriteBlockedList::kHighestPriority, |
- reliable_stream->EffectivePriority()); |
- |
- // Set Delegate to nullptr and make sure EffectivePriority returns highest |
- // priority. |
- reliable_stream->SetDelegate(nullptr); |
- DCHECK_EQ(QuicWriteBlockedList::kHighestPriority, |
- reliable_stream->EffectivePriority()); |
- reliable_stream->SetDelegate(delegate); |
-} |
- |
-} // namespace test |
-} // namespace net |