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"
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_chromium_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_flags.h"
27 #include "net/quic/quic_http_utils.h"
28 #include "net/quic/quic_reliable_client_stream.h"
29 #include "net/quic/quic_write_blocked_list.h"
30 #include "net/quic/spdy_utils.h"
31 #include "net/quic/test_tools/mock_clock.h"
32 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
33 #include "net/quic/test_tools/mock_random.h"
34 #include "net/quic/test_tools/quic_connection_peer.h"
35 #include "net/quic/test_tools/quic_test_packet_maker.h"
36 #include "net/quic/test_tools/quic_test_utils.h"
37 #include "net/quic/test_tools/test_task_runner.h"
38 #include "net/socket/socket_test_util.h"
39 #include "net/spdy/spdy_frame_builder.h"
40 #include "net/spdy/spdy_framer.h"
41 #include "net/spdy/spdy_http_utils.h"
42 #include "net/spdy/spdy_protocol.h"
43 #include "testing/gmock/include/gmock/gmock.h"
44 #include "testing/gtest/include/gtest/gtest.h"
47 using testing::AnyNumber
;
48 using testing::Return
;
54 const char kUploadData
[] = "Really nifty data!";
55 const char kDefaultServerHostName
[] = "www.google.com";
56 const uint16 kDefaultServerPort
= 80;
58 class TestQuicConnection
: public QuicConnection
{
60 TestQuicConnection(const QuicVersionVector
& versions
,
61 QuicConnectionId connection_id
,
63 QuicConnectionHelper
* helper
,
64 const QuicConnection::PacketWriterFactory
& writer_factory
)
65 : QuicConnection(connection_id
,
69 true /* owns_writer */,
70 Perspective::IS_CLIENT
,
71 false /* is_secure */,
74 void SetSendAlgorithm(SendAlgorithmInterface
* send_algorithm
) {
75 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm
);
79 // Subclass of QuicHttpStream that closes itself when the first piece of data
81 class AutoClosingStream
: public QuicHttpStream
{
83 explicit AutoClosingStream(
84 const base::WeakPtr
<QuicChromiumClientSession
>& session
)
85 : QuicHttpStream(session
) {}
87 void OnHeadersAvailable(const SpdyHeaderBlock
& headers
) override
{
91 void OnDataAvailable() override
{ Close(false); }
94 class TestPacketWriterFactory
: public QuicConnection::PacketWriterFactory
{
96 explicit TestPacketWriterFactory(DatagramClientSocket
* socket
)
98 ~TestPacketWriterFactory() override
{}
100 QuicPacketWriter
* Create(QuicConnection
* connection
) const override
{
101 return new QuicDefaultPacketWriter(socket_
);
105 DatagramClientSocket
* socket_
;
110 class QuicHttpStreamPeer
{
112 static QuicReliableClientStream
* GetQuicReliableClientStream(
113 QuicHttpStream
* stream
) {
114 return stream
->stream_
;
118 class QuicHttpStreamTest
: public ::testing::TestWithParam
<QuicVersion
> {
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
)
132 QuicEncryptedPacket
* packet
;
136 : net_log_(BoundNetLog()),
137 use_closing_stream_(false),
138 read_buffer_(new IOBufferWithSize(4096)),
140 stream_id_(kClientDataStreamId1
),
141 maker_(GetParam(), connection_id_
, &clock_
, kDefaultServerHostName
),
142 random_generator_(0) {
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
;
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.
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(),
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())
198 .WillRepeatedly(Return(QuicTime::Delta::Zero()));
199 EXPECT_CALL(*send_algorithm_
, GetCongestionWindow())
200 .WillRepeatedly(Return(kMaxPacketSize
));
201 EXPECT_CALL(*send_algorithm_
, PacingRate())
202 .WillRepeatedly(Return(QuicBandwidth::Zero()));
203 EXPECT_CALL(*send_algorithm_
, TimeUntilSend(_
, _
, _
))
204 .WillRepeatedly(Return(QuicTime::Delta::Zero()));
205 EXPECT_CALL(*send_algorithm_
, BandwidthEstimate())
206 .WillRepeatedly(Return(QuicBandwidth::Zero()));
207 EXPECT_CALL(*send_algorithm_
, SetFromConfig(_
, _
)).Times(AnyNumber());
208 helper_
.reset(new QuicConnectionHelper(runner_
.get(), &clock_
,
209 &random_generator_
));
210 TestPacketWriterFactory
writer_factory(socket
);
211 connection_
= new TestQuicConnection(SupportedVersions(GetParam()),
212 connection_id_
, peer_addr_
,
213 helper_
.get(), writer_factory
);
214 connection_
->set_visitor(&visitor_
);
215 connection_
->SetSendAlgorithm(send_algorithm_
);
216 session_
.reset(new QuicChromiumClientSession(
217 connection_
, scoped_ptr
<DatagramClientSocket
>(socket
),
218 /*stream_factory=*/nullptr, &crypto_client_stream_factory_
,
219 &transport_security_state_
, make_scoped_ptr((QuicServerInfo
*)nullptr),
220 QuicServerId(kDefaultServerHostName
, kDefaultServerPort
,
221 /*is_secure=*/false, PRIVACY_MODE_DISABLED
),
222 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_
,
223 "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
224 base::ThreadTaskRunnerHandle::Get().get(), nullptr));
225 session_
->Initialize();
226 session_
->GetCryptoStream()->CryptoConnect();
227 EXPECT_TRUE(session_
->IsCryptoHandshakeConfirmed());
228 stream_
.reset(use_closing_stream_
?
229 new AutoClosingStream(session_
->GetWeakPtr()) :
230 new QuicHttpStream(session_
->GetWeakPtr()));
233 void SetRequest(const std::string
& method
,
234 const std::string
& path
,
235 RequestPriority priority
) {
236 request_headers_
= maker_
.GetRequestHeaders(method
, "http", path
);
239 void SetResponse(const std::string
& status
, const std::string
& body
) {
240 response_headers_
= maker_
.GetResponseHeaders(status
);
241 response_data_
= body
;
244 scoped_ptr
<QuicEncryptedPacket
> ConstructDataPacket(
245 QuicPacketSequenceNumber sequence_number
,
246 bool should_include_version
,
248 QuicStreamOffset offset
,
249 base::StringPiece data
) {
250 return maker_
.MakeDataPacket(sequence_number
, stream_id_
,
251 should_include_version
, fin
, offset
, data
);
254 scoped_ptr
<QuicEncryptedPacket
> ConstructRequestHeadersPacket(
255 QuicPacketSequenceNumber sequence_number
,
257 RequestPriority request_priority
) {
258 QuicPriority priority
=
259 ConvertRequestPriorityToQuicPriority(request_priority
);
260 return maker_
.MakeRequestHeadersPacket(sequence_number
, stream_id_
,
261 kIncludeVersion
, fin
, priority
,
265 scoped_ptr
<QuicEncryptedPacket
> ConstructResponseHeadersPacket(
266 QuicPacketSequenceNumber sequence_number
,
268 return maker_
.MakeResponseHeadersPacket(
269 sequence_number
, stream_id_
, !kIncludeVersion
, fin
, response_headers_
);
272 scoped_ptr
<QuicEncryptedPacket
> ConstructRstStreamPacket(
273 QuicPacketSequenceNumber sequence_number
) {
274 return maker_
.MakeRstPacket(
275 sequence_number
, true, stream_id_
,
276 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT
, GetParam()));
279 scoped_ptr
<QuicEncryptedPacket
> ConstructRstStreamCancelledPacket(
280 QuicPacketSequenceNumber sequence_number
) {
281 return maker_
.MakeRstPacket(sequence_number
, !kIncludeVersion
, stream_id_
,
282 QUIC_STREAM_CANCELLED
);
285 scoped_ptr
<QuicEncryptedPacket
> ConstructAckAndRstStreamPacket(
286 QuicPacketSequenceNumber sequence_number
) {
287 return maker_
.MakeAckAndRstPacket(
288 sequence_number
, !kIncludeVersion
, stream_id_
, QUIC_STREAM_CANCELLED
,
289 2, 1, !kIncludeCongestionFeedback
);
292 scoped_ptr
<QuicEncryptedPacket
> ConstructAckPacket(
293 QuicPacketSequenceNumber sequence_number
,
294 QuicPacketSequenceNumber largest_received
,
295 QuicPacketSequenceNumber least_unacked
) {
296 return maker_
.MakeAckPacket(sequence_number
, largest_received
,
297 least_unacked
, !kIncludeCongestionFeedback
);
300 BoundNetLog net_log_
;
301 bool use_closing_stream_
;
302 MockSendAlgorithm
* send_algorithm_
;
303 scoped_refptr
<TestTaskRunner
> runner_
;
304 scoped_ptr
<MockWrite
[]> mock_writes_
;
306 TestQuicConnection
* connection_
;
307 scoped_ptr
<QuicConnectionHelper
> helper_
;
308 testing::StrictMock
<MockConnectionVisitor
> visitor_
;
309 scoped_ptr
<QuicHttpStream
> stream_
;
310 TransportSecurityState transport_security_state_
;
311 scoped_ptr
<QuicChromiumClientSession
> session_
;
312 QuicCryptoClientConfig crypto_config_
;
313 TestCompletionCallback callback_
;
314 HttpRequestInfo request_
;
315 HttpRequestHeaders headers_
;
316 HttpResponseInfo response_
;
317 scoped_refptr
<IOBufferWithSize
> read_buffer_
;
318 SpdyHeaderBlock request_headers_
;
319 SpdyHeaderBlock response_headers_
;
320 std::string request_data_
;
321 std::string response_data_
;
324 const QuicConnectionId connection_id_
;
325 const QuicStreamId stream_id_
;
326 QuicTestPacketMaker maker_
;
327 IPEndPoint self_addr_
;
328 IPEndPoint peer_addr_
;
329 MockRandom random_generator_
;
330 MockCryptoClientStreamFactory crypto_client_stream_factory_
;
331 scoped_ptr
<StaticSocketDataProvider
> socket_data_
;
332 std::vector
<PacketToWrite
> writes_
;
335 INSTANTIATE_TEST_CASE_P(Version
, QuicHttpStreamTest
,
336 ::testing::ValuesIn(QuicSupportedVersions()));
338 TEST_P(QuicHttpStreamTest
, RenewStreamForAuth
) {
340 EXPECT_EQ(nullptr, stream_
->RenewStreamForAuth());
343 TEST_P(QuicHttpStreamTest
, CanFindEndOfResponse
) {
345 EXPECT_TRUE(stream_
->CanFindEndOfResponse());
348 TEST_P(QuicHttpStreamTest
, IsConnectionReusable
) {
350 EXPECT_FALSE(stream_
->IsConnectionReusable());
353 TEST_P(QuicHttpStreamTest
, GetRequest
) {
354 SetRequest("GET", "/", DEFAULT_PRIORITY
);
355 AddWrite(ConstructRequestHeadersPacket(1, kFin
, DEFAULT_PRIORITY
));
358 request_
.method
= "GET";
359 request_
.url
= GURL("http://www.google.com/");
361 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
362 net_log_
, callback_
.callback()));
363 EXPECT_EQ(OK
, stream_
->SendRequest(headers_
, &response_
,
364 callback_
.callback()));
367 ProcessPacket(ConstructAckPacket(1, 0, 0));
369 EXPECT_EQ(ERR_IO_PENDING
,
370 stream_
->ReadResponseHeaders(callback_
.callback()));
372 SetResponse("404 Not Found", std::string());
373 ProcessPacket(ConstructResponseHeadersPacket(2, kFin
));
375 // Now that the headers have been processed, the callback will return.
376 EXPECT_EQ(OK
, callback_
.WaitForResult());
377 ASSERT_TRUE(response_
.headers
.get());
378 EXPECT_EQ(404, response_
.headers
->response_code());
379 EXPECT_TRUE(response_
.headers
->HasHeaderValue("Content-Type", "text/plain"));
380 EXPECT_FALSE(response_
.response_time
.is_null());
381 EXPECT_FALSE(response_
.request_time
.is_null());
383 // There is no body, so this should return immediately.
384 EXPECT_EQ(0, stream_
->ReadResponseBody(read_buffer_
.get(),
385 read_buffer_
->size(),
386 callback_
.callback()));
387 EXPECT_TRUE(stream_
->IsResponseBodyComplete());
388 EXPECT_TRUE(AtEof());
391 // Regression test for http://crbug.com/288128
392 TEST_P(QuicHttpStreamTest
, GetRequestLargeResponse
) {
393 SetRequest("GET", "/", DEFAULT_PRIORITY
);
394 AddWrite(ConstructRequestHeadersPacket(1, kFin
, DEFAULT_PRIORITY
));
397 request_
.method
= "GET";
398 request_
.url
= GURL("http://www.google.com/");
400 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
401 net_log_
, callback_
.callback()));
402 EXPECT_EQ(OK
, stream_
->SendRequest(headers_
, &response_
,
403 callback_
.callback()));
406 ProcessPacket(ConstructAckPacket(1, 0, 0));
408 EXPECT_EQ(ERR_IO_PENDING
,
409 stream_
->ReadResponseHeaders(callback_
.callback()));
411 SpdyHeaderBlock headers
;
412 headers
[":status"] = "200 OK";
413 headers
[":version"] = "HTTP/1.1";
414 headers
["content-type"] = "text/plain";
415 headers
["big6"] = std::string(1000, 'x'); // Lots of x's.
417 response_headers_
= headers
;
418 ProcessPacket(ConstructResponseHeadersPacket(2, kFin
));
420 // Now that the headers have been processed, the callback will return.
421 EXPECT_EQ(OK
, callback_
.WaitForResult());
422 ASSERT_TRUE(response_
.headers
.get());
423 EXPECT_EQ(200, response_
.headers
->response_code());
424 EXPECT_TRUE(response_
.headers
->HasHeaderValue("Content-Type", "text/plain"));
426 // There is no body, so this should return immediately.
427 EXPECT_EQ(0, stream_
->ReadResponseBody(read_buffer_
.get(),
428 read_buffer_
->size(),
429 callback_
.callback()));
430 EXPECT_TRUE(stream_
->IsResponseBodyComplete());
431 EXPECT_TRUE(AtEof());
434 // Regression test for http://crbug.com/409101
435 TEST_P(QuicHttpStreamTest
, SessionClosedBeforeSendRequest
) {
436 SetRequest("GET", "/", DEFAULT_PRIORITY
);
439 request_
.method
= "GET";
440 request_
.url
= GURL("http://www.google.com/");
442 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
443 net_log_
, callback_
.callback()));
445 session_
->connection()->CloseConnection(QUIC_NO_ERROR
, true);
447 EXPECT_EQ(ERR_CONNECTION_CLOSED
,
448 stream_
->SendRequest(headers_
, &response_
,
449 callback_
.callback()));
452 // Regression test for http://crbug.com/409871
453 TEST_P(QuicHttpStreamTest
, SessionClosedBeforeReadResponseHeaders
) {
454 SetRequest("GET", "/", DEFAULT_PRIORITY
);
455 AddWrite(ConstructRequestHeadersPacket(1, kFin
, DEFAULT_PRIORITY
));
458 request_
.method
= "GET";
459 request_
.url
= GURL("http://www.google.com/");
461 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
462 net_log_
, callback_
.callback()));
464 EXPECT_EQ(OK
, stream_
->SendRequest(headers_
, &response_
,
465 callback_
.callback()));
467 session_
->connection()->CloseConnection(QUIC_NO_ERROR
, true);
469 EXPECT_NE(OK
, stream_
->ReadResponseHeaders(callback_
.callback()));
472 TEST_P(QuicHttpStreamTest
, SendPostRequest
) {
473 SetRequest("POST", "/", DEFAULT_PRIORITY
);
474 AddWrite(ConstructRequestHeadersPacket(1, !kFin
, DEFAULT_PRIORITY
));
475 AddWrite(ConstructDataPacket(2, kIncludeVersion
, kFin
, 0, kUploadData
));
476 AddWrite(ConstructAckPacket(3, 3, 1));
480 ScopedVector
<UploadElementReader
> element_readers
;
481 element_readers
.push_back(
482 new UploadBytesElementReader(kUploadData
, strlen(kUploadData
)));
483 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
484 request_
.method
= "POST";
485 request_
.url
= GURL("http://www.google.com/");
486 request_
.upload_data_stream
= &upload_data_stream
;
487 ASSERT_EQ(OK
, request_
.upload_data_stream
->Init(CompletionCallback()));
489 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
490 net_log_
, callback_
.callback()));
491 EXPECT_EQ(OK
, stream_
->SendRequest(headers_
, &response_
,
492 callback_
.callback()));
494 // Ack both packets in the request.
495 ProcessPacket(ConstructAckPacket(1, 0, 0));
497 // Send the response headers (but not the body).
498 SetResponse("200 OK", std::string());
499 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin
));
501 // The headers have arrived, but they are delivered asynchronously.
502 EXPECT_EQ(ERR_IO_PENDING
, stream_
->ReadResponseHeaders(callback_
.callback()));
503 EXPECT_EQ(OK
, callback_
.WaitForResult());
504 ASSERT_TRUE(response_
.headers
.get());
505 EXPECT_EQ(200, response_
.headers
->response_code());
506 EXPECT_TRUE(response_
.headers
->HasHeaderValue("Content-Type", "text/plain"));
508 // Send the response body.
509 const char kResponseBody
[] = "Hello world!";
510 ProcessPacket(ConstructDataPacket(3, false, kFin
, 0, kResponseBody
));
511 // Since the body has already arrived, this should return immediately.
512 EXPECT_EQ(static_cast<int>(strlen(kResponseBody
)),
513 stream_
->ReadResponseBody(read_buffer_
.get(), read_buffer_
->size(),
514 callback_
.callback()));
516 EXPECT_TRUE(stream_
->IsResponseBodyComplete());
517 EXPECT_TRUE(AtEof());
520 TEST_P(QuicHttpStreamTest
, SendChunkedPostRequest
) {
521 SetRequest("POST", "/", DEFAULT_PRIORITY
);
522 size_t chunk_size
= strlen(kUploadData
);
523 AddWrite(ConstructRequestHeadersPacket(1, !kFin
, DEFAULT_PRIORITY
));
524 AddWrite(ConstructDataPacket(2, kIncludeVersion
, !kFin
, 0, kUploadData
));
525 AddWrite(ConstructDataPacket(3, kIncludeVersion
, kFin
, chunk_size
,
527 AddWrite(ConstructAckPacket(4, 3, 1));
530 ChunkedUploadDataStream
upload_data_stream(0);
531 upload_data_stream
.AppendData(kUploadData
, chunk_size
, false);
533 request_
.method
= "POST";
534 request_
.url
= GURL("http://www.google.com/");
535 request_
.upload_data_stream
= &upload_data_stream
;
536 ASSERT_EQ(OK
, request_
.upload_data_stream
->Init(
537 TestCompletionCallback().callback()));
539 ASSERT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
540 net_log_
, callback_
.callback()));
541 ASSERT_EQ(ERR_IO_PENDING
, stream_
->SendRequest(headers_
, &response_
,
542 callback_
.callback()));
544 upload_data_stream
.AppendData(kUploadData
, chunk_size
, true);
545 EXPECT_EQ(OK
, callback_
.WaitForResult());
547 // Ack both packets in the request.
548 ProcessPacket(ConstructAckPacket(1, 0, 0));
550 // Send the response headers (but not the body).
551 SetResponse("200 OK", std::string());
552 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin
));
554 // The headers have arrived, but they are delivered asynchronously
555 EXPECT_EQ(ERR_IO_PENDING
, stream_
->ReadResponseHeaders(callback_
.callback()));
556 EXPECT_EQ(OK
, callback_
.WaitForResult());
557 ASSERT_TRUE(response_
.headers
.get());
558 EXPECT_EQ(200, response_
.headers
->response_code());
559 EXPECT_TRUE(response_
.headers
->HasHeaderValue("Content-Type", "text/plain"));
561 // Send the response body.
562 const char kResponseBody
[] = "Hello world!";
563 ProcessPacket(ConstructDataPacket(3, false, kFin
, response_data_
.length(),
566 // Since the body has already arrived, this should return immediately.
567 ASSERT_EQ(static_cast<int>(strlen(kResponseBody
)),
568 stream_
->ReadResponseBody(read_buffer_
.get(), read_buffer_
->size(),
569 callback_
.callback()));
571 EXPECT_TRUE(stream_
->IsResponseBodyComplete());
572 EXPECT_TRUE(AtEof());
575 TEST_P(QuicHttpStreamTest
, SendChunkedPostRequestWithFinalEmptyDataPacket
) {
576 SetRequest("POST", "/", DEFAULT_PRIORITY
);
577 size_t chunk_size
= strlen(kUploadData
);
578 AddWrite(ConstructRequestHeadersPacket(1, !kFin
, DEFAULT_PRIORITY
));
579 AddWrite(ConstructDataPacket(2, kIncludeVersion
, !kFin
, 0, kUploadData
));
580 AddWrite(ConstructDataPacket(3, kIncludeVersion
, kFin
, chunk_size
, ""));
581 AddWrite(ConstructAckPacket(4, 3, 1));
584 ChunkedUploadDataStream
upload_data_stream(0);
585 upload_data_stream
.AppendData(kUploadData
, chunk_size
, false);
587 request_
.method
= "POST";
588 request_
.url
= GURL("http://www.google.com/");
589 request_
.upload_data_stream
= &upload_data_stream
;
590 ASSERT_EQ(OK
, request_
.upload_data_stream
->Init(
591 TestCompletionCallback().callback()));
593 ASSERT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
594 net_log_
, callback_
.callback()));
595 ASSERT_EQ(ERR_IO_PENDING
, stream_
->SendRequest(headers_
, &response_
,
596 callback_
.callback()));
598 upload_data_stream
.AppendData(nullptr, 0, true);
599 EXPECT_EQ(OK
, callback_
.WaitForResult());
601 ProcessPacket(ConstructAckPacket(1, 0, 0));
603 // Send the response headers (but not the body).
604 SetResponse("200 OK", std::string());
605 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin
));
607 // The headers have arrived, but they are delivered asynchronously
608 EXPECT_EQ(ERR_IO_PENDING
, stream_
->ReadResponseHeaders(callback_
.callback()));
609 EXPECT_EQ(OK
, callback_
.WaitForResult());
610 ASSERT_TRUE(response_
.headers
.get());
611 EXPECT_EQ(200, response_
.headers
->response_code());
612 EXPECT_TRUE(response_
.headers
->HasHeaderValue("Content-Type", "text/plain"));
614 // Send the response body.
615 const char kResponseBody
[] = "Hello world!";
616 ProcessPacket(ConstructDataPacket(3, false, kFin
, response_data_
.length(),
619 // The body has arrived, but it is delivered asynchronously
620 ASSERT_EQ(static_cast<int>(strlen(kResponseBody
)),
621 stream_
->ReadResponseBody(read_buffer_
.get(), read_buffer_
->size(),
622 callback_
.callback()));
623 EXPECT_TRUE(stream_
->IsResponseBodyComplete());
624 EXPECT_TRUE(AtEof());
627 TEST_P(QuicHttpStreamTest
, SendChunkedPostRequestWithOneEmptyDataPacket
) {
628 SetRequest("POST", "/", DEFAULT_PRIORITY
);
629 AddWrite(ConstructRequestHeadersPacket(1, !kFin
, DEFAULT_PRIORITY
));
630 AddWrite(ConstructDataPacket(2, kIncludeVersion
, kFin
, 0, ""));
631 AddWrite(ConstructAckPacket(3, 3, 1));
634 ChunkedUploadDataStream
upload_data_stream(0);
636 request_
.method
= "POST";
637 request_
.url
= GURL("http://www.google.com/");
638 request_
.upload_data_stream
= &upload_data_stream
;
639 ASSERT_EQ(OK
, request_
.upload_data_stream
->Init(
640 TestCompletionCallback().callback()));
642 ASSERT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
643 net_log_
, callback_
.callback()));
644 ASSERT_EQ(ERR_IO_PENDING
, stream_
->SendRequest(headers_
, &response_
,
645 callback_
.callback()));
647 upload_data_stream
.AppendData(nullptr, 0, true);
648 EXPECT_EQ(OK
, callback_
.WaitForResult());
650 ProcessPacket(ConstructAckPacket(1, 0, 0));
652 // Send the response headers (but not the body).
653 SetResponse("200 OK", std::string());
654 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin
));
656 // The headers have arrived, but they are delivered asynchronously
657 EXPECT_EQ(ERR_IO_PENDING
, stream_
->ReadResponseHeaders(callback_
.callback()));
658 EXPECT_EQ(OK
, callback_
.WaitForResult());
659 ASSERT_TRUE(response_
.headers
.get());
660 EXPECT_EQ(200, response_
.headers
->response_code());
661 EXPECT_TRUE(response_
.headers
->HasHeaderValue("Content-Type", "text/plain"));
663 // Send the response body.
664 const char kResponseBody
[] = "Hello world!";
665 ProcessPacket(ConstructDataPacket(3, false, kFin
, response_data_
.length(),
668 // The body has arrived, but it is delivered asynchronously
669 ASSERT_EQ(static_cast<int>(strlen(kResponseBody
)),
670 stream_
->ReadResponseBody(read_buffer_
.get(), read_buffer_
->size(),
671 callback_
.callback()));
673 EXPECT_TRUE(stream_
->IsResponseBodyComplete());
674 EXPECT_TRUE(AtEof());
677 TEST_P(QuicHttpStreamTest
, DestroyedEarly
) {
678 SetRequest("GET", "/", DEFAULT_PRIORITY
);
679 AddWrite(ConstructRequestHeadersPacket(1, kFin
, DEFAULT_PRIORITY
));
680 if (!FLAGS_quic_process_frames_inline
) {
681 AddWrite(ConstructRstStreamCancelledPacket(2));
683 AddWrite(ConstructAckAndRstStreamPacket(2));
685 use_closing_stream_
= true;
688 request_
.method
= "GET";
689 request_
.url
= GURL("http://www.google.com/");
691 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
692 net_log_
, callback_
.callback()));
693 EXPECT_EQ(OK
, stream_
->SendRequest(headers_
, &response_
,
694 callback_
.callback()));
697 ProcessPacket(ConstructAckPacket(1, 0, 0));
698 EXPECT_EQ(ERR_IO_PENDING
,
699 stream_
->ReadResponseHeaders(callback_
.callback()));
701 // Send the response with a body.
702 SetResponse("404 OK", "hello world!");
703 // In the course of processing this packet, the QuicHttpStream close itself.
704 ProcessPacket(ConstructResponseHeadersPacket(2, kFin
));
706 base::MessageLoop::current()->RunUntilIdle();
708 EXPECT_TRUE(AtEof());
711 TEST_P(QuicHttpStreamTest
, Priority
) {
712 SetRequest("GET", "/", MEDIUM
);
713 AddWrite(ConstructRequestHeadersPacket(1, kFin
, MEDIUM
));
714 if (!FLAGS_quic_process_frames_inline
) {
715 AddWrite(ConstructRstStreamCancelledPacket(2));
717 AddWrite(ConstructAckAndRstStreamPacket(2));
719 use_closing_stream_
= true;
722 request_
.method
= "GET";
723 request_
.url
= GURL("http://www.google.com/");
725 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, MEDIUM
,
726 net_log_
, callback_
.callback()));
728 // Check that priority is highest.
729 QuicReliableClientStream
* reliable_stream
=
730 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_
.get());
731 DCHECK(reliable_stream
);
732 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority
,
733 reliable_stream
->EffectivePriority());
735 EXPECT_EQ(OK
, stream_
->SendRequest(headers_
, &response_
,
736 callback_
.callback()));
738 // Check that priority has now dropped back to MEDIUM.
739 DCHECK_EQ(MEDIUM
, ConvertQuicPriorityToRequestPriority(
740 reliable_stream
->EffectivePriority()));
743 ProcessPacket(ConstructAckPacket(1, 0, 0));
744 EXPECT_EQ(ERR_IO_PENDING
,
745 stream_
->ReadResponseHeaders(callback_
.callback()));
747 // Send the response with a body.
748 SetResponse("404 OK", "hello world!");
749 // In the course of processing this packet, the QuicHttpStream close itself.
750 ProcessPacket(ConstructResponseHeadersPacket(2, kFin
));
752 base::MessageLoop::current()->RunUntilIdle();
754 EXPECT_TRUE(AtEof());
757 // Regression test for http://crbug.com/294870
758 TEST_P(QuicHttpStreamTest
, CheckPriorityWithNoDelegate
) {
759 SetRequest("GET", "/", MEDIUM
);
760 use_closing_stream_
= true;
762 AddWrite(ConstructRstStreamPacket(1));
766 request_
.method
= "GET";
767 request_
.url
= GURL("http://www.google.com/");
769 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, MEDIUM
,
770 net_log_
, callback_
.callback()));
772 // Check that priority is highest.
773 QuicReliableClientStream
* reliable_stream
=
774 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_
.get());
775 DCHECK(reliable_stream
);
776 QuicReliableClientStream::Delegate
* delegate
= reliable_stream
->GetDelegate();
778 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority
,
779 reliable_stream
->EffectivePriority());
781 // Set Delegate to nullptr and make sure EffectivePriority returns highest
783 reliable_stream
->SetDelegate(nullptr);
784 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority
,
785 reliable_stream
->EffectivePriority());
786 reliable_stream
->SetDelegate(delegate
);