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 "net/base/net_errors.h"
10 #include "net/base/test_completion_callback.h"
11 #include "net/base/upload_bytes_element_reader.h"
12 #include "net/base/upload_data_stream.h"
13 #include "net/http/http_response_headers.h"
14 #include "net/quic/congestion_control/receive_algorithm_interface.h"
15 #include "net/quic/congestion_control/send_algorithm_interface.h"
16 #include "net/quic/crypto/crypto_protocol.h"
17 #include "net/quic/crypto/quic_decrypter.h"
18 #include "net/quic/crypto/quic_encrypter.h"
19 #include "net/quic/quic_client_session.h"
20 #include "net/quic/quic_connection.h"
21 #include "net/quic/quic_connection_helper.h"
22 #include "net/quic/quic_default_packet_writer.h"
23 #include "net/quic/quic_http_utils.h"
24 #include "net/quic/quic_reliable_client_stream.h"
25 #include "net/quic/quic_write_blocked_list.h"
26 #include "net/quic/spdy_utils.h"
27 #include "net/quic/test_tools/mock_clock.h"
28 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
29 #include "net/quic/test_tools/mock_random.h"
30 #include "net/quic/test_tools/quic_connection_peer.h"
31 #include "net/quic/test_tools/quic_test_packet_maker.h"
32 #include "net/quic/test_tools/quic_test_utils.h"
33 #include "net/quic/test_tools/test_task_runner.h"
34 #include "net/socket/socket_test_util.h"
35 #include "net/spdy/spdy_frame_builder.h"
36 #include "net/spdy/spdy_framer.h"
37 #include "net/spdy/spdy_http_utils.h"
38 #include "net/spdy/spdy_protocol.h"
39 #include "testing/gmock/include/gmock/gmock.h"
40 #include "testing/gtest/include/gtest/gtest.h"
43 using testing::AnyNumber
;
44 using testing::Return
;
50 const char kUploadData
[] = "hello world!";
52 class TestQuicConnection
: public QuicConnection
{
54 TestQuicConnection(const QuicVersionVector
& versions
,
57 QuicConnectionHelper
* helper
,
58 QuicPacketWriter
* writer
)
59 : QuicConnection(guid
, address
, helper
, writer
, false, versions
) {
62 void SetSendAlgorithm(SendAlgorithmInterface
* send_algorithm
) {
63 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm
);
66 void SetReceiveAlgorithm(ReceiveAlgorithmInterface
* receive_algorithm
) {
67 QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm
);
71 class TestReceiveAlgorithm
: public ReceiveAlgorithmInterface
{
73 virtual bool GenerateCongestionFeedback(
74 QuicCongestionFeedbackFrame
* /*congestion_feedback*/) {
78 MOCK_METHOD3(RecordIncomingPacket
,
79 void(QuicByteCount
, QuicPacketSequenceNumber
, QuicTime
));
82 // Subclass of QuicHttpStream that closes itself when the first piece of data
84 class AutoClosingStream
: public QuicHttpStream
{
86 explicit AutoClosingStream(const base::WeakPtr
<QuicClientSession
>& session
)
87 : QuicHttpStream(session
) {
90 virtual int OnDataReceived(const char* data
, int length
) OVERRIDE
{
98 class QuicHttpStreamPeer
{
100 static QuicReliableClientStream
* GetQuicReliableClientStream(
101 QuicHttpStream
* stream
) {
102 return stream
->stream_
;
106 class QuicHttpStreamTest
: public ::testing::TestWithParam
<QuicVersion
> {
108 static const bool kFin
= true;
109 static const bool kIncludeVersion
= true;
110 static const bool kIncludeCongestionFeedback
= true;
112 // Holds a packet to be written to the wire, and the IO mode that should
113 // be used by the mock socket when performing the write.
114 struct PacketToWrite
{
115 PacketToWrite(IoMode mode
, QuicEncryptedPacket
* packet
)
120 QuicEncryptedPacket
* packet
;
124 : net_log_(BoundNetLog()),
125 use_closing_stream_(false),
126 read_buffer_(new IOBufferWithSize(4096)),
128 stream_id_(GetParam() > QUIC_VERSION_12
? 5 : 3),
129 maker_(GetParam(), guid_
),
130 random_generator_(0) {
132 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip
));
133 peer_addr_
= IPEndPoint(ip
, 443);
134 self_addr_
= IPEndPoint(ip
, 8435);
137 ~QuicHttpStreamTest() {
138 session_
->CloseSessionOnError(ERR_ABORTED
);
139 for (size_t i
= 0; i
< writes_
.size(); i
++) {
140 delete writes_
[i
].packet
;
144 // Adds a packet to the list of expected writes.
145 void AddWrite(scoped_ptr
<QuicEncryptedPacket
> packet
) {
146 writes_
.push_back(PacketToWrite(SYNCHRONOUS
, packet
.release()));
149 // Returns the packet to be written at position |pos|.
150 QuicEncryptedPacket
* GetWrite(size_t pos
) {
151 return writes_
[pos
].packet
;
155 return socket_data_
->at_read_eof() && socket_data_
->at_write_eof();
158 void ProcessPacket(scoped_ptr
<QuicEncryptedPacket
> packet
) {
159 connection_
->ProcessUdpPacket(self_addr_
, peer_addr_
, *packet
);
162 // Configures the test fixture to use the list of expected writes.
164 mock_writes_
.reset(new MockWrite
[writes_
.size()]);
165 for (size_t i
= 0; i
< writes_
.size(); i
++) {
166 mock_writes_
[i
] = MockWrite(writes_
[i
].mode
,
167 writes_
[i
].packet
->data(),
168 writes_
[i
].packet
->length());
171 socket_data_
.reset(new StaticSocketDataProvider(NULL
, 0, mock_writes_
.get(),
174 MockUDPClientSocket
* socket
= new MockUDPClientSocket(socket_data_
.get(),
176 socket
->Connect(peer_addr_
);
177 runner_
= new TestTaskRunner(&clock_
);
178 send_algorithm_
= new MockSendAlgorithm();
179 receive_algorithm_
= new TestReceiveAlgorithm();
180 EXPECT_CALL(*receive_algorithm_
, RecordIncomingPacket(_
, _
, _
)).
182 EXPECT_CALL(*send_algorithm_
,
183 OnPacketSent(_
, _
, _
, _
, _
)).WillRepeatedly(Return(true));
184 EXPECT_CALL(*send_algorithm_
, RetransmissionDelay()).WillRepeatedly(
185 Return(QuicTime::Delta::Zero()));
186 EXPECT_CALL(*send_algorithm_
, TimeUntilSend(_
, _
, _
, _
)).
187 WillRepeatedly(Return(QuicTime::Delta::Zero()));
188 EXPECT_CALL(*send_algorithm_
, SmoothedRtt()).WillRepeatedly(
189 Return(QuicTime::Delta::Zero()));
190 EXPECT_CALL(*send_algorithm_
, BandwidthEstimate()).WillRepeatedly(
191 Return(QuicBandwidth::Zero()));
192 EXPECT_CALL(*send_algorithm_
, SetFromConfig(_
, _
)).Times(AnyNumber());
193 helper_
.reset(new QuicConnectionHelper(runner_
.get(), &clock_
,
194 &random_generator_
));
195 writer_
.reset(new QuicDefaultPacketWriter(socket
));
196 connection_
= new TestQuicConnection(SupportedVersions(GetParam()), guid_
,
197 peer_addr_
, helper_
.get(),
199 connection_
->set_visitor(&visitor_
);
200 connection_
->SetSendAlgorithm(send_algorithm_
);
201 connection_
->SetReceiveAlgorithm(receive_algorithm_
);
202 crypto_config_
.SetDefaults();
204 new QuicClientSession(connection_
,
205 scoped_ptr
<DatagramClientSocket
>(socket
),
206 writer_
.Pass(), NULL
,
207 &crypto_client_stream_factory_
,
208 "www.google.com", DefaultQuicConfig(),
209 &crypto_config_
, NULL
));
210 session_
->GetCryptoStream()->CryptoConnect();
211 EXPECT_TRUE(session_
->IsCryptoHandshakeConfirmed());
212 stream_
.reset(use_closing_stream_
?
213 new AutoClosingStream(session_
->GetWeakPtr()) :
214 new QuicHttpStream(session_
->GetWeakPtr()));
217 void SetRequest(const std::string
& method
,
218 const std::string
& path
,
219 RequestPriority priority
) {
220 request_headers_
= maker_
.GetRequestHeaders(method
, "http", path
);
221 request_data_
= GetParam() > QUIC_VERSION_12
? "" :
222 SerializeHeaderBlock(request_headers_
, true, priority
);
225 void SetResponse(const std::string
& status
, const std::string
& body
) {
226 response_headers_
= maker_
.GetResponseHeaders(status
);
227 if (GetParam() > QUIC_VERSION_12
) {
228 response_data_
= body
;
231 SerializeHeaderBlock(response_headers_
, false, DEFAULT_PRIORITY
) +
236 scoped_ptr
<QuicEncryptedPacket
> ConstructDataPacket(
237 QuicPacketSequenceNumber sequence_number
,
238 bool should_include_version
,
240 QuicStreamOffset offset
,
241 base::StringPiece data
) {
242 return maker_
.MakeDataPacket(
243 sequence_number
, stream_id_
, should_include_version
, fin
, offset
, data
);
246 scoped_ptr
<QuicEncryptedPacket
> ConstructRequestHeadersPacket(
247 QuicPacketSequenceNumber sequence_number
,
249 return maker_
.MakeRequestHeadersPacket(
250 sequence_number
, stream_id_
, kIncludeVersion
, fin
, request_headers_
);
253 scoped_ptr
<QuicEncryptedPacket
> ConstructResponseHeadersPacket(
254 QuicPacketSequenceNumber sequence_number
,
256 return maker_
.MakeResponseHeadersPacket(
257 sequence_number
, stream_id_
, !kIncludeVersion
, fin
, response_headers_
);
260 scoped_ptr
<QuicEncryptedPacket
> ConstructRstStreamPacket(
261 QuicPacketSequenceNumber sequence_number
) {
262 return maker_
.MakeRstPacket(
263 sequence_number
, true, stream_id_
, QUIC_STREAM_NO_ERROR
);
266 scoped_ptr
<QuicEncryptedPacket
> ConstructAckAndRstStreamPacket(
267 QuicPacketSequenceNumber sequence_number
) {
268 return maker_
.MakeAckAndRstPacket(
269 sequence_number
, !kIncludeVersion
, stream_id_
, QUIC_STREAM_CANCELLED
,
270 1, 1, !kIncludeCongestionFeedback
);
273 scoped_ptr
<QuicEncryptedPacket
> ConstructAckPacket(
274 QuicPacketSequenceNumber sequence_number
,
275 QuicPacketSequenceNumber largest_received
,
276 QuicPacketSequenceNumber least_unacked
) {
277 return maker_
.MakeAckPacket(sequence_number
, largest_received
,
278 least_unacked
, !kIncludeCongestionFeedback
);
281 BoundNetLog net_log_
;
282 bool use_closing_stream_
;
283 MockSendAlgorithm
* send_algorithm_
;
284 TestReceiveAlgorithm
* receive_algorithm_
;
285 scoped_refptr
<TestTaskRunner
> runner_
;
286 scoped_ptr
<MockWrite
[]> mock_writes_
;
288 TestQuicConnection
* connection_
;
289 scoped_ptr
<QuicConnectionHelper
> helper_
;
290 testing::StrictMock
<MockConnectionVisitor
> visitor_
;
291 scoped_ptr
<QuicHttpStream
> stream_
;
292 scoped_ptr
<QuicDefaultPacketWriter
> writer_
;
293 scoped_ptr
<QuicClientSession
> session_
;
294 QuicCryptoClientConfig crypto_config_
;
295 TestCompletionCallback callback_
;
296 HttpRequestInfo request_
;
297 HttpRequestHeaders headers_
;
298 HttpResponseInfo response_
;
299 scoped_refptr
<IOBufferWithSize
> read_buffer_
;
300 SpdyHeaderBlock request_headers_
;
301 SpdyHeaderBlock response_headers_
;
302 std::string request_data_
;
303 std::string response_data_
;
306 std::string
SerializeHeaderBlock(const SpdyHeaderBlock
& headers
,
308 RequestPriority priority
) {
309 QuicSpdyCompressor compressor
;
310 if (write_priority
) {
311 return compressor
.CompressHeadersWithPriority(
312 ConvertRequestPriorityToQuicPriority(priority
), headers
);
314 return compressor
.CompressHeaders(headers
);
317 const QuicGuid guid_
;
318 const QuicStreamId stream_id_
;
319 QuicTestPacketMaker maker_
;
320 IPEndPoint self_addr_
;
321 IPEndPoint peer_addr_
;
322 MockRandom random_generator_
;
323 MockCryptoClientStreamFactory crypto_client_stream_factory_
;
324 scoped_ptr
<StaticSocketDataProvider
> socket_data_
;
325 std::vector
<PacketToWrite
> writes_
;
328 INSTANTIATE_TEST_CASE_P(Version
, QuicHttpStreamTest
,
329 ::testing::ValuesIn(QuicSupportedVersions()));
331 TEST_P(QuicHttpStreamTest
, RenewStreamForAuth
) {
333 EXPECT_EQ(NULL
, stream_
->RenewStreamForAuth());
336 TEST_P(QuicHttpStreamTest
, CanFindEndOfResponse
) {
338 EXPECT_TRUE(stream_
->CanFindEndOfResponse());
341 TEST_P(QuicHttpStreamTest
, IsConnectionReusable
) {
343 EXPECT_FALSE(stream_
->IsConnectionReusable());
346 TEST_P(QuicHttpStreamTest
, GetRequest
) {
347 SetRequest("GET", "/", DEFAULT_PRIORITY
);
348 if (GetParam() > QUIC_VERSION_12
) {
349 AddWrite(ConstructRequestHeadersPacket(1, kFin
));
351 AddWrite(ConstructDataPacket(1, kIncludeVersion
, kFin
, 0, request_data_
));
355 request_
.method
= "GET";
356 request_
.url
= GURL("http://www.google.com/");
358 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
359 net_log_
, callback_
.callback()));
360 EXPECT_EQ(OK
, stream_
->SendRequest(headers_
, &response_
,
361 callback_
.callback()));
362 EXPECT_EQ(&response_
, stream_
->GetResponseInfo());
365 ProcessPacket(ConstructAckPacket(1, 0, 0));
367 EXPECT_EQ(ERR_IO_PENDING
,
368 stream_
->ReadResponseHeaders(callback_
.callback()));
370 SetResponse("404 Not Found", std::string());
371 if (GetParam() > QUIC_VERSION_12
) {
372 ProcessPacket(ConstructResponseHeadersPacket(2, kFin
));
374 ProcessPacket(ConstructDataPacket(2, false, kFin
, 0, response_data_
));
377 // Now that the headers have been processed, the callback will return.
378 EXPECT_EQ(OK
, callback_
.WaitForResult());
379 ASSERT_TRUE(response_
.headers
.get());
380 EXPECT_EQ(404, response_
.headers
->response_code());
381 EXPECT_TRUE(response_
.headers
->HasHeaderValue("Content-Type", "text/plain"));
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 if (GetParam() > QUIC_VERSION_12
) {
395 AddWrite(ConstructRequestHeadersPacket(1, kFin
));
397 AddWrite(ConstructDataPacket(1, kIncludeVersion
, kFin
, 0, request_data_
));
401 request_
.method
= "GET";
402 request_
.url
= GURL("http://www.google.com/");
404 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
405 net_log_
, callback_
.callback()));
406 EXPECT_EQ(OK
, stream_
->SendRequest(headers_
, &response_
,
407 callback_
.callback()));
408 EXPECT_EQ(&response_
, stream_
->GetResponseInfo());
411 ProcessPacket(ConstructAckPacket(1, 0, 0));
413 EXPECT_EQ(ERR_IO_PENDING
,
414 stream_
->ReadResponseHeaders(callback_
.callback()));
416 SpdyHeaderBlock headers
;
417 headers
[":status"] = "200 OK";
418 headers
[":version"] = "HTTP/1.1";
419 headers
["content-type"] = "text/plain";
420 headers
["big6"] = std::string(10000, 'x'); // Lots of x's.
422 std::string response
= SpdyUtils::SerializeUncompressedHeaders(headers
);
423 EXPECT_LT(4096u, response
.length());
424 stream_
->OnDataReceived(response
.data(), response
.length());
425 stream_
->OnClose(QUIC_NO_ERROR
);
427 // Now that the headers have been processed, the callback will return.
428 EXPECT_EQ(OK
, callback_
.WaitForResult());
429 ASSERT_TRUE(response_
.headers
.get());
430 EXPECT_EQ(200, response_
.headers
->response_code());
431 EXPECT_TRUE(response_
.headers
->HasHeaderValue("Content-Type", "text/plain"));
433 // There is no body, so this should return immediately.
434 EXPECT_EQ(0, stream_
->ReadResponseBody(read_buffer_
.get(),
435 read_buffer_
->size(),
436 callback_
.callback()));
437 EXPECT_TRUE(stream_
->IsResponseBodyComplete());
438 EXPECT_TRUE(AtEof());
441 TEST_P(QuicHttpStreamTest
, GetRequestFullResponseInSinglePacket
) {
442 SetRequest("GET", "/", DEFAULT_PRIORITY
);
443 AddWrite(ConstructDataPacket(1, kIncludeVersion
, kFin
, 0, request_data_
));
446 if (GetParam() > QUIC_VERSION_12
) {
447 // we can't put the request and response into a single frame.
451 request_
.method
= "GET";
452 request_
.url
= GURL("http://www.google.com/");
454 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
455 net_log_
, callback_
.callback()));
456 EXPECT_EQ(OK
, stream_
->SendRequest(headers_
, &response_
,
457 callback_
.callback()));
458 EXPECT_EQ(&response_
, stream_
->GetResponseInfo());
461 ProcessPacket(ConstructAckPacket(1, 0, 0));
463 EXPECT_EQ(ERR_IO_PENDING
,
464 stream_
->ReadResponseHeaders(callback_
.callback()));
466 // Send the response with a body.
467 SetResponse("200 OK", "hello world!");
468 ProcessPacket(ConstructDataPacket(2, false, kFin
, 0, response_data_
));
470 // Now that the headers have been processed, the callback will return.
471 EXPECT_EQ(OK
, callback_
.WaitForResult());
472 ASSERT_TRUE(response_
.headers
.get());
473 EXPECT_EQ(200, response_
.headers
->response_code());
474 EXPECT_TRUE(response_
.headers
->HasHeaderValue("Content-Type", "text/plain"));
476 // There is no body, so this should return immediately.
477 // Since the body has already arrived, this should return immediately.
478 EXPECT_EQ(12, stream_
->ReadResponseBody(read_buffer_
.get(),
479 read_buffer_
->size(),
480 callback_
.callback()));
481 EXPECT_TRUE(stream_
->IsResponseBodyComplete());
482 EXPECT_TRUE(AtEof());
485 TEST_P(QuicHttpStreamTest
, SendPostRequest
) {
486 SetRequest("POST", "/", DEFAULT_PRIORITY
);
487 if (GetParam() > QUIC_VERSION_12
) {
488 AddWrite(ConstructRequestHeadersPacket(1, !kFin
));
489 AddWrite(ConstructDataPacket(2, kIncludeVersion
, kFin
, 0, kUploadData
));
491 AddWrite(ConstructDataPacket(1, kIncludeVersion
, !kFin
, 0, request_data_
));
492 AddWrite(ConstructDataPacket(2, kIncludeVersion
, kFin
,
493 request_data_
.length(), kUploadData
));
495 AddWrite(ConstructAckPacket(3, 3, 1));
499 ScopedVector
<UploadElementReader
> element_readers
;
500 element_readers
.push_back(
501 new UploadBytesElementReader(kUploadData
, strlen(kUploadData
)));
502 UploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
503 request_
.method
= "POST";
504 request_
.url
= GURL("http://www.google.com/");
505 request_
.upload_data_stream
= &upload_data_stream
;
506 ASSERT_EQ(OK
, request_
.upload_data_stream
->Init(CompletionCallback()));
508 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
509 net_log_
, callback_
.callback()));
510 EXPECT_EQ(OK
, stream_
->SendRequest(headers_
, &response_
,
511 callback_
.callback()));
512 EXPECT_EQ(&response_
, stream_
->GetResponseInfo());
514 // Ack both packets in the request.
515 ProcessPacket(ConstructAckPacket(1, 0, 0));
517 // Send the response headers (but not the body).
518 SetResponse("200 OK", std::string());
519 if (GetParam() > QUIC_VERSION_12
) {
520 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin
));
522 ProcessPacket(ConstructDataPacket(2, false, !kFin
, 0, response_data_
));
525 // Since the headers have already arrived, this should return immediately.
526 EXPECT_EQ(OK
, stream_
->ReadResponseHeaders(callback_
.callback()));
527 ASSERT_TRUE(response_
.headers
.get());
528 EXPECT_EQ(200, response_
.headers
->response_code());
529 EXPECT_TRUE(response_
.headers
->HasHeaderValue("Content-Type", "text/plain"));
531 // Send the response body.
532 const char kResponseBody
[] = "Hello world!";
533 if (GetParam() > QUIC_VERSION_12
) {
534 ProcessPacket(ConstructDataPacket(3, false, kFin
, 0, kResponseBody
));
536 ProcessPacket(ConstructDataPacket(3, false, kFin
, response_data_
.length(),
539 // Since the body has already arrived, this should return immediately.
540 EXPECT_EQ(static_cast<int>(strlen(kResponseBody
)),
541 stream_
->ReadResponseBody(read_buffer_
.get(), read_buffer_
->size(),
542 callback_
.callback()));
544 EXPECT_TRUE(stream_
->IsResponseBodyComplete());
545 EXPECT_TRUE(AtEof());
548 TEST_P(QuicHttpStreamTest
, SendChunkedPostRequest
) {
549 SetRequest("POST", "/", DEFAULT_PRIORITY
);
550 size_t chunk_size
= strlen(kUploadData
);
551 if (GetParam() > QUIC_VERSION_12
) {
552 AddWrite(ConstructRequestHeadersPacket(1, !kFin
));
553 AddWrite(ConstructDataPacket(2, kIncludeVersion
, !kFin
, 0, kUploadData
));
554 AddWrite(ConstructDataPacket(3, kIncludeVersion
, kFin
, chunk_size
,
557 AddWrite(ConstructDataPacket(1, kIncludeVersion
, !kFin
, 0, request_data_
));
558 AddWrite(ConstructDataPacket(2, kIncludeVersion
, !kFin
,
559 request_data_
.length(), kUploadData
));
560 AddWrite(ConstructDataPacket(3, kIncludeVersion
, kFin
,
561 request_data_
.length() + chunk_size
,
564 AddWrite(ConstructAckPacket(4, 3, 1));
567 UploadDataStream
upload_data_stream(UploadDataStream::CHUNKED
, 0);
568 upload_data_stream
.AppendChunk(kUploadData
, chunk_size
, false);
570 request_
.method
= "POST";
571 request_
.url
= GURL("http://www.google.com/");
572 request_
.upload_data_stream
= &upload_data_stream
;
573 ASSERT_EQ(OK
, request_
.upload_data_stream
->Init(CompletionCallback()));
575 ASSERT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
576 net_log_
, callback_
.callback()));
577 ASSERT_EQ(ERR_IO_PENDING
, stream_
->SendRequest(headers_
, &response_
,
578 callback_
.callback()));
579 EXPECT_EQ(&response_
, stream_
->GetResponseInfo());
581 upload_data_stream
.AppendChunk(kUploadData
, chunk_size
, true);
583 // Ack both packets in the request.
584 ProcessPacket(ConstructAckPacket(1, 0, 0));
586 // Send the response headers (but not the body).
587 SetResponse("200 OK", std::string());
588 if (GetParam() > QUIC_VERSION_12
) {
589 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin
));
591 ProcessPacket(ConstructDataPacket(2, false, !kFin
, 0, response_data_
));
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(),
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
, DestroyedEarly
) {
615 SetRequest("GET", "/", DEFAULT_PRIORITY
);
616 if (GetParam() > QUIC_VERSION_12
) {
617 AddWrite(ConstructRequestHeadersPacket(1, kFin
));
619 AddWrite(ConstructDataPacket(1, kIncludeVersion
, kFin
, 0, request_data_
));
621 AddWrite(ConstructAckAndRstStreamPacket(2));
622 use_closing_stream_
= true;
625 request_
.method
= "GET";
626 request_
.url
= GURL("http://www.google.com/");
628 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, DEFAULT_PRIORITY
,
629 net_log_
, callback_
.callback()));
630 EXPECT_EQ(OK
, stream_
->SendRequest(headers_
, &response_
,
631 callback_
.callback()));
632 EXPECT_EQ(&response_
, stream_
->GetResponseInfo());
635 ProcessPacket(ConstructAckPacket(1, 0, 0));
636 EXPECT_EQ(ERR_IO_PENDING
,
637 stream_
->ReadResponseHeaders(callback_
.callback()));
639 // Send the response with a body.
640 SetResponse("404 OK", "hello world!");
641 // In the course of processing this packet, the QuicHttpStream close itself.
642 if (GetParam() > QUIC_VERSION_12
) {
643 ProcessPacket(ConstructResponseHeadersPacket(2, kFin
));
645 ProcessPacket(ConstructDataPacket(2, false, kFin
, 0, response_data_
));
648 EXPECT_TRUE(AtEof());
651 TEST_P(QuicHttpStreamTest
, Priority
) {
652 SetRequest("GET", "/", MEDIUM
);
653 if (GetParam() > QUIC_VERSION_12
) {
654 AddWrite(ConstructRequestHeadersPacket(1, kFin
));
656 AddWrite(ConstructDataPacket(1, kIncludeVersion
, kFin
, 0, request_data_
));
658 AddWrite(ConstructAckAndRstStreamPacket(2));
659 use_closing_stream_
= true;
662 request_
.method
= "GET";
663 request_
.url
= GURL("http://www.google.com/");
665 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, MEDIUM
,
666 net_log_
, callback_
.callback()));
668 // Check that priority is highest.
669 QuicReliableClientStream
* reliable_stream
=
670 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_
.get());
671 DCHECK(reliable_stream
);
672 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority
,
673 reliable_stream
->EffectivePriority());
675 EXPECT_EQ(OK
, stream_
->SendRequest(headers_
, &response_
,
676 callback_
.callback()));
677 EXPECT_EQ(&response_
, stream_
->GetResponseInfo());
679 // Check that priority has now dropped back to MEDIUM.
680 DCHECK_EQ(MEDIUM
, ConvertQuicPriorityToRequestPriority(
681 reliable_stream
->EffectivePriority()));
684 ProcessPacket(ConstructAckPacket(1, 0, 0));
685 EXPECT_EQ(ERR_IO_PENDING
,
686 stream_
->ReadResponseHeaders(callback_
.callback()));
688 // Send the response with a body.
689 SetResponse("404 OK", "hello world!");
690 // In the course of processing this packet, the QuicHttpStream close itself.
691 if (GetParam() > QUIC_VERSION_12
) {
692 ProcessPacket(ConstructResponseHeadersPacket(2, kFin
));
694 ProcessPacket(ConstructDataPacket(2, !kIncludeVersion
, kFin
, 0,
698 EXPECT_TRUE(AtEof());
701 // Regression test for http://crbug.com/294870
702 TEST_P(QuicHttpStreamTest
, CheckPriorityWithNoDelegate
) {
703 SetRequest("GET", "/", MEDIUM
);
704 use_closing_stream_
= true;
706 if (GetParam() > QUIC_VERSION_13
) {
707 AddWrite(ConstructRstStreamPacket(1));
712 request_
.method
= "GET";
713 request_
.url
= GURL("http://www.google.com/");
715 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, MEDIUM
,
716 net_log_
, callback_
.callback()));
718 // Check that priority is highest.
719 QuicReliableClientStream
* reliable_stream
=
720 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_
.get());
721 DCHECK(reliable_stream
);
722 QuicReliableClientStream::Delegate
* delegate
= reliable_stream
->GetDelegate();
724 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority
,
725 reliable_stream
->EffectivePriority());
727 // Set Delegate to NULL and make sure EffectivePriority returns highest
729 reliable_stream
->SetDelegate(NULL
);
730 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority
,
731 reliable_stream
->EffectivePriority());
732 reliable_stream
->SetDelegate(delegate
);
735 TEST_P(QuicHttpStreamTest
, DontCompressHeadersWhenNotWritable
) {
736 SetRequest("GET", "/", MEDIUM
);
737 AddWrite(ConstructDataPacket(1, kIncludeVersion
, kFin
, 0, request_data_
));
740 if (GetParam() > QUIC_VERSION_12
) {
741 // The behavior tested here is obsolete.
744 request_
.method
= "GET";
745 request_
.url
= GURL("http://www.google.com/");
747 EXPECT_CALL(*send_algorithm_
, TimeUntilSend(_
, _
, _
, _
)).
748 WillRepeatedly(Return(QuicTime::Delta::Infinite()));
749 EXPECT_EQ(OK
, stream_
->InitializeStream(&request_
, MEDIUM
,
750 net_log_
, callback_
.callback()));
751 EXPECT_EQ(ERR_IO_PENDING
, stream_
->SendRequest(headers_
, &response_
,
752 callback_
.callback()));
754 // Verify that the headers have not been compressed and buffered in
756 QuicReliableClientStream
* reliable_stream
=
757 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_
.get());
758 EXPECT_FALSE(reliable_stream
->HasBufferedData());
759 EXPECT_FALSE(AtEof());
761 EXPECT_CALL(*send_algorithm_
, TimeUntilSend(_
, _
, _
, _
)).
762 WillRepeatedly(Return(QuicTime::Delta::Zero()));
764 // Data should flush out now.
765 connection_
->OnCanWrite();
766 EXPECT_FALSE(reliable_stream
->HasBufferedData());
767 EXPECT_TRUE(AtEof());