Snap pinch zoom gestures near the screen edge.
[chromium-blink-merge.git] / net / quic / quic_http_stream_test.cc
blob1fcbf271f0bb1bc29c8e9f042fe8a09744b72b2e
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 int OnDataReceived(const char* data, int length) override {
87 Close(false);
88 return OK;
92 class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
93 public:
94 explicit TestPacketWriterFactory(DatagramClientSocket* socket)
95 : socket_(socket) {}
96 ~TestPacketWriterFactory() override {}
98 QuicPacketWriter* Create(QuicConnection* connection) const override {
99 return new QuicDefaultPacketWriter(socket_);
102 private:
103 DatagramClientSocket* socket_;
106 } // namespace
108 class QuicHttpStreamPeer {
109 public:
110 static QuicReliableClientStream* GetQuicReliableClientStream(
111 QuicHttpStream* stream) {
112 return stream->stream_;
116 class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
117 protected:
118 static const bool kFin = true;
119 static const bool kIncludeVersion = true;
120 static const bool kIncludeCongestionFeedback = true;
122 // Holds a packet to be written to the wire, and the IO mode that should
123 // be used by the mock socket when performing the write.
124 struct PacketToWrite {
125 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
126 : mode(mode),
127 packet(packet) {
129 IoMode mode;
130 QuicEncryptedPacket* packet;
133 QuicHttpStreamTest()
134 : net_log_(BoundNetLog()),
135 use_closing_stream_(false),
136 read_buffer_(new IOBufferWithSize(4096)),
137 connection_id_(2),
138 stream_id_(kClientDataStreamId1),
139 maker_(GetParam(), connection_id_, &clock_, kDefaultServerHostName),
140 random_generator_(0) {
141 IPAddressNumber ip;
142 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
143 peer_addr_ = IPEndPoint(ip, 443);
144 self_addr_ = IPEndPoint(ip, 8435);
145 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
148 ~QuicHttpStreamTest() {
149 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
150 for (size_t i = 0; i < writes_.size(); i++) {
151 delete writes_[i].packet;
155 // Adds a packet to the list of expected writes.
156 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
157 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
160 // Returns the packet to be written at position |pos|.
161 QuicEncryptedPacket* GetWrite(size_t pos) {
162 return writes_[pos].packet;
165 bool AtEof() {
166 return socket_data_->AllReadDataConsumed() &&
167 socket_data_->AllWriteDataConsumed();
170 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
171 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
174 // Configures the test fixture to use the list of expected writes.
175 void Initialize() {
176 mock_writes_.reset(new MockWrite[writes_.size()]);
177 for (size_t i = 0; i < writes_.size(); i++) {
178 mock_writes_[i] = MockWrite(writes_[i].mode,
179 writes_[i].packet->data(),
180 writes_[i].packet->length());
183 socket_data_.reset(new StaticSocketDataProvider(
184 nullptr, 0, mock_writes_.get(), writes_.size()));
186 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
187 net_log_.net_log());
188 socket->Connect(peer_addr_);
189 runner_ = new TestTaskRunner(&clock_);
190 send_algorithm_ = new MockSendAlgorithm();
191 EXPECT_CALL(*send_algorithm_,
192 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
193 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
194 Return(QuicTime::Delta::Zero()));
195 EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
196 Return(kMaxPacketSize));
197 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).
198 WillRepeatedly(Return(QuicTime::Delta::Zero()));
199 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
200 Return(QuicBandwidth::Zero()));
201 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
202 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
203 &random_generator_));
204 TestPacketWriterFactory writer_factory(socket);
205 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
206 connection_id_, peer_addr_,
207 helper_.get(), writer_factory);
208 connection_->set_visitor(&visitor_);
209 connection_->SetSendAlgorithm(send_algorithm_);
210 session_.reset(new QuicClientSession(
211 connection_, scoped_ptr<DatagramClientSocket>(socket),
212 /*stream_factory=*/nullptr, &crypto_client_stream_factory_,
213 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
214 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
215 /*is_secure=*/false, PRIVACY_MODE_DISABLED),
216 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
217 "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
218 base::ThreadTaskRunnerHandle::Get().get(), nullptr));
219 session_->Initialize();
220 session_->GetCryptoStream()->CryptoConnect();
221 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
222 stream_.reset(use_closing_stream_ ?
223 new AutoClosingStream(session_->GetWeakPtr()) :
224 new QuicHttpStream(session_->GetWeakPtr()));
227 void SetRequest(const std::string& method,
228 const std::string& path,
229 RequestPriority priority) {
230 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
233 void SetResponse(const std::string& status, const std::string& body) {
234 response_headers_ = maker_.GetResponseHeaders(status);
235 response_data_ = body;
238 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
239 QuicPacketSequenceNumber sequence_number,
240 bool should_include_version,
241 bool fin,
242 QuicStreamOffset offset,
243 base::StringPiece data) {
244 return maker_.MakeDataPacket(sequence_number, stream_id_,
245 should_include_version, fin, offset, data);
248 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
249 QuicPacketSequenceNumber sequence_number,
250 bool fin,
251 RequestPriority request_priority) {
252 QuicPriority priority =
253 ConvertRequestPriorityToQuicPriority(request_priority);
254 return maker_.MakeRequestHeadersPacket(sequence_number, stream_id_,
255 kIncludeVersion, fin, priority,
256 request_headers_);
259 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
260 QuicPacketSequenceNumber sequence_number,
261 bool fin) {
262 return maker_.MakeResponseHeadersPacket(
263 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_);
266 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
267 QuicPacketSequenceNumber sequence_number) {
268 return maker_.MakeRstPacket(
269 sequence_number, true, stream_id_,
270 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
273 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
274 QuicPacketSequenceNumber sequence_number) {
275 return maker_.MakeAckAndRstPacket(
276 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
277 2, 1, !kIncludeCongestionFeedback);
280 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
281 QuicPacketSequenceNumber sequence_number,
282 QuicPacketSequenceNumber largest_received,
283 QuicPacketSequenceNumber least_unacked) {
284 return maker_.MakeAckPacket(sequence_number, largest_received,
285 least_unacked, !kIncludeCongestionFeedback);
288 BoundNetLog net_log_;
289 bool use_closing_stream_;
290 MockSendAlgorithm* send_algorithm_;
291 scoped_refptr<TestTaskRunner> runner_;
292 scoped_ptr<MockWrite[]> mock_writes_;
293 MockClock clock_;
294 TestQuicConnection* connection_;
295 scoped_ptr<QuicConnectionHelper> helper_;
296 testing::StrictMock<MockConnectionVisitor> visitor_;
297 scoped_ptr<QuicHttpStream> stream_;
298 TransportSecurityState transport_security_state_;
299 scoped_ptr<QuicClientSession> session_;
300 QuicCryptoClientConfig crypto_config_;
301 TestCompletionCallback callback_;
302 HttpRequestInfo request_;
303 HttpRequestHeaders headers_;
304 HttpResponseInfo response_;
305 scoped_refptr<IOBufferWithSize> read_buffer_;
306 SpdyHeaderBlock request_headers_;
307 SpdyHeaderBlock response_headers_;
308 std::string request_data_;
309 std::string response_data_;
311 private:
312 const QuicConnectionId connection_id_;
313 const QuicStreamId stream_id_;
314 QuicTestPacketMaker maker_;
315 IPEndPoint self_addr_;
316 IPEndPoint peer_addr_;
317 MockRandom random_generator_;
318 MockCryptoClientStreamFactory crypto_client_stream_factory_;
319 scoped_ptr<StaticSocketDataProvider> socket_data_;
320 std::vector<PacketToWrite> writes_;
323 INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
324 ::testing::ValuesIn(QuicSupportedVersions()));
326 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
327 Initialize();
328 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
331 TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
332 Initialize();
333 EXPECT_TRUE(stream_->CanFindEndOfResponse());
336 TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
337 Initialize();
338 EXPECT_FALSE(stream_->IsConnectionReusable());
341 TEST_P(QuicHttpStreamTest, GetRequest) {
342 SetRequest("GET", "/", DEFAULT_PRIORITY);
343 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
344 Initialize();
346 request_.method = "GET";
347 request_.url = GURL("http://www.google.com/");
349 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
350 net_log_, callback_.callback()));
351 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
352 callback_.callback()));
354 // Ack the request.
355 ProcessPacket(ConstructAckPacket(1, 0, 0));
357 EXPECT_EQ(ERR_IO_PENDING,
358 stream_->ReadResponseHeaders(callback_.callback()));
360 SetResponse("404 Not Found", std::string());
361 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
363 // Now that the headers have been processed, the callback will return.
364 EXPECT_EQ(OK, callback_.WaitForResult());
365 ASSERT_TRUE(response_.headers.get());
366 EXPECT_EQ(404, response_.headers->response_code());
367 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
368 EXPECT_FALSE(response_.response_time.is_null());
369 EXPECT_FALSE(response_.request_time.is_null());
371 // There is no body, so this should return immediately.
372 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
373 read_buffer_->size(),
374 callback_.callback()));
375 EXPECT_TRUE(stream_->IsResponseBodyComplete());
376 EXPECT_TRUE(AtEof());
379 // Regression test for http://crbug.com/288128
380 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
381 SetRequest("GET", "/", DEFAULT_PRIORITY);
382 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
383 Initialize();
385 request_.method = "GET";
386 request_.url = GURL("http://www.google.com/");
388 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
389 net_log_, callback_.callback()));
390 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
391 callback_.callback()));
393 // Ack the request.
394 ProcessPacket(ConstructAckPacket(1, 0, 0));
396 EXPECT_EQ(ERR_IO_PENDING,
397 stream_->ReadResponseHeaders(callback_.callback()));
399 SpdyHeaderBlock headers;
400 headers[":status"] = "200 OK";
401 headers[":version"] = "HTTP/1.1";
402 headers["content-type"] = "text/plain";
403 headers["big6"] = std::string(10000, 'x'); // Lots of x's.
405 std::string response =
406 SpdyUtils::SerializeUncompressedHeaders(headers, GetParam());
407 EXPECT_LT(4096u, response.length());
408 stream_->OnDataReceived(response.data(), response.length());
409 stream_->OnClose(QUIC_NO_ERROR);
411 // Now that the headers have been processed, the callback will return.
412 EXPECT_EQ(OK, callback_.WaitForResult());
413 ASSERT_TRUE(response_.headers.get());
414 EXPECT_EQ(200, response_.headers->response_code());
415 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
417 // There is no body, so this should return immediately.
418 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
419 read_buffer_->size(),
420 callback_.callback()));
421 EXPECT_TRUE(stream_->IsResponseBodyComplete());
422 EXPECT_TRUE(AtEof());
425 // Regression test for http://crbug.com/409101
426 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
427 SetRequest("GET", "/", DEFAULT_PRIORITY);
428 Initialize();
430 request_.method = "GET";
431 request_.url = GURL("http://www.google.com/");
433 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
434 net_log_, callback_.callback()));
436 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
438 EXPECT_EQ(ERR_CONNECTION_CLOSED,
439 stream_->SendRequest(headers_, &response_,
440 callback_.callback()));
443 // Regression test for http://crbug.com/409871
444 TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
445 SetRequest("GET", "/", DEFAULT_PRIORITY);
446 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
447 Initialize();
449 request_.method = "GET";
450 request_.url = GURL("http://www.google.com/");
452 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
453 net_log_, callback_.callback()));
455 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
456 callback_.callback()));
458 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
460 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
463 TEST_P(QuicHttpStreamTest, SendPostRequest) {
464 SetRequest("POST", "/", DEFAULT_PRIORITY);
465 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
466 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
467 AddWrite(ConstructAckPacket(3, 3, 1));
469 Initialize();
471 ScopedVector<UploadElementReader> element_readers;
472 element_readers.push_back(
473 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
474 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
475 request_.method = "POST";
476 request_.url = GURL("http://www.google.com/");
477 request_.upload_data_stream = &upload_data_stream;
478 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
480 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
481 net_log_, callback_.callback()));
482 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
483 callback_.callback()));
485 // Ack both packets in the request.
486 ProcessPacket(ConstructAckPacket(1, 0, 0));
488 // Send the response headers (but not the body).
489 SetResponse("200 OK", std::string());
490 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
492 // Since the headers have already arrived, this should return immediately.
493 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
494 ASSERT_TRUE(response_.headers.get());
495 EXPECT_EQ(200, response_.headers->response_code());
496 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
498 // Send the response body.
499 const char kResponseBody[] = "Hello world!";
500 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
501 // Since the body has already arrived, this should return immediately.
502 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
503 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
504 callback_.callback()));
506 EXPECT_TRUE(stream_->IsResponseBodyComplete());
507 EXPECT_TRUE(AtEof());
510 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
511 SetRequest("POST", "/", DEFAULT_PRIORITY);
512 size_t chunk_size = strlen(kUploadData);
513 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
514 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
515 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
516 kUploadData));
517 AddWrite(ConstructAckPacket(4, 3, 1));
518 Initialize();
520 ChunkedUploadDataStream upload_data_stream(0);
521 upload_data_stream.AppendData(kUploadData, chunk_size, false);
523 request_.method = "POST";
524 request_.url = GURL("http://www.google.com/");
525 request_.upload_data_stream = &upload_data_stream;
526 ASSERT_EQ(OK, request_.upload_data_stream->Init(
527 TestCompletionCallback().callback()));
529 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
530 net_log_, callback_.callback()));
531 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
532 callback_.callback()));
534 upload_data_stream.AppendData(kUploadData, chunk_size, true);
536 // Ack both packets in the request.
537 ProcessPacket(ConstructAckPacket(1, 0, 0));
539 // Send the response headers (but not the body).
540 SetResponse("200 OK", std::string());
541 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
543 // Since the headers have already arrived, this should return immediately.
544 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
545 ASSERT_TRUE(response_.headers.get());
546 EXPECT_EQ(200, response_.headers->response_code());
547 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
549 // Send the response body.
550 const char kResponseBody[] = "Hello world!";
551 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
552 kResponseBody));
554 // Since the body has already arrived, this should return immediately.
555 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
556 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
557 callback_.callback()));
559 EXPECT_TRUE(stream_->IsResponseBodyComplete());
560 EXPECT_TRUE(AtEof());
563 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
564 SetRequest("POST", "/", DEFAULT_PRIORITY);
565 size_t chunk_size = strlen(kUploadData);
566 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
567 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
568 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
569 AddWrite(ConstructAckPacket(4, 3, 1));
570 Initialize();
572 ChunkedUploadDataStream upload_data_stream(0);
573 upload_data_stream.AppendData(kUploadData, chunk_size, false);
575 request_.method = "POST";
576 request_.url = GURL("http://www.google.com/");
577 request_.upload_data_stream = &upload_data_stream;
578 ASSERT_EQ(OK, request_.upload_data_stream->Init(
579 TestCompletionCallback().callback()));
581 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
582 net_log_, callback_.callback()));
583 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
584 callback_.callback()));
586 upload_data_stream.AppendData(nullptr, 0, true);
588 ProcessPacket(ConstructAckPacket(1, 0, 0));
590 // Send the response headers (but not the body).
591 SetResponse("200 OK", std::string());
592 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
594 // Since the headers have already arrived, this should return immediately.
595 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
596 ASSERT_TRUE(response_.headers.get());
597 EXPECT_EQ(200, response_.headers->response_code());
598 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
600 // Send the response body.
601 const char kResponseBody[] = "Hello world!";
602 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
603 kResponseBody));
605 // Since the body has already arrived, this should return immediately.
606 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
607 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
608 callback_.callback()));
610 EXPECT_TRUE(stream_->IsResponseBodyComplete());
611 EXPECT_TRUE(AtEof());
614 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
615 SetRequest("POST", "/", DEFAULT_PRIORITY);
616 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
617 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
618 AddWrite(ConstructAckPacket(3, 3, 1));
619 Initialize();
621 ChunkedUploadDataStream upload_data_stream(0);
623 request_.method = "POST";
624 request_.url = GURL("http://www.google.com/");
625 request_.upload_data_stream = &upload_data_stream;
626 ASSERT_EQ(OK, request_.upload_data_stream->Init(
627 TestCompletionCallback().callback()));
629 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
630 net_log_, callback_.callback()));
631 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
632 callback_.callback()));
634 upload_data_stream.AppendData(nullptr, 0, true);
636 ProcessPacket(ConstructAckPacket(1, 0, 0));
638 // Send the response headers (but not the body).
639 SetResponse("200 OK", std::string());
640 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
642 // Since the headers have already arrived, this should return immediately.
643 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
644 ASSERT_TRUE(response_.headers.get());
645 EXPECT_EQ(200, response_.headers->response_code());
646 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
648 // Send the response body.
649 const char kResponseBody[] = "Hello world!";
650 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
651 kResponseBody));
653 // Since the body has already arrived, this should return immediately.
654 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
655 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
656 callback_.callback()));
658 EXPECT_TRUE(stream_->IsResponseBodyComplete());
659 EXPECT_TRUE(AtEof());
662 TEST_P(QuicHttpStreamTest, DestroyedEarly) {
663 SetRequest("GET", "/", DEFAULT_PRIORITY);
664 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
665 AddWrite(ConstructAckAndRstStreamPacket(2));
666 use_closing_stream_ = true;
667 Initialize();
669 request_.method = "GET";
670 request_.url = GURL("http://www.google.com/");
672 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
673 net_log_, callback_.callback()));
674 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
675 callback_.callback()));
677 // Ack the request.
678 ProcessPacket(ConstructAckPacket(1, 0, 0));
679 EXPECT_EQ(ERR_IO_PENDING,
680 stream_->ReadResponseHeaders(callback_.callback()));
682 // Send the response with a body.
683 SetResponse("404 OK", "hello world!");
684 // In the course of processing this packet, the QuicHttpStream close itself.
685 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
687 EXPECT_TRUE(AtEof());
690 TEST_P(QuicHttpStreamTest, Priority) {
691 SetRequest("GET", "/", MEDIUM);
692 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM));
693 AddWrite(ConstructAckAndRstStreamPacket(2));
694 use_closing_stream_ = true;
695 Initialize();
697 request_.method = "GET";
698 request_.url = GURL("http://www.google.com/");
700 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
701 net_log_, callback_.callback()));
703 // Check that priority is highest.
704 QuicReliableClientStream* reliable_stream =
705 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
706 DCHECK(reliable_stream);
707 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
708 reliable_stream->EffectivePriority());
710 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
711 callback_.callback()));
713 // Check that priority has now dropped back to MEDIUM.
714 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
715 reliable_stream->EffectivePriority()));
717 // Ack the request.
718 ProcessPacket(ConstructAckPacket(1, 0, 0));
719 EXPECT_EQ(ERR_IO_PENDING,
720 stream_->ReadResponseHeaders(callback_.callback()));
722 // Send the response with a body.
723 SetResponse("404 OK", "hello world!");
724 // In the course of processing this packet, the QuicHttpStream close itself.
725 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
727 EXPECT_TRUE(AtEof());
730 // Regression test for http://crbug.com/294870
731 TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
732 SetRequest("GET", "/", MEDIUM);
733 use_closing_stream_ = true;
735 AddWrite(ConstructRstStreamPacket(1));
737 Initialize();
739 request_.method = "GET";
740 request_.url = GURL("http://www.google.com/");
742 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
743 net_log_, callback_.callback()));
745 // Check that priority is highest.
746 QuicReliableClientStream* reliable_stream =
747 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
748 DCHECK(reliable_stream);
749 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
750 DCHECK(delegate);
751 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
752 reliable_stream->EffectivePriority());
754 // Set Delegate to nullptr and make sure EffectivePriority returns highest
755 // priority.
756 reliable_stream->SetDelegate(nullptr);
757 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
758 reliable_stream->EffectivePriority());
759 reliable_stream->SetDelegate(delegate);
762 } // namespace test
763 } // namespace net