blob: e571e2e24359c4b1d5405fe07f0302bec61e9578 [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
rch7dd15702015-07-01 18:57:5787 void OnHeadersAvailable(StringPiece headers) override { Close(false); }
88
dchengb03027d2014-10-21 12:00:2089 int OnDataReceived(const char* data, int length) override {
[email protected]63534512012-12-23 18:49:0090 Close(false);
91 return OK;
92 }
93};
94
[email protected]6d515822014-08-22 01:58:0695class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
96 public:
97 explicit TestPacketWriterFactory(DatagramClientSocket* socket)
98 : socket_(socket) {}
dchengb03027d2014-10-21 12:00:2099 ~TestPacketWriterFactory() override {}
[email protected]6d515822014-08-22 01:58:06100
dchengb03027d2014-10-21 12:00:20101 QuicPacketWriter* Create(QuicConnection* connection) const override {
[email protected]6d515822014-08-22 01:58:06102 return new QuicDefaultPacketWriter(socket_);
103 }
104
105 private:
106 DatagramClientSocket* socket_;
107};
108
[email protected]f702d572012-12-04 15:56:20109} // namespace
110
[email protected]24e5bc52013-09-18 15:36:58111class QuicHttpStreamPeer {
112 public:
113 static QuicReliableClientStream* GetQuicReliableClientStream(
114 QuicHttpStream* stream) {
115 return stream->stream_;
116 }
117};
118
[email protected]1e960032013-12-20 19:00:20119class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
[email protected]f702d572012-12-04 15:56:20120 protected:
[email protected]1e960032013-12-20 19:00:20121 static const bool kFin = true;
122 static const bool kIncludeVersion = true;
123 static const bool kIncludeCongestionFeedback = true;
124
[email protected]f702d572012-12-04 15:56:20125 // Holds a packet to be written to the wire, and the IO mode that should
126 // be used by the mock socket when performing the write.
127 struct PacketToWrite {
128 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
129 : mode(mode),
130 packet(packet) {
131 }
132 IoMode mode;
133 QuicEncryptedPacket* packet;
134 };
135
136 QuicHttpStreamTest()
137 : net_log_(BoundNetLog()),
[email protected]63534512012-12-23 18:49:00138 use_closing_stream_(false),
[email protected]f702d572012-12-04 15:56:20139 read_buffer_(new IOBufferWithSize(4096)),
[email protected]3aa9ca72014-02-27 19:39:43140 connection_id_(2),
[email protected]66ae5962014-05-22 11:13:05141 stream_id_(kClientDataStreamId1),
bncb07c05532015-05-14 19:07:20142 maker_(GetParam(), connection_id_, &clock_, kDefaultServerHostName),
[email protected]1e960032013-12-20 19:00:20143 random_generator_(0) {
[email protected]f702d572012-12-04 15:56:20144 IPAddressNumber ip;
145 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
146 peer_addr_ = IPEndPoint(ip, 443);
147 self_addr_ = IPEndPoint(ip, 8435);
rtenneti4b06ae72014-08-26 03:43:43148 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
[email protected]f702d572012-12-04 15:56:20149 }
150
151 ~QuicHttpStreamTest() {
rtenneti85dcfac22015-03-27 20:22:19152 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
[email protected]f702d572012-12-04 15:56:20153 for (size_t i = 0; i < writes_.size(); i++) {
154 delete writes_[i].packet;
155 }
156 }
157
158 // Adds a packet to the list of expected writes.
[email protected]1e960032013-12-20 19:00:20159 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
160 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20161 }
162
163 // Returns the packet to be written at position |pos|.
164 QuicEncryptedPacket* GetWrite(size_t pos) {
165 return writes_[pos].packet;
166 }
167
168 bool AtEof() {
rch37de576c2015-05-17 20:28:17169 return socket_data_->AllReadDataConsumed() &&
170 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20171 }
172
[email protected]1e960032013-12-20 19:00:20173 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
174 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
[email protected]f702d572012-12-04 15:56:20175 }
176
177 // Configures the test fixture to use the list of expected writes.
178 void Initialize() {
179 mock_writes_.reset(new MockWrite[writes_.size()]);
180 for (size_t i = 0; i < writes_.size(); i++) {
181 mock_writes_[i] = MockWrite(writes_[i].mode,
182 writes_[i].packet->data(),
183 writes_[i].packet->length());
184 };
185
rtennetibe635732014-10-02 22:51:42186 socket_data_.reset(new StaticSocketDataProvider(
187 nullptr, 0, mock_writes_.get(), writes_.size()));
[email protected]f702d572012-12-04 15:56:20188
[email protected]e13201d82012-12-12 05:00:32189 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
190 net_log_.net_log());
191 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20192 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41193 send_algorithm_ = new MockSendAlgorithm();
rch7dd15702015-07-01 18:57:57194 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
195 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
[email protected]efecff92013-09-24 07:49:23196 EXPECT_CALL(*send_algorithm_,
[email protected]ef0da582014-05-09 07:16:30197 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
[email protected]48878092013-07-26 14:51:56198 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05199 Return(QuicTime::Delta::Zero()));
[email protected]08da9adb2014-04-24 08:33:31200 EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
201 Return(kMaxPacketSize));
[email protected]77b5d50b2014-05-07 22:48:48202 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).
[email protected]06ff5152013-08-29 01:03:05203 WillRepeatedly(Return(QuicTime::Delta::Zero()));
[email protected]ea825e02013-08-21 18:12:45204 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05205 Return(QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40206 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
[email protected]2cfc6bb82013-10-27 03:40:44207 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
208 &random_generator_));
[email protected]6d515822014-08-22 01:58:06209 TestPacketWriterFactory writer_factory(socket);
[email protected]3aa9ca72014-02-27 19:39:43210 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
211 connection_id_, peer_addr_,
[email protected]6d515822014-08-22 01:58:06212 helper_.get(), writer_factory);
[email protected]f702d572012-12-04 15:56:20213 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41214 connection_->SetSendAlgorithm(send_algorithm_);
ckrasic4f9d88d2015-07-22 22:23:16215 session_.reset(new QuicChromiumClientSession(
rtennetid39bd762015-06-12 01:05:52216 connection_, scoped_ptr<DatagramClientSocket>(socket),
217 /*stream_factory=*/nullptr, &crypto_client_stream_factory_,
rtenneti041b2992015-02-23 23:03:28218 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
bncb07c05532015-05-14 19:07:20219 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
220 /*is_secure=*/false, PRIVACY_MODE_DISABLED),
rtennetia75df622015-06-21 23:59:50221 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
222 "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
223 base::ThreadTaskRunnerHandle::Get().get(), nullptr));
rtennetid39bd762015-06-12 01:05:52224 session_->Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44225 session_->GetCryptoStream()->CryptoConnect();
[email protected]8ba81212013-05-03 13:11:48226 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
[email protected]6cca996b2013-01-25 07:43:36227 stream_.reset(use_closing_stream_ ?
[email protected]0b2294d32013-08-02 00:46:36228 new AutoClosingStream(session_->GetWeakPtr()) :
229 new QuicHttpStream(session_->GetWeakPtr()));
[email protected]6cca996b2013-01-25 07:43:36230 }
231
[email protected]1e960032013-12-20 19:00:20232 void SetRequest(const std::string& method,
233 const std::string& path,
234 RequestPriority priority) {
235 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
[email protected]6cca996b2013-01-25 07:43:36236 }
237
[email protected]1e960032013-12-20 19:00:20238 void SetResponse(const std::string& status, const std::string& body) {
239 response_headers_ = maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03240 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36241 }
[email protected]f702d572012-12-04 15:56:20242
[email protected]1e960032013-12-20 19:00:20243 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
[email protected]f702d572012-12-04 15:56:20244 QuicPacketSequenceNumber sequence_number,
[email protected]e8ff26842013-03-22 21:02:05245 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20246 bool fin,
247 QuicStreamOffset offset,
248 base::StringPiece data) {
rtennetif4bdb542015-01-21 14:33:05249 return maker_.MakeDataPacket(sequence_number, stream_id_,
250 should_include_version, fin, offset, data);
[email protected]f702d572012-12-04 15:56:20251 }
252
[email protected]1e960032013-12-20 19:00:20253 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
254 QuicPacketSequenceNumber sequence_number,
rtennetif4bdb542015-01-21 14:33:05255 bool fin,
256 RequestPriority request_priority) {
257 QuicPriority priority =
258 ConvertRequestPriorityToQuicPriority(request_priority);
259 return maker_.MakeRequestHeadersPacket(sequence_number, stream_id_,
260 kIncludeVersion, fin, priority,
261 request_headers_);
[email protected]1e960032013-12-20 19:00:20262 }
263
264 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
265 QuicPacketSequenceNumber sequence_number,
266 bool fin) {
267 return maker_.MakeResponseHeadersPacket(
268 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_);
269 }
270
271 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
[email protected]06ff5152013-08-29 01:03:05272 QuicPacketSequenceNumber sequence_number) {
[email protected]1e960032013-12-20 19:00:20273 return maker_.MakeRstPacket(
[email protected]51cc1342014-04-18 23:44:37274 sequence_number, true, stream_id_,
rtenneti4a5df262014-11-07 00:43:58275 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
[email protected]06ff5152013-08-29 01:03:05276 }
277
rtenneti6bd660b2015-07-18 00:19:53278 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamCancelledPacket(
279 QuicPacketSequenceNumber sequence_number) {
280 return maker_.MakeRstPacket(sequence_number, !kIncludeVersion, stream_id_,
281 QUIC_STREAM_CANCELLED);
282 }
283
[email protected]c5e1aca2014-01-30 04:03:04284 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
285 QuicPacketSequenceNumber sequence_number) {
286 return maker_.MakeAckAndRstPacket(
287 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
[email protected]08da9adb2014-04-24 08:33:31288 2, 1, !kIncludeCongestionFeedback);
[email protected]c5e1aca2014-01-30 04:03:04289 }
290
[email protected]1e960032013-12-20 19:00:20291 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
[email protected]f702d572012-12-04 15:56:20292 QuicPacketSequenceNumber sequence_number,
[email protected]63534512012-12-23 18:49:00293 QuicPacketSequenceNumber largest_received,
294 QuicPacketSequenceNumber least_unacked) {
[email protected]1e960032013-12-20 19:00:20295 return maker_.MakeAckPacket(sequence_number, largest_received,
296 least_unacked, !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00297 }
298
[email protected]f702d572012-12-04 15:56:20299 BoundNetLog net_log_;
[email protected]63534512012-12-23 18:49:00300 bool use_closing_stream_;
[email protected]fee17f72013-02-03 07:47:41301 MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20302 scoped_refptr<TestTaskRunner> runner_;
[email protected]4356f0f2013-04-07 00:58:17303 scoped_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20304 MockClock clock_;
305 TestQuicConnection* connection_;
[email protected]2cfc6bb82013-10-27 03:40:44306 scoped_ptr<QuicConnectionHelper> helper_;
[email protected]f702d572012-12-04 15:56:20307 testing::StrictMock<MockConnectionVisitor> visitor_;
308 scoped_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15309 TransportSecurityState transport_security_state_;
ckrasic4f9d88d2015-07-22 22:23:16310 scoped_ptr<QuicChromiumClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01311 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20312 TestCompletionCallback callback_;
313 HttpRequestInfo request_;
314 HttpRequestHeaders headers_;
315 HttpResponseInfo response_;
316 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]1e960032013-12-20 19:00:20317 SpdyHeaderBlock request_headers_;
318 SpdyHeaderBlock response_headers_;
[email protected]6cca996b2013-01-25 07:43:36319 std::string request_data_;
320 std::string response_data_;
[email protected]f702d572012-12-04 15:56:20321
322 private:
[email protected]3aa9ca72014-02-27 19:39:43323 const QuicConnectionId connection_id_;
[email protected]1e960032013-12-20 19:00:20324 const QuicStreamId stream_id_;
325 QuicTestPacketMaker maker_;
[email protected]f702d572012-12-04 15:56:20326 IPEndPoint self_addr_;
327 IPEndPoint peer_addr_;
[email protected]457d6952013-12-13 09:24:58328 MockRandom random_generator_;
[email protected]e8ff26842013-03-22 21:02:05329 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]f702d572012-12-04 15:56:20330 scoped_ptr<StaticSocketDataProvider> socket_data_;
331 std::vector<PacketToWrite> writes_;
332};
333
[email protected]1e960032013-12-20 19:00:20334INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
335 ::testing::ValuesIn(QuicSupportedVersions()));
336
337TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44338 Initialize();
rtennetibe635732014-10-02 22:51:42339 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20340}
341
[email protected]1e960032013-12-20 19:00:20342TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
[email protected]ed3fc15d2013-03-08 18:37:44343 Initialize();
[email protected]f702d572012-12-04 15:56:20344 EXPECT_TRUE(stream_->CanFindEndOfResponse());
345}
346
[email protected]1e960032013-12-20 19:00:20347TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
[email protected]ed3fc15d2013-03-08 18:37:44348 Initialize();
[email protected]f702d572012-12-04 15:56:20349 EXPECT_FALSE(stream_->IsConnectionReusable());
350}
351
[email protected]1e960032013-12-20 19:00:20352TEST_P(QuicHttpStreamTest, GetRequest) {
353 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05354 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
[email protected]f702d572012-12-04 15:56:20355 Initialize();
356
357 request_.method = "GET";
358 request_.url = GURL("http://www.google.com/");
359
[email protected]262eec82013-03-19 21:01:36360 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
361 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20362 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
363 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20364
365 // Ack the request.
[email protected]1e960032013-12-20 19:00:20366 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20367
368 EXPECT_EQ(ERR_IO_PENDING,
369 stream_->ReadResponseHeaders(callback_.callback()));
370
[email protected]1e960032013-12-20 19:00:20371 SetResponse("404 Not Found", std::string());
[email protected]92bf17c2014-03-03 21:14:03372 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]f702d572012-12-04 15:56:20373
374 // Now that the headers have been processed, the callback will return.
375 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36376 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20377 EXPECT_EQ(404, response_.headers->response_code());
378 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53379 EXPECT_FALSE(response_.response_time.is_null());
380 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20381
382 // There is no body, so this should return immediately.
383 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
384 read_buffer_->size(),
385 callback_.callback()));
386 EXPECT_TRUE(stream_->IsResponseBodyComplete());
387 EXPECT_TRUE(AtEof());
388}
389
[email protected]3e7dca62013-09-10 16:14:23390// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20391TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
392 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05393 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
[email protected]3e7dca62013-09-10 16:14:23394 Initialize();
395
396 request_.method = "GET";
397 request_.url = GURL("http://www.google.com/");
398
399 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
400 net_log_, callback_.callback()));
401 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
402 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23403
404 // Ack the request.
[email protected]1e960032013-12-20 19:00:20405 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]3e7dca62013-09-10 16:14:23406
407 EXPECT_EQ(ERR_IO_PENDING,
408 stream_->ReadResponseHeaders(callback_.callback()));
409
410 SpdyHeaderBlock headers;
411 headers[":status"] = "200 OK";
412 headers[":version"] = "HTTP/1.1";
413 headers["content-type"] = "text/plain";
rch7dd15702015-07-01 18:57:57414 headers["big6"] = std::string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:23415
rch7dd15702015-07-01 18:57:57416 response_headers_ = headers;
417 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]3e7dca62013-09-10 16:14:23418
419 // Now that the headers have been processed, the callback will return.
420 EXPECT_EQ(OK, callback_.WaitForResult());
421 ASSERT_TRUE(response_.headers.get());
422 EXPECT_EQ(200, response_.headers->response_code());
423 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
424
425 // There is no body, so this should return immediately.
426 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
427 read_buffer_->size(),
428 callback_.callback()));
429 EXPECT_TRUE(stream_->IsResponseBodyComplete());
430 EXPECT_TRUE(AtEof());
431}
432
rchf9f103cbc2014-08-30 05:28:04433// Regression test for http://crbug.com/409101
434TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
435 SetRequest("GET", "/", DEFAULT_PRIORITY);
436 Initialize();
437
438 request_.method = "GET";
439 request_.url = GURL("http://www.google.com/");
440
441 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
442 net_log_, callback_.callback()));
443
444 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
445
446 EXPECT_EQ(ERR_CONNECTION_CLOSED,
447 stream_->SendRequest(headers_, &response_,
448 callback_.callback()));
449}
450
rch11a114a2014-09-04 23:41:59451// Regression test for http://crbug.com/409871
452TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
453 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05454 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
rch11a114a2014-09-04 23:41:59455 Initialize();
456
457 request_.method = "GET";
458 request_.url = GURL("http://www.google.com/");
459
460 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
461 net_log_, callback_.callback()));
462
463 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
464 callback_.callback()));
465
466 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
467
468 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
469}
470
[email protected]1e960032013-12-20 19:00:20471TEST_P(QuicHttpStreamTest, SendPostRequest) {
472 SetRequest("POST", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05473 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]92bf17c2014-03-03 21:14:03474 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
[email protected]1e960032013-12-20 19:00:20475 AddWrite(ConstructAckPacket(3, 3, 1));
[email protected]f702d572012-12-04 15:56:20476
477 Initialize();
478
[email protected]b2d26cfd2012-12-11 10:36:06479 ScopedVector<UploadElementReader> element_readers;
480 element_readers.push_back(
481 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
mmenkecbc2b712014-10-09 20:29:07482 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f702d572012-12-04 15:56:20483 request_.method = "POST";
484 request_.url = GURL("http://www.google.com/");
485 request_.upload_data_stream = &upload_data_stream;
[email protected]4db27d82012-12-20 11:50:24486 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
[email protected]f702d572012-12-04 15:56:20487
[email protected]262eec82013-03-19 21:01:36488 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
489 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20490 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
491 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20492
493 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20494 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20495
496 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20497 SetResponse("200 OK", std::string());
[email protected]92bf17c2014-03-03 21:14:03498 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
[email protected]f702d572012-12-04 15:56:20499
500 // Since the headers have already arrived, this should return immediately.
501 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36502 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20503 EXPECT_EQ(200, response_.headers->response_code());
504 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
505
506 // Send the response body.
507 const char kResponseBody[] = "Hello world!";
[email protected]92bf17c2014-03-03 21:14:03508 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
[email protected]f702d572012-12-04 15:56:20509 // Since the body has already arrived, this should return immediately.
510 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
511 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
512 callback_.callback()));
513
514 EXPECT_TRUE(stream_->IsResponseBodyComplete());
515 EXPECT_TRUE(AtEof());
516}
517
[email protected]1e960032013-12-20 19:00:20518TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
519 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:47520 size_t chunk_size = strlen(kUploadData);
rtennetif4bdb542015-01-21 14:33:05521 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]92bf17c2014-03-03 21:14:03522 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
523 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
524 kUploadData));
[email protected]1e960032013-12-20 19:00:20525 AddWrite(ConstructAckPacket(4, 3, 1));
[email protected]c9e49a02013-02-26 05:56:47526 Initialize();
527
mmenkecbc2b712014-10-09 20:29:07528 ChunkedUploadDataStream upload_data_stream(0);
529 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:47530
531 request_.method = "POST";
532 request_.url = GURL("http://www.google.com/");
533 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07534 ASSERT_EQ(OK, request_.upload_data_stream->Init(
535 TestCompletionCallback().callback()));
[email protected]c9e49a02013-02-26 05:56:47536
[email protected]262eec82013-03-19 21:01:36537 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
538 net_log_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47539 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
540 callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47541
mmenkecbc2b712014-10-09 20:29:07542 upload_data_stream.AppendData(kUploadData, chunk_size, true);
[email protected]c9e49a02013-02-26 05:56:47543
544 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20545 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]c9e49a02013-02-26 05:56:47546
547 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20548 SetResponse("200 OK", std::string());
[email protected]92bf17c2014-03-03 21:14:03549 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
[email protected]c9e49a02013-02-26 05:56:47550
551 // Since the headers have already arrived, this should return immediately.
552 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36553 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:47554 EXPECT_EQ(200, response_.headers->response_code());
555 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
556
557 // Send the response body.
558 const char kResponseBody[] = "Hello world!";
[email protected]1e960032013-12-20 19:00:20559 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
560 kResponseBody));
[email protected]c9e49a02013-02-26 05:56:47561
562 // Since the body has already arrived, this should return immediately.
563 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
564 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
565 callback_.callback()));
566
567 EXPECT_TRUE(stream_->IsResponseBodyComplete());
568 EXPECT_TRUE(AtEof());
569}
570
[email protected]16ba7742014-08-22 00:57:25571TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
572 SetRequest("POST", "/", DEFAULT_PRIORITY);
573 size_t chunk_size = strlen(kUploadData);
rtennetif4bdb542015-01-21 14:33:05574 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]16ba7742014-08-22 00:57:25575 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
576 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
577 AddWrite(ConstructAckPacket(4, 3, 1));
578 Initialize();
579
mmenkecbc2b712014-10-09 20:29:07580 ChunkedUploadDataStream upload_data_stream(0);
581 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:25582
583 request_.method = "POST";
584 request_.url = GURL("http://www.google.com/");
585 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07586 ASSERT_EQ(OK, request_.upload_data_stream->Init(
587 TestCompletionCallback().callback()));
[email protected]16ba7742014-08-22 00:57:25588
589 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
590 net_log_, callback_.callback()));
591 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
592 callback_.callback()));
593
mmenkecbc2b712014-10-09 20:29:07594 upload_data_stream.AppendData(nullptr, 0, true);
[email protected]16ba7742014-08-22 00:57:25595
596 ProcessPacket(ConstructAckPacket(1, 0, 0));
597
598 // Send the response headers (but not the body).
599 SetResponse("200 OK", std::string());
600 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
601
602 // Since the headers have already arrived, this should return immediately.
603 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
604 ASSERT_TRUE(response_.headers.get());
605 EXPECT_EQ(200, response_.headers->response_code());
606 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
607
608 // Send the response body.
609 const char kResponseBody[] = "Hello world!";
610 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
611 kResponseBody));
612
613 // Since the body has already arrived, this should return immediately.
614 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
615 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
616 callback_.callback()));
617
618 EXPECT_TRUE(stream_->IsResponseBodyComplete());
619 EXPECT_TRUE(AtEof());
620}
621
622TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
623 SetRequest("POST", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05624 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]16ba7742014-08-22 00:57:25625 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
626 AddWrite(ConstructAckPacket(3, 3, 1));
627 Initialize();
628
mmenkecbc2b712014-10-09 20:29:07629 ChunkedUploadDataStream upload_data_stream(0);
[email protected]16ba7742014-08-22 00:57:25630
631 request_.method = "POST";
632 request_.url = GURL("http://www.google.com/");
633 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07634 ASSERT_EQ(OK, request_.upload_data_stream->Init(
635 TestCompletionCallback().callback()));
[email protected]16ba7742014-08-22 00:57:25636
637 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
638 net_log_, callback_.callback()));
639 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
640 callback_.callback()));
641
mmenkecbc2b712014-10-09 20:29:07642 upload_data_stream.AppendData(nullptr, 0, true);
[email protected]16ba7742014-08-22 00:57:25643
644 ProcessPacket(ConstructAckPacket(1, 0, 0));
645
646 // Send the response headers (but not the body).
647 SetResponse("200 OK", std::string());
648 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
649
650 // Since the headers have already arrived, this should return immediately.
651 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
652 ASSERT_TRUE(response_.headers.get());
653 EXPECT_EQ(200, response_.headers->response_code());
654 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
655
656 // Send the response body.
657 const char kResponseBody[] = "Hello world!";
658 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
659 kResponseBody));
660
661 // Since the body has already arrived, this should return immediately.
662 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
663 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
664 callback_.callback()));
665
666 EXPECT_TRUE(stream_->IsResponseBodyComplete());
667 EXPECT_TRUE(AtEof());
668}
669
[email protected]1e960032013-12-20 19:00:20670TEST_P(QuicHttpStreamTest, DestroyedEarly) {
671 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05672 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
rtenneti6bd660b2015-07-18 00:19:53673 if (FLAGS_quic_process_frames_inline) {
674 AddWrite(ConstructRstStreamCancelledPacket(2));
675 } else {
676 AddWrite(ConstructAckAndRstStreamPacket(2));
677 }
[email protected]63534512012-12-23 18:49:00678 use_closing_stream_ = true;
679 Initialize();
680
681 request_.method = "GET";
682 request_.url = GURL("http://www.google.com/");
683
[email protected]262eec82013-03-19 21:01:36684 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
685 net_log_, callback_.callback()));
[email protected]63534512012-12-23 18:49:00686 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
[email protected]24e5bc52013-09-18 15:36:58687 callback_.callback()));
[email protected]63534512012-12-23 18:49:00688
689 // Ack the request.
[email protected]1e960032013-12-20 19:00:20690 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]63534512012-12-23 18:49:00691 EXPECT_EQ(ERR_IO_PENDING,
692 stream_->ReadResponseHeaders(callback_.callback()));
693
694 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20695 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:00696 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]92bf17c2014-03-03 21:14:03697 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]63534512012-12-23 18:49:00698
699 EXPECT_TRUE(AtEof());
700}
701
[email protected]1e960032013-12-20 19:00:20702TEST_P(QuicHttpStreamTest, Priority) {
703 SetRequest("GET", "/", MEDIUM);
rtennetif4bdb542015-01-21 14:33:05704 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM));
rtenneti6bd660b2015-07-18 00:19:53705 if (FLAGS_quic_process_frames_inline) {
706 AddWrite(ConstructRstStreamCancelledPacket(2));
707 } else {
708 AddWrite(ConstructAckAndRstStreamPacket(2));
709 }
[email protected]24e5bc52013-09-18 15:36:58710 use_closing_stream_ = true;
711 Initialize();
712
713 request_.method = "GET";
714 request_.url = GURL("http://www.google.com/");
715
716 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
717 net_log_, callback_.callback()));
718
719 // Check that priority is highest.
720 QuicReliableClientStream* reliable_stream =
721 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
722 DCHECK(reliable_stream);
[email protected]9f0dcd4e2014-01-16 15:58:14723 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]24e5bc52013-09-18 15:36:58724 reliable_stream->EffectivePriority());
725
726 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
727 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:58728
729 // Check that priority has now dropped back to MEDIUM.
730 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
731 reliable_stream->EffectivePriority()));
732
733 // Ack the request.
[email protected]1e960032013-12-20 19:00:20734 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]24e5bc52013-09-18 15:36:58735 EXPECT_EQ(ERR_IO_PENDING,
736 stream_->ReadResponseHeaders(callback_.callback()));
737
738 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20739 SetResponse("404 OK", "hello world!");
[email protected]24e5bc52013-09-18 15:36:58740 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]92bf17c2014-03-03 21:14:03741 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]24e5bc52013-09-18 15:36:58742
743 EXPECT_TRUE(AtEof());
744}
745
[email protected]e1cca9a2013-09-20 17:14:44746// Regression test for http://crbug.com/294870
[email protected]1e960032013-12-20 19:00:20747TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
748 SetRequest("GET", "/", MEDIUM);
[email protected]e1cca9a2013-09-20 17:14:44749 use_closing_stream_ = true;
[email protected]459a7402014-02-10 12:58:52750
[email protected]08da9adb2014-04-24 08:33:31751 AddWrite(ConstructRstStreamPacket(1));
[email protected]459a7402014-02-10 12:58:52752
[email protected]e1cca9a2013-09-20 17:14:44753 Initialize();
754
755 request_.method = "GET";
756 request_.url = GURL("http://www.google.com/");
757
758 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
759 net_log_, callback_.callback()));
760
761 // Check that priority is highest.
762 QuicReliableClientStream* reliable_stream =
763 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
764 DCHECK(reliable_stream);
765 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
766 DCHECK(delegate);
[email protected]9f0dcd4e2014-01-16 15:58:14767 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44768 reliable_stream->EffectivePriority());
769
rtennetibe635732014-10-02 22:51:42770 // Set Delegate to nullptr and make sure EffectivePriority returns highest
[email protected]e1cca9a2013-09-20 17:14:44771 // priority.
rtennetibe635732014-10-02 22:51:42772 reliable_stream->SetDelegate(nullptr);
[email protected]9f0dcd4e2014-01-16 15:58:14773 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44774 reliable_stream->EffectivePriority());
775 reliable_stream->SetDelegate(delegate);
776}
777
[email protected]f702d572012-12-04 15:56:20778} // namespace test
[email protected]f702d572012-12-04 15:56:20779} // namespace net