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.
5 #include "net/quic/quic_http_stream.h"
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"
46 using testing::AnyNumber;
47 using testing::Return;
53 const char kUploadData[] = "Really nifty data!";
54 const char kServerHostname[] = "www.google.com";
55 const uint16 kServerPort = 80;
57 class TestQuicConnection : public QuicConnection {
59 TestQuicConnection(const QuicVersionVector& versions,
60 QuicConnectionId connection_id,
62 QuicConnectionHelper* helper,
63 const QuicConnection::PacketWriterFactory& writer_factory)
64 : QuicConnection(connection_id,
68 true /* owns_writer */,
69 false /* is_server */,
73 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
74 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
77 void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) {
78 QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm);
82 class TestReceiveAlgorithm : public ReceiveAlgorithmInterface {
84 virtual bool GenerateCongestionFeedback(
85 QuicCongestionFeedbackFrame* /*congestion_feedback*/) {
89 MOCK_METHOD3(RecordIncomingPacket,
90 void(QuicByteCount, QuicPacketSequenceNumber, QuicTime));
93 // Subclass of QuicHttpStream that closes itself when the first piece of data
95 class AutoClosingStream : public QuicHttpStream {
97 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session)
98 : QuicHttpStream(session) {
101 int OnDataReceived(const char* data, int length) override {
107 class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
109 explicit TestPacketWriterFactory(DatagramClientSocket* socket)
111 ~TestPacketWriterFactory() override {}
113 QuicPacketWriter* Create(QuicConnection* connection) const override {
114 return new QuicDefaultPacketWriter(socket_);
118 DatagramClientSocket* socket_;
123 class QuicHttpStreamPeer {
125 static QuicReliableClientStream* GetQuicReliableClientStream(
126 QuicHttpStream* stream) {
127 return stream->stream_;
131 class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
133 static const bool kFin = true;
134 static const bool kIncludeVersion = true;
135 static const bool kIncludeCongestionFeedback = true;
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)
145 QuicEncryptedPacket* packet;
149 : net_log_(BoundNetLog()),
150 use_closing_stream_(false),
151 read_buffer_(new IOBufferWithSize(4096)),
153 stream_id_(kClientDataStreamId1),
154 maker_(GetParam(), connection_id_, &clock_),
155 random_generator_(0) {
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));
163 ~QuicHttpStreamTest() {
164 session_->CloseSessionOnError(ERR_ABORTED);
165 for (size_t i = 0; i < writes_.size(); i++) {
166 delete writes_[i].packet;
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()));
175 // Returns the packet to be written at position |pos|.
176 QuicEncryptedPacket* GetWrite(size_t pos) {
177 return writes_[pos].packet;
181 return socket_data_->at_read_eof() && socket_data_->at_write_eof();
184 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
185 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
188 // Configures the test fixture to use the list of expected writes.
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());
197 socket_data_.reset(new StaticSocketDataProvider(
198 nullptr, 0, mock_writes_.get(), writes_.size()));
200 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
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(_, _, _)).
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_);
229 new QuicClientSession(connection_,
230 scoped_ptr<DatagramClientSocket>(socket),
232 &transport_security_state_,
233 make_scoped_ptr((QuicServerInfo*)nullptr),
236 base::MessageLoop::current()->
237 message_loop_proxy().get(),
239 session_->InitializeSession(QuicServerId(kServerHostname, kServerPort,
241 PRIVACY_MODE_DISABLED),
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()));
251 void SetRequest(const std::string& method,
252 const std::string& path,
253 RequestPriority priority) {
254 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
257 void SetResponse(const std::string& status, const std::string& body) {
258 response_headers_ = maker_.GetResponseHeaders(status);
259 response_data_ = body;
262 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
263 QuicPacketSequenceNumber sequence_number,
264 bool should_include_version,
266 QuicStreamOffset offset,
267 base::StringPiece data) {
268 return maker_.MakeDataPacket(
269 sequence_number, stream_id_, should_include_version, fin, offset, data);
272 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
273 QuicPacketSequenceNumber sequence_number,
275 return maker_.MakeRequestHeadersPacket(
276 sequence_number, stream_id_, kIncludeVersion, fin, request_headers_);
279 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
280 QuicPacketSequenceNumber sequence_number,
282 return maker_.MakeResponseHeadersPacket(
283 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_);
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()));
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);
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);
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_;
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_;
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_;
344 INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
345 ::testing::ValuesIn(QuicSupportedVersions()));
347 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
349 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
352 TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
354 EXPECT_TRUE(stream_->CanFindEndOfResponse());
357 TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
359 EXPECT_FALSE(stream_->IsConnectionReusable());
362 TEST_P(QuicHttpStreamTest, GetRequest) {
363 SetRequest("GET", "/", DEFAULT_PRIORITY);
364 AddWrite(ConstructRequestHeadersPacket(1, kFin));
367 request_.method = "GET";
368 request_.url = GURL("http://www.google.com/");
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()));
376 ProcessPacket(ConstructAckPacket(1, 0, 0));
378 EXPECT_EQ(ERR_IO_PENDING,
379 stream_->ReadResponseHeaders(callback_.callback()));
381 SetResponse("404 Not Found", std::string());
382 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
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());
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());
400 // Regression test for http://crbug.com/288128
401 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
402 SetRequest("GET", "/", DEFAULT_PRIORITY);
403 AddWrite(ConstructRequestHeadersPacket(1, kFin));
406 request_.method = "GET";
407 request_.url = GURL("http://www.google.com/");
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()));
415 ProcessPacket(ConstructAckPacket(1, 0, 0));
417 EXPECT_EQ(ERR_IO_PENDING,
418 stream_->ReadResponseHeaders(callback_.callback()));
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.
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);
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"));
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());
445 // Regression test for http://crbug.com/409101
446 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
447 SetRequest("GET", "/", DEFAULT_PRIORITY);
450 request_.method = "GET";
451 request_.url = GURL("http://www.google.com/");
453 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
454 net_log_, callback_.callback()));
456 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
458 EXPECT_EQ(ERR_CONNECTION_CLOSED,
459 stream_->SendRequest(headers_, &response_,
460 callback_.callback()));
463 // Regression test for http://crbug.com/409871
464 TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
465 SetRequest("GET", "/", DEFAULT_PRIORITY);
466 AddWrite(ConstructRequestHeadersPacket(1, kFin));
469 request_.method = "GET";
470 request_.url = GURL("http://www.google.com/");
472 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
473 net_log_, callback_.callback()));
475 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
476 callback_.callback()));
478 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
480 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
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));
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()));
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()));
505 // Ack both packets in the request.
506 ProcessPacket(ConstructAckPacket(1, 0, 0));
508 // Send the response headers (but not the body).
509 SetResponse("200 OK", std::string());
510 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
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"));
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()));
526 EXPECT_TRUE(stream_->IsResponseBodyComplete());
527 EXPECT_TRUE(AtEof());
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,
537 AddWrite(ConstructAckPacket(4, 3, 1));
540 ChunkedUploadDataStream upload_data_stream(0);
541 upload_data_stream.AppendData(kUploadData, chunk_size, false);
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()));
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()));
554 upload_data_stream.AppendData(kUploadData, chunk_size, true);
556 // Ack both packets in the request.
557 ProcessPacket(ConstructAckPacket(1, 0, 0));
559 // Send the response headers (but not the body).
560 SetResponse("200 OK", std::string());
561 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
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"));
569 // Send the response body.
570 const char kResponseBody[] = "Hello world!";
571 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
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()));
579 EXPECT_TRUE(stream_->IsResponseBodyComplete());
580 EXPECT_TRUE(AtEof());
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));
592 ChunkedUploadDataStream upload_data_stream(0);
593 upload_data_stream.AppendData(kUploadData, chunk_size, false);
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()));
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()));
606 upload_data_stream.AppendData(nullptr, 0, true);
608 ProcessPacket(ConstructAckPacket(1, 0, 0));
610 // Send the response headers (but not the body).
611 SetResponse("200 OK", std::string());
612 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
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"));
620 // Send the response body.
621 const char kResponseBody[] = "Hello world!";
622 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
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()));
630 EXPECT_TRUE(stream_->IsResponseBodyComplete());
631 EXPECT_TRUE(AtEof());
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));
641 ChunkedUploadDataStream upload_data_stream(0);
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()));
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()));
654 upload_data_stream.AppendData(nullptr, 0, true);
656 ProcessPacket(ConstructAckPacket(1, 0, 0));
658 // Send the response headers (but not the body).
659 SetResponse("200 OK", std::string());
660 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
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"));
668 // Send the response body.
669 const char kResponseBody[] = "Hello world!";
670 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
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()));
678 EXPECT_TRUE(stream_->IsResponseBodyComplete());
679 EXPECT_TRUE(AtEof());
682 TEST_P(QuicHttpStreamTest, DestroyedEarly) {
683 SetRequest("GET", "/", DEFAULT_PRIORITY);
684 AddWrite(ConstructRequestHeadersPacket(1, kFin));
685 AddWrite(ConstructAckAndRstStreamPacket(2));
686 use_closing_stream_ = true;
689 request_.method = "GET";
690 request_.url = GURL("http://www.google.com/");
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()));
698 ProcessPacket(ConstructAckPacket(1, 0, 0));
699 EXPECT_EQ(ERR_IO_PENDING,
700 stream_->ReadResponseHeaders(callback_.callback()));
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));
707 EXPECT_TRUE(AtEof());
710 TEST_P(QuicHttpStreamTest, Priority) {
711 SetRequest("GET", "/", MEDIUM);
712 AddWrite(ConstructRequestHeadersPacket(1, kFin));
713 AddWrite(ConstructAckAndRstStreamPacket(2));
714 use_closing_stream_ = true;
717 request_.method = "GET";
718 request_.url = GURL("http://www.google.com/");
720 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
721 net_log_, callback_.callback()));
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());
730 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
731 callback_.callback()));
733 // Check that priority has now dropped back to MEDIUM.
734 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
735 reliable_stream->EffectivePriority()));
738 ProcessPacket(ConstructAckPacket(1, 0, 0));
739 EXPECT_EQ(ERR_IO_PENDING,
740 stream_->ReadResponseHeaders(callback_.callback()));
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));
747 EXPECT_TRUE(AtEof());
750 // Regression test for http://crbug.com/294870
751 TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
752 SetRequest("GET", "/", MEDIUM);
753 use_closing_stream_ = true;
755 AddWrite(ConstructRstStreamPacket(1));
759 request_.method = "GET";
760 request_.url = GURL("http://www.google.com/");
762 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
763 net_log_, callback_.callback()));
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();
771 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
772 reliable_stream->EffectivePriority());
774 // Set Delegate to nullptr and make sure EffectivePriority returns highest
776 reliable_stream->SetDelegate(nullptr);
777 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
778 reliable_stream->EffectivePriority());
779 reliable_stream->SetDelegate(delegate);