Revert of Add support for escaped target names in isolate driver. (patchset #6 id...
[chromium-blink-merge.git] / net / quic / quic_http_stream_test.cc
blob71417a1ba9fcaac89dab9eed758626a416854ef2
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 false /* is_server */,
69 false /* is_secure */,
70 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_),
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);
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_->at_read_eof() && socket_data_->at_write_eof();
169 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
170 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
173 // Configures the test fixture to use the list of expected writes.
174 void Initialize() {
175 mock_writes_.reset(new MockWrite[writes_.size()]);
176 for (size_t i = 0; i < writes_.size(); i++) {
177 mock_writes_[i] = MockWrite(writes_[i].mode,
178 writes_[i].packet->data(),
179 writes_[i].packet->length());
182 socket_data_.reset(new StaticSocketDataProvider(
183 nullptr, 0, mock_writes_.get(), writes_.size()));
185 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
186 net_log_.net_log());
187 socket->Connect(peer_addr_);
188 runner_ = new TestTaskRunner(&clock_);
189 send_algorithm_ = new MockSendAlgorithm();
190 EXPECT_CALL(*send_algorithm_,
191 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
192 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
193 Return(QuicTime::Delta::Zero()));
194 EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
195 Return(kMaxPacketSize));
196 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).
197 WillRepeatedly(Return(QuicTime::Delta::Zero()));
198 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
199 Return(QuicBandwidth::Zero()));
200 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _)).Times(AnyNumber());
201 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
202 &random_generator_));
203 TestPacketWriterFactory writer_factory(socket);
204 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
205 connection_id_, peer_addr_,
206 helper_.get(), writer_factory);
207 connection_->set_visitor(&visitor_);
208 connection_->SetSendAlgorithm(send_algorithm_);
209 session_.reset(new QuicClientSession(
210 connection_, scoped_ptr<DatagramClientSocket>(socket), nullptr,
211 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
212 DefaultQuicConfig(), "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
213 base::MessageLoop::current()->message_loop_proxy().get(), nullptr));
214 session_->InitializeSession(QuicServerId(kServerHostname, kServerPort,
215 /*is_secure=*/false,
216 PRIVACY_MODE_DISABLED),
217 &crypto_config_,
218 &crypto_client_stream_factory_);
219 session_->GetCryptoStream()->CryptoConnect();
220 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
221 stream_.reset(use_closing_stream_ ?
222 new AutoClosingStream(session_->GetWeakPtr()) :
223 new QuicHttpStream(session_->GetWeakPtr()));
226 void SetRequest(const std::string& method,
227 const std::string& path,
228 RequestPriority priority) {
229 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
232 void SetResponse(const std::string& status, const std::string& body) {
233 response_headers_ = maker_.GetResponseHeaders(status);
234 response_data_ = body;
237 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
238 QuicPacketSequenceNumber sequence_number,
239 bool should_include_version,
240 bool fin,
241 QuicStreamOffset offset,
242 base::StringPiece data) {
243 return maker_.MakeDataPacket(sequence_number, stream_id_,
244 should_include_version, fin, offset, data);
247 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
248 QuicPacketSequenceNumber sequence_number,
249 bool fin,
250 RequestPriority request_priority) {
251 QuicPriority priority =
252 ConvertRequestPriorityToQuicPriority(request_priority);
253 return maker_.MakeRequestHeadersPacket(sequence_number, stream_id_,
254 kIncludeVersion, fin, priority,
255 request_headers_);
258 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
259 QuicPacketSequenceNumber sequence_number,
260 bool fin) {
261 return maker_.MakeResponseHeadersPacket(
262 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_);
265 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
266 QuicPacketSequenceNumber sequence_number) {
267 return maker_.MakeRstPacket(
268 sequence_number, true, stream_id_,
269 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
272 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
273 QuicPacketSequenceNumber sequence_number) {
274 return maker_.MakeAckAndRstPacket(
275 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
276 2, 1, !kIncludeCongestionFeedback);
279 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
280 QuicPacketSequenceNumber sequence_number,
281 QuicPacketSequenceNumber largest_received,
282 QuicPacketSequenceNumber least_unacked) {
283 return maker_.MakeAckPacket(sequence_number, largest_received,
284 least_unacked, !kIncludeCongestionFeedback);
287 BoundNetLog net_log_;
288 bool use_closing_stream_;
289 MockSendAlgorithm* send_algorithm_;
290 scoped_refptr<TestTaskRunner> runner_;
291 scoped_ptr<MockWrite[]> mock_writes_;
292 MockClock clock_;
293 TestQuicConnection* connection_;
294 scoped_ptr<QuicConnectionHelper> helper_;
295 testing::StrictMock<MockConnectionVisitor> visitor_;
296 scoped_ptr<QuicHttpStream> stream_;
297 TransportSecurityState transport_security_state_;
298 scoped_ptr<QuicClientSession> session_;
299 QuicCryptoClientConfig crypto_config_;
300 TestCompletionCallback callback_;
301 HttpRequestInfo request_;
302 HttpRequestHeaders headers_;
303 HttpResponseInfo response_;
304 scoped_refptr<IOBufferWithSize> read_buffer_;
305 SpdyHeaderBlock request_headers_;
306 SpdyHeaderBlock response_headers_;
307 std::string request_data_;
308 std::string response_data_;
310 private:
311 const QuicConnectionId connection_id_;
312 const QuicStreamId stream_id_;
313 QuicTestPacketMaker maker_;
314 IPEndPoint self_addr_;
315 IPEndPoint peer_addr_;
316 MockRandom random_generator_;
317 MockCryptoClientStreamFactory crypto_client_stream_factory_;
318 scoped_ptr<StaticSocketDataProvider> socket_data_;
319 std::vector<PacketToWrite> writes_;
322 INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
323 ::testing::ValuesIn(QuicSupportedVersions()));
325 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
326 Initialize();
327 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
330 TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
331 Initialize();
332 EXPECT_TRUE(stream_->CanFindEndOfResponse());
335 TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
336 Initialize();
337 EXPECT_FALSE(stream_->IsConnectionReusable());
340 TEST_P(QuicHttpStreamTest, GetRequest) {
341 SetRequest("GET", "/", DEFAULT_PRIORITY);
342 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
343 Initialize();
345 request_.method = "GET";
346 request_.url = GURL("http://www.google.com/");
348 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
349 net_log_, callback_.callback()));
350 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
351 callback_.callback()));
353 // Ack the request.
354 ProcessPacket(ConstructAckPacket(1, 0, 0));
356 EXPECT_EQ(ERR_IO_PENDING,
357 stream_->ReadResponseHeaders(callback_.callback()));
359 SetResponse("404 Not Found", std::string());
360 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
362 // Now that the headers have been processed, the callback will return.
363 EXPECT_EQ(OK, callback_.WaitForResult());
364 ASSERT_TRUE(response_.headers.get());
365 EXPECT_EQ(404, response_.headers->response_code());
366 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
367 EXPECT_FALSE(response_.response_time.is_null());
368 EXPECT_FALSE(response_.request_time.is_null());
370 // There is no body, so this should return immediately.
371 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
372 read_buffer_->size(),
373 callback_.callback()));
374 EXPECT_TRUE(stream_->IsResponseBodyComplete());
375 EXPECT_TRUE(AtEof());
378 // Regression test for http://crbug.com/288128
379 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
380 SetRequest("GET", "/", DEFAULT_PRIORITY);
381 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
382 Initialize();
384 request_.method = "GET";
385 request_.url = GURL("http://www.google.com/");
387 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
388 net_log_, callback_.callback()));
389 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
390 callback_.callback()));
392 // Ack the request.
393 ProcessPacket(ConstructAckPacket(1, 0, 0));
395 EXPECT_EQ(ERR_IO_PENDING,
396 stream_->ReadResponseHeaders(callback_.callback()));
398 SpdyHeaderBlock headers;
399 headers[":status"] = "200 OK";
400 headers[":version"] = "HTTP/1.1";
401 headers["content-type"] = "text/plain";
402 headers["big6"] = std::string(10000, 'x'); // Lots of x's.
404 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers);
405 EXPECT_LT(4096u, response.length());
406 stream_->OnDataReceived(response.data(), response.length());
407 stream_->OnClose(QUIC_NO_ERROR);
409 // Now that the headers have been processed, the callback will return.
410 EXPECT_EQ(OK, callback_.WaitForResult());
411 ASSERT_TRUE(response_.headers.get());
412 EXPECT_EQ(200, response_.headers->response_code());
413 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
415 // There is no body, so this should return immediately.
416 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
417 read_buffer_->size(),
418 callback_.callback()));
419 EXPECT_TRUE(stream_->IsResponseBodyComplete());
420 EXPECT_TRUE(AtEof());
423 // Regression test for http://crbug.com/409101
424 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
425 SetRequest("GET", "/", DEFAULT_PRIORITY);
426 Initialize();
428 request_.method = "GET";
429 request_.url = GURL("http://www.google.com/");
431 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
432 net_log_, callback_.callback()));
434 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
436 EXPECT_EQ(ERR_CONNECTION_CLOSED,
437 stream_->SendRequest(headers_, &response_,
438 callback_.callback()));
441 // Regression test for http://crbug.com/409871
442 TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
443 SetRequest("GET", "/", DEFAULT_PRIORITY);
444 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
445 Initialize();
447 request_.method = "GET";
448 request_.url = GURL("http://www.google.com/");
450 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
451 net_log_, callback_.callback()));
453 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
454 callback_.callback()));
456 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
458 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
461 TEST_P(QuicHttpStreamTest, SendPostRequest) {
462 SetRequest("POST", "/", DEFAULT_PRIORITY);
463 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
464 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
465 AddWrite(ConstructAckPacket(3, 3, 1));
467 Initialize();
469 ScopedVector<UploadElementReader> element_readers;
470 element_readers.push_back(
471 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
472 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
473 request_.method = "POST";
474 request_.url = GURL("http://www.google.com/");
475 request_.upload_data_stream = &upload_data_stream;
476 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
478 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
479 net_log_, callback_.callback()));
480 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
481 callback_.callback()));
483 // Ack both packets in the request.
484 ProcessPacket(ConstructAckPacket(1, 0, 0));
486 // Send the response headers (but not the body).
487 SetResponse("200 OK", std::string());
488 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
490 // Since the headers have already arrived, this should return immediately.
491 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
492 ASSERT_TRUE(response_.headers.get());
493 EXPECT_EQ(200, response_.headers->response_code());
494 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
496 // Send the response body.
497 const char kResponseBody[] = "Hello world!";
498 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
499 // Since the body has already arrived, this should return immediately.
500 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
501 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
502 callback_.callback()));
504 EXPECT_TRUE(stream_->IsResponseBodyComplete());
505 EXPECT_TRUE(AtEof());
508 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
509 SetRequest("POST", "/", DEFAULT_PRIORITY);
510 size_t chunk_size = strlen(kUploadData);
511 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
512 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
513 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
514 kUploadData));
515 AddWrite(ConstructAckPacket(4, 3, 1));
516 Initialize();
518 ChunkedUploadDataStream upload_data_stream(0);
519 upload_data_stream.AppendData(kUploadData, chunk_size, false);
521 request_.method = "POST";
522 request_.url = GURL("http://www.google.com/");
523 request_.upload_data_stream = &upload_data_stream;
524 ASSERT_EQ(OK, request_.upload_data_stream->Init(
525 TestCompletionCallback().callback()));
527 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
528 net_log_, callback_.callback()));
529 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
530 callback_.callback()));
532 upload_data_stream.AppendData(kUploadData, chunk_size, true);
534 // Ack both packets in the request.
535 ProcessPacket(ConstructAckPacket(1, 0, 0));
537 // Send the response headers (but not the body).
538 SetResponse("200 OK", std::string());
539 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
541 // Since the headers have already arrived, this should return immediately.
542 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
543 ASSERT_TRUE(response_.headers.get());
544 EXPECT_EQ(200, response_.headers->response_code());
545 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
547 // Send the response body.
548 const char kResponseBody[] = "Hello world!";
549 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
550 kResponseBody));
552 // Since the body has already arrived, this should return immediately.
553 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
554 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
555 callback_.callback()));
557 EXPECT_TRUE(stream_->IsResponseBodyComplete());
558 EXPECT_TRUE(AtEof());
561 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
562 SetRequest("POST", "/", DEFAULT_PRIORITY);
563 size_t chunk_size = strlen(kUploadData);
564 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
565 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
566 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
567 AddWrite(ConstructAckPacket(4, 3, 1));
568 Initialize();
570 ChunkedUploadDataStream upload_data_stream(0);
571 upload_data_stream.AppendData(kUploadData, chunk_size, false);
573 request_.method = "POST";
574 request_.url = GURL("http://www.google.com/");
575 request_.upload_data_stream = &upload_data_stream;
576 ASSERT_EQ(OK, request_.upload_data_stream->Init(
577 TestCompletionCallback().callback()));
579 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
580 net_log_, callback_.callback()));
581 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
582 callback_.callback()));
584 upload_data_stream.AppendData(nullptr, 0, true);
586 ProcessPacket(ConstructAckPacket(1, 0, 0));
588 // Send the response headers (but not the body).
589 SetResponse("200 OK", std::string());
590 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
592 // Since the headers have already arrived, this should return immediately.
593 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
594 ASSERT_TRUE(response_.headers.get());
595 EXPECT_EQ(200, response_.headers->response_code());
596 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
598 // Send the response body.
599 const char kResponseBody[] = "Hello world!";
600 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
601 kResponseBody));
603 // Since the body has already arrived, this should return immediately.
604 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
605 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
606 callback_.callback()));
608 EXPECT_TRUE(stream_->IsResponseBodyComplete());
609 EXPECT_TRUE(AtEof());
612 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
613 SetRequest("POST", "/", DEFAULT_PRIORITY);
614 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
615 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
616 AddWrite(ConstructAckPacket(3, 3, 1));
617 Initialize();
619 ChunkedUploadDataStream upload_data_stream(0);
621 request_.method = "POST";
622 request_.url = GURL("http://www.google.com/");
623 request_.upload_data_stream = &upload_data_stream;
624 ASSERT_EQ(OK, request_.upload_data_stream->Init(
625 TestCompletionCallback().callback()));
627 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
628 net_log_, callback_.callback()));
629 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
630 callback_.callback()));
632 upload_data_stream.AppendData(nullptr, 0, true);
634 ProcessPacket(ConstructAckPacket(1, 0, 0));
636 // Send the response headers (but not the body).
637 SetResponse("200 OK", std::string());
638 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
640 // Since the headers have already arrived, this should return immediately.
641 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
642 ASSERT_TRUE(response_.headers.get());
643 EXPECT_EQ(200, response_.headers->response_code());
644 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
646 // Send the response body.
647 const char kResponseBody[] = "Hello world!";
648 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
649 kResponseBody));
651 // Since the body has already arrived, this should return immediately.
652 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
653 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
654 callback_.callback()));
656 EXPECT_TRUE(stream_->IsResponseBodyComplete());
657 EXPECT_TRUE(AtEof());
660 TEST_P(QuicHttpStreamTest, DestroyedEarly) {
661 SetRequest("GET", "/", DEFAULT_PRIORITY);
662 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
663 AddWrite(ConstructAckAndRstStreamPacket(2));
664 use_closing_stream_ = true;
665 Initialize();
667 request_.method = "GET";
668 request_.url = GURL("http://www.google.com/");
670 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
671 net_log_, callback_.callback()));
672 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
673 callback_.callback()));
675 // Ack the request.
676 ProcessPacket(ConstructAckPacket(1, 0, 0));
677 EXPECT_EQ(ERR_IO_PENDING,
678 stream_->ReadResponseHeaders(callback_.callback()));
680 // Send the response with a body.
681 SetResponse("404 OK", "hello world!");
682 // In the course of processing this packet, the QuicHttpStream close itself.
683 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
685 EXPECT_TRUE(AtEof());
688 TEST_P(QuicHttpStreamTest, Priority) {
689 SetRequest("GET", "/", MEDIUM);
690 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM));
691 AddWrite(ConstructAckAndRstStreamPacket(2));
692 use_closing_stream_ = true;
693 Initialize();
695 request_.method = "GET";
696 request_.url = GURL("http://www.google.com/");
698 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
699 net_log_, callback_.callback()));
701 // Check that priority is highest.
702 QuicReliableClientStream* reliable_stream =
703 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
704 DCHECK(reliable_stream);
705 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
706 reliable_stream->EffectivePriority());
708 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
709 callback_.callback()));
711 // Check that priority has now dropped back to MEDIUM.
712 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
713 reliable_stream->EffectivePriority()));
715 // Ack the request.
716 ProcessPacket(ConstructAckPacket(1, 0, 0));
717 EXPECT_EQ(ERR_IO_PENDING,
718 stream_->ReadResponseHeaders(callback_.callback()));
720 // Send the response with a body.
721 SetResponse("404 OK", "hello world!");
722 // In the course of processing this packet, the QuicHttpStream close itself.
723 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
725 EXPECT_TRUE(AtEof());
728 // Regression test for http://crbug.com/294870
729 TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
730 SetRequest("GET", "/", MEDIUM);
731 use_closing_stream_ = true;
733 AddWrite(ConstructRstStreamPacket(1));
735 Initialize();
737 request_.method = "GET";
738 request_.url = GURL("http://www.google.com/");
740 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
741 net_log_, callback_.callback()));
743 // Check that priority is highest.
744 QuicReliableClientStream* reliable_stream =
745 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
746 DCHECK(reliable_stream);
747 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
748 DCHECK(delegate);
749 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
750 reliable_stream->EffectivePriority());
752 // Set Delegate to nullptr and make sure EffectivePriority returns highest
753 // priority.
754 reliable_stream->SetDelegate(nullptr);
755 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
756 reliable_stream->EffectivePriority());
757 reliable_stream->SetDelegate(delegate);
760 } // namespace test
761 } // namespace net