We started redesigning GpuMemoryBuffer interface to handle multiple buffers [0].
[chromium-blink-merge.git] / net / quic / quic_http_stream_test.cc
blob37cfdd002d6a005db56fd08ea7fba625f0cd9cc3
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 "net/base/chunked_upload_data_stream.h"
10 #include "net/base/elements_upload_data_stream.h"
11 #include "net/base/net_errors.h"
12 #include "net/base/test_completion_callback.h"
13 #include "net/base/upload_bytes_element_reader.h"
14 #include "net/http/http_response_headers.h"
15 #include "net/http/transport_security_state.h"
16 #include "net/quic/congestion_control/send_algorithm_interface.h"
17 #include "net/quic/crypto/crypto_protocol.h"
18 #include "net/quic/crypto/quic_decrypter.h"
19 #include "net/quic/crypto/quic_encrypter.h"
20 #include "net/quic/crypto/quic_server_info.h"
21 #include "net/quic/quic_client_session.h"
22 #include "net/quic/quic_connection.h"
23 #include "net/quic/quic_connection_helper.h"
24 #include "net/quic/quic_default_packet_writer.h"
25 #include "net/quic/quic_http_utils.h"
26 #include "net/quic/quic_reliable_client_stream.h"
27 #include "net/quic/quic_write_blocked_list.h"
28 #include "net/quic/spdy_utils.h"
29 #include "net/quic/test_tools/mock_clock.h"
30 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
31 #include "net/quic/test_tools/mock_random.h"
32 #include "net/quic/test_tools/quic_connection_peer.h"
33 #include "net/quic/test_tools/quic_test_packet_maker.h"
34 #include "net/quic/test_tools/quic_test_utils.h"
35 #include "net/quic/test_tools/test_task_runner.h"
36 #include "net/socket/socket_test_util.h"
37 #include "net/spdy/spdy_frame_builder.h"
38 #include "net/spdy/spdy_framer.h"
39 #include "net/spdy/spdy_http_utils.h"
40 #include "net/spdy/spdy_protocol.h"
41 #include "testing/gmock/include/gmock/gmock.h"
42 #include "testing/gtest/include/gtest/gtest.h"
44 using testing::_;
45 using testing::AnyNumber;
46 using testing::Return;
48 namespace net {
49 namespace test {
50 namespace {
52 const char kUploadData[] = "Really nifty data!";
53 const char kServerHostname[] = "www.google.com";
54 const uint16 kServerPort = 80;
56 class TestQuicConnection : public QuicConnection {
57 public:
58 TestQuicConnection(const QuicVersionVector& versions,
59 QuicConnectionId connection_id,
60 IPEndPoint address,
61 QuicConnectionHelper* helper,
62 const QuicConnection::PacketWriterFactory& writer_factory)
63 : QuicConnection(connection_id,
64 address,
65 helper,
66 writer_factory,
67 true /* owns_writer */,
68 Perspective::IS_CLIENT,
69 false /* is_secure */,
70 versions) {}
72 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
73 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
77 // Subclass of QuicHttpStream that closes itself when the first piece of data
78 // is received.
79 class AutoClosingStream : public QuicHttpStream {
80 public:
81 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session)
82 : QuicHttpStream(session) {
85 int OnDataReceived(const char* data, int length) override {
86 Close(false);
87 return OK;
91 class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
92 public:
93 explicit TestPacketWriterFactory(DatagramClientSocket* socket)
94 : socket_(socket) {}
95 ~TestPacketWriterFactory() override {}
97 QuicPacketWriter* Create(QuicConnection* connection) const override {
98 return new QuicDefaultPacketWriter(socket_);
101 private:
102 DatagramClientSocket* socket_;
105 } // namespace
107 class QuicHttpStreamPeer {
108 public:
109 static QuicReliableClientStream* GetQuicReliableClientStream(
110 QuicHttpStream* stream) {
111 return stream->stream_;
115 class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
116 protected:
117 static const bool kFin = true;
118 static const bool kIncludeVersion = true;
119 static const bool kIncludeCongestionFeedback = true;
121 // Holds a packet to be written to the wire, and the IO mode that should
122 // be used by the mock socket when performing the write.
123 struct PacketToWrite {
124 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
125 : mode(mode),
126 packet(packet) {
128 IoMode mode;
129 QuicEncryptedPacket* packet;
132 QuicHttpStreamTest()
133 : net_log_(BoundNetLog()),
134 use_closing_stream_(false),
135 read_buffer_(new IOBufferWithSize(4096)),
136 connection_id_(2),
137 stream_id_(kClientDataStreamId1),
138 maker_(GetParam(), connection_id_, &clock_),
139 random_generator_(0) {
140 IPAddressNumber ip;
141 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
142 peer_addr_ = IPEndPoint(ip, 443);
143 self_addr_ = IPEndPoint(ip, 8435);
144 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
147 ~QuicHttpStreamTest() {
148 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
149 for (size_t i = 0; i < writes_.size(); i++) {
150 delete writes_[i].packet;
154 // Adds a packet to the list of expected writes.
155 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
156 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
159 // Returns the packet to be written at position |pos|.
160 QuicEncryptedPacket* GetWrite(size_t pos) {
161 return writes_[pos].packet;
164 bool AtEof() {
165 return socket_data_->at_read_eof() && socket_data_->at_write_eof();
168 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
169 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
172 // Configures the test fixture to use the list of expected writes.
173 void Initialize() {
174 mock_writes_.reset(new MockWrite[writes_.size()]);
175 for (size_t i = 0; i < writes_.size(); i++) {
176 mock_writes_[i] = MockWrite(writes_[i].mode,
177 writes_[i].packet->data(),
178 writes_[i].packet->length());
181 socket_data_.reset(new StaticSocketDataProvider(
182 nullptr, 0, mock_writes_.get(), writes_.size()));
184 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
185 net_log_.net_log());
186 socket->Connect(peer_addr_);
187 runner_ = new TestTaskRunner(&clock_);
188 send_algorithm_ = new MockSendAlgorithm();
189 EXPECT_CALL(*send_algorithm_,
190 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
191 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
192 Return(QuicTime::Delta::Zero()));
193 EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
194 Return(kMaxPacketSize));
195 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).
196 WillRepeatedly(Return(QuicTime::Delta::Zero()));
197 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
198 Return(QuicBandwidth::Zero()));
199 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
200 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
201 &random_generator_));
202 TestPacketWriterFactory writer_factory(socket);
203 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
204 connection_id_, peer_addr_,
205 helper_.get(), writer_factory);
206 connection_->set_visitor(&visitor_);
207 connection_->SetSendAlgorithm(send_algorithm_);
208 session_.reset(new QuicClientSession(
209 connection_, scoped_ptr<DatagramClientSocket>(socket), nullptr,
210 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
211 DefaultQuicConfig(), "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
212 base::MessageLoop::current()->message_loop_proxy().get(), nullptr));
213 session_->InitializeSession(QuicServerId(kServerHostname, kServerPort,
214 /*is_secure=*/false,
215 PRIVACY_MODE_DISABLED),
216 &crypto_config_,
217 &crypto_client_stream_factory_);
218 session_->GetCryptoStream()->CryptoConnect();
219 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
220 stream_.reset(use_closing_stream_ ?
221 new AutoClosingStream(session_->GetWeakPtr()) :
222 new QuicHttpStream(session_->GetWeakPtr()));
225 void SetRequest(const std::string& method,
226 const std::string& path,
227 RequestPriority priority) {
228 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
231 void SetResponse(const std::string& status, const std::string& body) {
232 response_headers_ = maker_.GetResponseHeaders(status);
233 response_data_ = body;
236 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
237 QuicPacketSequenceNumber sequence_number,
238 bool should_include_version,
239 bool fin,
240 QuicStreamOffset offset,
241 base::StringPiece data) {
242 return maker_.MakeDataPacket(sequence_number, stream_id_,
243 should_include_version, fin, offset, data);
246 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
247 QuicPacketSequenceNumber sequence_number,
248 bool fin,
249 RequestPriority request_priority) {
250 QuicPriority priority =
251 ConvertRequestPriorityToQuicPriority(request_priority);
252 return maker_.MakeRequestHeadersPacket(sequence_number, stream_id_,
253 kIncludeVersion, fin, priority,
254 request_headers_);
257 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
258 QuicPacketSequenceNumber sequence_number,
259 bool fin) {
260 return maker_.MakeResponseHeadersPacket(
261 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_);
264 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
265 QuicPacketSequenceNumber sequence_number) {
266 return maker_.MakeRstPacket(
267 sequence_number, true, stream_id_,
268 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
271 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
272 QuicPacketSequenceNumber sequence_number) {
273 return maker_.MakeAckAndRstPacket(
274 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
275 2, 1, !kIncludeCongestionFeedback);
278 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
279 QuicPacketSequenceNumber sequence_number,
280 QuicPacketSequenceNumber largest_received,
281 QuicPacketSequenceNumber least_unacked) {
282 return maker_.MakeAckPacket(sequence_number, largest_received,
283 least_unacked, !kIncludeCongestionFeedback);
286 BoundNetLog net_log_;
287 bool use_closing_stream_;
288 MockSendAlgorithm* send_algorithm_;
289 scoped_refptr<TestTaskRunner> runner_;
290 scoped_ptr<MockWrite[]> mock_writes_;
291 MockClock clock_;
292 TestQuicConnection* connection_;
293 scoped_ptr<QuicConnectionHelper> helper_;
294 testing::StrictMock<MockConnectionVisitor> visitor_;
295 scoped_ptr<QuicHttpStream> stream_;
296 TransportSecurityState transport_security_state_;
297 scoped_ptr<QuicClientSession> session_;
298 QuicCryptoClientConfig crypto_config_;
299 TestCompletionCallback callback_;
300 HttpRequestInfo request_;
301 HttpRequestHeaders headers_;
302 HttpResponseInfo response_;
303 scoped_refptr<IOBufferWithSize> read_buffer_;
304 SpdyHeaderBlock request_headers_;
305 SpdyHeaderBlock response_headers_;
306 std::string request_data_;
307 std::string response_data_;
309 private:
310 const QuicConnectionId connection_id_;
311 const QuicStreamId stream_id_;
312 QuicTestPacketMaker maker_;
313 IPEndPoint self_addr_;
314 IPEndPoint peer_addr_;
315 MockRandom random_generator_;
316 MockCryptoClientStreamFactory crypto_client_stream_factory_;
317 scoped_ptr<StaticSocketDataProvider> socket_data_;
318 std::vector<PacketToWrite> writes_;
321 INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
322 ::testing::ValuesIn(QuicSupportedVersions()));
324 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
325 Initialize();
326 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
329 TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
330 Initialize();
331 EXPECT_TRUE(stream_->CanFindEndOfResponse());
334 TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
335 Initialize();
336 EXPECT_FALSE(stream_->IsConnectionReusable());
339 TEST_P(QuicHttpStreamTest, GetRequest) {
340 SetRequest("GET", "/", DEFAULT_PRIORITY);
341 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
342 Initialize();
344 request_.method = "GET";
345 request_.url = GURL("http://www.google.com/");
347 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
348 net_log_, callback_.callback()));
349 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
350 callback_.callback()));
352 // Ack the request.
353 ProcessPacket(ConstructAckPacket(1, 0, 0));
355 EXPECT_EQ(ERR_IO_PENDING,
356 stream_->ReadResponseHeaders(callback_.callback()));
358 SetResponse("404 Not Found", std::string());
359 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
361 // Now that the headers have been processed, the callback will return.
362 EXPECT_EQ(OK, callback_.WaitForResult());
363 ASSERT_TRUE(response_.headers.get());
364 EXPECT_EQ(404, response_.headers->response_code());
365 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
366 EXPECT_FALSE(response_.response_time.is_null());
367 EXPECT_FALSE(response_.request_time.is_null());
369 // There is no body, so this should return immediately.
370 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
371 read_buffer_->size(),
372 callback_.callback()));
373 EXPECT_TRUE(stream_->IsResponseBodyComplete());
374 EXPECT_TRUE(AtEof());
377 // Regression test for http://crbug.com/288128
378 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
379 SetRequest("GET", "/", DEFAULT_PRIORITY);
380 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
381 Initialize();
383 request_.method = "GET";
384 request_.url = GURL("http://www.google.com/");
386 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
387 net_log_, callback_.callback()));
388 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
389 callback_.callback()));
391 // Ack the request.
392 ProcessPacket(ConstructAckPacket(1, 0, 0));
394 EXPECT_EQ(ERR_IO_PENDING,
395 stream_->ReadResponseHeaders(callback_.callback()));
397 SpdyHeaderBlock headers;
398 headers[":status"] = "200 OK";
399 headers[":version"] = "HTTP/1.1";
400 headers["content-type"] = "text/plain";
401 headers["big6"] = std::string(10000, 'x'); // Lots of x's.
403 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers);
404 EXPECT_LT(4096u, response.length());
405 stream_->OnDataReceived(response.data(), response.length());
406 stream_->OnClose(QUIC_NO_ERROR);
408 // Now that the headers have been processed, the callback will return.
409 EXPECT_EQ(OK, callback_.WaitForResult());
410 ASSERT_TRUE(response_.headers.get());
411 EXPECT_EQ(200, response_.headers->response_code());
412 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
414 // There is no body, so this should return immediately.
415 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
416 read_buffer_->size(),
417 callback_.callback()));
418 EXPECT_TRUE(stream_->IsResponseBodyComplete());
419 EXPECT_TRUE(AtEof());
422 // Regression test for http://crbug.com/409101
423 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
424 SetRequest("GET", "/", DEFAULT_PRIORITY);
425 Initialize();
427 request_.method = "GET";
428 request_.url = GURL("http://www.google.com/");
430 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
431 net_log_, callback_.callback()));
433 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
435 EXPECT_EQ(ERR_CONNECTION_CLOSED,
436 stream_->SendRequest(headers_, &response_,
437 callback_.callback()));
440 // Regression test for http://crbug.com/409871
441 TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
442 SetRequest("GET", "/", DEFAULT_PRIORITY);
443 AddWrite(ConstructRequestHeadersPacket(1, kFin, 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 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
453 callback_.callback()));
455 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
457 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
460 TEST_P(QuicHttpStreamTest, SendPostRequest) {
461 SetRequest("POST", "/", DEFAULT_PRIORITY);
462 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
463 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
464 AddWrite(ConstructAckPacket(3, 3, 1));
466 Initialize();
468 ScopedVector<UploadElementReader> element_readers;
469 element_readers.push_back(
470 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
471 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
472 request_.method = "POST";
473 request_.url = GURL("http://www.google.com/");
474 request_.upload_data_stream = &upload_data_stream;
475 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
477 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
478 net_log_, callback_.callback()));
479 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
480 callback_.callback()));
482 // Ack both packets in the request.
483 ProcessPacket(ConstructAckPacket(1, 0, 0));
485 // Send the response headers (but not the body).
486 SetResponse("200 OK", std::string());
487 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
489 // Since the headers have already arrived, this should return immediately.
490 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
491 ASSERT_TRUE(response_.headers.get());
492 EXPECT_EQ(200, response_.headers->response_code());
493 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
495 // Send the response body.
496 const char kResponseBody[] = "Hello world!";
497 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
498 // Since the body has already arrived, this should return immediately.
499 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
500 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
501 callback_.callback()));
503 EXPECT_TRUE(stream_->IsResponseBodyComplete());
504 EXPECT_TRUE(AtEof());
507 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
508 SetRequest("POST", "/", DEFAULT_PRIORITY);
509 size_t chunk_size = strlen(kUploadData);
510 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
511 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
512 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
513 kUploadData));
514 AddWrite(ConstructAckPacket(4, 3, 1));
515 Initialize();
517 ChunkedUploadDataStream upload_data_stream(0);
518 upload_data_stream.AppendData(kUploadData, chunk_size, false);
520 request_.method = "POST";
521 request_.url = GURL("http://www.google.com/");
522 request_.upload_data_stream = &upload_data_stream;
523 ASSERT_EQ(OK, request_.upload_data_stream->Init(
524 TestCompletionCallback().callback()));
526 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
527 net_log_, callback_.callback()));
528 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
529 callback_.callback()));
531 upload_data_stream.AppendData(kUploadData, chunk_size, true);
533 // Ack both packets in the request.
534 ProcessPacket(ConstructAckPacket(1, 0, 0));
536 // Send the response headers (but not the body).
537 SetResponse("200 OK", std::string());
538 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
540 // Since the headers have already arrived, this should return immediately.
541 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
542 ASSERT_TRUE(response_.headers.get());
543 EXPECT_EQ(200, response_.headers->response_code());
544 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
546 // Send the response body.
547 const char kResponseBody[] = "Hello world!";
548 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
549 kResponseBody));
551 // Since the body has already arrived, this should return immediately.
552 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
553 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
554 callback_.callback()));
556 EXPECT_TRUE(stream_->IsResponseBodyComplete());
557 EXPECT_TRUE(AtEof());
560 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
561 SetRequest("POST", "/", DEFAULT_PRIORITY);
562 size_t chunk_size = strlen(kUploadData);
563 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
564 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
565 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
566 AddWrite(ConstructAckPacket(4, 3, 1));
567 Initialize();
569 ChunkedUploadDataStream upload_data_stream(0);
570 upload_data_stream.AppendData(kUploadData, chunk_size, false);
572 request_.method = "POST";
573 request_.url = GURL("http://www.google.com/");
574 request_.upload_data_stream = &upload_data_stream;
575 ASSERT_EQ(OK, request_.upload_data_stream->Init(
576 TestCompletionCallback().callback()));
578 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
579 net_log_, callback_.callback()));
580 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
581 callback_.callback()));
583 upload_data_stream.AppendData(nullptr, 0, true);
585 ProcessPacket(ConstructAckPacket(1, 0, 0));
587 // Send the response headers (but not the body).
588 SetResponse("200 OK", std::string());
589 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
591 // Since the headers have already arrived, this should return immediately.
592 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
593 ASSERT_TRUE(response_.headers.get());
594 EXPECT_EQ(200, response_.headers->response_code());
595 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
597 // Send the response body.
598 const char kResponseBody[] = "Hello world!";
599 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
600 kResponseBody));
602 // Since the body has already arrived, this should return immediately.
603 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
604 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
605 callback_.callback()));
607 EXPECT_TRUE(stream_->IsResponseBodyComplete());
608 EXPECT_TRUE(AtEof());
611 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
612 SetRequest("POST", "/", DEFAULT_PRIORITY);
613 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
614 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
615 AddWrite(ConstructAckPacket(3, 3, 1));
616 Initialize();
618 ChunkedUploadDataStream upload_data_stream(0);
620 request_.method = "POST";
621 request_.url = GURL("http://www.google.com/");
622 request_.upload_data_stream = &upload_data_stream;
623 ASSERT_EQ(OK, request_.upload_data_stream->Init(
624 TestCompletionCallback().callback()));
626 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
627 net_log_, callback_.callback()));
628 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
629 callback_.callback()));
631 upload_data_stream.AppendData(nullptr, 0, true);
633 ProcessPacket(ConstructAckPacket(1, 0, 0));
635 // Send the response headers (but not the body).
636 SetResponse("200 OK", std::string());
637 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
639 // Since the headers have already arrived, this should return immediately.
640 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
641 ASSERT_TRUE(response_.headers.get());
642 EXPECT_EQ(200, response_.headers->response_code());
643 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
645 // Send the response body.
646 const char kResponseBody[] = "Hello world!";
647 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
648 kResponseBody));
650 // Since the body has already arrived, this should return immediately.
651 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
652 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
653 callback_.callback()));
655 EXPECT_TRUE(stream_->IsResponseBodyComplete());
656 EXPECT_TRUE(AtEof());
659 TEST_P(QuicHttpStreamTest, DestroyedEarly) {
660 SetRequest("GET", "/", DEFAULT_PRIORITY);
661 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
662 AddWrite(ConstructAckAndRstStreamPacket(2));
663 use_closing_stream_ = true;
664 Initialize();
666 request_.method = "GET";
667 request_.url = GURL("http://www.google.com/");
669 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
670 net_log_, callback_.callback()));
671 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
672 callback_.callback()));
674 // Ack the request.
675 ProcessPacket(ConstructAckPacket(1, 0, 0));
676 EXPECT_EQ(ERR_IO_PENDING,
677 stream_->ReadResponseHeaders(callback_.callback()));
679 // Send the response with a body.
680 SetResponse("404 OK", "hello world!");
681 // In the course of processing this packet, the QuicHttpStream close itself.
682 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
684 EXPECT_TRUE(AtEof());
687 TEST_P(QuicHttpStreamTest, Priority) {
688 SetRequest("GET", "/", MEDIUM);
689 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM));
690 AddWrite(ConstructAckAndRstStreamPacket(2));
691 use_closing_stream_ = true;
692 Initialize();
694 request_.method = "GET";
695 request_.url = GURL("http://www.google.com/");
697 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
698 net_log_, callback_.callback()));
700 // Check that priority is highest.
701 QuicReliableClientStream* reliable_stream =
702 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
703 DCHECK(reliable_stream);
704 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
705 reliable_stream->EffectivePriority());
707 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
708 callback_.callback()));
710 // Check that priority has now dropped back to MEDIUM.
711 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
712 reliable_stream->EffectivePriority()));
714 // Ack the request.
715 ProcessPacket(ConstructAckPacket(1, 0, 0));
716 EXPECT_EQ(ERR_IO_PENDING,
717 stream_->ReadResponseHeaders(callback_.callback()));
719 // Send the response with a body.
720 SetResponse("404 OK", "hello world!");
721 // In the course of processing this packet, the QuicHttpStream close itself.
722 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
724 EXPECT_TRUE(AtEof());
727 // Regression test for http://crbug.com/294870
728 TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
729 SetRequest("GET", "/", MEDIUM);
730 use_closing_stream_ = true;
732 AddWrite(ConstructRstStreamPacket(1));
734 Initialize();
736 request_.method = "GET";
737 request_.url = GURL("http://www.google.com/");
739 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
740 net_log_, callback_.callback()));
742 // Check that priority is highest.
743 QuicReliableClientStream* reliable_stream =
744 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
745 DCHECK(reliable_stream);
746 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
747 DCHECK(delegate);
748 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
749 reliable_stream->EffectivePriority());
751 // Set Delegate to nullptr and make sure EffectivePriority returns highest
752 // priority.
753 reliable_stream->SetDelegate(nullptr);
754 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
755 reliable_stream->EffectivePriority());
756 reliable_stream->SetDelegate(delegate);
759 } // namespace test
760 } // namespace net