Let Custom Tabs Use Light Progressbar for Dark Toolbar
[chromium-blink-merge.git] / net / quic / quic_http_stream_test.cc
blob91d57196cdaf8663f4beb4425ad10ecb5e5a1383
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"
7 #include <stdint.h>
9 #include <vector>
11 #include "base/thread_task_runner_handle.h"
12 #include "net/base/chunked_upload_data_stream.h"
13 #include "net/base/elements_upload_data_stream.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/test_completion_callback.h"
16 #include "net/base/upload_bytes_element_reader.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/http/transport_security_state.h"
19 #include "net/quic/congestion_control/send_algorithm_interface.h"
20 #include "net/quic/crypto/crypto_protocol.h"
21 #include "net/quic/crypto/quic_decrypter.h"
22 #include "net/quic/crypto/quic_encrypter.h"
23 #include "net/quic/crypto/quic_server_info.h"
24 #include "net/quic/quic_chromium_client_session.h"
25 #include "net/quic/quic_connection.h"
26 #include "net/quic/quic_connection_helper.h"
27 #include "net/quic/quic_default_packet_writer.h"
28 #include "net/quic/quic_http_utils.h"
29 #include "net/quic/quic_reliable_client_stream.h"
30 #include "net/quic/quic_write_blocked_list.h"
31 #include "net/quic/spdy_utils.h"
32 #include "net/quic/test_tools/mock_clock.h"
33 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
34 #include "net/quic/test_tools/mock_random.h"
35 #include "net/quic/test_tools/quic_connection_peer.h"
36 #include "net/quic/test_tools/quic_test_packet_maker.h"
37 #include "net/quic/test_tools/quic_test_utils.h"
38 #include "net/quic/test_tools/test_task_runner.h"
39 #include "net/socket/socket_test_util.h"
40 #include "net/spdy/spdy_frame_builder.h"
41 #include "net/spdy/spdy_framer.h"
42 #include "net/spdy/spdy_http_utils.h"
43 #include "net/spdy/spdy_protocol.h"
44 #include "testing/gmock/include/gmock/gmock.h"
45 #include "testing/gtest/include/gtest/gtest.h"
47 using testing::_;
48 using testing::AnyNumber;
49 using testing::Return;
51 namespace net {
52 namespace test {
53 namespace {
55 const char kUploadData[] = "Really nifty data!";
56 const char kDefaultServerHostName[] = "www.google.com";
57 const uint16 kDefaultServerPort = 80;
59 class TestQuicConnection : public QuicConnection {
60 public:
61 TestQuicConnection(const QuicVersionVector& versions,
62 QuicConnectionId connection_id,
63 IPEndPoint address,
64 QuicConnectionHelper* helper,
65 const QuicConnection::PacketWriterFactory& writer_factory)
66 : QuicConnection(connection_id,
67 address,
68 helper,
69 writer_factory,
70 true /* owns_writer */,
71 Perspective::IS_CLIENT,
72 false /* is_secure */,
73 versions) {}
75 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
76 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
80 // Subclass of QuicHttpStream that closes itself when the first piece of data
81 // is received.
82 class AutoClosingStream : public QuicHttpStream {
83 public:
84 explicit AutoClosingStream(
85 const base::WeakPtr<QuicChromiumClientSession>& session)
86 : QuicHttpStream(session) {}
88 void OnHeadersAvailable(const SpdyHeaderBlock& headers) override {
89 Close(false);
92 void OnDataAvailable() override { Close(false); }
95 class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
96 public:
97 explicit TestPacketWriterFactory(DatagramClientSocket* socket)
98 : socket_(socket) {}
99 ~TestPacketWriterFactory() override {}
101 QuicPacketWriter* Create(QuicConnection* connection) const override {
102 return new QuicDefaultPacketWriter(socket_);
105 private:
106 DatagramClientSocket* socket_;
109 } // namespace
111 class QuicHttpStreamPeer {
112 public:
113 static QuicReliableClientStream* GetQuicReliableClientStream(
114 QuicHttpStream* stream) {
115 return stream->stream_;
119 class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
120 protected:
121 static const bool kFin = true;
122 static const bool kIncludeVersion = true;
123 static const bool kIncludeCongestionFeedback = true;
125 // Holds a packet to be written to the wire, and the IO mode that should
126 // be used by the mock socket when performing the write.
127 struct PacketToWrite {
128 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
129 : mode(mode),
130 packet(packet) {
132 IoMode mode;
133 QuicEncryptedPacket* packet;
136 QuicHttpStreamTest()
137 : net_log_(BoundNetLog()),
138 use_closing_stream_(false),
139 read_buffer_(new IOBufferWithSize(4096)),
140 connection_id_(2),
141 stream_id_(kClientDataStreamId1),
142 maker_(GetParam(), connection_id_, &clock_, kDefaultServerHostName),
143 random_generator_(0) {
144 IPAddressNumber ip;
145 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
146 peer_addr_ = IPEndPoint(ip, 443);
147 self_addr_ = IPEndPoint(ip, 8435);
148 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
151 ~QuicHttpStreamTest() {
152 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
153 for (size_t i = 0; i < writes_.size(); i++) {
154 delete writes_[i].packet;
158 // Adds a packet to the list of expected writes.
159 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
160 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
163 // Returns the packet to be written at position |pos|.
164 QuicEncryptedPacket* GetWrite(size_t pos) {
165 return writes_[pos].packet;
168 bool AtEof() {
169 return socket_data_->AllReadDataConsumed() &&
170 socket_data_->AllWriteDataConsumed();
173 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
174 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
177 // Configures the test fixture to use the list of expected writes.
178 void Initialize() {
179 mock_writes_.reset(new MockWrite[writes_.size()]);
180 for (size_t i = 0; i < writes_.size(); i++) {
181 mock_writes_[i] = MockWrite(writes_[i].mode,
182 writes_[i].packet->data(),
183 writes_[i].packet->length());
186 socket_data_.reset(new StaticSocketDataProvider(
187 nullptr, 0, mock_writes_.get(), writes_.size()));
189 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
190 net_log_.net_log());
191 socket->Connect(peer_addr_);
192 runner_ = new TestTaskRunner(&clock_);
193 send_algorithm_ = new MockSendAlgorithm();
194 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
195 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
196 EXPECT_CALL(*send_algorithm_,
197 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
198 EXPECT_CALL(*send_algorithm_, RetransmissionDelay())
199 .WillRepeatedly(Return(QuicTime::Delta::Zero()));
200 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
201 .WillRepeatedly(Return(kMaxPacketSize));
202 EXPECT_CALL(*send_algorithm_, PacingRate())
203 .WillRepeatedly(Return(QuicBandwidth::Zero()));
204 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
205 .WillRepeatedly(Return(QuicTime::Delta::Zero()));
206 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
207 .WillRepeatedly(Return(QuicBandwidth::Zero()));
208 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
209 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
210 &random_generator_));
211 TestPacketWriterFactory writer_factory(socket);
212 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
213 connection_id_, peer_addr_,
214 helper_.get(), writer_factory);
215 connection_->set_visitor(&visitor_);
216 connection_->SetSendAlgorithm(send_algorithm_);
217 session_.reset(new QuicChromiumClientSession(
218 connection_, scoped_ptr<DatagramClientSocket>(socket),
219 /*stream_factory=*/nullptr, &crypto_client_stream_factory_,
220 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
221 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
222 /*is_secure=*/false, PRIVACY_MODE_DISABLED),
223 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
224 "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
225 base::ThreadTaskRunnerHandle::Get().get(), nullptr));
226 session_->Initialize();
227 session_->GetCryptoStream()->CryptoConnect();
228 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
229 stream_.reset(use_closing_stream_ ?
230 new AutoClosingStream(session_->GetWeakPtr()) :
231 new QuicHttpStream(session_->GetWeakPtr()));
234 void SetRequest(const std::string& method,
235 const std::string& path,
236 RequestPriority priority) {
237 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
240 void SetResponse(const std::string& status, const std::string& body) {
241 response_headers_ = maker_.GetResponseHeaders(status);
242 response_data_ = body;
245 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
246 QuicPacketNumber packet_number,
247 bool should_include_version,
248 bool fin,
249 QuicStreamOffset offset,
250 base::StringPiece data) {
251 return maker_.MakeDataPacket(packet_number, stream_id_,
252 should_include_version, fin, offset, data);
255 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
256 QuicPacketNumber packet_number,
257 bool fin,
258 RequestPriority request_priority) {
259 QuicPriority priority =
260 ConvertRequestPriorityToQuicPriority(request_priority);
261 return maker_.MakeRequestHeadersPacket(packet_number, stream_id_,
262 kIncludeVersion, fin, priority,
263 request_headers_);
266 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
267 QuicPacketNumber packet_number,
268 bool fin) {
269 return maker_.MakeResponseHeadersPacket(
270 packet_number, stream_id_, !kIncludeVersion, fin, response_headers_);
273 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
274 QuicPacketNumber packet_number) {
275 return maker_.MakeRstPacket(
276 packet_number, true, stream_id_,
277 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
280 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamCancelledPacket(
281 QuicPacketNumber packet_number) {
282 return maker_.MakeRstPacket(packet_number, !kIncludeVersion, stream_id_,
283 QUIC_STREAM_CANCELLED);
286 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
287 QuicPacketNumber packet_number) {
288 return maker_.MakeAckAndRstPacket(packet_number, !kIncludeVersion,
289 stream_id_, QUIC_STREAM_CANCELLED, 2, 1,
290 !kIncludeCongestionFeedback);
293 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
294 QuicPacketNumber packet_number,
295 QuicPacketNumber largest_received,
296 QuicPacketNumber least_unacked) {
297 return maker_.MakeAckPacket(packet_number, largest_received, least_unacked,
298 !kIncludeCongestionFeedback);
301 BoundNetLog net_log_;
302 bool use_closing_stream_;
303 MockSendAlgorithm* send_algorithm_;
304 scoped_refptr<TestTaskRunner> runner_;
305 scoped_ptr<MockWrite[]> mock_writes_;
306 MockClock clock_;
307 TestQuicConnection* connection_;
308 scoped_ptr<QuicConnectionHelper> helper_;
309 testing::StrictMock<MockConnectionVisitor> visitor_;
310 scoped_ptr<QuicHttpStream> stream_;
311 TransportSecurityState transport_security_state_;
312 scoped_ptr<QuicChromiumClientSession> session_;
313 QuicCryptoClientConfig crypto_config_;
314 TestCompletionCallback callback_;
315 HttpRequestInfo request_;
316 HttpRequestHeaders headers_;
317 HttpResponseInfo response_;
318 scoped_refptr<IOBufferWithSize> read_buffer_;
319 SpdyHeaderBlock request_headers_;
320 SpdyHeaderBlock response_headers_;
321 std::string request_data_;
322 std::string response_data_;
324 private:
325 const QuicConnectionId connection_id_;
326 const QuicStreamId stream_id_;
327 QuicTestPacketMaker maker_;
328 IPEndPoint self_addr_;
329 IPEndPoint peer_addr_;
330 MockRandom random_generator_;
331 MockCryptoClientStreamFactory crypto_client_stream_factory_;
332 scoped_ptr<StaticSocketDataProvider> socket_data_;
333 std::vector<PacketToWrite> writes_;
336 INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
337 ::testing::ValuesIn(QuicSupportedVersions()));
339 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
340 Initialize();
341 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
344 TEST_P(QuicHttpStreamTest, CanReuseConnection) {
345 Initialize();
346 EXPECT_FALSE(stream_->CanReuseConnection());
349 TEST_P(QuicHttpStreamTest, GetRequest) {
350 SetRequest("GET", "/", DEFAULT_PRIORITY);
351 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
352 Initialize();
354 request_.method = "GET";
355 request_.url = GURL("http://www.google.com/");
357 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
358 net_log_, callback_.callback()));
359 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
360 callback_.callback()));
362 // Ack the request.
363 ProcessPacket(ConstructAckPacket(1, 0, 0));
365 EXPECT_EQ(ERR_IO_PENDING,
366 stream_->ReadResponseHeaders(callback_.callback()));
368 SetResponse("404 Not Found", std::string());
369 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
371 // Now that the headers have been processed, the callback will return.
372 EXPECT_EQ(OK, callback_.WaitForResult());
373 ASSERT_TRUE(response_.headers.get());
374 EXPECT_EQ(404, response_.headers->response_code());
375 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
376 EXPECT_FALSE(response_.response_time.is_null());
377 EXPECT_FALSE(response_.request_time.is_null());
379 // There is no body, so this should return immediately.
380 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
381 read_buffer_->size(),
382 callback_.callback()));
383 EXPECT_TRUE(stream_->IsResponseBodyComplete());
384 EXPECT_TRUE(AtEof());
386 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
387 // payload.
388 EXPECT_EQ(0, stream_->GetTotalSentBytes());
389 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
392 // Regression test for http://crbug.com/288128
393 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
394 SetRequest("GET", "/", DEFAULT_PRIORITY);
395 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
396 Initialize();
398 request_.method = "GET";
399 request_.url = GURL("http://www.google.com/");
401 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
402 net_log_, callback_.callback()));
403 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
404 callback_.callback()));
406 // Ack the request.
407 ProcessPacket(ConstructAckPacket(1, 0, 0));
409 EXPECT_EQ(ERR_IO_PENDING,
410 stream_->ReadResponseHeaders(callback_.callback()));
412 SpdyHeaderBlock headers;
413 headers[":status"] = "200 OK";
414 headers[":version"] = "HTTP/1.1";
415 headers["content-type"] = "text/plain";
416 headers["big6"] = std::string(1000, 'x'); // Lots of x's.
418 response_headers_ = headers;
419 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
421 // Now that the headers have been processed, the callback will return.
422 EXPECT_EQ(OK, callback_.WaitForResult());
423 ASSERT_TRUE(response_.headers.get());
424 EXPECT_EQ(200, response_.headers->response_code());
425 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
427 // There is no body, so this should return immediately.
428 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
429 read_buffer_->size(),
430 callback_.callback()));
431 EXPECT_TRUE(stream_->IsResponseBodyComplete());
432 EXPECT_TRUE(AtEof());
434 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
435 // payload.
436 EXPECT_EQ(0, stream_->GetTotalSentBytes());
437 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
440 // Regression test for http://crbug.com/409101
441 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
442 SetRequest("GET", "/", DEFAULT_PRIORITY);
443 Initialize();
445 request_.method = "GET";
446 request_.url = GURL("http://www.google.com/");
448 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
449 net_log_, callback_.callback()));
451 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
453 EXPECT_EQ(ERR_CONNECTION_CLOSED,
454 stream_->SendRequest(headers_, &response_,
455 callback_.callback()));
457 EXPECT_EQ(0, stream_->GetTotalSentBytes());
458 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
461 // Regression test for http://crbug.com/409871
462 TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
463 SetRequest("GET", "/", DEFAULT_PRIORITY);
464 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
465 Initialize();
467 request_.method = "GET";
468 request_.url = GURL("http://www.google.com/");
470 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
471 net_log_, callback_.callback()));
473 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
474 callback_.callback()));
476 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
478 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
480 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
481 // payload.
482 EXPECT_EQ(0, stream_->GetTotalSentBytes());
483 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
486 TEST_P(QuicHttpStreamTest, SendPostRequest) {
487 SetRequest("POST", "/", DEFAULT_PRIORITY);
488 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
489 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
490 AddWrite(ConstructAckPacket(3, 3, 1));
492 Initialize();
494 ScopedVector<UploadElementReader> element_readers;
495 element_readers.push_back(
496 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
497 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
498 request_.method = "POST";
499 request_.url = GURL("http://www.google.com/");
500 request_.upload_data_stream = &upload_data_stream;
501 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
503 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
504 net_log_, callback_.callback()));
505 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
506 callback_.callback()));
508 // Ack both packets in the request.
509 ProcessPacket(ConstructAckPacket(1, 0, 0));
511 // Send the response headers (but not the body).
512 SetResponse("200 OK", std::string());
513 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
515 // The headers have arrived, but they are delivered asynchronously.
516 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
517 EXPECT_EQ(OK, callback_.WaitForResult());
518 ASSERT_TRUE(response_.headers.get());
519 EXPECT_EQ(200, response_.headers->response_code());
520 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
522 // Send the response body.
523 const char kResponseBody[] = "Hello world!";
524 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
525 // Since the body has already arrived, this should return immediately.
526 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
527 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
528 callback_.callback()));
530 EXPECT_TRUE(stream_->IsResponseBodyComplete());
531 EXPECT_TRUE(AtEof());
533 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
534 // payload.
535 EXPECT_EQ(static_cast<int64_t>(strlen(kUploadData)),
536 stream_->GetTotalSentBytes());
537 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)),
538 stream_->GetTotalReceivedBytes());
541 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
542 SetRequest("POST", "/", DEFAULT_PRIORITY);
543 size_t chunk_size = strlen(kUploadData);
544 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
545 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
546 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
547 kUploadData));
548 AddWrite(ConstructAckPacket(4, 3, 1));
549 Initialize();
551 ChunkedUploadDataStream upload_data_stream(0);
552 upload_data_stream.AppendData(kUploadData, chunk_size, false);
554 request_.method = "POST";
555 request_.url = GURL("http://www.google.com/");
556 request_.upload_data_stream = &upload_data_stream;
557 ASSERT_EQ(OK, request_.upload_data_stream->Init(
558 TestCompletionCallback().callback()));
560 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
561 net_log_, callback_.callback()));
562 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
563 callback_.callback()));
565 upload_data_stream.AppendData(kUploadData, chunk_size, true);
566 EXPECT_EQ(OK, callback_.WaitForResult());
568 // Ack both packets in the request.
569 ProcessPacket(ConstructAckPacket(1, 0, 0));
571 // Send the response headers (but not the body).
572 SetResponse("200 OK", std::string());
573 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
575 // The headers have arrived, but they are delivered asynchronously
576 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
577 EXPECT_EQ(OK, callback_.WaitForResult());
578 ASSERT_TRUE(response_.headers.get());
579 EXPECT_EQ(200, response_.headers->response_code());
580 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
582 // Send the response body.
583 const char kResponseBody[] = "Hello world!";
584 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
585 kResponseBody));
587 // Since the body has already arrived, this should return immediately.
588 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
589 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
590 callback_.callback()));
592 EXPECT_TRUE(stream_->IsResponseBodyComplete());
593 EXPECT_TRUE(AtEof());
595 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
596 // payload.
597 EXPECT_EQ(static_cast<int64_t>(strlen(kUploadData) * 2),
598 stream_->GetTotalSentBytes());
599 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)),
600 stream_->GetTotalReceivedBytes());
603 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
604 SetRequest("POST", "/", DEFAULT_PRIORITY);
605 size_t chunk_size = strlen(kUploadData);
606 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
607 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
608 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
609 AddWrite(ConstructAckPacket(4, 3, 1));
610 Initialize();
612 ChunkedUploadDataStream upload_data_stream(0);
613 upload_data_stream.AppendData(kUploadData, chunk_size, false);
615 request_.method = "POST";
616 request_.url = GURL("http://www.google.com/");
617 request_.upload_data_stream = &upload_data_stream;
618 ASSERT_EQ(OK, request_.upload_data_stream->Init(
619 TestCompletionCallback().callback()));
621 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
622 net_log_, callback_.callback()));
623 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
624 callback_.callback()));
626 upload_data_stream.AppendData(nullptr, 0, true);
627 EXPECT_EQ(OK, callback_.WaitForResult());
629 ProcessPacket(ConstructAckPacket(1, 0, 0));
631 // Send the response headers (but not the body).
632 SetResponse("200 OK", std::string());
633 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
635 // The headers have arrived, but they are delivered asynchronously
636 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
637 EXPECT_EQ(OK, callback_.WaitForResult());
638 ASSERT_TRUE(response_.headers.get());
639 EXPECT_EQ(200, response_.headers->response_code());
640 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
642 // Send the response body.
643 const char kResponseBody[] = "Hello world!";
644 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
645 kResponseBody));
647 // The body has arrived, but it is delivered asynchronously
648 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
649 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
650 callback_.callback()));
651 EXPECT_TRUE(stream_->IsResponseBodyComplete());
652 EXPECT_TRUE(AtEof());
654 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
655 // payload.
656 EXPECT_EQ(static_cast<int64_t>(strlen(kUploadData)),
657 stream_->GetTotalSentBytes());
658 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)),
659 stream_->GetTotalReceivedBytes());
662 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
663 SetRequest("POST", "/", DEFAULT_PRIORITY);
664 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
665 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
666 AddWrite(ConstructAckPacket(3, 3, 1));
667 Initialize();
669 ChunkedUploadDataStream upload_data_stream(0);
671 request_.method = "POST";
672 request_.url = GURL("http://www.google.com/");
673 request_.upload_data_stream = &upload_data_stream;
674 ASSERT_EQ(OK, request_.upload_data_stream->Init(
675 TestCompletionCallback().callback()));
677 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
678 net_log_, callback_.callback()));
679 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
680 callback_.callback()));
682 upload_data_stream.AppendData(nullptr, 0, true);
683 EXPECT_EQ(OK, callback_.WaitForResult());
685 ProcessPacket(ConstructAckPacket(1, 0, 0));
687 // Send the response headers (but not the body).
688 SetResponse("200 OK", std::string());
689 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
691 // The headers have arrived, but they are delivered asynchronously
692 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
693 EXPECT_EQ(OK, callback_.WaitForResult());
694 ASSERT_TRUE(response_.headers.get());
695 EXPECT_EQ(200, response_.headers->response_code());
696 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
698 // Send the response body.
699 const char kResponseBody[] = "Hello world!";
700 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
701 kResponseBody));
703 // The body has arrived, but it is delivered asynchronously
704 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
705 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
706 callback_.callback()));
708 EXPECT_TRUE(stream_->IsResponseBodyComplete());
709 EXPECT_TRUE(AtEof());
711 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
712 // payload.
713 EXPECT_EQ(0, stream_->GetTotalSentBytes());
714 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)),
715 stream_->GetTotalReceivedBytes());
718 TEST_P(QuicHttpStreamTest, DestroyedEarly) {
719 SetRequest("GET", "/", DEFAULT_PRIORITY);
720 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
721 AddWrite(ConstructAckAndRstStreamPacket(2));
722 use_closing_stream_ = true;
723 Initialize();
725 request_.method = "GET";
726 request_.url = GURL("http://www.google.com/");
728 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
729 net_log_, callback_.callback()));
730 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
731 callback_.callback()));
733 // Ack the request.
734 ProcessPacket(ConstructAckPacket(1, 0, 0));
735 EXPECT_EQ(ERR_IO_PENDING,
736 stream_->ReadResponseHeaders(callback_.callback()));
738 // Send the response with a body.
739 SetResponse("404 OK", "hello world!");
740 // In the course of processing this packet, the QuicHttpStream close itself.
741 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
743 base::MessageLoop::current()->RunUntilIdle();
745 EXPECT_TRUE(AtEof());
747 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
748 // payload.
749 EXPECT_EQ(0, stream_->GetTotalSentBytes());
750 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
753 TEST_P(QuicHttpStreamTest, Priority) {
754 SetRequest("GET", "/", MEDIUM);
755 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM));
756 AddWrite(ConstructAckAndRstStreamPacket(2));
757 use_closing_stream_ = true;
758 Initialize();
760 request_.method = "GET";
761 request_.url = GURL("http://www.google.com/");
763 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
764 net_log_, callback_.callback()));
766 // Check that priority is highest.
767 QuicReliableClientStream* reliable_stream =
768 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
769 DCHECK(reliable_stream);
770 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
771 reliable_stream->EffectivePriority());
773 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
774 callback_.callback()));
776 // Check that priority has now dropped back to MEDIUM.
777 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
778 reliable_stream->EffectivePriority()));
780 // Ack the request.
781 ProcessPacket(ConstructAckPacket(1, 0, 0));
782 EXPECT_EQ(ERR_IO_PENDING,
783 stream_->ReadResponseHeaders(callback_.callback()));
785 // Send the response with a body.
786 SetResponse("404 OK", "hello world!");
787 // In the course of processing this packet, the QuicHttpStream close itself.
788 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
790 base::MessageLoop::current()->RunUntilIdle();
792 EXPECT_TRUE(AtEof());
794 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
795 // payload.
796 EXPECT_EQ(0, stream_->GetTotalSentBytes());
797 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
800 // Regression test for http://crbug.com/294870
801 TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
802 SetRequest("GET", "/", MEDIUM);
803 use_closing_stream_ = true;
805 AddWrite(ConstructRstStreamPacket(1));
807 Initialize();
809 request_.method = "GET";
810 request_.url = GURL("http://www.google.com/");
812 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
813 net_log_, callback_.callback()));
815 // Check that priority is highest.
816 QuicReliableClientStream* reliable_stream =
817 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
818 DCHECK(reliable_stream);
819 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
820 DCHECK(delegate);
821 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
822 reliable_stream->EffectivePriority());
824 // Set Delegate to nullptr and make sure EffectivePriority returns highest
825 // priority.
826 reliable_stream->SetDelegate(nullptr);
827 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
828 reliable_stream->EffectivePriority());
829 reliable_stream->SetDelegate(delegate);
831 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
832 // payload.
833 EXPECT_EQ(0, stream_->GetTotalSentBytes());
834 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
837 } // namespace test
838 } // namespace net