Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / net / quic / quic_http_stream_test.cc
blob84d1bf458084f69f05c55139de6c1a3b8ac09746
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_flags.h"
29 #include "net/quic/quic_http_utils.h"
30 #include "net/quic/quic_reliable_client_stream.h"
31 #include "net/quic/quic_write_blocked_list.h"
32 #include "net/quic/spdy_utils.h"
33 #include "net/quic/test_tools/mock_clock.h"
34 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
35 #include "net/quic/test_tools/mock_random.h"
36 #include "net/quic/test_tools/quic_connection_peer.h"
37 #include "net/quic/test_tools/quic_test_packet_maker.h"
38 #include "net/quic/test_tools/quic_test_utils.h"
39 #include "net/quic/test_tools/test_task_runner.h"
40 #include "net/socket/socket_test_util.h"
41 #include "net/spdy/spdy_frame_builder.h"
42 #include "net/spdy/spdy_framer.h"
43 #include "net/spdy/spdy_http_utils.h"
44 #include "net/spdy/spdy_protocol.h"
45 #include "testing/gmock/include/gmock/gmock.h"
46 #include "testing/gtest/include/gtest/gtest.h"
48 using testing::_;
49 using testing::AnyNumber;
50 using testing::Return;
52 namespace net {
53 namespace test {
54 namespace {
56 const char kUploadData[] = "Really nifty data!";
57 const char kDefaultServerHostName[] = "www.google.com";
58 const uint16 kDefaultServerPort = 80;
60 class TestQuicConnection : public QuicConnection {
61 public:
62 TestQuicConnection(const QuicVersionVector& versions,
63 QuicConnectionId connection_id,
64 IPEndPoint address,
65 QuicConnectionHelper* helper,
66 const QuicConnection::PacketWriterFactory& writer_factory)
67 : QuicConnection(connection_id,
68 address,
69 helper,
70 writer_factory,
71 true /* owns_writer */,
72 Perspective::IS_CLIENT,
73 false /* is_secure */,
74 versions) {}
76 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
77 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
81 // Subclass of QuicHttpStream that closes itself when the first piece of data
82 // is received.
83 class AutoClosingStream : public QuicHttpStream {
84 public:
85 explicit AutoClosingStream(
86 const base::WeakPtr<QuicChromiumClientSession>& session)
87 : QuicHttpStream(session) {}
89 void OnHeadersAvailable(const SpdyHeaderBlock& headers) override {
90 Close(false);
93 void OnDataAvailable() override { Close(false); }
96 class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
97 public:
98 explicit TestPacketWriterFactory(DatagramClientSocket* socket)
99 : socket_(socket) {}
100 ~TestPacketWriterFactory() override {}
102 QuicPacketWriter* Create(QuicConnection* connection) const override {
103 return new QuicDefaultPacketWriter(socket_);
106 private:
107 DatagramClientSocket* socket_;
110 } // namespace
112 class QuicHttpStreamPeer {
113 public:
114 static QuicReliableClientStream* GetQuicReliableClientStream(
115 QuicHttpStream* stream) {
116 return stream->stream_;
120 class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
121 protected:
122 static const bool kFin = true;
123 static const bool kIncludeVersion = true;
124 static const bool kIncludeCongestionFeedback = true;
126 // Holds a packet to be written to the wire, and the IO mode that should
127 // be used by the mock socket when performing the write.
128 struct PacketToWrite {
129 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
130 : mode(mode),
131 packet(packet) {
133 IoMode mode;
134 QuicEncryptedPacket* packet;
137 QuicHttpStreamTest()
138 : net_log_(BoundNetLog()),
139 use_closing_stream_(false),
140 read_buffer_(new IOBufferWithSize(4096)),
141 connection_id_(2),
142 stream_id_(kClientDataStreamId1),
143 maker_(GetParam(), connection_id_, &clock_, kDefaultServerHostName),
144 random_generator_(0) {
145 IPAddressNumber ip;
146 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
147 peer_addr_ = IPEndPoint(ip, 443);
148 self_addr_ = IPEndPoint(ip, 8435);
149 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
152 ~QuicHttpStreamTest() {
153 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
154 for (size_t i = 0; i < writes_.size(); i++) {
155 delete writes_[i].packet;
159 // Adds a packet to the list of expected writes.
160 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
161 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
164 // Returns the packet to be written at position |pos|.
165 QuicEncryptedPacket* GetWrite(size_t pos) {
166 return writes_[pos].packet;
169 bool AtEof() {
170 return socket_data_->AllReadDataConsumed() &&
171 socket_data_->AllWriteDataConsumed();
174 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
175 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
178 // Configures the test fixture to use the list of expected writes.
179 void Initialize() {
180 mock_writes_.reset(new MockWrite[writes_.size()]);
181 for (size_t i = 0; i < writes_.size(); i++) {
182 mock_writes_[i] = MockWrite(writes_[i].mode,
183 writes_[i].packet->data(),
184 writes_[i].packet->length());
187 socket_data_.reset(new StaticSocketDataProvider(
188 nullptr, 0, mock_writes_.get(), writes_.size()));
190 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
191 net_log_.net_log());
192 socket->Connect(peer_addr_);
193 runner_ = new TestTaskRunner(&clock_);
194 send_algorithm_ = new MockSendAlgorithm();
195 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
196 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
197 EXPECT_CALL(*send_algorithm_,
198 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
199 EXPECT_CALL(*send_algorithm_, RetransmissionDelay())
200 .WillRepeatedly(Return(QuicTime::Delta::Zero()));
201 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
202 .WillRepeatedly(Return(kMaxPacketSize));
203 EXPECT_CALL(*send_algorithm_, PacingRate())
204 .WillRepeatedly(Return(QuicBandwidth::Zero()));
205 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
206 .WillRepeatedly(Return(QuicTime::Delta::Zero()));
207 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
208 .WillRepeatedly(Return(QuicBandwidth::Zero()));
209 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
210 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
211 &random_generator_));
212 TestPacketWriterFactory writer_factory(socket);
213 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
214 connection_id_, peer_addr_,
215 helper_.get(), writer_factory);
216 connection_->set_visitor(&visitor_);
217 connection_->SetSendAlgorithm(send_algorithm_);
218 session_.reset(new QuicChromiumClientSession(
219 connection_, scoped_ptr<DatagramClientSocket>(socket),
220 /*stream_factory=*/nullptr, &crypto_client_stream_factory_,
221 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
222 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
223 /*is_secure=*/false, PRIVACY_MODE_DISABLED),
224 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
225 "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
226 base::ThreadTaskRunnerHandle::Get().get(), nullptr));
227 session_->Initialize();
228 session_->GetCryptoStream()->CryptoConnect();
229 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
230 stream_.reset(use_closing_stream_ ?
231 new AutoClosingStream(session_->GetWeakPtr()) :
232 new QuicHttpStream(session_->GetWeakPtr()));
235 void SetRequest(const std::string& method,
236 const std::string& path,
237 RequestPriority priority) {
238 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
241 void SetResponse(const std::string& status, const std::string& body) {
242 response_headers_ = maker_.GetResponseHeaders(status);
243 response_data_ = body;
246 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
247 QuicPacketNumber packet_number,
248 bool should_include_version,
249 bool fin,
250 QuicStreamOffset offset,
251 base::StringPiece data) {
252 return maker_.MakeDataPacket(packet_number, stream_id_,
253 should_include_version, fin, offset, data);
256 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
257 QuicPacketNumber packet_number,
258 bool fin,
259 RequestPriority request_priority) {
260 QuicPriority priority =
261 ConvertRequestPriorityToQuicPriority(request_priority);
262 return maker_.MakeRequestHeadersPacket(packet_number, stream_id_,
263 kIncludeVersion, fin, priority,
264 request_headers_);
267 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
268 QuicPacketNumber packet_number,
269 bool fin) {
270 return maker_.MakeResponseHeadersPacket(
271 packet_number, stream_id_, !kIncludeVersion, fin, response_headers_);
274 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
275 QuicPacketNumber packet_number) {
276 return maker_.MakeRstPacket(
277 packet_number, true, stream_id_,
278 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
281 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamCancelledPacket(
282 QuicPacketNumber packet_number) {
283 return maker_.MakeRstPacket(packet_number, !kIncludeVersion, stream_id_,
284 QUIC_STREAM_CANCELLED);
287 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
288 QuicPacketNumber packet_number) {
289 return maker_.MakeAckAndRstPacket(packet_number, !kIncludeVersion,
290 stream_id_, QUIC_STREAM_CANCELLED, 2, 1,
291 !kIncludeCongestionFeedback);
294 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
295 QuicPacketNumber packet_number,
296 QuicPacketNumber largest_received,
297 QuicPacketNumber least_unacked) {
298 return maker_.MakeAckPacket(packet_number, largest_received, least_unacked,
299 !kIncludeCongestionFeedback);
302 BoundNetLog net_log_;
303 bool use_closing_stream_;
304 MockSendAlgorithm* send_algorithm_;
305 scoped_refptr<TestTaskRunner> runner_;
306 scoped_ptr<MockWrite[]> mock_writes_;
307 MockClock clock_;
308 TestQuicConnection* connection_;
309 scoped_ptr<QuicConnectionHelper> helper_;
310 testing::StrictMock<MockConnectionVisitor> visitor_;
311 scoped_ptr<QuicHttpStream> stream_;
312 TransportSecurityState transport_security_state_;
313 scoped_ptr<QuicChromiumClientSession> session_;
314 QuicCryptoClientConfig crypto_config_;
315 TestCompletionCallback callback_;
316 HttpRequestInfo request_;
317 HttpRequestHeaders headers_;
318 HttpResponseInfo response_;
319 scoped_refptr<IOBufferWithSize> read_buffer_;
320 SpdyHeaderBlock request_headers_;
321 SpdyHeaderBlock response_headers_;
322 std::string request_data_;
323 std::string response_data_;
325 private:
326 const QuicConnectionId connection_id_;
327 const QuicStreamId stream_id_;
328 QuicTestPacketMaker maker_;
329 IPEndPoint self_addr_;
330 IPEndPoint peer_addr_;
331 MockRandom random_generator_;
332 MockCryptoClientStreamFactory crypto_client_stream_factory_;
333 scoped_ptr<StaticSocketDataProvider> socket_data_;
334 std::vector<PacketToWrite> writes_;
337 INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
338 ::testing::ValuesIn(QuicSupportedVersions()));
340 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
341 Initialize();
342 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
345 TEST_P(QuicHttpStreamTest, CanReuseConnection) {
346 Initialize();
347 EXPECT_FALSE(stream_->CanReuseConnection());
350 TEST_P(QuicHttpStreamTest, GetRequest) {
351 SetRequest("GET", "/", DEFAULT_PRIORITY);
352 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
353 Initialize();
355 request_.method = "GET";
356 request_.url = GURL("http://www.google.com/");
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()));
363 // Ack the request.
364 ProcessPacket(ConstructAckPacket(1, 0, 0));
366 EXPECT_EQ(ERR_IO_PENDING,
367 stream_->ReadResponseHeaders(callback_.callback()));
369 SetResponse("404 Not Found", std::string());
370 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
372 // Now that the headers have been processed, the callback will return.
373 EXPECT_EQ(OK, callback_.WaitForResult());
374 ASSERT_TRUE(response_.headers.get());
375 EXPECT_EQ(404, response_.headers->response_code());
376 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
377 EXPECT_FALSE(response_.response_time.is_null());
378 EXPECT_FALSE(response_.request_time.is_null());
380 // There is no body, so this should return immediately.
381 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
382 read_buffer_->size(),
383 callback_.callback()));
384 EXPECT_TRUE(stream_->IsResponseBodyComplete());
385 EXPECT_TRUE(AtEof());
387 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
388 // payload.
389 EXPECT_EQ(0, stream_->GetTotalSentBytes());
390 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
393 // Regression test for http://crbug.com/288128
394 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
395 SetRequest("GET", "/", DEFAULT_PRIORITY);
396 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
397 Initialize();
399 request_.method = "GET";
400 request_.url = GURL("http://www.google.com/");
402 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
403 net_log_, callback_.callback()));
404 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
405 callback_.callback()));
407 // Ack the request.
408 ProcessPacket(ConstructAckPacket(1, 0, 0));
410 EXPECT_EQ(ERR_IO_PENDING,
411 stream_->ReadResponseHeaders(callback_.callback()));
413 SpdyHeaderBlock headers;
414 headers[":status"] = "200 OK";
415 headers[":version"] = "HTTP/1.1";
416 headers["content-type"] = "text/plain";
417 headers["big6"] = std::string(1000, 'x'); // Lots of x's.
419 response_headers_ = headers;
420 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
422 // Now that the headers have been processed, the callback will return.
423 EXPECT_EQ(OK, callback_.WaitForResult());
424 ASSERT_TRUE(response_.headers.get());
425 EXPECT_EQ(200, response_.headers->response_code());
426 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
428 // There is no body, so this should return immediately.
429 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
430 read_buffer_->size(),
431 callback_.callback()));
432 EXPECT_TRUE(stream_->IsResponseBodyComplete());
433 EXPECT_TRUE(AtEof());
435 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
436 // payload.
437 EXPECT_EQ(0, stream_->GetTotalSentBytes());
438 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
441 // Regression test for http://crbug.com/409101
442 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
443 SetRequest("GET", "/", DEFAULT_PRIORITY);
444 Initialize();
446 request_.method = "GET";
447 request_.url = GURL("http://www.google.com/");
449 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
450 net_log_, callback_.callback()));
452 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
454 EXPECT_EQ(ERR_CONNECTION_CLOSED,
455 stream_->SendRequest(headers_, &response_,
456 callback_.callback()));
458 EXPECT_EQ(0, stream_->GetTotalSentBytes());
459 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
462 // Regression test for http://crbug.com/409871
463 TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
464 SetRequest("GET", "/", DEFAULT_PRIORITY);
465 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
466 Initialize();
468 request_.method = "GET";
469 request_.url = GURL("http://www.google.com/");
471 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
472 net_log_, callback_.callback()));
474 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
475 callback_.callback()));
477 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
479 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
481 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
482 // payload.
483 EXPECT_EQ(0, stream_->GetTotalSentBytes());
484 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
487 TEST_P(QuicHttpStreamTest, SendPostRequest) {
488 SetRequest("POST", "/", DEFAULT_PRIORITY);
489 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
490 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
491 AddWrite(ConstructAckPacket(3, 3, 1));
493 Initialize();
495 ScopedVector<UploadElementReader> element_readers;
496 element_readers.push_back(
497 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
498 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
499 request_.method = "POST";
500 request_.url = GURL("http://www.google.com/");
501 request_.upload_data_stream = &upload_data_stream;
502 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
504 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
505 net_log_, callback_.callback()));
506 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
507 callback_.callback()));
509 // Ack both packets in the request.
510 ProcessPacket(ConstructAckPacket(1, 0, 0));
512 // Send the response headers (but not the body).
513 SetResponse("200 OK", std::string());
514 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
516 // The headers have arrived, but they are delivered asynchronously.
517 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
518 EXPECT_EQ(OK, callback_.WaitForResult());
519 ASSERT_TRUE(response_.headers.get());
520 EXPECT_EQ(200, response_.headers->response_code());
521 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
523 // Send the response body.
524 const char kResponseBody[] = "Hello world!";
525 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
526 // Since the body has already arrived, this should return immediately.
527 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
528 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
529 callback_.callback()));
531 EXPECT_TRUE(stream_->IsResponseBodyComplete());
532 EXPECT_TRUE(AtEof());
534 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
535 // payload.
536 EXPECT_EQ(static_cast<int64_t>(strlen(kUploadData)),
537 stream_->GetTotalSentBytes());
538 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)),
539 stream_->GetTotalReceivedBytes());
542 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
543 SetRequest("POST", "/", DEFAULT_PRIORITY);
544 size_t chunk_size = strlen(kUploadData);
545 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
546 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
547 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
548 kUploadData));
549 AddWrite(ConstructAckPacket(4, 3, 1));
550 Initialize();
552 ChunkedUploadDataStream upload_data_stream(0);
553 upload_data_stream.AppendData(kUploadData, chunk_size, false);
555 request_.method = "POST";
556 request_.url = GURL("http://www.google.com/");
557 request_.upload_data_stream = &upload_data_stream;
558 ASSERT_EQ(OK, request_.upload_data_stream->Init(
559 TestCompletionCallback().callback()));
561 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
562 net_log_, callback_.callback()));
563 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
564 callback_.callback()));
566 upload_data_stream.AppendData(kUploadData, chunk_size, true);
567 EXPECT_EQ(OK, callback_.WaitForResult());
569 // Ack both packets in the request.
570 ProcessPacket(ConstructAckPacket(1, 0, 0));
572 // Send the response headers (but not the body).
573 SetResponse("200 OK", std::string());
574 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
576 // The headers have arrived, but they are delivered asynchronously
577 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
578 EXPECT_EQ(OK, callback_.WaitForResult());
579 ASSERT_TRUE(response_.headers.get());
580 EXPECT_EQ(200, response_.headers->response_code());
581 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
583 // Send the response body.
584 const char kResponseBody[] = "Hello world!";
585 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
586 kResponseBody));
588 // Since the body has already arrived, this should return immediately.
589 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
590 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
591 callback_.callback()));
593 EXPECT_TRUE(stream_->IsResponseBodyComplete());
594 EXPECT_TRUE(AtEof());
596 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
597 // payload.
598 EXPECT_EQ(static_cast<int64_t>(strlen(kUploadData) * 2),
599 stream_->GetTotalSentBytes());
600 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)),
601 stream_->GetTotalReceivedBytes());
604 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
605 SetRequest("POST", "/", DEFAULT_PRIORITY);
606 size_t chunk_size = strlen(kUploadData);
607 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
608 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
609 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
610 AddWrite(ConstructAckPacket(4, 3, 1));
611 Initialize();
613 ChunkedUploadDataStream upload_data_stream(0);
614 upload_data_stream.AppendData(kUploadData, chunk_size, false);
616 request_.method = "POST";
617 request_.url = GURL("http://www.google.com/");
618 request_.upload_data_stream = &upload_data_stream;
619 ASSERT_EQ(OK, request_.upload_data_stream->Init(
620 TestCompletionCallback().callback()));
622 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
623 net_log_, callback_.callback()));
624 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
625 callback_.callback()));
627 upload_data_stream.AppendData(nullptr, 0, true);
628 EXPECT_EQ(OK, callback_.WaitForResult());
630 ProcessPacket(ConstructAckPacket(1, 0, 0));
632 // Send the response headers (but not the body).
633 SetResponse("200 OK", std::string());
634 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
636 // The headers have arrived, but they are delivered asynchronously
637 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
638 EXPECT_EQ(OK, callback_.WaitForResult());
639 ASSERT_TRUE(response_.headers.get());
640 EXPECT_EQ(200, response_.headers->response_code());
641 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
643 // Send the response body.
644 const char kResponseBody[] = "Hello world!";
645 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
646 kResponseBody));
648 // The body has arrived, but it is delivered asynchronously
649 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
650 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
651 callback_.callback()));
652 EXPECT_TRUE(stream_->IsResponseBodyComplete());
653 EXPECT_TRUE(AtEof());
655 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
656 // payload.
657 EXPECT_EQ(static_cast<int64_t>(strlen(kUploadData)),
658 stream_->GetTotalSentBytes());
659 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)),
660 stream_->GetTotalReceivedBytes());
663 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
664 SetRequest("POST", "/", DEFAULT_PRIORITY);
665 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
666 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
667 AddWrite(ConstructAckPacket(3, 3, 1));
668 Initialize();
670 ChunkedUploadDataStream upload_data_stream(0);
672 request_.method = "POST";
673 request_.url = GURL("http://www.google.com/");
674 request_.upload_data_stream = &upload_data_stream;
675 ASSERT_EQ(OK, request_.upload_data_stream->Init(
676 TestCompletionCallback().callback()));
678 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
679 net_log_, callback_.callback()));
680 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
681 callback_.callback()));
683 upload_data_stream.AppendData(nullptr, 0, true);
684 EXPECT_EQ(OK, callback_.WaitForResult());
686 ProcessPacket(ConstructAckPacket(1, 0, 0));
688 // Send the response headers (but not the body).
689 SetResponse("200 OK", std::string());
690 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
692 // The headers have arrived, but they are delivered asynchronously
693 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
694 EXPECT_EQ(OK, callback_.WaitForResult());
695 ASSERT_TRUE(response_.headers.get());
696 EXPECT_EQ(200, response_.headers->response_code());
697 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
699 // Send the response body.
700 const char kResponseBody[] = "Hello world!";
701 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
702 kResponseBody));
704 // The body has arrived, but it is delivered asynchronously
705 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
706 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
707 callback_.callback()));
709 EXPECT_TRUE(stream_->IsResponseBodyComplete());
710 EXPECT_TRUE(AtEof());
712 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
713 // payload.
714 EXPECT_EQ(0, stream_->GetTotalSentBytes());
715 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)),
716 stream_->GetTotalReceivedBytes());
719 TEST_P(QuicHttpStreamTest, DestroyedEarly) {
720 SetRequest("GET", "/", DEFAULT_PRIORITY);
721 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
722 if (!FLAGS_quic_process_frames_inline) {
723 AddWrite(ConstructRstStreamCancelledPacket(2));
724 } else {
725 AddWrite(ConstructAckAndRstStreamPacket(2));
727 use_closing_stream_ = true;
728 Initialize();
730 request_.method = "GET";
731 request_.url = GURL("http://www.google.com/");
733 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
734 net_log_, callback_.callback()));
735 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
736 callback_.callback()));
738 // Ack the request.
739 ProcessPacket(ConstructAckPacket(1, 0, 0));
740 EXPECT_EQ(ERR_IO_PENDING,
741 stream_->ReadResponseHeaders(callback_.callback()));
743 // Send the response with a body.
744 SetResponse("404 OK", "hello world!");
745 // In the course of processing this packet, the QuicHttpStream close itself.
746 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
748 base::MessageLoop::current()->RunUntilIdle();
750 EXPECT_TRUE(AtEof());
752 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
753 // payload.
754 EXPECT_EQ(0, stream_->GetTotalSentBytes());
755 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
758 TEST_P(QuicHttpStreamTest, Priority) {
759 SetRequest("GET", "/", MEDIUM);
760 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM));
761 if (!FLAGS_quic_process_frames_inline) {
762 AddWrite(ConstructRstStreamCancelledPacket(2));
763 } else {
764 AddWrite(ConstructAckAndRstStreamPacket(2));
766 use_closing_stream_ = true;
767 Initialize();
769 request_.method = "GET";
770 request_.url = GURL("http://www.google.com/");
772 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
773 net_log_, callback_.callback()));
775 // Check that priority is highest.
776 QuicReliableClientStream* reliable_stream =
777 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
778 DCHECK(reliable_stream);
779 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
780 reliable_stream->EffectivePriority());
782 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
783 callback_.callback()));
785 // Check that priority has now dropped back to MEDIUM.
786 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
787 reliable_stream->EffectivePriority()));
789 // Ack the request.
790 ProcessPacket(ConstructAckPacket(1, 0, 0));
791 EXPECT_EQ(ERR_IO_PENDING,
792 stream_->ReadResponseHeaders(callback_.callback()));
794 // Send the response with a body.
795 SetResponse("404 OK", "hello world!");
796 // In the course of processing this packet, the QuicHttpStream close itself.
797 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
799 base::MessageLoop::current()->RunUntilIdle();
801 EXPECT_TRUE(AtEof());
803 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
804 // payload.
805 EXPECT_EQ(0, stream_->GetTotalSentBytes());
806 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
809 // Regression test for http://crbug.com/294870
810 TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
811 SetRequest("GET", "/", MEDIUM);
812 use_closing_stream_ = true;
814 AddWrite(ConstructRstStreamPacket(1));
816 Initialize();
818 request_.method = "GET";
819 request_.url = GURL("http://www.google.com/");
821 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
822 net_log_, callback_.callback()));
824 // Check that priority is highest.
825 QuicReliableClientStream* reliable_stream =
826 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
827 DCHECK(reliable_stream);
828 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
829 DCHECK(delegate);
830 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
831 reliable_stream->EffectivePriority());
833 // Set Delegate to nullptr and make sure EffectivePriority returns highest
834 // priority.
835 reliable_stream->SetDelegate(nullptr);
836 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
837 reliable_stream->EffectivePriority());
838 reliable_stream->SetDelegate(delegate);
840 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
841 // payload.
842 EXPECT_EQ(0, stream_->GetTotalSentBytes());
843 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
846 } // namespace test
847 } // namespace net