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
44using testing::_;
45using testing::AnyNumber;
46using testing::Return;
47
48namespace net {
49namespace test {
50namespace {
51
52const char kUploadData[] = "Really nifty data!";
53const char kServerHostname[] = "www.google.com";
54const uint16 kServerPort = 80;
55
56class 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
81class 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.
94class 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
106class 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
122class QuicHttpStreamPeer {
123 public:
124  static QuicReliableClientStream* GetQuicReliableClientStream(
125      QuicHttpStream* stream) {
126    return stream->stream_;
127  }
128};
129
130class 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
342INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
343                        ::testing::ValuesIn(QuicSupportedVersions()));
344
345TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
346  Initialize();
347  EXPECT_EQ(NULL, stream_->RenewStreamForAuth());
348}
349
350TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
351  Initialize();
352  EXPECT_TRUE(stream_->CanFindEndOfResponse());
353}
354
355TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
356  Initialize();
357  EXPECT_FALSE(stream_->IsConnectionReusable());
358}
359
360TEST_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
399TEST_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
444TEST_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
462TEST_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
481TEST_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
528TEST_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
580TEST_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
630TEST_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
677TEST_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
705TEST_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
746TEST_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