Compute if a layer is clipped outside CalcDrawProps
[chromium-blink-merge.git] / net / quic / quic_http_stream_test.cc
blob412bd23ef2aabe08547d759d416fdfaa2cc29dbd
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 <vector>
9 #include "base/thread_task_runner_handle.h"
10 #include "net/base/chunked_upload_data_stream.h"
11 #include "net/base/elements_upload_data_stream.h"
12 #include "net/base/net_errors.h"
13 #include "net/base/test_completion_callback.h"
14 #include "net/base/upload_bytes_element_reader.h"
15 #include "net/http/http_response_headers.h"
16 #include "net/http/transport_security_state.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"
45 using testing::_;
46 using testing::AnyNumber;
47 using testing::Return;
49 namespace net {
50 namespace test {
51 namespace {
53 const char kUploadData[] = "Really nifty data!";
54 const char kDefaultServerHostName[] = "www.google.com";
55 const uint16 kDefaultServerPort = 80;
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 Perspective::IS_CLIENT,
70 false /* is_secure */,
71 versions) {}
73 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
74 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
78 // Subclass of QuicHttpStream that closes itself when the first piece of data
79 // is received.
80 class AutoClosingStream : public QuicHttpStream {
81 public:
82 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session)
83 : QuicHttpStream(session) {
86 void OnHeadersAvailable(StringPiece headers) override { Close(false); }
88 int OnDataReceived(const char* data, int length) override {
89 Close(false);
90 return OK;
94 class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
95 public:
96 explicit TestPacketWriterFactory(DatagramClientSocket* socket)
97 : socket_(socket) {}
98 ~TestPacketWriterFactory() override {}
100 QuicPacketWriter* Create(QuicConnection* connection) const override {
101 return new QuicDefaultPacketWriter(socket_);
104 private:
105 DatagramClientSocket* socket_;
108 } // namespace
110 class QuicHttpStreamPeer {
111 public:
112 static QuicReliableClientStream* GetQuicReliableClientStream(
113 QuicHttpStream* stream) {
114 return stream->stream_;
118 class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
119 protected:
120 static const bool kFin = true;
121 static const bool kIncludeVersion = true;
122 static const bool kIncludeCongestionFeedback = true;
124 // Holds a packet to be written to the wire, and the IO mode that should
125 // be used by the mock socket when performing the write.
126 struct PacketToWrite {
127 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
128 : mode(mode),
129 packet(packet) {
131 IoMode mode;
132 QuicEncryptedPacket* packet;
135 QuicHttpStreamTest()
136 : net_log_(BoundNetLog()),
137 use_closing_stream_(false),
138 read_buffer_(new IOBufferWithSize(4096)),
139 connection_id_(2),
140 stream_id_(kClientDataStreamId1),
141 maker_(GetParam(), connection_id_, &clock_, kDefaultServerHostName),
142 random_generator_(0) {
143 IPAddressNumber ip;
144 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
145 peer_addr_ = IPEndPoint(ip, 443);
146 self_addr_ = IPEndPoint(ip, 8435);
147 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
150 ~QuicHttpStreamTest() {
151 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
152 for (size_t i = 0; i < writes_.size(); i++) {
153 delete writes_[i].packet;
157 // Adds a packet to the list of expected writes.
158 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
159 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
162 // Returns the packet to be written at position |pos|.
163 QuicEncryptedPacket* GetWrite(size_t pos) {
164 return writes_[pos].packet;
167 bool AtEof() {
168 return socket_data_->AllReadDataConsumed() &&
169 socket_data_->AllWriteDataConsumed();
172 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
173 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
176 // Configures the test fixture to use the list of expected writes.
177 void Initialize() {
178 mock_writes_.reset(new MockWrite[writes_.size()]);
179 for (size_t i = 0; i < writes_.size(); i++) {
180 mock_writes_[i] = MockWrite(writes_[i].mode,
181 writes_[i].packet->data(),
182 writes_[i].packet->length());
185 socket_data_.reset(new StaticSocketDataProvider(
186 nullptr, 0, mock_writes_.get(), writes_.size()));
188 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
189 net_log_.net_log());
190 socket->Connect(peer_addr_);
191 runner_ = new TestTaskRunner(&clock_);
192 send_algorithm_ = new MockSendAlgorithm();
193 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
194 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
195 EXPECT_CALL(*send_algorithm_,
196 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
197 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
198 Return(QuicTime::Delta::Zero()));
199 EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
200 Return(kMaxPacketSize));
201 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).
202 WillRepeatedly(Return(QuicTime::Delta::Zero()));
203 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
204 Return(QuicBandwidth::Zero()));
205 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
206 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
207 &random_generator_));
208 TestPacketWriterFactory writer_factory(socket);
209 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
210 connection_id_, peer_addr_,
211 helper_.get(), writer_factory);
212 connection_->set_visitor(&visitor_);
213 connection_->SetSendAlgorithm(send_algorithm_);
214 session_.reset(new QuicClientSession(
215 connection_, scoped_ptr<DatagramClientSocket>(socket),
216 /*stream_factory=*/nullptr, &crypto_client_stream_factory_,
217 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
218 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
219 /*is_secure=*/false, PRIVACY_MODE_DISABLED),
220 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
221 "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
222 base::ThreadTaskRunnerHandle::Get().get(), nullptr));
223 session_->Initialize();
224 session_->GetCryptoStream()->CryptoConnect();
225 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
226 stream_.reset(use_closing_stream_ ?
227 new AutoClosingStream(session_->GetWeakPtr()) :
228 new QuicHttpStream(session_->GetWeakPtr()));
231 void SetRequest(const std::string& method,
232 const std::string& path,
233 RequestPriority priority) {
234 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
237 void SetResponse(const std::string& status, const std::string& body) {
238 response_headers_ = maker_.GetResponseHeaders(status);
239 response_data_ = body;
242 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
243 QuicPacketSequenceNumber sequence_number,
244 bool should_include_version,
245 bool fin,
246 QuicStreamOffset offset,
247 base::StringPiece data) {
248 return maker_.MakeDataPacket(sequence_number, stream_id_,
249 should_include_version, fin, offset, data);
252 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
253 QuicPacketSequenceNumber sequence_number,
254 bool fin,
255 RequestPriority request_priority) {
256 QuicPriority priority =
257 ConvertRequestPriorityToQuicPriority(request_priority);
258 return maker_.MakeRequestHeadersPacket(sequence_number, stream_id_,
259 kIncludeVersion, fin, priority,
260 request_headers_);
263 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
264 QuicPacketSequenceNumber sequence_number,
265 bool fin) {
266 return maker_.MakeResponseHeadersPacket(
267 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_);
270 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
271 QuicPacketSequenceNumber sequence_number) {
272 return maker_.MakeRstPacket(
273 sequence_number, true, stream_id_,
274 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
277 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
278 QuicPacketSequenceNumber sequence_number) {
279 return maker_.MakeAckAndRstPacket(
280 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
281 2, 1, !kIncludeCongestionFeedback);
284 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
285 QuicPacketSequenceNumber sequence_number,
286 QuicPacketSequenceNumber largest_received,
287 QuicPacketSequenceNumber least_unacked) {
288 return maker_.MakeAckPacket(sequence_number, largest_received,
289 least_unacked, !kIncludeCongestionFeedback);
292 BoundNetLog net_log_;
293 bool use_closing_stream_;
294 MockSendAlgorithm* send_algorithm_;
295 scoped_refptr<TestTaskRunner> runner_;
296 scoped_ptr<MockWrite[]> mock_writes_;
297 MockClock clock_;
298 TestQuicConnection* connection_;
299 scoped_ptr<QuicConnectionHelper> helper_;
300 testing::StrictMock<MockConnectionVisitor> visitor_;
301 scoped_ptr<QuicHttpStream> stream_;
302 TransportSecurityState transport_security_state_;
303 scoped_ptr<QuicClientSession> session_;
304 QuicCryptoClientConfig crypto_config_;
305 TestCompletionCallback callback_;
306 HttpRequestInfo request_;
307 HttpRequestHeaders headers_;
308 HttpResponseInfo response_;
309 scoped_refptr<IOBufferWithSize> read_buffer_;
310 SpdyHeaderBlock request_headers_;
311 SpdyHeaderBlock response_headers_;
312 std::string request_data_;
313 std::string response_data_;
315 private:
316 const QuicConnectionId connection_id_;
317 const QuicStreamId stream_id_;
318 QuicTestPacketMaker maker_;
319 IPEndPoint self_addr_;
320 IPEndPoint peer_addr_;
321 MockRandom random_generator_;
322 MockCryptoClientStreamFactory crypto_client_stream_factory_;
323 scoped_ptr<StaticSocketDataProvider> socket_data_;
324 std::vector<PacketToWrite> writes_;
327 INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
328 ::testing::ValuesIn(QuicSupportedVersions()));
330 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
331 Initialize();
332 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
335 TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
336 Initialize();
337 EXPECT_TRUE(stream_->CanFindEndOfResponse());
340 TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
341 Initialize();
342 EXPECT_FALSE(stream_->IsConnectionReusable());
345 TEST_P(QuicHttpStreamTest, GetRequest) {
346 SetRequest("GET", "/", DEFAULT_PRIORITY);
347 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
348 Initialize();
350 request_.method = "GET";
351 request_.url = GURL("http://www.google.com/");
353 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
354 net_log_, callback_.callback()));
355 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
356 callback_.callback()));
358 // Ack the request.
359 ProcessPacket(ConstructAckPacket(1, 0, 0));
361 EXPECT_EQ(ERR_IO_PENDING,
362 stream_->ReadResponseHeaders(callback_.callback()));
364 SetResponse("404 Not Found", std::string());
365 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
367 // Now that the headers have been processed, the callback will return.
368 EXPECT_EQ(OK, callback_.WaitForResult());
369 ASSERT_TRUE(response_.headers.get());
370 EXPECT_EQ(404, response_.headers->response_code());
371 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
372 EXPECT_FALSE(response_.response_time.is_null());
373 EXPECT_FALSE(response_.request_time.is_null());
375 // There is no body, so this should return immediately.
376 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
377 read_buffer_->size(),
378 callback_.callback()));
379 EXPECT_TRUE(stream_->IsResponseBodyComplete());
380 EXPECT_TRUE(AtEof());
383 // Regression test for http://crbug.com/288128
384 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
385 SetRequest("GET", "/", DEFAULT_PRIORITY);
386 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
387 Initialize();
389 request_.method = "GET";
390 request_.url = GURL("http://www.google.com/");
392 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
393 net_log_, callback_.callback()));
394 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
395 callback_.callback()));
397 // Ack the request.
398 ProcessPacket(ConstructAckPacket(1, 0, 0));
400 EXPECT_EQ(ERR_IO_PENDING,
401 stream_->ReadResponseHeaders(callback_.callback()));
403 SpdyHeaderBlock headers;
404 headers[":status"] = "200 OK";
405 headers[":version"] = "HTTP/1.1";
406 headers["content-type"] = "text/plain";
407 headers["big6"] = std::string(1000, 'x'); // Lots of x's.
409 response_headers_ = headers;
410 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
412 // Now that the headers have been processed, the callback will return.
413 EXPECT_EQ(OK, callback_.WaitForResult());
414 ASSERT_TRUE(response_.headers.get());
415 EXPECT_EQ(200, response_.headers->response_code());
416 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
418 // There is no body, so this should return immediately.
419 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
420 read_buffer_->size(),
421 callback_.callback()));
422 EXPECT_TRUE(stream_->IsResponseBodyComplete());
423 EXPECT_TRUE(AtEof());
426 // Regression test for http://crbug.com/409101
427 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
428 SetRequest("GET", "/", DEFAULT_PRIORITY);
429 Initialize();
431 request_.method = "GET";
432 request_.url = GURL("http://www.google.com/");
434 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
435 net_log_, callback_.callback()));
437 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
439 EXPECT_EQ(ERR_CONNECTION_CLOSED,
440 stream_->SendRequest(headers_, &response_,
441 callback_.callback()));
444 // Regression test for http://crbug.com/409871
445 TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
446 SetRequest("GET", "/", DEFAULT_PRIORITY);
447 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
448 Initialize();
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 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
457 callback_.callback()));
459 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
461 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
464 TEST_P(QuicHttpStreamTest, SendPostRequest) {
465 SetRequest("POST", "/", DEFAULT_PRIORITY);
466 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
467 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
468 AddWrite(ConstructAckPacket(3, 3, 1));
470 Initialize();
472 ScopedVector<UploadElementReader> element_readers;
473 element_readers.push_back(
474 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
475 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
476 request_.method = "POST";
477 request_.url = GURL("http://www.google.com/");
478 request_.upload_data_stream = &upload_data_stream;
479 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
481 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
482 net_log_, callback_.callback()));
483 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
484 callback_.callback()));
486 // Ack both packets in the request.
487 ProcessPacket(ConstructAckPacket(1, 0, 0));
489 // Send the response headers (but not the body).
490 SetResponse("200 OK", std::string());
491 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
493 // Since the headers have already arrived, this should return immediately.
494 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
495 ASSERT_TRUE(response_.headers.get());
496 EXPECT_EQ(200, response_.headers->response_code());
497 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
499 // Send the response body.
500 const char kResponseBody[] = "Hello world!";
501 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
502 // Since the body has already arrived, this should return immediately.
503 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
504 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
505 callback_.callback()));
507 EXPECT_TRUE(stream_->IsResponseBodyComplete());
508 EXPECT_TRUE(AtEof());
511 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
512 SetRequest("POST", "/", DEFAULT_PRIORITY);
513 size_t chunk_size = strlen(kUploadData);
514 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
515 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
516 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
517 kUploadData));
518 AddWrite(ConstructAckPacket(4, 3, 1));
519 Initialize();
521 ChunkedUploadDataStream upload_data_stream(0);
522 upload_data_stream.AppendData(kUploadData, chunk_size, false);
524 request_.method = "POST";
525 request_.url = GURL("http://www.google.com/");
526 request_.upload_data_stream = &upload_data_stream;
527 ASSERT_EQ(OK, request_.upload_data_stream->Init(
528 TestCompletionCallback().callback()));
530 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
531 net_log_, callback_.callback()));
532 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
533 callback_.callback()));
535 upload_data_stream.AppendData(kUploadData, chunk_size, true);
537 // Ack both packets in the request.
538 ProcessPacket(ConstructAckPacket(1, 0, 0));
540 // Send the response headers (but not the body).
541 SetResponse("200 OK", std::string());
542 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
544 // Since the headers have already arrived, this should return immediately.
545 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
546 ASSERT_TRUE(response_.headers.get());
547 EXPECT_EQ(200, response_.headers->response_code());
548 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
550 // Send the response body.
551 const char kResponseBody[] = "Hello world!";
552 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
553 kResponseBody));
555 // Since the body has already arrived, this should return immediately.
556 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
557 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
558 callback_.callback()));
560 EXPECT_TRUE(stream_->IsResponseBodyComplete());
561 EXPECT_TRUE(AtEof());
564 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
565 SetRequest("POST", "/", DEFAULT_PRIORITY);
566 size_t chunk_size = strlen(kUploadData);
567 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
568 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
569 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
570 AddWrite(ConstructAckPacket(4, 3, 1));
571 Initialize();
573 ChunkedUploadDataStream upload_data_stream(0);
574 upload_data_stream.AppendData(kUploadData, chunk_size, false);
576 request_.method = "POST";
577 request_.url = GURL("http://www.google.com/");
578 request_.upload_data_stream = &upload_data_stream;
579 ASSERT_EQ(OK, request_.upload_data_stream->Init(
580 TestCompletionCallback().callback()));
582 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
583 net_log_, callback_.callback()));
584 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
585 callback_.callback()));
587 upload_data_stream.AppendData(nullptr, 0, true);
589 ProcessPacket(ConstructAckPacket(1, 0, 0));
591 // Send the response headers (but not the body).
592 SetResponse("200 OK", std::string());
593 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
595 // Since the headers have already arrived, this should return immediately.
596 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
597 ASSERT_TRUE(response_.headers.get());
598 EXPECT_EQ(200, response_.headers->response_code());
599 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
601 // Send the response body.
602 const char kResponseBody[] = "Hello world!";
603 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
604 kResponseBody));
606 // Since the body has already arrived, this should return immediately.
607 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
608 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
609 callback_.callback()));
611 EXPECT_TRUE(stream_->IsResponseBodyComplete());
612 EXPECT_TRUE(AtEof());
615 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
616 SetRequest("POST", "/", DEFAULT_PRIORITY);
617 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
618 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
619 AddWrite(ConstructAckPacket(3, 3, 1));
620 Initialize();
622 ChunkedUploadDataStream upload_data_stream(0);
624 request_.method = "POST";
625 request_.url = GURL("http://www.google.com/");
626 request_.upload_data_stream = &upload_data_stream;
627 ASSERT_EQ(OK, request_.upload_data_stream->Init(
628 TestCompletionCallback().callback()));
630 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
631 net_log_, callback_.callback()));
632 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
633 callback_.callback()));
635 upload_data_stream.AppendData(nullptr, 0, true);
637 ProcessPacket(ConstructAckPacket(1, 0, 0));
639 // Send the response headers (but not the body).
640 SetResponse("200 OK", std::string());
641 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
643 // Since the headers have already arrived, this should return immediately.
644 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
645 ASSERT_TRUE(response_.headers.get());
646 EXPECT_EQ(200, response_.headers->response_code());
647 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
649 // Send the response body.
650 const char kResponseBody[] = "Hello world!";
651 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
652 kResponseBody));
654 // Since the body has already arrived, this should return immediately.
655 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
656 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
657 callback_.callback()));
659 EXPECT_TRUE(stream_->IsResponseBodyComplete());
660 EXPECT_TRUE(AtEof());
663 TEST_P(QuicHttpStreamTest, DestroyedEarly) {
664 SetRequest("GET", "/", DEFAULT_PRIORITY);
665 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
666 AddWrite(ConstructAckAndRstStreamPacket(2));
667 use_closing_stream_ = true;
668 Initialize();
670 request_.method = "GET";
671 request_.url = GURL("http://www.google.com/");
673 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
674 net_log_, callback_.callback()));
675 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
676 callback_.callback()));
678 // Ack the request.
679 ProcessPacket(ConstructAckPacket(1, 0, 0));
680 EXPECT_EQ(ERR_IO_PENDING,
681 stream_->ReadResponseHeaders(callback_.callback()));
683 // Send the response with a body.
684 SetResponse("404 OK", "hello world!");
685 // In the course of processing this packet, the QuicHttpStream close itself.
686 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
688 EXPECT_TRUE(AtEof());
691 TEST_P(QuicHttpStreamTest, Priority) {
692 SetRequest("GET", "/", MEDIUM);
693 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM));
694 AddWrite(ConstructAckAndRstStreamPacket(2));
695 use_closing_stream_ = true;
696 Initialize();
698 request_.method = "GET";
699 request_.url = GURL("http://www.google.com/");
701 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
702 net_log_, callback_.callback()));
704 // Check that priority is highest.
705 QuicReliableClientStream* reliable_stream =
706 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
707 DCHECK(reliable_stream);
708 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
709 reliable_stream->EffectivePriority());
711 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
712 callback_.callback()));
714 // Check that priority has now dropped back to MEDIUM.
715 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
716 reliable_stream->EffectivePriority()));
718 // Ack the request.
719 ProcessPacket(ConstructAckPacket(1, 0, 0));
720 EXPECT_EQ(ERR_IO_PENDING,
721 stream_->ReadResponseHeaders(callback_.callback()));
723 // Send the response with a body.
724 SetResponse("404 OK", "hello world!");
725 // In the course of processing this packet, the QuicHttpStream close itself.
726 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
728 EXPECT_TRUE(AtEof());
731 // Regression test for http://crbug.com/294870
732 TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
733 SetRequest("GET", "/", MEDIUM);
734 use_closing_stream_ = true;
736 AddWrite(ConstructRstStreamPacket(1));
738 Initialize();
740 request_.method = "GET";
741 request_.url = GURL("http://www.google.com/");
743 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
744 net_log_, callback_.callback()));
746 // Check that priority is highest.
747 QuicReliableClientStream* reliable_stream =
748 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
749 DCHECK(reliable_stream);
750 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
751 DCHECK(delegate);
752 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
753 reliable_stream->EffectivePriority());
755 // Set Delegate to nullptr and make sure EffectivePriority returns highest
756 // priority.
757 reliable_stream->SetDelegate(nullptr);
758 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
759 reliable_stream->EffectivePriority());
760 reliable_stream->SetDelegate(delegate);
763 } // namespace test
764 } // namespace net