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