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