12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_http_stream.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/test_completion_callback.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_bytes_element_reader.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_data_stream.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_response_headers.h" 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/http/transport_security_state.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/congestion_control/receive_algorithm_interface.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/congestion_control/send_algorithm_interface.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/crypto_protocol.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/quic_decrypter.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/quic_encrypter.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/quic/crypto/quic_server_info.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_client_session.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_connection.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_connection_helper.h" 241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/quic/quic_default_packet_writer.h" 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/quic/quic_http_utils.h" 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/quic/quic_reliable_client_stream.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_write_blocked_list.h" 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/quic/spdy_utils.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/mock_clock.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/mock_crypto_client_stream_factory.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/mock_random.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/quic_connection_peer.h" 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/test_tools/quic_test_packet_maker.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h" 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/test_task_runner.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/socket/socket_test_util.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_frame_builder.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_framer.h" 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_http_utils.h" 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_protocol.h" 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::_; 45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using testing::AnyNumber; 46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using testing::Return; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const char kUploadData[] = "Really nifty data!"; 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char kServerHostname[] = "www.google.com"; 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const uint16 kServerPort = 80; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestQuicConnection : public QuicConnection { 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TestQuicConnection(const QuicVersionVector& versions, 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicConnectionId connection_id, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPEndPoint address, 611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) QuicConnectionHelper* helper, 6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const QuicConnection::PacketWriterFactory& writer_factory) 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : QuicConnection(connection_id, 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) address, 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) helper, 6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) writer_factory, 6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) true /* owns_writer */, 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) false /* is_server */, 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) versions) { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) { 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestReceiveAlgorithm : public ReceiveAlgorithmInterface { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool GenerateCongestionFeedback( 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicCongestionFeedbackFrame* /*congestion_feedback*/) { 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD3(RecordIncomingPacket, 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void(QuicByteCount, QuicPacketSequenceNumber, QuicTime)); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Subclass of QuicHttpStream that closes itself when the first piece of data 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is received. 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AutoClosingStream : public QuicHttpStream { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session) 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) : QuicHttpStream(session) { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual int OnDataReceived(const char* data, int length) OVERRIDE { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Close(false); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return OK; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory { 10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public: 10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) explicit TestPacketWriterFactory(DatagramClientSocket* socket) 10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : socket_(socket) {} 11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) virtual ~TestPacketWriterFactory() {} 11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) virtual QuicPacketWriter* Create(QuicConnection* connection) const OVERRIDE { 11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return new QuicDefaultPacketWriter(socket_); 11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private: 11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DatagramClientSocket* socket_; 11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}; 11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class QuicHttpStreamPeer { 123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) static QuicReliableClientStream* GetQuicReliableClientStream( 125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) QuicHttpStream* stream) { 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return stream->stream_; 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> { 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static const bool kFin = true; 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static const bool kIncludeVersion = true; 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static const bool kIncludeCongestionFeedback = true; 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Holds a packet to be written to the wire, and the IO mode that should 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // be used by the mock socket when performing the write. 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct PacketToWrite { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PacketToWrite(IoMode mode, QuicEncryptedPacket* packet) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : mode(mode), 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) packet(packet) { 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IoMode mode; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicEncryptedPacket* packet; 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicHttpStreamTest() 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : net_log_(BoundNetLog()), 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) use_closing_stream_(false), 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_buffer_(new IOBufferWithSize(4096)), 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection_id_(2), 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream_id_(kClientDataStreamId1), 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci maker_(GetParam(), connection_id_, &clock_), 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) random_generator_(0) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPAddressNumber ip; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) peer_addr_ = IPEndPoint(ip, 443); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self_addr_ = IPEndPoint(ip, 8435); 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20)); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~QuicHttpStreamTest() { 1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) session_->CloseSessionOnError(ERR_ABORTED); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < writes_.size(); i++) { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete writes_[i].packet; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Adds a packet to the list of expected writes. 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) { 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release())); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns the packet to be written at position |pos|. 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicEncryptedPacket* GetWrite(size_t pos) { 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return writes_[pos].packet; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool AtEof() { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return socket_data_->at_read_eof() && socket_data_->at_write_eof(); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) { 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Configures the test fixture to use the list of expected writes. 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Initialize() { 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mock_writes_.reset(new MockWrite[writes_.size()]); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < writes_.size(); i++) { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mock_writes_[i] = MockWrite(writes_[i].mode, 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes_[i].packet->data(), 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes_[i].packet->length()); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(), 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) writes_.size())); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(), 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log_.net_log()); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) socket->Connect(peer_addr_); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) runner_ = new TestTaskRunner(&clock_); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) send_algorithm_ = new MockSendAlgorithm(); 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) receive_algorithm_ = new TestReceiveAlgorithm(); 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _)). 206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Times(AnyNumber()); 20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_CALL(*send_algorithm_, 208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true)); 209558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( 210424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Return(QuicTime::Delta::Zero())); 2115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly( 2125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Return(kMaxPacketSize)); 213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)). 214424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) WillRepeatedly(Return(QuicTime::Delta::Zero())); 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly( 216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Return(QuicBandwidth::Zero())); 2170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber()); 2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_, 2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) &random_generator_)); 22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TestPacketWriterFactory writer_factory(socket); 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection_ = new TestQuicConnection(SupportedVersions(GetParam()), 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection_id_, peer_addr_, 22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) helper_.get(), writer_factory); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_->set_visitor(&visitor_); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_->SetSendAlgorithm(send_algorithm_); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_->SetReceiveAlgorithm(receive_algorithm_); 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) crypto_config_.SetDefaults(); 2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) session_.reset( 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new QuicClientSession(connection_, 2301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<DatagramClientSocket>(socket), 23103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NULL, 23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &transport_security_state_, 23323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) make_scoped_ptr((QuicServerInfo*)NULL), 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DefaultQuicConfig(), 23546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()-> 23646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) message_loop_proxy().get(), 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NULL)); 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci session_->InitializeSession(QuicServerId(kServerHostname, kServerPort, 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci false, PRIVACY_MODE_DISABLED), 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &crypto_config_, 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &crypto_client_stream_factory_); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_->GetCryptoStream()->CryptoConnect(); 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed()); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_.reset(use_closing_stream_ ? 245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) new AutoClosingStream(session_->GetWeakPtr()) : 246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) new QuicHttpStream(session_->GetWeakPtr())); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SetRequest(const std::string& method, 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& path, 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RequestPriority priority) { 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_headers_ = maker_.GetRequestHeaders(method, "http", path); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SetResponse(const std::string& status, const std::string& body) { 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) response_headers_ = maker_.GetResponseHeaders(status); 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_data_ = body; 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<QuicEncryptedPacket> ConstructDataPacket( 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicPacketSequenceNumber sequence_number, 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool should_include_version, 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fin, 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicStreamOffset offset, 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringPiece data) { 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return maker_.MakeDataPacket( 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sequence_number, stream_id_, should_include_version, fin, offset, data); 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket( 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicPacketSequenceNumber sequence_number, 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin) { 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return maker_.MakeRequestHeadersPacket( 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sequence_number, stream_id_, kIncludeVersion, fin, request_headers_); 275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket( 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicPacketSequenceNumber sequence_number, 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin) { 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return maker_.MakeResponseHeadersPacket( 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_); 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket( 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicPacketSequenceNumber sequence_number) { 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return maker_.MakeRstPacket( 2870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch sequence_number, true, stream_id_, 2880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch AdjustErrorForVersion(QUIC_RST_FLOW_CONTROL_ACCOUNTING, GetParam())); 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket( 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicPacketSequenceNumber sequence_number) { 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return maker_.MakeAckAndRstPacket( 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED, 2955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2, 1, !kIncludeCongestionFeedback); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<QuicEncryptedPacket> ConstructAckPacket( 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicPacketSequenceNumber sequence_number, 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicPacketSequenceNumber largest_received, 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicPacketSequenceNumber least_unacked) { 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return maker_.MakeAckPacket(sequence_number, largest_received, 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) least_unacked, !kIncludeCongestionFeedback); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BoundNetLog net_log_; 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool use_closing_stream_; 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockSendAlgorithm* send_algorithm_; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestReceiveAlgorithm* receive_algorithm_; 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TestTaskRunner> runner_; 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<MockWrite[]> mock_writes_; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockClock clock_; 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestQuicConnection* connection_; 3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<QuicConnectionHelper> helper_; 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) testing::StrictMock<MockConnectionVisitor> visitor_; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<QuicHttpStream> stream_; 31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TransportSecurityState transport_security_state_; 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<QuicClientSession> session_; 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicCryptoClientConfig crypto_config_; 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestCompletionCallback callback_; 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HttpRequestInfo request_; 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HttpRequestHeaders headers_; 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HttpResponseInfo response_; 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<IOBufferWithSize> read_buffer_; 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyHeaderBlock request_headers_; 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyHeaderBlock response_headers_; 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string request_data_; 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string response_data_; 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const QuicConnectionId connection_id_; 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const QuicStreamId stream_id_; 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicTestPacketMaker maker_; 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPEndPoint self_addr_; 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPEndPoint peer_addr_; 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MockRandom random_generator_; 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockCryptoClientStreamFactory crypto_client_stream_factory_; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<StaticSocketDataProvider> socket_data_; 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<PacketToWrite> writes_; 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest, 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ::testing::ValuesIn(QuicSupportedVersions())); 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHttpStreamTest, RenewStreamForAuth) { 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Initialize(); 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NULL, stream_->RenewStreamForAuth()); 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) { 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Initialize(); 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream_->CanFindEndOfResponse()); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHttpStreamTest, IsConnectionReusable) { 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Initialize(); 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream_->IsConnectionReusable()); 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHttpStreamTest, GetRequest) { 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetRequest("GET", "/", DEFAULT_PRIORITY); 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddWrite(ConstructRequestHeadersPacket(1, kFin)); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Initialize(); 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_.method = "GET"; 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_.url = GURL("http://www.google.com/"); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log_, callback_.callback())); 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.callback())); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ack the request. 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessPacket(ConstructAckPacket(1, 0, 0)); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_->ReadResponseHeaders(callback_.callback())); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetResponse("404 Not Found", std::string()); 380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Now that the headers have been processed, the callback will return. 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(OK, callback_.WaitForResult()); 3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(response_.headers.get()); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(404, response_.headers->response_code()); 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); 387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_FALSE(response_.response_time.is_null()); 388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_FALSE(response_.request_time.is_null()); 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // There is no body, so this should return immediately. 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_buffer_->size(), 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.callback())); 39458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_TRUE(stream_->IsResponseBodyComplete()); 39558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_TRUE(AtEof()); 39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 39758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 39858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Regression test for http://crbug.com/288128 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) { 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetRequest("GET", "/", DEFAULT_PRIORITY); 401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddWrite(ConstructRequestHeadersPacket(1, kFin)); 40258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Initialize(); 40358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 40458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_.method = "GET"; 40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_.url = GURL("http://www.google.com/"); 40658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 40758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) net_log_, callback_.callback())); 40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, 41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback_.callback())); 41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Ack the request. 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessPacket(ConstructAckPacket(1, 0, 0)); 41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 41558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 41658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) stream_->ReadResponseHeaders(callback_.callback())); 41758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SpdyHeaderBlock headers; 41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) headers[":status"] = "200 OK"; 42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) headers[":version"] = "HTTP/1.1"; 42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) headers["content-type"] = "text/plain"; 42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) headers["big6"] = std::string(10000, 'x'); // Lots of x's. 42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 42458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string response = SpdyUtils::SerializeUncompressedHeaders(headers); 42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_LT(4096u, response.length()); 42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) stream_->OnDataReceived(response.data(), response.length()); 42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) stream_->OnClose(QUIC_NO_ERROR); 42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Now that the headers have been processed, the callback will return. 43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(OK, callback_.WaitForResult()); 43158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(response_.headers.get()); 43258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(200, response_.headers->response_code()); 43358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); 43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // There is no body, so this should return immediately. 43658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), 43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) read_buffer_->size(), 43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback_.callback())); 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream_->IsResponseBodyComplete()); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(AtEof()); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Regression test for http://crbug.com/409101 4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) { 4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetRequest("GET", "/", DEFAULT_PRIORITY); 4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Initialize(); 4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_.method = "GET"; 4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_.url = GURL("http://www.google.com/"); 4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net_log_, callback_.callback())); 4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci session_->connection()->CloseConnection(QUIC_NO_ERROR, true); 4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(ERR_CONNECTION_CLOSED, 4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stream_->SendRequest(headers_, &response_, 4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_.callback())); 4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Regression test for http://crbug.com/409871 4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) { 4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetRequest("GET", "/", DEFAULT_PRIORITY); 4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AddWrite(ConstructRequestHeadersPacket(1, kFin)); 4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Initialize(); 4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_.method = "GET"; 4681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_.url = GURL("http://www.google.com/"); 4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net_log_, callback_.callback())); 4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, 4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_.callback())); 4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci session_->connection()->CloseConnection(QUIC_NO_ERROR, true); 4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback())); 4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHttpStreamTest, SendPostRequest) { 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetRequest("POST", "/", DEFAULT_PRIORITY); 483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddWrite(ConstructRequestHeadersPacket(1, !kFin)); 484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData)); 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddWrite(ConstructAckPacket(3, 3, 1)); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Initialize(); 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedVector<UploadElementReader> element_readers; 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) element_readers.push_back( 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new UploadBytesElementReader(kUploadData, strlen(kUploadData))); 49268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UploadDataStream upload_data_stream(element_readers.Pass(), 0); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_.method = "POST"; 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_.url = GURL("http://www.google.com/"); 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_.upload_data_stream = &upload_data_stream; 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log_, callback_.callback())); 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.callback())); 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ack both packets in the request. 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessPacket(ConstructAckPacket(1, 0, 0)); 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send the response headers (but not the body). 5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetResponse("200 OK", std::string()); 508a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since the headers have already arrived, this should return immediately. 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); 5127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(response_.headers.get()); 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(200, response_.headers->response_code()); 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send the response body. 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kResponseBody[] = "Hello world!"; 518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody)); 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since the body has already arrived, this should return immediately. 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.callback())); 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream_->IsResponseBodyComplete()); 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(AtEof()); 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) { 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetRequest("POST", "/", DEFAULT_PRIORITY); 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t chunk_size = strlen(kUploadData); 531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddWrite(ConstructRequestHeadersPacket(1, !kFin)); 532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData)); 533a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, 534a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kUploadData)); 5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddWrite(ConstructAckPacket(4, 3, 1)); 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Initialize(); 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0); 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_data_stream.AppendChunk(kUploadData, chunk_size, false); 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_.method = "POST"; 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_.url = GURL("http://www.google.com/"); 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_.upload_data_stream = &upload_data_stream; 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log_, callback_.callback())); 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.callback())); 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_data_stream.AppendChunk(kUploadData, chunk_size, true); 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ack both packets in the request. 5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessPacket(ConstructAckPacket(1, 0, 0)); 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send the response headers (but not the body). 5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetResponse("200 OK", std::string()); 558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since the headers have already arrived, this should return immediately. 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); 5627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(response_.headers.get()); 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(200, response_.headers->response_code()); 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); 56503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 56603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Send the response body. 56703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const char kResponseBody[] = "Hello world!"; 56803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(), 56903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) kResponseBody)); 57003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 57103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Since the body has already arrived, this should return immediately. 57203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), 57303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), 57403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) callback_.callback())); 57503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 57603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(stream_->IsResponseBodyComplete()); 57703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(AtEof()); 57803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 57903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 58003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) { 58103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SetRequest("POST", "/", DEFAULT_PRIORITY); 58203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) size_t chunk_size = strlen(kUploadData); 58303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) AddWrite(ConstructRequestHeadersPacket(1, !kFin)); 58403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData)); 58503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, "")); 58603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) AddWrite(ConstructAckPacket(4, 3, 1)); 58703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) Initialize(); 58803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 58903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0); 59003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) upload_data_stream.AppendChunk(kUploadData, chunk_size, false); 59103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 59203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request_.method = "POST"; 59303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request_.url = GURL("http://www.google.com/"); 59403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request_.upload_data_stream = &upload_data_stream; 59503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); 59603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 59703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 59803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) net_log_, callback_.callback())); 59903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, 60003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) callback_.callback())); 60103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 60203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) upload_data_stream.AppendChunk(NULL, 0, true); 60303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 60403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ProcessPacket(ConstructAckPacket(1, 0, 0)); 60503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 60603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Send the response headers (but not the body). 60703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SetResponse("200 OK", std::string()); 60803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); 60903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 61003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Since the headers have already arrived, this should return immediately. 61103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); 61203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_TRUE(response_.headers.get()); 61303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(200, response_.headers->response_code()); 61403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); 61503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 61603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Send the response body. 61703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const char kResponseBody[] = "Hello world!"; 61803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(), 61903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) kResponseBody)); 62003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 62103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Since the body has already arrived, this should return immediately. 62203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), 62303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), 62403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) callback_.callback())); 62503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 62603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(stream_->IsResponseBodyComplete()); 62703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(AtEof()); 62803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 62903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 63003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) { 63103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SetRequest("POST", "/", DEFAULT_PRIORITY); 63203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) AddWrite(ConstructRequestHeadersPacket(1, !kFin)); 63303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, "")); 63403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) AddWrite(ConstructAckPacket(3, 3, 1)); 63503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) Initialize(); 63603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 63703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0); 63803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 63903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request_.method = "POST"; 64003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request_.url = GURL("http://www.google.com/"); 64103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request_.upload_data_stream = &upload_data_stream; 64203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); 64303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 64403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 64503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) net_log_, callback_.callback())); 64603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, 64703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) callback_.callback())); 64803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 64903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) upload_data_stream.AppendChunk(NULL, 0, true); 65003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 65103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ProcessPacket(ConstructAckPacket(1, 0, 0)); 65203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 65303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Send the response headers (but not the body). 65403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SetResponse("200 OK", std::string()); 65503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); 65603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 65703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Since the headers have already arrived, this should return immediately. 65803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); 65903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_TRUE(response_.headers.get()); 66003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(200, response_.headers->response_code()); 66103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send the response body. 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kResponseBody[] = "Hello world!"; 6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(), 6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kResponseBody)); 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since the body has already arrived, this should return immediately. 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.callback())); 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream_->IsResponseBodyComplete()); 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(AtEof()); 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHttpStreamTest, DestroyedEarly) { 6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetRequest("GET", "/", DEFAULT_PRIORITY); 679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddWrite(ConstructRequestHeadersPacket(1, kFin)); 6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddWrite(ConstructAckAndRstStreamPacket(2)); 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) use_closing_stream_ = true; 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Initialize(); 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_.method = "GET"; 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_.url = GURL("http://www.google.com/"); 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log_, callback_.callback())); 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, 690d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback_.callback())); 691d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 692d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Ack the request. 6935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessPacket(ConstructAckPacket(1, 0, 0)); 694d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 695d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) stream_->ReadResponseHeaders(callback_.callback())); 696d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 697d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Send the response with a body. 6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetResponse("404 OK", "hello world!"); 699d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // In the course of processing this packet, the QuicHttpStream close itself. 700a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); 701d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 702d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE(AtEof()); 703d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 704d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHttpStreamTest, Priority) { 7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetRequest("GET", "/", MEDIUM); 707a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddWrite(ConstructRequestHeadersPacket(1, kFin)); 7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddWrite(ConstructAckAndRstStreamPacket(2)); 709d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) use_closing_stream_ = true; 710d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Initialize(); 711d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 712d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) request_.method = "GET"; 713d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) request_.url = GURL("http://www.google.com/"); 714d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 715d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, 716d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) net_log_, callback_.callback())); 717d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 718d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Check that priority is highest. 719d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) QuicReliableClientStream* reliable_stream = 720d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); 721d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(reliable_stream); 7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(QuicWriteBlockedList::kHighestPriority, 723d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) reliable_stream->EffectivePriority()); 724d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 725d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, 726d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback_.callback())); 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 728d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Check that priority has now dropped back to MEDIUM. 729d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority( 730d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) reliable_stream->EffectivePriority())); 731d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ack the request. 7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessPacket(ConstructAckPacket(1, 0, 0)); 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_->ReadResponseHeaders(callback_.callback())); 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send the response with a body. 7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetResponse("404 OK", "hello world!"); 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In the course of processing this packet, the QuicHttpStream close itself. 740a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(AtEof()); 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 74568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Regression test for http://crbug.com/294870 7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) { 7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetRequest("GET", "/", MEDIUM); 74868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) use_closing_stream_ = true; 7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu AddWrite(ConstructRstStreamPacket(1)); 7515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Initialize(); 75368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 75468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_.method = "GET"; 75568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_.url = GURL("http://www.google.com/"); 75668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 75768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, 75868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net_log_, callback_.callback())); 75968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 76068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Check that priority is highest. 76168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) QuicReliableClientStream* reliable_stream = 76268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); 76368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(reliable_stream); 76468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate(); 76568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(delegate); 7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(QuicWriteBlockedList::kHighestPriority, 76768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) reliable_stream->EffectivePriority()); 76868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 76968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Set Delegate to NULL and make sure EffectivePriority returns highest 77068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // priority. 77168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) reliable_stream->SetDelegate(NULL); 7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(QuicWriteBlockedList::kHighestPriority, 77368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) reliable_stream->EffectivePriority()); 77468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) reliable_stream->SetDelegate(delegate); 77568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 77668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace test 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace net 779