blob: 625b33b89db284c9175bc67bb705c375053088fc [file] [log] [blame]
[email protected]f702d572012-12-04 15:56:201// 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.
4
5#include "net/quic/quic_http_stream.h"
6
7#include <vector>
8
skyostil4891b25b2015-06-11 11:43:459#include "base/thread_task_runner_handle.h"
mmenkecbc2b712014-10-09 20:29:0710#include "net/base/chunked_upload_data_stream.h"
11#include "net/base/elements_upload_data_stream.h"
[email protected]f702d572012-12-04 15:56:2012#include "net/base/net_errors.h"
13#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0614#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2015#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1516#include "net/http/transport_security_state.h"
[email protected]fee17f72013-02-03 07:47:4117#include "net/quic/congestion_control/send_algorithm_interface.h"
[email protected]e8ff26842013-03-22 21:02:0518#include "net/quic/crypto/crypto_protocol.h"
[email protected]4df69842013-02-27 06:32:1619#include "net/quic/crypto/quic_decrypter.h"
20#include "net/quic/crypto/quic_encrypter.h"
[email protected]17bf15c2014-03-14 10:08:0421#include "net/quic/crypto/quic_server_info.h"
ckrasic4f9d88d2015-07-22 22:23:1622#include "net/quic/quic_chromium_client_session.h"
[email protected]f702d572012-12-04 15:56:2023#include "net/quic/quic_connection.h"
24#include "net/quic/quic_connection_helper.h"
[email protected]cbd731e2013-10-24 00:20:3925#include "net/quic/quic_default_packet_writer.h"
rtenneti6bd660b2015-07-18 00:19:5326#include "net/quic/quic_flags.h"
[email protected]24e5bc52013-09-18 15:36:5827#include "net/quic/quic_http_utils.h"
28#include "net/quic/quic_reliable_client_stream.h"
[email protected]9f0dcd4e2014-01-16 15:58:1429#include "net/quic/quic_write_blocked_list.h"
[email protected]3e7dca62013-09-10 16:14:2330#include "net/quic/spdy_utils.h"
[email protected]f702d572012-12-04 15:56:2031#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0532#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]9db443912013-02-25 05:27:0333#include "net/quic/test_tools/mock_random.h"
[email protected]b1f287d2012-12-22 17:25:3934#include "net/quic/test_tools/quic_connection_peer.h"
[email protected]1e960032013-12-20 19:00:2035#include "net/quic/test_tools/quic_test_packet_maker.h"
[email protected]f702d572012-12-04 15:56:2036#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"
[email protected]6cca996b2013-01-25 07:43:3639#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"
[email protected]f702d572012-12-04 15:56:2043#include "testing/gmock/include/gmock/gmock.h"
44#include "testing/gtest/include/gtest/gtest.h"
45
46using testing::_;
[email protected]06ff5152013-08-29 01:03:0547using testing::AnyNumber;
48using testing::Return;
[email protected]f702d572012-12-04 15:56:2049
50namespace net {
[email protected]f702d572012-12-04 15:56:2051namespace test {
[email protected]f702d572012-12-04 15:56:2052namespace {
53
[email protected]16ba7742014-08-22 00:57:2554const char kUploadData[] = "Really nifty data!";
bncb07c05532015-05-14 19:07:2055const char kDefaultServerHostName[] = "www.google.com";
56const uint16 kDefaultServerPort = 80;
[email protected]f702d572012-12-04 15:56:2057
58class TestQuicConnection : public QuicConnection {
59 public:
[email protected]1e960032013-12-20 19:00:2060 TestQuicConnection(const QuicVersionVector& versions,
[email protected]3aa9ca72014-02-27 19:39:4361 QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2062 IPEndPoint address,
[email protected]cbd731e2013-10-24 00:20:3963 QuicConnectionHelper* helper,
[email protected]6d515822014-08-22 01:58:0664 const QuicConnection::PacketWriterFactory& writer_factory)
[email protected]66cd2d62014-08-01 18:42:3965 : QuicConnection(connection_id,
66 address,
67 helper,
[email protected]6d515822014-08-22 01:58:0668 writer_factory,
rtenneti6f48aa92015-03-16 02:18:4869 true /* owns_writer */,
70 Perspective::IS_CLIENT,
71 false /* is_secure */,
72 versions) {}
[email protected]f702d572012-12-04 15:56:2073
[email protected]fee17f72013-02-03 07:47:4174 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
75 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:2076 }
77};
78
[email protected]63534512012-12-23 18:49:0079// Subclass of QuicHttpStream that closes itself when the first piece of data
80// is received.
81class AutoClosingStream : public QuicHttpStream {
82 public:
ckrasic4f9d88d2015-07-22 22:23:1683 explicit AutoClosingStream(
84 const base::WeakPtr<QuicChromiumClientSession>& session)
85 : QuicHttpStream(session) {}
[email protected]63534512012-12-23 18:49:0086
rchb27683c2015-07-29 23:53:5087 void OnHeadersAvailable(const SpdyHeaderBlock& headers) override {
[email protected]63534512012-12-23 18:49:0088 Close(false);
[email protected]63534512012-12-23 18:49:0089 }
rchb27683c2015-07-29 23:53:5090
91 void OnDataAvailable() override { Close(false); }
[email protected]63534512012-12-23 18:49:0092};
93
[email protected]6d515822014-08-22 01:58:0694class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
95 public:
96 explicit TestPacketWriterFactory(DatagramClientSocket* socket)
97 : socket_(socket) {}
dchengb03027d2014-10-21 12:00:2098 ~TestPacketWriterFactory() override {}
[email protected]6d515822014-08-22 01:58:0699
dchengb03027d2014-10-21 12:00:20100 QuicPacketWriter* Create(QuicConnection* connection) const override {
[email protected]6d515822014-08-22 01:58:06101 return new QuicDefaultPacketWriter(socket_);
102 }
103
104 private:
105 DatagramClientSocket* socket_;
106};
107
[email protected]f702d572012-12-04 15:56:20108} // namespace
109
[email protected]24e5bc52013-09-18 15:36:58110class QuicHttpStreamPeer {
111 public:
112 static QuicReliableClientStream* GetQuicReliableClientStream(
113 QuicHttpStream* stream) {
114 return stream->stream_;
115 }
116};
117
[email protected]1e960032013-12-20 19:00:20118class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
[email protected]f702d572012-12-04 15:56:20119 protected:
[email protected]1e960032013-12-20 19:00:20120 static const bool kFin = true;
121 static const bool kIncludeVersion = true;
122 static const bool kIncludeCongestionFeedback = true;
123
[email protected]f702d572012-12-04 15:56:20124 // 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)
128 : mode(mode),
129 packet(packet) {
130 }
131 IoMode mode;
132 QuicEncryptedPacket* packet;
133 };
134
135 QuicHttpStreamTest()
136 : net_log_(BoundNetLog()),
[email protected]63534512012-12-23 18:49:00137 use_closing_stream_(false),
[email protected]f702d572012-12-04 15:56:20138 read_buffer_(new IOBufferWithSize(4096)),
[email protected]3aa9ca72014-02-27 19:39:43139 connection_id_(2),
[email protected]66ae5962014-05-22 11:13:05140 stream_id_(kClientDataStreamId1),
bncb07c05532015-05-14 19:07:20141 maker_(GetParam(), connection_id_, &clock_, kDefaultServerHostName),
[email protected]1e960032013-12-20 19:00:20142 random_generator_(0) {
[email protected]f702d572012-12-04 15:56:20143 IPAddressNumber ip;
144 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
145 peer_addr_ = IPEndPoint(ip, 443);
146 self_addr_ = IPEndPoint(ip, 8435);
rtenneti4b06ae72014-08-26 03:43:43147 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
[email protected]f702d572012-12-04 15:56:20148 }
149
150 ~QuicHttpStreamTest() {
rtenneti85dcfac22015-03-27 20:22:19151 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
[email protected]f702d572012-12-04 15:56:20152 for (size_t i = 0; i < writes_.size(); i++) {
153 delete writes_[i].packet;
154 }
155 }
156
157 // Adds a packet to the list of expected writes.
[email protected]1e960032013-12-20 19:00:20158 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
159 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20160 }
161
162 // Returns the packet to be written at position |pos|.
163 QuicEncryptedPacket* GetWrite(size_t pos) {
164 return writes_[pos].packet;
165 }
166
167 bool AtEof() {
rch37de576c2015-05-17 20:28:17168 return socket_data_->AllReadDataConsumed() &&
169 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20170 }
171
[email protected]1e960032013-12-20 19:00:20172 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
173 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
[email protected]f702d572012-12-04 15:56:20174 }
175
176 // Configures the test fixture to use the list of expected writes.
177 void Initialize() {
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());
183 };
184
rtennetibe635732014-10-02 22:51:42185 socket_data_.reset(new StaticSocketDataProvider(
186 nullptr, 0, mock_writes_.get(), writes_.size()));
[email protected]f702d572012-12-04 15:56:20187
[email protected]e13201d82012-12-12 05:00:32188 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
189 net_log_.net_log());
190 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20191 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41192 send_algorithm_ = new MockSendAlgorithm();
rch7dd15702015-07-01 18:57:57193 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
194 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
[email protected]efecff92013-09-24 07:49:23195 EXPECT_CALL(*send_algorithm_,
[email protected]ef0da582014-05-09 07:16:30196 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
rtenneti44f4a2e2015-08-07 14:00:07197 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()));
rch1e543ec2015-03-29 07:04:40207 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
[email protected]2cfc6bb82013-10-27 03:40:44208 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
209 &random_generator_));
[email protected]6d515822014-08-22 01:58:06210 TestPacketWriterFactory writer_factory(socket);
[email protected]3aa9ca72014-02-27 19:39:43211 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
212 connection_id_, peer_addr_,
[email protected]6d515822014-08-22 01:58:06213 helper_.get(), writer_factory);
[email protected]f702d572012-12-04 15:56:20214 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41215 connection_->SetSendAlgorithm(send_algorithm_);
ckrasic4f9d88d2015-07-22 22:23:16216 session_.reset(new QuicChromiumClientSession(
rtennetid39bd762015-06-12 01:05:52217 connection_, scoped_ptr<DatagramClientSocket>(socket),
218 /*stream_factory=*/nullptr, &crypto_client_stream_factory_,
rtenneti041b2992015-02-23 23:03:28219 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
bncb07c05532015-05-14 19:07:20220 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
221 /*is_secure=*/false, PRIVACY_MODE_DISABLED),
rtennetia75df622015-06-21 23:59:50222 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
223 "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
224 base::ThreadTaskRunnerHandle::Get().get(), nullptr));
rtennetid39bd762015-06-12 01:05:52225 session_->Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44226 session_->GetCryptoStream()->CryptoConnect();
[email protected]8ba81212013-05-03 13:11:48227 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
[email protected]6cca996b2013-01-25 07:43:36228 stream_.reset(use_closing_stream_ ?
[email protected]0b2294d32013-08-02 00:46:36229 new AutoClosingStream(session_->GetWeakPtr()) :
230 new QuicHttpStream(session_->GetWeakPtr()));
[email protected]6cca996b2013-01-25 07:43:36231 }
232
[email protected]1e960032013-12-20 19:00:20233 void SetRequest(const std::string& method,
234 const std::string& path,
235 RequestPriority priority) {
236 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
[email protected]6cca996b2013-01-25 07:43:36237 }
238
[email protected]1e960032013-12-20 19:00:20239 void SetResponse(const std::string& status, const std::string& body) {
240 response_headers_ = maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03241 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36242 }
[email protected]f702d572012-12-04 15:56:20243
[email protected]1e960032013-12-20 19:00:20244 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
rtennetia004d332015-08-28 06:44:57245 QuicPacketNumber packet_number,
[email protected]e8ff26842013-03-22 21:02:05246 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20247 bool fin,
248 QuicStreamOffset offset,
249 base::StringPiece data) {
rtennetia004d332015-08-28 06:44:57250 return maker_.MakeDataPacket(packet_number, stream_id_,
rtennetif4bdb542015-01-21 14:33:05251 should_include_version, fin, offset, data);
[email protected]f702d572012-12-04 15:56:20252 }
253
[email protected]1e960032013-12-20 19:00:20254 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
rtennetia004d332015-08-28 06:44:57255 QuicPacketNumber packet_number,
rtennetif4bdb542015-01-21 14:33:05256 bool fin,
257 RequestPriority request_priority) {
258 QuicPriority priority =
259 ConvertRequestPriorityToQuicPriority(request_priority);
rtennetia004d332015-08-28 06:44:57260 return maker_.MakeRequestHeadersPacket(packet_number, stream_id_,
rtennetif4bdb542015-01-21 14:33:05261 kIncludeVersion, fin, priority,
262 request_headers_);
[email protected]1e960032013-12-20 19:00:20263 }
264
265 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
rtennetia004d332015-08-28 06:44:57266 QuicPacketNumber packet_number,
[email protected]1e960032013-12-20 19:00:20267 bool fin) {
268 return maker_.MakeResponseHeadersPacket(
rtennetia004d332015-08-28 06:44:57269 packet_number, stream_id_, !kIncludeVersion, fin, response_headers_);
[email protected]1e960032013-12-20 19:00:20270 }
271
272 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
rtennetia004d332015-08-28 06:44:57273 QuicPacketNumber packet_number) {
[email protected]1e960032013-12-20 19:00:20274 return maker_.MakeRstPacket(
rtennetia004d332015-08-28 06:44:57275 packet_number, true, stream_id_,
rtenneti4a5df262014-11-07 00:43:58276 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
[email protected]06ff5152013-08-29 01:03:05277 }
278
rtenneti6bd660b2015-07-18 00:19:53279 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamCancelledPacket(
rtennetia004d332015-08-28 06:44:57280 QuicPacketNumber packet_number) {
281 return maker_.MakeRstPacket(packet_number, !kIncludeVersion, stream_id_,
rtenneti6bd660b2015-07-18 00:19:53282 QUIC_STREAM_CANCELLED);
283 }
284
[email protected]c5e1aca2014-01-30 04:03:04285 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
rtennetia004d332015-08-28 06:44:57286 QuicPacketNumber packet_number) {
287 return maker_.MakeAckAndRstPacket(packet_number, !kIncludeVersion,
288 stream_id_, QUIC_STREAM_CANCELLED, 2, 1,
289 !kIncludeCongestionFeedback);
[email protected]c5e1aca2014-01-30 04:03:04290 }
291
[email protected]1e960032013-12-20 19:00:20292 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
rtennetia004d332015-08-28 06:44:57293 QuicPacketNumber packet_number,
294 QuicPacketNumber largest_received,
295 QuicPacketNumber least_unacked) {
296 return maker_.MakeAckPacket(packet_number, largest_received, least_unacked,
297 !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00298 }
299
[email protected]f702d572012-12-04 15:56:20300 BoundNetLog net_log_;
[email protected]63534512012-12-23 18:49:00301 bool use_closing_stream_;
[email protected]fee17f72013-02-03 07:47:41302 MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20303 scoped_refptr<TestTaskRunner> runner_;
[email protected]4356f0f2013-04-07 00:58:17304 scoped_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20305 MockClock clock_;
306 TestQuicConnection* connection_;
[email protected]2cfc6bb82013-10-27 03:40:44307 scoped_ptr<QuicConnectionHelper> helper_;
[email protected]f702d572012-12-04 15:56:20308 testing::StrictMock<MockConnectionVisitor> visitor_;
309 scoped_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15310 TransportSecurityState transport_security_state_;
ckrasic4f9d88d2015-07-22 22:23:16311 scoped_ptr<QuicChromiumClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01312 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20313 TestCompletionCallback callback_;
314 HttpRequestInfo request_;
315 HttpRequestHeaders headers_;
316 HttpResponseInfo response_;
317 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]1e960032013-12-20 19:00:20318 SpdyHeaderBlock request_headers_;
319 SpdyHeaderBlock response_headers_;
[email protected]6cca996b2013-01-25 07:43:36320 std::string request_data_;
321 std::string response_data_;
[email protected]f702d572012-12-04 15:56:20322
323 private:
[email protected]3aa9ca72014-02-27 19:39:43324 const QuicConnectionId connection_id_;
[email protected]1e960032013-12-20 19:00:20325 const QuicStreamId stream_id_;
326 QuicTestPacketMaker maker_;
[email protected]f702d572012-12-04 15:56:20327 IPEndPoint self_addr_;
328 IPEndPoint peer_addr_;
[email protected]457d6952013-12-13 09:24:58329 MockRandom random_generator_;
[email protected]e8ff26842013-03-22 21:02:05330 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]f702d572012-12-04 15:56:20331 scoped_ptr<StaticSocketDataProvider> socket_data_;
332 std::vector<PacketToWrite> writes_;
333};
334
[email protected]1e960032013-12-20 19:00:20335INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
336 ::testing::ValuesIn(QuicSupportedVersions()));
337
338TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44339 Initialize();
rtennetibe635732014-10-02 22:51:42340 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20341}
342
[email protected]1e960032013-12-20 19:00:20343TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
[email protected]ed3fc15d2013-03-08 18:37:44344 Initialize();
[email protected]f702d572012-12-04 15:56:20345 EXPECT_TRUE(stream_->CanFindEndOfResponse());
346}
347
[email protected]1e960032013-12-20 19:00:20348TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
[email protected]ed3fc15d2013-03-08 18:37:44349 Initialize();
[email protected]f702d572012-12-04 15:56:20350 EXPECT_FALSE(stream_->IsConnectionReusable());
351}
352
[email protected]1e960032013-12-20 19:00:20353TEST_P(QuicHttpStreamTest, GetRequest) {
354 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05355 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
[email protected]f702d572012-12-04 15:56:20356 Initialize();
357
358 request_.method = "GET";
359 request_.url = GURL("http://www.google.com/");
360
[email protected]262eec82013-03-19 21:01:36361 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
362 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20363 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
364 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20365
366 // Ack the request.
[email protected]1e960032013-12-20 19:00:20367 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20368
369 EXPECT_EQ(ERR_IO_PENDING,
370 stream_->ReadResponseHeaders(callback_.callback()));
371
[email protected]1e960032013-12-20 19:00:20372 SetResponse("404 Not Found", std::string());
[email protected]92bf17c2014-03-03 21:14:03373 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]f702d572012-12-04 15:56:20374
375 // Now that the headers have been processed, the callback will return.
376 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36377 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20378 EXPECT_EQ(404, response_.headers->response_code());
379 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53380 EXPECT_FALSE(response_.response_time.is_null());
381 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20382
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());
389}
390
[email protected]3e7dca62013-09-10 16:14:23391// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20392TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
393 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05394 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
[email protected]3e7dca62013-09-10 16:14:23395 Initialize();
396
397 request_.method = "GET";
398 request_.url = GURL("http://www.google.com/");
399
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()));
[email protected]3e7dca62013-09-10 16:14:23404
405 // Ack the request.
[email protected]1e960032013-12-20 19:00:20406 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]3e7dca62013-09-10 16:14:23407
408 EXPECT_EQ(ERR_IO_PENDING,
409 stream_->ReadResponseHeaders(callback_.callback()));
410
411 SpdyHeaderBlock headers;
412 headers[":status"] = "200 OK";
413 headers[":version"] = "HTTP/1.1";
414 headers["content-type"] = "text/plain";
rch7dd15702015-07-01 18:57:57415 headers["big6"] = std::string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:23416
rch7dd15702015-07-01 18:57:57417 response_headers_ = headers;
418 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]3e7dca62013-09-10 16:14:23419
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"));
425
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());
432}
433
rchf9f103cbc2014-08-30 05:28:04434// Regression test for http://crbug.com/409101
435TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
436 SetRequest("GET", "/", DEFAULT_PRIORITY);
437 Initialize();
438
439 request_.method = "GET";
440 request_.url = GURL("http://www.google.com/");
441
442 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
443 net_log_, callback_.callback()));
444
445 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
446
447 EXPECT_EQ(ERR_CONNECTION_CLOSED,
448 stream_->SendRequest(headers_, &response_,
449 callback_.callback()));
450}
451
rch11a114a2014-09-04 23:41:59452// Regression test for http://crbug.com/409871
453TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
454 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05455 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
rch11a114a2014-09-04 23:41:59456 Initialize();
457
458 request_.method = "GET";
459 request_.url = GURL("http://www.google.com/");
460
461 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
462 net_log_, callback_.callback()));
463
464 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
465 callback_.callback()));
466
467 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
468
469 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
470}
471
[email protected]1e960032013-12-20 19:00:20472TEST_P(QuicHttpStreamTest, SendPostRequest) {
473 SetRequest("POST", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05474 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]92bf17c2014-03-03 21:14:03475 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
[email protected]1e960032013-12-20 19:00:20476 AddWrite(ConstructAckPacket(3, 3, 1));
[email protected]f702d572012-12-04 15:56:20477
478 Initialize();
479
[email protected]b2d26cfd2012-12-11 10:36:06480 ScopedVector<UploadElementReader> element_readers;
481 element_readers.push_back(
482 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
mmenkecbc2b712014-10-09 20:29:07483 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f702d572012-12-04 15:56:20484 request_.method = "POST";
485 request_.url = GURL("http://www.google.com/");
486 request_.upload_data_stream = &upload_data_stream;
[email protected]4db27d82012-12-20 11:50:24487 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
[email protected]f702d572012-12-04 15:56:20488
[email protected]262eec82013-03-19 21:01:36489 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
490 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20491 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
492 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20493
494 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20495 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20496
497 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20498 SetResponse("200 OK", std::string());
[email protected]92bf17c2014-03-03 21:14:03499 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
[email protected]f702d572012-12-04 15:56:20500
rchb27683c2015-07-29 23:53:50501 // 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());
[email protected]cadac622013-06-11 16:46:36504 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20505 EXPECT_EQ(200, response_.headers->response_code());
506 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
507
508 // Send the response body.
509 const char kResponseBody[] = "Hello world!";
[email protected]92bf17c2014-03-03 21:14:03510 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
[email protected]f702d572012-12-04 15:56:20511 // 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()));
515
516 EXPECT_TRUE(stream_->IsResponseBodyComplete());
517 EXPECT_TRUE(AtEof());
518}
519
[email protected]1e960032013-12-20 19:00:20520TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
521 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:47522 size_t chunk_size = strlen(kUploadData);
rtennetif4bdb542015-01-21 14:33:05523 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]92bf17c2014-03-03 21:14:03524 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
525 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
526 kUploadData));
[email protected]1e960032013-12-20 19:00:20527 AddWrite(ConstructAckPacket(4, 3, 1));
[email protected]c9e49a02013-02-26 05:56:47528 Initialize();
529
mmenkecbc2b712014-10-09 20:29:07530 ChunkedUploadDataStream upload_data_stream(0);
531 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:47532
533 request_.method = "POST";
534 request_.url = GURL("http://www.google.com/");
535 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07536 ASSERT_EQ(OK, request_.upload_data_stream->Init(
537 TestCompletionCallback().callback()));
[email protected]c9e49a02013-02-26 05:56:47538
[email protected]262eec82013-03-19 21:01:36539 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
540 net_log_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47541 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
542 callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47543
mmenkecbc2b712014-10-09 20:29:07544 upload_data_stream.AppendData(kUploadData, chunk_size, true);
rchb27683c2015-07-29 23:53:50545 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]c9e49a02013-02-26 05:56:47546
547 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20548 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]c9e49a02013-02-26 05:56:47549
550 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20551 SetResponse("200 OK", std::string());
[email protected]92bf17c2014-03-03 21:14:03552 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
[email protected]c9e49a02013-02-26 05:56:47553
rchb27683c2015-07-29 23:53:50554 // 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());
[email protected]cadac622013-06-11 16:46:36557 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:47558 EXPECT_EQ(200, response_.headers->response_code());
559 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
560
561 // Send the response body.
562 const char kResponseBody[] = "Hello world!";
[email protected]1e960032013-12-20 19:00:20563 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
564 kResponseBody));
[email protected]c9e49a02013-02-26 05:56:47565
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()));
570
571 EXPECT_TRUE(stream_->IsResponseBodyComplete());
572 EXPECT_TRUE(AtEof());
573}
574
[email protected]16ba7742014-08-22 00:57:25575TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
576 SetRequest("POST", "/", DEFAULT_PRIORITY);
577 size_t chunk_size = strlen(kUploadData);
rtennetif4bdb542015-01-21 14:33:05578 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]16ba7742014-08-22 00:57:25579 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
580 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
581 AddWrite(ConstructAckPacket(4, 3, 1));
582 Initialize();
583
mmenkecbc2b712014-10-09 20:29:07584 ChunkedUploadDataStream upload_data_stream(0);
585 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:25586
587 request_.method = "POST";
588 request_.url = GURL("http://www.google.com/");
589 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07590 ASSERT_EQ(OK, request_.upload_data_stream->Init(
591 TestCompletionCallback().callback()));
[email protected]16ba7742014-08-22 00:57:25592
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()));
597
mmenkecbc2b712014-10-09 20:29:07598 upload_data_stream.AppendData(nullptr, 0, true);
rchb27683c2015-07-29 23:53:50599 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]16ba7742014-08-22 00:57:25600
601 ProcessPacket(ConstructAckPacket(1, 0, 0));
602
603 // Send the response headers (but not the body).
604 SetResponse("200 OK", std::string());
605 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
606
rchb27683c2015-07-29 23:53:50607 // 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());
[email protected]16ba7742014-08-22 00:57:25610 ASSERT_TRUE(response_.headers.get());
611 EXPECT_EQ(200, response_.headers->response_code());
612 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
613
614 // Send the response body.
615 const char kResponseBody[] = "Hello world!";
616 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
617 kResponseBody));
618
rchb27683c2015-07-29 23:53:50619 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:25620 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
621 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
622 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:25623 EXPECT_TRUE(stream_->IsResponseBodyComplete());
624 EXPECT_TRUE(AtEof());
625}
626
627TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
628 SetRequest("POST", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05629 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]16ba7742014-08-22 00:57:25630 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
631 AddWrite(ConstructAckPacket(3, 3, 1));
632 Initialize();
633
mmenkecbc2b712014-10-09 20:29:07634 ChunkedUploadDataStream upload_data_stream(0);
[email protected]16ba7742014-08-22 00:57:25635
636 request_.method = "POST";
637 request_.url = GURL("http://www.google.com/");
638 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07639 ASSERT_EQ(OK, request_.upload_data_stream->Init(
640 TestCompletionCallback().callback()));
[email protected]16ba7742014-08-22 00:57:25641
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()));
646
mmenkecbc2b712014-10-09 20:29:07647 upload_data_stream.AppendData(nullptr, 0, true);
rchb27683c2015-07-29 23:53:50648 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]16ba7742014-08-22 00:57:25649
650 ProcessPacket(ConstructAckPacket(1, 0, 0));
651
652 // Send the response headers (but not the body).
653 SetResponse("200 OK", std::string());
654 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
655
rchb27683c2015-07-29 23:53:50656 // 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());
[email protected]16ba7742014-08-22 00:57:25659 ASSERT_TRUE(response_.headers.get());
660 EXPECT_EQ(200, response_.headers->response_code());
661 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
662
663 // Send the response body.
664 const char kResponseBody[] = "Hello world!";
665 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
666 kResponseBody));
667
rchb27683c2015-07-29 23:53:50668 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:25669 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
670 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
671 callback_.callback()));
672
673 EXPECT_TRUE(stream_->IsResponseBodyComplete());
674 EXPECT_TRUE(AtEof());
675}
676
[email protected]1e960032013-12-20 19:00:20677TEST_P(QuicHttpStreamTest, DestroyedEarly) {
678 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05679 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
rchb27683c2015-07-29 23:53:50680 if (!FLAGS_quic_process_frames_inline) {
rtenneti6bd660b2015-07-18 00:19:53681 AddWrite(ConstructRstStreamCancelledPacket(2));
682 } else {
683 AddWrite(ConstructAckAndRstStreamPacket(2));
684 }
[email protected]63534512012-12-23 18:49:00685 use_closing_stream_ = true;
686 Initialize();
687
688 request_.method = "GET";
689 request_.url = GURL("http://www.google.com/");
690
[email protected]262eec82013-03-19 21:01:36691 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
692 net_log_, callback_.callback()));
[email protected]63534512012-12-23 18:49:00693 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
[email protected]24e5bc52013-09-18 15:36:58694 callback_.callback()));
[email protected]63534512012-12-23 18:49:00695
696 // Ack the request.
[email protected]1e960032013-12-20 19:00:20697 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]63534512012-12-23 18:49:00698 EXPECT_EQ(ERR_IO_PENDING,
699 stream_->ReadResponseHeaders(callback_.callback()));
700
701 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20702 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:00703 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]92bf17c2014-03-03 21:14:03704 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]63534512012-12-23 18:49:00705
rchb27683c2015-07-29 23:53:50706 base::MessageLoop::current()->RunUntilIdle();
707
[email protected]63534512012-12-23 18:49:00708 EXPECT_TRUE(AtEof());
709}
710
[email protected]1e960032013-12-20 19:00:20711TEST_P(QuicHttpStreamTest, Priority) {
712 SetRequest("GET", "/", MEDIUM);
rtennetif4bdb542015-01-21 14:33:05713 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM));
rchb27683c2015-07-29 23:53:50714 if (!FLAGS_quic_process_frames_inline) {
rtenneti6bd660b2015-07-18 00:19:53715 AddWrite(ConstructRstStreamCancelledPacket(2));
716 } else {
717 AddWrite(ConstructAckAndRstStreamPacket(2));
718 }
[email protected]24e5bc52013-09-18 15:36:58719 use_closing_stream_ = true;
720 Initialize();
721
722 request_.method = "GET";
723 request_.url = GURL("http://www.google.com/");
724
725 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
726 net_log_, callback_.callback()));
727
728 // Check that priority is highest.
729 QuicReliableClientStream* reliable_stream =
730 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
731 DCHECK(reliable_stream);
[email protected]9f0dcd4e2014-01-16 15:58:14732 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]24e5bc52013-09-18 15:36:58733 reliable_stream->EffectivePriority());
734
735 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
736 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:58737
738 // Check that priority has now dropped back to MEDIUM.
739 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
740 reliable_stream->EffectivePriority()));
741
742 // Ack the request.
[email protected]1e960032013-12-20 19:00:20743 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]24e5bc52013-09-18 15:36:58744 EXPECT_EQ(ERR_IO_PENDING,
745 stream_->ReadResponseHeaders(callback_.callback()));
746
747 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20748 SetResponse("404 OK", "hello world!");
[email protected]24e5bc52013-09-18 15:36:58749 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]92bf17c2014-03-03 21:14:03750 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]24e5bc52013-09-18 15:36:58751
rchb27683c2015-07-29 23:53:50752 base::MessageLoop::current()->RunUntilIdle();
753
[email protected]24e5bc52013-09-18 15:36:58754 EXPECT_TRUE(AtEof());
755}
756
[email protected]e1cca9a2013-09-20 17:14:44757// Regression test for http://crbug.com/294870
[email protected]1e960032013-12-20 19:00:20758TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
759 SetRequest("GET", "/", MEDIUM);
[email protected]e1cca9a2013-09-20 17:14:44760 use_closing_stream_ = true;
[email protected]459a7402014-02-10 12:58:52761
[email protected]08da9adb2014-04-24 08:33:31762 AddWrite(ConstructRstStreamPacket(1));
[email protected]459a7402014-02-10 12:58:52763
[email protected]e1cca9a2013-09-20 17:14:44764 Initialize();
765
766 request_.method = "GET";
767 request_.url = GURL("http://www.google.com/");
768
769 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
770 net_log_, callback_.callback()));
771
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();
777 DCHECK(delegate);
[email protected]9f0dcd4e2014-01-16 15:58:14778 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44779 reliable_stream->EffectivePriority());
780
rtennetibe635732014-10-02 22:51:42781 // Set Delegate to nullptr and make sure EffectivePriority returns highest
[email protected]e1cca9a2013-09-20 17:14:44782 // priority.
rtennetibe635732014-10-02 22:51:42783 reliable_stream->SetDelegate(nullptr);
[email protected]9f0dcd4e2014-01-16 15:58:14784 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44785 reliable_stream->EffectivePriority());
786 reliable_stream->SetDelegate(delegate);
787}
788
[email protected]f702d572012-12-04 15:56:20789} // namespace test
[email protected]f702d572012-12-04 15:56:20790} // namespace net