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/http/transport_security_state.h"
     15 #include "net/quic/congestion_control/receive_algorithm_interface.h"
     16 #include "net/quic/congestion_control/send_algorithm_interface.h"
     17 #include "net/quic/crypto/crypto_protocol.h"
     18 #include "net/quic/crypto/quic_decrypter.h"
     19 #include "net/quic/crypto/quic_encrypter.h"
     20 #include "net/quic/crypto/quic_server_info.h"
     21 #include "net/quic/quic_client_session.h"
     22 #include "net/quic/quic_connection.h"
     23 #include "net/quic/quic_connection_helper.h"
     24 #include "net/quic/quic_default_packet_writer.h"
     25 #include "net/quic/quic_http_utils.h"
     26 #include "net/quic/quic_reliable_client_stream.h"
     27 #include "net/quic/quic_write_blocked_list.h"
     28 #include "net/quic/spdy_utils.h"
     29 #include "net/quic/test_tools/mock_clock.h"
     30 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
     31 #include "net/quic/test_tools/mock_random.h"
     32 #include "net/quic/test_tools/quic_connection_peer.h"
     33 #include "net/quic/test_tools/quic_test_packet_maker.h"
     34 #include "net/quic/test_tools/quic_test_utils.h"
     35 #include "net/quic/test_tools/test_task_runner.h"
     36 #include "net/socket/socket_test_util.h"
     37 #include "net/spdy/spdy_frame_builder.h"
     38 #include "net/spdy/spdy_framer.h"
     39 #include "net/spdy/spdy_http_utils.h"
     40 #include "net/spdy/spdy_protocol.h"
     41 #include "testing/gmock/include/gmock/gmock.h"
     42 #include "testing/gtest/include/gtest/gtest.h"
     43 
     44 using testing::_;
     45 using testing::AnyNumber;
     46 using testing::Return;
     47 
     48 namespace net {
     49 namespace test {
     50 namespace {
     51 
     52 const char kUploadData[] = "Really nifty data!";
     53 const char kServerHostname[] = "www.google.com";
     54 const uint16 kServerPort = 80;
     55 
     56 class TestQuicConnection : public QuicConnection {
     57  public:
     58   TestQuicConnection(const QuicVersionVector& versions,
     59                      QuicConnectionId connection_id,
     60                      IPEndPoint address,
     61                      QuicConnectionHelper* helper,
     62                      const QuicConnection::PacketWriterFactory& writer_factory)
     63       : QuicConnection(connection_id,
     64                        address,
     65                        helper,
     66                        writer_factory,
     67                        true  /* owns_writer */,
     68                        false  /* is_server */,
     69                        versions) {
     70   }
     71 
     72   void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
     73     QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
     74   }
     75 
     76   void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) {
     77     QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm);
     78   }
     79 };
     80 
     81 class TestReceiveAlgorithm : public ReceiveAlgorithmInterface {
     82  public:
     83   virtual bool GenerateCongestionFeedback(
     84       QuicCongestionFeedbackFrame* /*congestion_feedback*/) {
     85     return false;
     86   }
     87 
     88   MOCK_METHOD3(RecordIncomingPacket,
     89                void(QuicByteCount, QuicPacketSequenceNumber, QuicTime));
     90 };
     91 
     92 // Subclass of QuicHttpStream that closes itself when the first piece of data
     93 // is received.
     94 class AutoClosingStream : public QuicHttpStream {
     95  public:
     96   explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session)
     97       : QuicHttpStream(session) {
     98   }
     99 
    100   virtual int OnDataReceived(const char* data, int length) OVERRIDE {
    101     Close(false);
    102     return OK;
    103   }
    104 };
    105 
    106 class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
    107  public:
    108   explicit TestPacketWriterFactory(DatagramClientSocket* socket)
    109       : socket_(socket) {}
    110   virtual ~TestPacketWriterFactory() {}
    111 
    112   virtual QuicPacketWriter* Create(QuicConnection* connection) const OVERRIDE {
    113     return new QuicDefaultPacketWriter(socket_);
    114   }
    115 
    116  private:
    117   DatagramClientSocket* socket_;
    118 };
    119 
    120 }  // namespace
    121 
    122 class QuicHttpStreamPeer {
    123  public:
    124   static QuicReliableClientStream* GetQuicReliableClientStream(
    125       QuicHttpStream* stream) {
    126     return stream->stream_;
    127   }
    128 };
    129 
    130 class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
    131  protected:
    132   static const bool kFin = true;
    133   static const bool kIncludeVersion = true;
    134   static const bool kIncludeCongestionFeedback = true;
    135 
    136   // Holds a packet to be written to the wire, and the IO mode that should
    137   // be used by the mock socket when performing the write.
    138   struct PacketToWrite {
    139     PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
    140         : mode(mode),
    141           packet(packet) {
    142     }
    143     IoMode mode;
    144     QuicEncryptedPacket* packet;
    145   };
    146 
    147   QuicHttpStreamTest()
    148       : net_log_(BoundNetLog()),
    149         use_closing_stream_(false),
    150         read_buffer_(new IOBufferWithSize(4096)),
    151         connection_id_(2),
    152         stream_id_(kClientDataStreamId1),
    153         maker_(GetParam(), connection_id_, &clock_),
    154         random_generator_(0) {
    155     IPAddressNumber ip;
    156     CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
    157     peer_addr_ = IPEndPoint(ip, 443);
    158     self_addr_ = IPEndPoint(ip, 8435);
    159     clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
    160   }
    161 
    162   ~QuicHttpStreamTest() {
    163     session_->CloseSessionOnError(ERR_ABORTED);
    164     for (size_t i = 0; i < writes_.size(); i++) {
    165       delete writes_[i].packet;
    166     }
    167   }
    168 
    169   // Adds a packet to the list of expected writes.
    170   void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
    171     writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
    172   }
    173 
    174   // Returns the packet to be written at position |pos|.
    175   QuicEncryptedPacket* GetWrite(size_t pos) {
    176     return writes_[pos].packet;
    177   }
    178 
    179   bool AtEof() {
    180     return socket_data_->at_read_eof() && socket_data_->at_write_eof();
    181   }
    182 
    183   void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
    184     connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
    185   }
    186 
    187   // Configures the test fixture to use the list of expected writes.
    188   void Initialize() {
    189     mock_writes_.reset(new MockWrite[writes_.size()]);
    190     for (size_t i = 0; i < writes_.size(); i++) {
    191       mock_writes_[i] = MockWrite(writes_[i].mode,
    192                                   writes_[i].packet->data(),
    193                                   writes_[i].packet->length());
    194     };
    195 
    196     socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(),
    197                                                     writes_.size()));
    198 
    199     MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
    200                                                           net_log_.net_log());
    201     socket->Connect(peer_addr_);
    202     runner_ = new TestTaskRunner(&clock_);
    203     send_algorithm_ = new MockSendAlgorithm();
    204     receive_algorithm_ = new TestReceiveAlgorithm();
    205     EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _)).
    206         Times(AnyNumber());
    207     EXPECT_CALL(*send_algorithm_,
    208                 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
    209     EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
    210         Return(QuicTime::Delta::Zero()));
    211     EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
    212         Return(kMaxPacketSize));
    213     EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).
    214         WillRepeatedly(Return(QuicTime::Delta::Zero()));
    215     EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
    216         Return(QuicBandwidth::Zero()));
    217     EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
    218     helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
    219                                            &random_generator_));
    220     TestPacketWriterFactory writer_factory(socket);
    221     connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
    222                                          connection_id_, peer_addr_,
    223                                          helper_.get(), writer_factory);
    224     connection_->set_visitor(&visitor_);
    225     connection_->SetSendAlgorithm(send_algorithm_);
    226     connection_->SetReceiveAlgorithm(receive_algorithm_);
    227     crypto_config_.SetDefaults();
    228     session_.reset(
    229         new QuicClientSession(connection_,
    230                               scoped_ptr<DatagramClientSocket>(socket),
    231                               NULL,
    232                               &transport_security_state_,
    233                               make_scoped_ptr((QuicServerInfo*)NULL),
    234                               DefaultQuicConfig(),
    235                               base::MessageLoop::current()->
    236                                   message_loop_proxy().get(),
    237                               NULL));
    238     session_->InitializeSession(QuicServerId(kServerHostname, kServerPort,
    239                                              false, PRIVACY_MODE_DISABLED),
    240                                 &crypto_config_,
    241                                 &crypto_client_stream_factory_);
    242     session_->GetCryptoStream()->CryptoConnect();
    243     EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
    244     stream_.reset(use_closing_stream_ ?
    245                   new AutoClosingStream(session_->GetWeakPtr()) :
    246                   new QuicHttpStream(session_->GetWeakPtr()));
    247   }
    248 
    249   void SetRequest(const std::string& method,
    250                   const std::string& path,
    251                   RequestPriority priority) {
    252     request_headers_ = maker_.GetRequestHeaders(method, "http", path);
    253   }
    254 
    255   void SetResponse(const std::string& status, const std::string& body) {
    256     response_headers_ = maker_.GetResponseHeaders(status);
    257     response_data_ = body;
    258   }
    259 
    260   scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
    261       QuicPacketSequenceNumber sequence_number,
    262       bool should_include_version,
    263       bool fin,
    264       QuicStreamOffset offset,
    265       base::StringPiece data) {
    266     return maker_.MakeDataPacket(
    267         sequence_number, stream_id_, should_include_version, fin, offset, data);
    268   }
    269 
    270   scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
    271       QuicPacketSequenceNumber sequence_number,
    272       bool fin) {
    273     return maker_.MakeRequestHeadersPacket(
    274         sequence_number, stream_id_, kIncludeVersion, fin, request_headers_);
    275   }
    276 
    277   scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
    278       QuicPacketSequenceNumber sequence_number,
    279       bool fin) {
    280     return maker_.MakeResponseHeadersPacket(
    281         sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_);
    282   }
    283 
    284   scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
    285       QuicPacketSequenceNumber sequence_number) {
    286     return maker_.MakeRstPacket(
    287         sequence_number, true, stream_id_,
    288         AdjustErrorForVersion(QUIC_RST_FLOW_CONTROL_ACCOUNTING, GetParam()));
    289   }
    290 
    291   scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
    292       QuicPacketSequenceNumber sequence_number) {
    293     return maker_.MakeAckAndRstPacket(
    294         sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
    295         2, 1, !kIncludeCongestionFeedback);
    296   }
    297 
    298   scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
    299       QuicPacketSequenceNumber sequence_number,
    300       QuicPacketSequenceNumber largest_received,
    301       QuicPacketSequenceNumber least_unacked) {
    302     return maker_.MakeAckPacket(sequence_number, largest_received,
    303                                 least_unacked, !kIncludeCongestionFeedback);
    304   }
    305 
    306   BoundNetLog net_log_;
    307   bool use_closing_stream_;
    308   MockSendAlgorithm* send_algorithm_;
    309   TestReceiveAlgorithm* receive_algorithm_;
    310   scoped_refptr<TestTaskRunner> runner_;
    311   scoped_ptr<MockWrite[]> mock_writes_;
    312   MockClock clock_;
    313   TestQuicConnection* connection_;
    314   scoped_ptr<QuicConnectionHelper> helper_;
    315   testing::StrictMock<MockConnectionVisitor> visitor_;
    316   scoped_ptr<QuicHttpStream> stream_;
    317   TransportSecurityState transport_security_state_;
    318   scoped_ptr<QuicClientSession> session_;
    319   QuicCryptoClientConfig crypto_config_;
    320   TestCompletionCallback callback_;
    321   HttpRequestInfo request_;
    322   HttpRequestHeaders headers_;
    323   HttpResponseInfo response_;
    324   scoped_refptr<IOBufferWithSize> read_buffer_;
    325   SpdyHeaderBlock request_headers_;
    326   SpdyHeaderBlock response_headers_;
    327   std::string request_data_;
    328   std::string response_data_;
    329 
    330  private:
    331   const QuicConnectionId connection_id_;
    332   const QuicStreamId stream_id_;
    333   QuicTestPacketMaker maker_;
    334   IPEndPoint self_addr_;
    335   IPEndPoint peer_addr_;
    336   MockRandom random_generator_;
    337   MockCryptoClientStreamFactory crypto_client_stream_factory_;
    338   scoped_ptr<StaticSocketDataProvider> socket_data_;
    339   std::vector<PacketToWrite> writes_;
    340 };
    341 
    342 INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
    343                         ::testing::ValuesIn(QuicSupportedVersions()));
    344 
    345 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
    346   Initialize();
    347   EXPECT_EQ(NULL, stream_->RenewStreamForAuth());
    348 }
    349 
    350 TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
    351   Initialize();
    352   EXPECT_TRUE(stream_->CanFindEndOfResponse());
    353 }
    354 
    355 TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
    356   Initialize();
    357   EXPECT_FALSE(stream_->IsConnectionReusable());
    358 }
    359 
    360 TEST_P(QuicHttpStreamTest, GetRequest) {
    361   SetRequest("GET", "/", DEFAULT_PRIORITY);
    362   AddWrite(ConstructRequestHeadersPacket(1, kFin));
    363   Initialize();
    364 
    365   request_.method = "GET";
    366   request_.url = GURL("http://www.google.com/");
    367 
    368   EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    369                                           net_log_, callback_.callback()));
    370   EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
    371                                      callback_.callback()));
    372 
    373   // Ack the request.
    374   ProcessPacket(ConstructAckPacket(1, 0, 0));
    375 
    376   EXPECT_EQ(ERR_IO_PENDING,
    377             stream_->ReadResponseHeaders(callback_.callback()));
    378 
    379   SetResponse("404 Not Found", std::string());
    380   ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
    381 
    382   // Now that the headers have been processed, the callback will return.
    383   EXPECT_EQ(OK, callback_.WaitForResult());
    384   ASSERT_TRUE(response_.headers.get());
    385   EXPECT_EQ(404, response_.headers->response_code());
    386   EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
    387   EXPECT_FALSE(response_.response_time.is_null());
    388   EXPECT_FALSE(response_.request_time.is_null());
    389 
    390   // There is no body, so this should return immediately.
    391   EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
    392                                          read_buffer_->size(),
    393                                          callback_.callback()));
    394   EXPECT_TRUE(stream_->IsResponseBodyComplete());
    395   EXPECT_TRUE(AtEof());
    396 }
    397 
    398 // Regression test for http://crbug.com/288128
    399 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
    400   SetRequest("GET", "/", DEFAULT_PRIORITY);
    401   AddWrite(ConstructRequestHeadersPacket(1, kFin));
    402   Initialize();
    403 
    404   request_.method = "GET";
    405   request_.url = GURL("http://www.google.com/");
    406 
    407   EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    408                                           net_log_, callback_.callback()));
    409   EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
    410                                      callback_.callback()));
    411 
    412   // Ack the request.
    413   ProcessPacket(ConstructAckPacket(1, 0, 0));
    414 
    415   EXPECT_EQ(ERR_IO_PENDING,
    416             stream_->ReadResponseHeaders(callback_.callback()));
    417 
    418   SpdyHeaderBlock headers;
    419   headers[":status"] = "200 OK";
    420   headers[":version"] = "HTTP/1.1";
    421   headers["content-type"] = "text/plain";
    422   headers["big6"] = std::string(10000, 'x');  // Lots of x's.
    423 
    424   std::string response = SpdyUtils::SerializeUncompressedHeaders(headers);
    425   EXPECT_LT(4096u, response.length());
    426   stream_->OnDataReceived(response.data(), response.length());
    427   stream_->OnClose(QUIC_NO_ERROR);
    428 
    429   // Now that the headers have been processed, the callback will return.
    430   EXPECT_EQ(OK, callback_.WaitForResult());
    431   ASSERT_TRUE(response_.headers.get());
    432   EXPECT_EQ(200, response_.headers->response_code());
    433   EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
    434 
    435   // There is no body, so this should return immediately.
    436   EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
    437                                          read_buffer_->size(),
    438                                          callback_.callback()));
    439   EXPECT_TRUE(stream_->IsResponseBodyComplete());
    440   EXPECT_TRUE(AtEof());
    441 }
    442 
    443 // Regression test for http://crbug.com/409101
    444 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
    445   SetRequest("GET", "/", DEFAULT_PRIORITY);
    446   Initialize();
    447 
    448   request_.method = "GET";
    449   request_.url = GURL("http://www.google.com/");
    450 
    451   EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    452                                           net_log_, callback_.callback()));
    453 
    454   session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
    455 
    456   EXPECT_EQ(ERR_CONNECTION_CLOSED,
    457             stream_->SendRequest(headers_, &response_,
    458                                  callback_.callback()));
    459 }
    460 
    461 // Regression test for http://crbug.com/409871
    462 TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
    463   SetRequest("GET", "/", DEFAULT_PRIORITY);
    464   AddWrite(ConstructRequestHeadersPacket(1, kFin));
    465   Initialize();
    466 
    467   request_.method = "GET";
    468   request_.url = GURL("http://www.google.com/");
    469 
    470   EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    471                                           net_log_, callback_.callback()));
    472 
    473   EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
    474                                      callback_.callback()));
    475 
    476   session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
    477 
    478   EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
    479 }
    480 
    481 TEST_P(QuicHttpStreamTest, SendPostRequest) {
    482   SetRequest("POST", "/", DEFAULT_PRIORITY);
    483   AddWrite(ConstructRequestHeadersPacket(1, !kFin));
    484   AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
    485   AddWrite(ConstructAckPacket(3, 3, 1));
    486 
    487   Initialize();
    488 
    489   ScopedVector<UploadElementReader> element_readers;
    490   element_readers.push_back(
    491       new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
    492   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
    493   request_.method = "POST";
    494   request_.url = GURL("http://www.google.com/");
    495   request_.upload_data_stream = &upload_data_stream;
    496   ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
    497 
    498   EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    499                                           net_log_, callback_.callback()));
    500   EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
    501                                      callback_.callback()));
    502 
    503   // Ack both packets in the request.
    504   ProcessPacket(ConstructAckPacket(1, 0, 0));
    505 
    506   // Send the response headers (but not the body).
    507   SetResponse("200 OK", std::string());
    508   ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
    509 
    510   // Since the headers have already arrived, this should return immediately.
    511   EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
    512   ASSERT_TRUE(response_.headers.get());
    513   EXPECT_EQ(200, response_.headers->response_code());
    514   EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
    515 
    516   // Send the response body.
    517   const char kResponseBody[] = "Hello world!";
    518   ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
    519   // Since the body has already arrived, this should return immediately.
    520   EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
    521             stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
    522                                       callback_.callback()));
    523 
    524   EXPECT_TRUE(stream_->IsResponseBodyComplete());
    525   EXPECT_TRUE(AtEof());
    526 }
    527 
    528 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
    529   SetRequest("POST", "/", DEFAULT_PRIORITY);
    530   size_t chunk_size = strlen(kUploadData);
    531   AddWrite(ConstructRequestHeadersPacket(1, !kFin));
    532   AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
    533   AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
    534                                kUploadData));
    535   AddWrite(ConstructAckPacket(4, 3, 1));
    536   Initialize();
    537 
    538   UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
    539   upload_data_stream.AppendChunk(kUploadData, chunk_size, false);
    540 
    541   request_.method = "POST";
    542   request_.url = GURL("http://www.google.com/");
    543   request_.upload_data_stream = &upload_data_stream;
    544   ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
    545 
    546   ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    547                                           net_log_, callback_.callback()));
    548   ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
    549                                                  callback_.callback()));
    550 
    551   upload_data_stream.AppendChunk(kUploadData, chunk_size, true);
    552 
    553   // Ack both packets in the request.
    554   ProcessPacket(ConstructAckPacket(1, 0, 0));
    555 
    556   // Send the response headers (but not the body).
    557   SetResponse("200 OK", std::string());
    558   ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
    559 
    560   // Since the headers have already arrived, this should return immediately.
    561   ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
    562   ASSERT_TRUE(response_.headers.get());
    563   EXPECT_EQ(200, response_.headers->response_code());
    564   EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
    565 
    566   // Send the response body.
    567   const char kResponseBody[] = "Hello world!";
    568   ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
    569                                     kResponseBody));
    570 
    571   // Since the body has already arrived, this should return immediately.
    572   ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
    573             stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
    574                                       callback_.callback()));
    575 
    576   EXPECT_TRUE(stream_->IsResponseBodyComplete());
    577   EXPECT_TRUE(AtEof());
    578 }
    579 
    580 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
    581   SetRequest("POST", "/", DEFAULT_PRIORITY);
    582   size_t chunk_size = strlen(kUploadData);
    583   AddWrite(ConstructRequestHeadersPacket(1, !kFin));
    584   AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
    585   AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
    586   AddWrite(ConstructAckPacket(4, 3, 1));
    587   Initialize();
    588 
    589   UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
    590   upload_data_stream.AppendChunk(kUploadData, chunk_size, false);
    591 
    592   request_.method = "POST";
    593   request_.url = GURL("http://www.google.com/");
    594   request_.upload_data_stream = &upload_data_stream;
    595   ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
    596 
    597   ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    598                                           net_log_, callback_.callback()));
    599   ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
    600                                                  callback_.callback()));
    601 
    602   upload_data_stream.AppendChunk(NULL, 0, true);
    603 
    604   ProcessPacket(ConstructAckPacket(1, 0, 0));
    605 
    606   // Send the response headers (but not the body).
    607   SetResponse("200 OK", std::string());
    608   ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
    609 
    610   // Since the headers have already arrived, this should return immediately.
    611   ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
    612   ASSERT_TRUE(response_.headers.get());
    613   EXPECT_EQ(200, response_.headers->response_code());
    614   EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
    615 
    616   // Send the response body.
    617   const char kResponseBody[] = "Hello world!";
    618   ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
    619                                     kResponseBody));
    620 
    621   // Since the body has already arrived, this should return immediately.
    622   ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
    623             stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
    624                                       callback_.callback()));
    625 
    626   EXPECT_TRUE(stream_->IsResponseBodyComplete());
    627   EXPECT_TRUE(AtEof());
    628 }
    629 
    630 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
    631   SetRequest("POST", "/", DEFAULT_PRIORITY);
    632   AddWrite(ConstructRequestHeadersPacket(1, !kFin));
    633   AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
    634   AddWrite(ConstructAckPacket(3, 3, 1));
    635   Initialize();
    636 
    637   UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
    638 
    639   request_.method = "POST";
    640   request_.url = GURL("http://www.google.com/");
    641   request_.upload_data_stream = &upload_data_stream;
    642   ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
    643 
    644   ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    645                                           net_log_, callback_.callback()));
    646   ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
    647                                                  callback_.callback()));
    648 
    649   upload_data_stream.AppendChunk(NULL, 0, true);
    650 
    651   ProcessPacket(ConstructAckPacket(1, 0, 0));
    652 
    653   // Send the response headers (but not the body).
    654   SetResponse("200 OK", std::string());
    655   ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
    656 
    657   // Since the headers have already arrived, this should return immediately.
    658   ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
    659   ASSERT_TRUE(response_.headers.get());
    660   EXPECT_EQ(200, response_.headers->response_code());
    661   EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
    662 
    663   // Send the response body.
    664   const char kResponseBody[] = "Hello world!";
    665   ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
    666                                     kResponseBody));
    667 
    668   // Since the body has already arrived, this should return immediately.
    669   ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
    670             stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
    671                                       callback_.callback()));
    672 
    673   EXPECT_TRUE(stream_->IsResponseBodyComplete());
    674   EXPECT_TRUE(AtEof());
    675 }
    676 
    677 TEST_P(QuicHttpStreamTest, DestroyedEarly) {
    678   SetRequest("GET", "/", DEFAULT_PRIORITY);
    679   AddWrite(ConstructRequestHeadersPacket(1, kFin));
    680   AddWrite(ConstructAckAndRstStreamPacket(2));
    681   use_closing_stream_ = true;
    682   Initialize();
    683 
    684   request_.method = "GET";
    685   request_.url = GURL("http://www.google.com/");
    686 
    687   EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
    688                                           net_log_, callback_.callback()));
    689   EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
    690                                      callback_.callback()));
    691 
    692   // Ack the request.
    693   ProcessPacket(ConstructAckPacket(1, 0, 0));
    694   EXPECT_EQ(ERR_IO_PENDING,
    695             stream_->ReadResponseHeaders(callback_.callback()));
    696 
    697   // Send the response with a body.
    698   SetResponse("404 OK", "hello world!");
    699   // In the course of processing this packet, the QuicHttpStream close itself.
    700   ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
    701 
    702   EXPECT_TRUE(AtEof());
    703 }
    704 
    705 TEST_P(QuicHttpStreamTest, Priority) {
    706   SetRequest("GET", "/", MEDIUM);
    707   AddWrite(ConstructRequestHeadersPacket(1, kFin));
    708   AddWrite(ConstructAckAndRstStreamPacket(2));
    709   use_closing_stream_ = true;
    710   Initialize();
    711 
    712   request_.method = "GET";
    713   request_.url = GURL("http://www.google.com/");
    714 
    715   EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
    716                                           net_log_, callback_.callback()));
    717 
    718   // Check that priority is highest.
    719   QuicReliableClientStream* reliable_stream =
    720       QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
    721   DCHECK(reliable_stream);
    722   DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
    723             reliable_stream->EffectivePriority());
    724 
    725   EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
    726                                      callback_.callback()));
    727 
    728   // Check that priority has now dropped back to MEDIUM.
    729   DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
    730       reliable_stream->EffectivePriority()));
    731 
    732   // Ack the request.
    733   ProcessPacket(ConstructAckPacket(1, 0, 0));
    734   EXPECT_EQ(ERR_IO_PENDING,
    735             stream_->ReadResponseHeaders(callback_.callback()));
    736 
    737   // Send the response with a body.
    738   SetResponse("404 OK", "hello world!");
    739   // In the course of processing this packet, the QuicHttpStream close itself.
    740   ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
    741 
    742   EXPECT_TRUE(AtEof());
    743 }
    744 
    745 // Regression test for http://crbug.com/294870
    746 TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
    747   SetRequest("GET", "/", MEDIUM);
    748   use_closing_stream_ = true;
    749 
    750   AddWrite(ConstructRstStreamPacket(1));
    751 
    752   Initialize();
    753 
    754   request_.method = "GET";
    755   request_.url = GURL("http://www.google.com/");
    756 
    757   EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
    758                                           net_log_, callback_.callback()));
    759 
    760   // Check that priority is highest.
    761   QuicReliableClientStream* reliable_stream =
    762       QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
    763   DCHECK(reliable_stream);
    764   QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
    765   DCHECK(delegate);
    766   DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
    767             reliable_stream->EffectivePriority());
    768 
    769   // Set Delegate to NULL and make sure EffectivePriority returns highest
    770   // priority.
    771   reliable_stream->SetDelegate(NULL);
    772   DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
    773             reliable_stream->EffectivePriority());
    774   reliable_stream->SetDelegate(delegate);
    775 }
    776 
    777 }  // namespace test
    778 }  // namespace net
    779