Home | History | Annotate | Download | only in quic
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/quic/quic_http_stream.h"
      6 
      7 #include <vector>
      8 
      9 #include "net/base/net_errors.h"
     10 #include "net/base/test_completion_callback.h"
     11 #include "net/base/upload_bytes_element_reader.h"
     12 #include "net/base/upload_data_stream.h"
     13 #include "net/http/http_response_headers.h"
     14 #include "net/quic/congestion_control/receive_algorithm_interface.h"
     15 #include "net/quic/congestion_control/send_algorithm_interface.h"
     16 #include "net/quic/crypto/crypto_protocol.h"
     17 #include "net/quic/crypto/quic_decrypter.h"
     18 #include "net/quic/crypto/quic_encrypter.h"
     19 #include "net/quic/quic_client_session.h"
     20 #include "net/quic/quic_connection.h"
     21 #include "net/quic/quic_connection_helper.h"
     22 #include "net/quic/test_tools/mock_clock.h"
     23 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
     24 #include "net/quic/test_tools/mock_random.h"
     25 #include "net/quic/test_tools/quic_connection_peer.h"
     26 #include "net/quic/test_tools/quic_test_utils.h"
     27 #include "net/quic/test_tools/test_task_runner.h"
     28 #include "net/socket/socket_test_util.h"
     29 #include "net/spdy/spdy_frame_builder.h"
     30 #include "net/spdy/spdy_framer.h"
     31 #include "net/spdy/spdy_http_utils.h"
     32 #include "net/spdy/spdy_protocol.h"
     33 #include "testing/gmock/include/gmock/gmock.h"
     34 #include "testing/gtest/include/gtest/gtest.h"
     35 
     36 using testing::_;
     37 
     38 namespace net {
     39 namespace test {
     40 namespace {
     41 
     42 const char kUploadData[] = "hello world!";
     43 
     44 class TestQuicConnection : public QuicConnection {
     45  public:
     46   TestQuicConnection(QuicGuid guid,
     47                      IPEndPoint address,
     48                      QuicConnectionHelper* helper)
     49       : QuicConnection(guid, address, helper, false, QuicVersionMax()) {
     50   }
     51 
     52   void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
     53     QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
     54   }
     55 
     56   void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) {
     57     QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm);
     58   }
     59 };
     60 
     61 class TestReceiveAlgorithm : public ReceiveAlgorithmInterface {
     62  public:
     63   explicit TestReceiveAlgorithm(QuicCongestionFeedbackFrame* feedback)
     64       : feedback_(feedback) {
     65   }
     66 
     67   bool GenerateCongestionFeedback(
     68       QuicCongestionFeedbackFrame* congestion_feedback) {
     69     if (feedback_ == NULL) {
     70       return false;
     71     }
     72     *congestion_feedback = *feedback_;
     73     return true;
     74   }
     75 
     76   MOCK_METHOD4(RecordIncomingPacket,
     77                void(QuicByteCount, QuicPacketSequenceNumber, QuicTime, bool));
     78 
     79  private:
     80   MockClock clock_;
     81   QuicCongestionFeedbackFrame* feedback_;
     82 
     83   DISALLOW_COPY_AND_ASSIGN(TestReceiveAlgorithm);
     84 };
     85 
     86 // Subclass of QuicHttpStream that closes itself when the first piece of data
     87 // is received.
     88 class AutoClosingStream : public QuicHttpStream {
     89  public:
     90   explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session)
     91       : QuicHttpStream(session) {
     92   }
     93 
     94   virtual int OnDataReceived(const char* data, int length) OVERRIDE {
     95     Close(false);
     96     return OK;
     97   }
     98 };
     99 
    100 }  // namespace
    101 
    102 class QuicHttpStreamTest : public ::testing::TestWithParam<bool> {
    103  protected:
    104   const static bool kFin = true;
    105   // Holds a packet to be written to the wire, and the IO mode that should
    106   // be used by the mock socket when performing the write.
    107   struct PacketToWrite {
    108     PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
    109         : mode(mode),
    110           packet(packet) {
    111     }
    112     IoMode mode;
    113     QuicEncryptedPacket* packet;
    114   };
    115 
    116   QuicHttpStreamTest()
    117       : net_log_(BoundNetLog()),
    118         use_closing_stream_(false),
    119         read_buffer_(new IOBufferWithSize(4096)),
    120         guid_(2),
    121         framer_(QuicVersionMax(), QuicTime::Zero(), false),
    122         creator_(guid_, &framer_, &random_, false) {
    123     IPAddressNumber ip;
    124     CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
    125     peer_addr_ = IPEndPoint(ip, 443);
    126     self_addr_ = IPEndPoint(ip, 8435);
    127   }
    128 
    129   ~QuicHttpStreamTest() {
    130     for (size_t i = 0; i < writes_.size(); i++) {
    131       delete writes_[i].packet;
    132     }
    133   }
    134 
    135   // Adds a packet to the list of expected writes.
    136   void AddWrite(IoMode mode, QuicEncryptedPacket* packet) {
    137     writes_.push_back(PacketToWrite(mode, packet));
    138   }
    139 
    140   // Returns the packet to be written at position |pos|.
    141   QuicEncryptedPacket* GetWrite(size_t pos) {
    142     return writes_[pos].packet;
    143   }
    144 
    145   bool AtEof() {
    146     return socket_data_->at_read_eof() && socket_data_->at_write_eof();
    147   }
    148 
    149   void ProcessPacket(const QuicEncryptedPacket& packet) {
    150     connection_->ProcessUdpPacket(self_addr_, peer_addr_, packet);
    151   }
    152 
    153   // Configures the test fixture to use the list of expected writes.
    154   void Initialize() {
    155     mock_writes_.reset(new MockWrite[writes_.size()]);
    156     for (size_t i = 0; i < writes_.size(); i++) {
    157       mock_writes_[i] = MockWrite(writes_[i].mode,
    158                                   writes_[i].packet->data(),
    159                                   writes_[i].packet->length());
    160     };
    161 
    162     socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(),
    163                                                     writes_.size()));
    164 
    165     MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
    166                                                           net_log_.net_log());
    167     socket->Connect(peer_addr_);
    168     runner_ = new TestTaskRunner(&clock_);
    169     send_algorithm_ = new MockSendAlgorithm();
    170     receive_algorithm_ = new TestReceiveAlgorithm(NULL);
    171     EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
    172         testing::Return(QuicTime::Delta::Zero()));
    173     EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)).
    174         WillRepeatedly(testing::Return(QuicTime::Delta::Zero()));
    175     helper_ = new QuicConnectionHelper(runner_.get(), &clock_,
    176                                        &random_generator_, socket);
    177     connection_ = new TestQuicConnection(guid_, peer_addr_, helper_);
    178     connection_->set_visitor(&visitor_);
    179     connection_->SetSendAlgorithm(send_algorithm_);
    180     connection_->SetReceiveAlgorithm(receive_algorithm_);
    181     crypto_config_.SetDefaults();
    182     session_.reset(new QuicClientSession(connection_, socket, NULL,
    183                                          &crypto_client_stream_factory_,
    184                                          "www.google.com", DefaultQuicConfig(),
    185                                          &crypto_config_, NULL));
    186     session_->GetCryptoStream()->CryptoConnect();
    187     EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
    188     stream_.reset(use_closing_stream_ ?
    189                   new AutoClosingStream(session_->GetWeakPtr()) :
    190                   new QuicHttpStream(session_->GetWeakPtr()));
    191   }
    192 
    193   void SetRequestString(const std::string& method, const std::string& path) {
    194     SpdyHeaderBlock headers;
    195     headers[":method"] = method;
    196     headers[":host"] = "www.google.com";
    197     headers[":path"] = path;
    198     headers[":scheme"] = "http";
    199     headers[":version"] = "HTTP/1.1";
    200     request_data_ = SerializeHeaderBlock(headers);
    201   }
    202 
    203   void SetResponseString(const std::string& status, const std::string& body) {
    204     SpdyHeaderBlock headers;
    205     headers[":status"] = status;
    206     headers[":version"] = "HTTP/1.1";
    207     headers["content-type"] = "text/plain";
    208     response_data_ = SerializeHeaderBlock(headers) + body;
    209   }
    210 
    211   std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers) {
    212     QuicSpdyCompressor compressor;
    213     return compressor.CompressHeaders(headers);
    214   }
    215 
    216   // Returns a newly created packet to send kData on stream 1.
    217   QuicEncryptedPacket* ConstructDataPacket(
    218       QuicPacketSequenceNumber sequence_number,
    219       bool should_include_version,
    220       bool fin,
    221       QuicStreamOffset offset,
    222       base::StringPiece data) {
    223     InitializeHeader(sequence_number, should_include_version);
    224     QuicStreamFrame frame(3, fin, offset, data);
    225     return ConstructPacket(header_, QuicFrame(&frame));
    226   }
    227 
    228   // Returns a newly created packet to send ack data.
    229   QuicEncryptedPacket* ConstructAckPacket(
    230       QuicPacketSequenceNumber sequence_number,
    231       QuicPacketSequenceNumber largest_received,
    232       QuicPacketSequenceNumber least_unacked) {
    233     InitializeHeader(sequence_number, false);
    234 
    235     QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked);
    236     ack.sent_info.entropy_hash = 0;
    237     ack.received_info.entropy_hash = 0;
    238 
    239     return ConstructPacket(header_, QuicFrame(&ack));
    240   }
    241 
    242   // Returns a newly created packet to send ack data.
    243   QuicEncryptedPacket* ConstructRstPacket(
    244       QuicPacketSequenceNumber sequence_number,
    245       QuicStreamId stream_id) {
    246     InitializeHeader(sequence_number, false);
    247 
    248     QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR);
    249     return ConstructPacket(header_, QuicFrame(&rst));
    250   }
    251 
    252   BoundNetLog net_log_;
    253   bool use_closing_stream_;
    254   MockSendAlgorithm* send_algorithm_;
    255   TestReceiveAlgorithm* receive_algorithm_;
    256   scoped_refptr<TestTaskRunner> runner_;
    257   scoped_ptr<MockWrite[]> mock_writes_;
    258   MockClock clock_;
    259   MockRandom random_generator_;
    260   TestQuicConnection* connection_;
    261   QuicConnectionHelper* helper_;
    262   testing::StrictMock<MockConnectionVisitor> visitor_;
    263   scoped_ptr<QuicHttpStream> stream_;
    264   scoped_ptr<QuicClientSession> session_;
    265   QuicCryptoClientConfig crypto_config_;
    266   TestCompletionCallback callback_;
    267   HttpRequestInfo request_;
    268   HttpRequestHeaders headers_;
    269   HttpResponseInfo response_;
    270   scoped_refptr<IOBufferWithSize> read_buffer_;
    271   std::string request_data_;
    272   std::string response_data_;
    273 
    274  private:
    275   void InitializeHeader(QuicPacketSequenceNumber sequence_number,
    276                         bool should_include_version) {
    277     header_.public_header.guid = guid_;
    278     header_.public_header.reset_flag = false;
    279     header_.public_header.version_flag = should_include_version;
    280     header_.packet_sequence_number = sequence_number;
    281     header_.fec_group = 0;
    282     header_.entropy_flag = false;
    283     header_.fec_flag = false;
    284   }
    285 
    286   QuicEncryptedPacket* ConstructPacket(const QuicPacketHeader& header,
    287                                        const QuicFrame& frame) {
    288     QuicFrames frames;
    289     frames.push_back(frame);
    290     scoped_ptr<QuicPacket> packet(
    291         framer_.BuildUnsizedDataPacket(header_, frames).packet);
    292     return framer_.EncryptPacket(
    293         ENCRYPTION_NONE, header.packet_sequence_number, *packet);
    294   }
    295 
    296   const QuicGuid guid_;
    297   QuicFramer framer_;
    298   IPEndPoint self_addr_;
    299   IPEndPoint peer_addr_;
    300   MockRandom random_;
    301   MockCryptoClientStreamFactory crypto_client_stream_factory_;
    302   QuicPacketCreator creator_;
    303   QuicPacketHeader header_;
    304   scoped_ptr<StaticSocketDataProvider> socket_data_;
    305   std::vector<PacketToWrite> writes_;
    306 };
    307 
    308 TEST_F(QuicHttpStreamTest, RenewStreamForAuth) {
    309   Initialize();
    310   EXPECT_EQ(NULL, stream_->RenewStreamForAuth());
    311 }
    312 
    313 TEST_F(QuicHttpStreamTest, CanFindEndOfResponse) {
    314   Initialize();
    315   EXPECT_TRUE(stream_->CanFindEndOfResponse());
    316 }
    317 
    318 TEST_F(QuicHttpStreamTest, IsConnectionReusable) {
    319   Initialize();
    320   EXPECT_FALSE(stream_->IsConnectionReusable());
    321 }
    322 
    323 TEST_F(QuicHttpStreamTest, GetRequest) {
    324   SetRequestString("GET", "/");
    325   AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0,
    326                                             request_data_));
    327   Initialize();
    328 
    329   request_.method = "GET";
    330   request_.url = GURL("http://www.google.com/");
    331 
    332   EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    333                                           net_log_, callback_.callback()));
    334   EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
    335                                      callback_.callback()));
    336   EXPECT_EQ(&response_, stream_->GetResponseInfo());
    337 
    338   // Ack the request.
    339   scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
    340   ProcessPacket(*ack);
    341 
    342   EXPECT_EQ(ERR_IO_PENDING,
    343             stream_->ReadResponseHeaders(callback_.callback()));
    344 
    345   // Send the response without a body.
    346   SetResponseString("404 Not Found", std::string());
    347   scoped_ptr<QuicEncryptedPacket> resp(
    348       ConstructDataPacket(2, false, kFin, 0, response_data_));
    349   ProcessPacket(*resp);
    350 
    351   // Now that the headers have been processed, the callback will return.
    352   EXPECT_EQ(OK, callback_.WaitForResult());
    353   ASSERT_TRUE(response_.headers.get());
    354   EXPECT_EQ(404, response_.headers->response_code());
    355   EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
    356 
    357   // There is no body, so this should return immediately.
    358   EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
    359                                          read_buffer_->size(),
    360                                          callback_.callback()));
    361   EXPECT_TRUE(stream_->IsResponseBodyComplete());
    362   EXPECT_TRUE(AtEof());
    363 }
    364 
    365 TEST_F(QuicHttpStreamTest, GetRequestFullResponseInSinglePacket) {
    366   SetRequestString("GET", "/");
    367   AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_));
    368   Initialize();
    369 
    370   request_.method = "GET";
    371   request_.url = GURL("http://www.google.com/");
    372 
    373   EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    374                                           net_log_, callback_.callback()));
    375   EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
    376                                      callback_.callback()));
    377   EXPECT_EQ(&response_, stream_->GetResponseInfo());
    378 
    379   // Ack the request.
    380   scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
    381   ProcessPacket(*ack);
    382 
    383   EXPECT_EQ(ERR_IO_PENDING,
    384             stream_->ReadResponseHeaders(callback_.callback()));
    385 
    386   // Send the response with a body.
    387   SetResponseString("200 OK", "hello world!");
    388   scoped_ptr<QuicEncryptedPacket> resp(
    389       ConstructDataPacket(2, false, kFin, 0, response_data_));
    390   ProcessPacket(*resp);
    391 
    392   // Now that the headers have been processed, the callback will return.
    393   EXPECT_EQ(OK, callback_.WaitForResult());
    394   ASSERT_TRUE(response_.headers.get());
    395   EXPECT_EQ(200, response_.headers->response_code());
    396   EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
    397 
    398   // There is no body, so this should return immediately.
    399   // Since the body has already arrived, this should return immediately.
    400   EXPECT_EQ(12, stream_->ReadResponseBody(read_buffer_.get(),
    401                                           read_buffer_->size(),
    402                                           callback_.callback()));
    403   EXPECT_TRUE(stream_->IsResponseBodyComplete());
    404   EXPECT_TRUE(AtEof());
    405 }
    406 
    407 TEST_F(QuicHttpStreamTest, SendPostRequest) {
    408   SetRequestString("POST", "/");
    409   AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_));
    410   AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, kFin,
    411                                             request_data_.length(),
    412                                             kUploadData));
    413   AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 3, 1));
    414 
    415   Initialize();
    416 
    417   ScopedVector<UploadElementReader> element_readers;
    418   element_readers.push_back(
    419       new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
    420   UploadDataStream upload_data_stream(&element_readers, 0);
    421   request_.method = "POST";
    422   request_.url = GURL("http://www.google.com/");
    423   request_.upload_data_stream = &upload_data_stream;
    424   ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
    425 
    426   EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    427                                           net_log_, callback_.callback()));
    428   EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
    429                                      callback_.callback()));
    430   EXPECT_EQ(&response_, stream_->GetResponseInfo());
    431 
    432   // Ack both packets in the request.
    433   scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
    434   ProcessPacket(*ack);
    435 
    436   // Send the response headers (but not the body).
    437   SetResponseString("200 OK", std::string());
    438   scoped_ptr<QuicEncryptedPacket> resp(
    439       ConstructDataPacket(2, false, !kFin, 0, response_data_));
    440   ProcessPacket(*resp);
    441 
    442   // Since the headers have already arrived, this should return immediately.
    443   EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
    444   ASSERT_TRUE(response_.headers.get());
    445   EXPECT_EQ(200, response_.headers->response_code());
    446   EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
    447 
    448   // Send the response body.
    449   const char kResponseBody[] = "Hello world!";
    450   scoped_ptr<QuicEncryptedPacket> resp_body(
    451       ConstructDataPacket(3, false, kFin, response_data_.length(),
    452                           kResponseBody));
    453   ProcessPacket(*resp_body);
    454 
    455   // Since the body has already arrived, this should return immediately.
    456   EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
    457             stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
    458                                       callback_.callback()));
    459 
    460   EXPECT_TRUE(stream_->IsResponseBodyComplete());
    461   EXPECT_TRUE(AtEof());
    462 }
    463 
    464 TEST_F(QuicHttpStreamTest, SendChunkedPostRequest) {
    465   SetRequestString("POST", "/");
    466   size_t chunk_size = strlen(kUploadData);
    467   AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_));
    468   AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, !kFin,
    469                                             request_data_.length(),
    470                                             kUploadData));
    471   AddWrite(SYNCHRONOUS, ConstructDataPacket(3, true, kFin,
    472                                             request_data_.length() + chunk_size,
    473                                             kUploadData));
    474   AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 3, 1));
    475 
    476   Initialize();
    477 
    478   UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
    479   upload_data_stream.AppendChunk(kUploadData, chunk_size, false);
    480 
    481   request_.method = "POST";
    482   request_.url = GURL("http://www.google.com/");
    483   request_.upload_data_stream = &upload_data_stream;
    484   ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
    485 
    486   ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    487                                           net_log_, callback_.callback()));
    488   ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
    489                                                  callback_.callback()));
    490   EXPECT_EQ(&response_, stream_->GetResponseInfo());
    491 
    492   upload_data_stream.AppendChunk(kUploadData, chunk_size, true);
    493 
    494   // Ack both packets in the request.
    495   scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
    496   ProcessPacket(*ack);
    497 
    498   // Send the response headers (but not the body).
    499   SetResponseString("200 OK", std::string());
    500   scoped_ptr<QuicEncryptedPacket> resp(
    501       ConstructDataPacket(2, false, !kFin, 0, response_data_));
    502   ProcessPacket(*resp);
    503 
    504   // Since the headers have already arrived, this should return immediately.
    505   ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
    506   ASSERT_TRUE(response_.headers.get());
    507   EXPECT_EQ(200, response_.headers->response_code());
    508   EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
    509 
    510   // Send the response body.
    511   const char kResponseBody[] = "Hello world!";
    512   scoped_ptr<QuicEncryptedPacket> resp_body(
    513       ConstructDataPacket(3, false, kFin, response_data_.length(),
    514                           kResponseBody));
    515   ProcessPacket(*resp_body);
    516 
    517   // Since the body has already arrived, this should return immediately.
    518   ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
    519             stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
    520                                       callback_.callback()));
    521 
    522   EXPECT_TRUE(stream_->IsResponseBodyComplete());
    523   EXPECT_TRUE(AtEof());
    524 }
    525 
    526 TEST_F(QuicHttpStreamTest, DestroyedEarly) {
    527   SetRequestString("GET", "/");
    528   AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_));
    529   use_closing_stream_ = true;
    530   Initialize();
    531 
    532   request_.method = "GET";
    533   request_.url = GURL("http://www.google.com/");
    534 
    535   EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    536                                           net_log_, callback_.callback()));
    537   EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
    538                                     callback_.callback()));
    539   EXPECT_EQ(&response_, stream_->GetResponseInfo());
    540 
    541   // Ack the request.
    542   scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
    543   ProcessPacket(*ack);
    544   EXPECT_EQ(ERR_IO_PENDING,
    545             stream_->ReadResponseHeaders(callback_.callback()));
    546 
    547   // Send the response with a body.
    548   SetResponseString("404 OK", "hello world!");
    549   scoped_ptr<QuicEncryptedPacket> resp(
    550       ConstructDataPacket(2, false, kFin, 0, response_data_));
    551 
    552   // In the course of processing this packet, the QuicHttpStream close itself.
    553   ProcessPacket(*resp);
    554 
    555   EXPECT_TRUE(AtEof());
    556 }
    557 
    558 }  // namespace test
    559 
    560 }  // namespace net
    561