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