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