blob: 338187d557fa215cc0e1065b464a2d7bbd4c68db [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
Ryan Hamiltona3ee93a72018-08-01 22:03:085#include "net/quic/quic_http_stream.h"
[email protected]f702d572012-12-04 15:56:206
sclittle1edeeb22015-09-02 20:46:107#include <stdint.h>
8
danakjad1777e2016-04-16 00:56:429#include <memory>
bnc086b39e12016-06-24 13:05:2610#include <utility>
[email protected]f702d572012-12-04 15:56:2011
Sebastien Marchand6d0558fd2019-01-25 16:49:3712#include "base/bind.h"
danakjad1777e2016-04-16 00:56:4213#include "base/memory/ptr_util.h"
fdoray92e35a72016-06-10 15:54:5514#include "base/run_loop.h"
Avi Drissman4365a4782018-12-28 19:26:2415#include "base/stl_util.h"
xunjieli188bd402016-03-12 00:17:2516#include "base/strings/string_number_conversions.h"
gabf767595f2016-05-11 18:50:3517#include "base/threading/thread_task_runner_handle.h"
Zhongyi Shic16b4102019-02-12 00:37:4018#include "base/time/default_tick_clock.h"
xunjieli84adaab2016-09-20 01:12:2819#include "base/time/time.h"
mmenkecbc2b712014-10-09 20:29:0720#include "net/base/chunked_upload_data_stream.h"
21#include "net/base/elements_upload_data_stream.h"
David Benjamin0288768a2019-07-22 15:00:2622#include "net/base/load_flags.h"
xunjieli84adaab2016-09-20 01:12:2823#include "net/base/load_timing_info.h"
24#include "net/base/load_timing_info_test_util.h"
[email protected]f702d572012-12-04 15:56:2025#include "net/base/net_errors.h"
26#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0627#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2028#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1529#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0030#include "net/log/net_log_event_type.h"
xunjieli5fafe142016-03-23 23:32:5431#include "net/log/test_net_log.h"
32#include "net/log/test_net_log_util.h"
Victor Vasiliev4f6fb892019-05-31 16:58:3133#include "net/quic/address_utils.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0834#include "net/quic/crypto/proof_verifier_chromium.h"
35#include "net/quic/mock_crypto_client_stream_factory.h"
Ryan Hamiltona1d1f4a2019-06-26 14:43:0436#include "net/quic/platform/impl/quic_test_impl.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0837#include "net/quic/quic_chromium_alarm_factory.h"
38#include "net/quic/quic_chromium_connection_helper.h"
39#include "net/quic/quic_chromium_packet_reader.h"
40#include "net/quic/quic_chromium_packet_writer.h"
41#include "net/quic/quic_http_utils.h"
42#include "net/quic/quic_server_info.h"
43#include "net/quic/quic_stream_factory.h"
44#include "net/quic/quic_test_packet_maker.h"
Ryan Hamilton0d65a8c2019-06-07 00:46:0245#include "net/quic/quic_test_packet_printer.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0846#include "net/quic/test_task_runner.h"
tbansalca83c002016-04-28 20:56:2847#include "net/socket/socket_performance_watcher.h"
[email protected]f702d572012-12-04 15:56:2048#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5849#include "net/spdy/spdy_http_utils.h"
rch03b7a202016-02-05 00:54:2050#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0151#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4352#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4053#include "net/test/test_with_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5154#include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h"
55#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
56#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
57#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
David Schinazi3f7465c2019-07-12 01:57:0558#include "net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5159#include "net/third_party/quiche/src/quic/core/quic_connection.h"
60#include "net/third_party/quiche/src/quic/core/quic_utils.h"
61#include "net/third_party/quiche/src/quic/core/quic_write_blocked_list.h"
Ryan Hamiltona1d1f4a2019-06-26 14:43:0462#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
63#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5164#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
65#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
66#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
67#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
68#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
69#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
70#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1471#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
72#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
73#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
Ramin Halavati683bcaa92018-02-14 08:42:3974#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]f702d572012-12-04 15:56:2075#include "testing/gmock/include/gmock/gmock.h"
76#include "testing/gtest/include/gtest/gtest.h"
77
bnc614a92d32016-04-04 13:56:0778using std::string;
[email protected]f702d572012-12-04 15:56:2079using testing::_;
[email protected]06ff5152013-08-29 01:03:0580using testing::AnyNumber;
81using testing::Return;
[email protected]f702d572012-12-04 15:56:2082
83namespace net {
[email protected]f702d572012-12-04 15:56:2084namespace test {
[email protected]f702d572012-12-04 15:56:2085namespace {
86
[email protected]16ba7742014-08-22 00:57:2587const char kUploadData[] = "Really nifty data!";
rch9ae5b3b2016-02-11 00:36:2988const char kDefaultServerHostName[] = "www.example.org";
rchcd379012017-04-12 21:53:3289const uint16_t kDefaultServerPort = 443;
[email protected]f702d572012-12-04 15:56:2090
Ryan Hamilton8d9ee76e2018-05-29 23:52:5291class TestQuicConnection : public quic::QuicConnection {
[email protected]f702d572012-12-04 15:56:2092 public:
Ryan Hamilton8d9ee76e2018-05-29 23:52:5293 TestQuicConnection(const quic::ParsedQuicVersionVector& versions,
94 quic::QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2095 IPEndPoint address,
rch12fef552016-01-15 16:26:3196 QuicChromiumConnectionHelper* helper,
rch16c74d1d2016-04-22 06:14:0797 QuicChromiumAlarmFactory* alarm_factory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5298 quic::QuicPacketWriter* writer)
Victor Vasiliev4f6fb892019-05-31 16:58:3199 : quic::QuicConnection(connection_id,
100 ToQuicSocketAddress(address),
101 helper,
102 alarm_factory,
103 writer,
104 true /* owns_writer */,
105 quic::Perspective::IS_CLIENT,
106 versions) {}
[email protected]f702d572012-12-04 15:56:20107
Ryan Hamilton8d9ee76e2018-05-29 23:52:52108 void SetSendAlgorithm(quic::SendAlgorithmInterface* send_algorithm) {
109 quic::test::QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:20110 }
111};
112
maksim.sisov84e20c92016-06-23 08:49:34113// UploadDataStream that always returns errors on data read.
114class ReadErrorUploadDataStream : public UploadDataStream {
115 public:
116 enum class FailureMode { SYNC, ASYNC };
117
118 explicit ReadErrorUploadDataStream(FailureMode mode)
Jeremy Romand54000b22019-07-08 18:40:16119 : UploadDataStream(true, 0), async_(mode) {}
maksim.sisov84e20c92016-06-23 08:49:34120 ~ReadErrorUploadDataStream() override {}
121
122 private:
123 void CompleteRead() { UploadDataStream::OnReadCompleted(ERR_FAILED); }
124
125 // UploadDataStream implementation:
tfarina42834112016-09-22 13:38:20126 int InitInternal(const NetLogWithSource& net_log) override { return OK; }
maksim.sisov84e20c92016-06-23 08:49:34127
128 int ReadInternal(IOBuffer* buf, int buf_len) override {
129 if (async_ == FailureMode::ASYNC) {
130 base::ThreadTaskRunnerHandle::Get()->PostTask(
kylecharf4fe5172019-02-15 18:53:49131 FROM_HERE, base::BindOnce(&ReadErrorUploadDataStream::CompleteRead,
132 weak_factory_.GetWeakPtr()));
maksim.sisov84e20c92016-06-23 08:49:34133 return ERR_IO_PENDING;
134 }
135 return ERR_FAILED;
136 }
137
138 void ResetInternal() override {}
139
140 const FailureMode async_;
141
Jeremy Romand54000b22019-07-08 18:40:16142 base::WeakPtrFactory<ReadErrorUploadDataStream> weak_factory_{this};
maksim.sisov84e20c92016-06-23 08:49:34143
144 DISALLOW_COPY_AND_ASSIGN(ReadErrorUploadDataStream);
145};
146
Bence Béky8ddc2492018-06-13 01:02:04147// A helper class that will delete |stream| when the callback is invoked.
xunjieli8dff50b2016-07-22 14:19:06148class DeleteStreamCallback : public TestCompletionCallbackBase {
149 public:
Bence Béky8ddc2492018-06-13 01:02:04150 explicit DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)
151 : stream_(std::move(stream)) {}
xunjieli8dff50b2016-07-22 14:19:06152
Bence Béky8ddc2492018-06-13 01:02:04153 CompletionOnceCallback callback() {
154 return base::BindOnce(&DeleteStreamCallback::DeleteStream,
155 base::Unretained(this));
156 }
xunjieli8dff50b2016-07-22 14:19:06157
158 private:
159 void DeleteStream(int result) {
160 stream_.reset();
161 SetResult(result);
162 }
163
164 std::unique_ptr<QuicHttpStream> stream_;
xunjieli8dff50b2016-07-22 14:19:06165};
166
[email protected]f702d572012-12-04 15:56:20167} // namespace
168
[email protected]24e5bc52013-09-18 15:36:58169class QuicHttpStreamPeer {
170 public:
rch08e198572017-05-09 16:56:55171 static QuicChromiumClientStream::Handle* GetQuicChromiumClientStream(
[email protected]24e5bc52013-09-18 15:36:58172 QuicHttpStream* stream) {
rch08e198572017-05-09 16:56:55173 return stream->stream_.get();
[email protected]24e5bc52013-09-18 15:36:58174 }
175};
176
Ryan Hamilton8d9ee76e2018-05-29 23:52:52177class QuicHttpStreamTest : public ::testing::TestWithParam<
Nick Harper23290b82019-05-02 00:02:56178 std::tuple<quic::ParsedQuicVersion, bool>>,
Gabriel Charette694c3c332019-08-19 14:53:05179 public WithTaskEnvironment {
rchfb47f712017-05-21 03:24:00180 public:
181 void CloseStream(QuicHttpStream* stream, int /*rv*/) { stream->Close(false); }
182
[email protected]f702d572012-12-04 15:56:20183 protected:
[email protected]1e960032013-12-20 19:00:20184 static const bool kFin = true;
185 static const bool kIncludeVersion = true;
186 static const bool kIncludeCongestionFeedback = true;
187
[email protected]f702d572012-12-04 15:56:20188 // Holds a packet to be written to the wire, and the IO mode that should
189 // be used by the mock socket when performing the write.
190 struct PacketToWrite {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52191 PacketToWrite(IoMode mode, quic::QuicReceivedPacket* packet)
rjshaded5ced072015-12-18 19:26:02192 : mode(mode), packet(packet) {}
rtenneti15656ae2016-01-23 03:05:03193 PacketToWrite(IoMode mode, int rv) : mode(mode), packet(nullptr), rv(rv) {}
[email protected]f702d572012-12-04 15:56:20194 IoMode mode;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52195 quic::QuicReceivedPacket* packet;
rtenneti15656ae2016-01-23 03:05:03196 int rv;
[email protected]f702d572012-12-04 15:56:20197 };
198
199 QuicHttpStreamTest()
Yixin Wang079ad542018-01-11 04:06:05200 : version_(std::get<0>(GetParam())),
201 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Nick Harpera598fc5f2019-06-21 08:46:50202 crypto_config_(
203 quic::test::crypto_test_utils::ProofVerifierForTesting()),
Victor Costan9c7302b2018-08-27 16:39:44204 read_buffer_(base::MakeRefCounted<IOBufferWithSize>(4096)),
Fan Yang32c5a112018-12-10 20:06:33205 promise_id_(GetNthServerInitiatedUnidirectionalStreamId(0)),
206 stream_id_(GetNthClientInitiatedBidirectionalStreamId(0)),
David Schinazic8281052019-01-24 06:14:17207 connection_id_(quic::test::TestConnectionId(2)),
Yixin Wang079ad542018-01-11 04:06:05208 client_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58209 connection_id_,
210 &clock_,
211 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52212 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05213 client_headers_include_h2_stream_dependency_),
214 server_maker_(version_,
zhongyi5dbfdd42017-06-20 05:22:15215 connection_id_,
alyssar2adf3ac2016-05-03 17:12:58216 &clock_,
217 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52218 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05219 false),
ckrasic3865ee0f2016-02-29 22:04:56220 random_generator_(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:02221 printer_(version_) {
Ryan Hamiltona1d1f4a2019-06-26 14:43:04222 SetQuicFlag(FLAGS_quic_supports_tls_handshake, true);
martijn21968ea2016-02-24 18:46:20223 IPAddress ip(192, 0, 2, 33);
[email protected]f702d572012-12-04 15:56:20224 peer_addr_ = IPEndPoint(ip, 443);
225 self_addr_ = IPEndPoint(ip, 8435);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52226 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
Ramin Halavati683bcaa92018-02-14 08:42:39227 request_.traffic_annotation =
228 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f702d572012-12-04 15:56:20229 }
230
231 ~QuicHttpStreamTest() {
Renjieba55fae2018-09-20 03:05:16232 session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
233 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]f702d572012-12-04 15:56:20234 for (size_t i = 0; i < writes_.size(); i++) {
235 delete writes_[i].packet;
236 }
237 }
238
239 // Adds a packet to the list of expected writes.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52240 void AddWrite(std::unique_ptr<quic::QuicReceivedPacket> packet) {
[email protected]1e960032013-12-20 19:00:20241 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20242 }
243
rtenneti15656ae2016-01-23 03:05:03244 void AddWrite(IoMode mode, int rv) {
245 writes_.push_back(PacketToWrite(mode, rv));
246 }
247
[email protected]f702d572012-12-04 15:56:20248 // Returns the packet to be written at position |pos|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52249 quic::QuicReceivedPacket* GetWrite(size_t pos) { return writes_[pos].packet; }
[email protected]f702d572012-12-04 15:56:20250
251 bool AtEof() {
rch37de576c2015-05-17 20:28:17252 return socket_data_->AllReadDataConsumed() &&
253 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20254 }
255
Ryan Hamilton8d9ee76e2018-05-29 23:52:52256 void ProcessPacket(std::unique_ptr<quic::QuicReceivedPacket> packet) {
Victor Vasiliev4f6fb892019-05-31 16:58:31257 connection_->ProcessUdpPacket(ToQuicSocketAddress(self_addr_),
258 ToQuicSocketAddress(peer_addr_), *packet);
[email protected]f702d572012-12-04 15:56:20259 }
260
261 // Configures the test fixture to use the list of expected writes.
262 void Initialize() {
263 mock_writes_.reset(new MockWrite[writes_.size()]);
264 for (size_t i = 0; i < writes_.size(); i++) {
rtenneti15656ae2016-01-23 03:05:03265 if (writes_[i].packet == nullptr) {
266 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
267 } else {
268 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
269 writes_[i].packet->length());
270 }
bnc614a92d32016-04-04 13:56:07271 }
[email protected]f702d572012-12-04 15:56:20272
rtennetibe635732014-10-02 22:51:42273 socket_data_.reset(new StaticSocketDataProvider(
Ryan Sleevib8d7ea02018-05-07 20:01:01274 base::span<MockRead>(),
275 base::make_span(mock_writes_.get(), writes_.size())));
Ryan Hamilton0d65a8c2019-06-07 00:46:02276 socket_data_->set_printer(&printer_);
[email protected]f702d572012-12-04 15:56:20277
danakjad1777e2016-04-16 00:56:42278 std::unique_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
xunjielib53b38c2016-03-24 15:54:36279 socket_data_.get(), net_log_.bound().net_log()));
[email protected]e13201d82012-12-12 05:00:32280 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20281 runner_ = new TestTaskRunner(&clock_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52282 send_algorithm_ = new quic::test::MockSendAlgorithm();
rch7dd15702015-07-01 18:57:57283 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
284 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
Renjie Tangaadb84b2019-08-31 01:00:23285 if (VersionUsesQpack(version_.transport_version)) {
286 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
287 .Times(testing::AtLeast(1));
288 }
Ryan Hamiltona1d1f4a2019-06-26 14:43:04289 EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
290 .Times(AnyNumber());
rtenneti44f4a2e2015-08-07 14:00:07291 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
Zhongyi Shica576df2019-04-12 17:43:40292 .WillRepeatedly(Return(quic::kMaxOutgoingPacketSize));
jokulik0e0a00c32016-06-13 21:51:58293 EXPECT_CALL(*send_algorithm_, PacingRate(_))
Ryan Hamilton8d9ee76e2018-05-29 23:52:52294 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Michael Warres74ee3ce2017-10-09 15:26:37295 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
rtenneti44f4a2e2015-08-07 14:00:07296 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52297 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40298 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
rch08cae032017-03-29 00:59:15299 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
rch0d5bcf62017-05-24 22:48:45300 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
301 .Times(AnyNumber());
rch16c74d1d2016-04-22 06:14:07302 helper_.reset(
303 new QuicChromiumConnectionHelper(&clock_, &random_generator_));
304 alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
305
Michael Warres74ee3ce2017-10-09 15:26:37306 connection_ = new TestQuicConnection(
Nick Harper23290b82019-05-02 00:02:56307 quic::test::SupportedVersions(version_), connection_id_, peer_addr_,
308 helper_.get(), alarm_factory_.get(),
Ryan Hamilton9edcf1a2017-11-22 05:55:17309 new QuicChromiumPacketWriter(
310 socket.get(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]f702d572012-12-04 15:56:20311 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41312 connection_->SetSendAlgorithm(send_algorithm_);
rch03b7a202016-02-05 00:54:20313
314 // Load a certificate that is valid for *.example.org
315 scoped_refptr<X509Certificate> test_cert(
316 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
317 EXPECT_TRUE(test_cert.get());
318
319 verify_details_.cert_verify_result.verified_cert = test_cert;
320 verify_details_.cert_verify_result.is_issued_by_known_root = true;
321 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
322
xunjieli84adaab2016-09-20 01:12:28323 base::TimeTicks dns_end = base::TimeTicks::Now();
324 base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);
ckrasic4f9d88d2015-07-22 22:23:16325 session_.reset(new QuicChromiumClientSession(
xunjielib53b38c2016-03-24 15:54:36326 connection_, std::move(socket),
rtenneti1cd3b162015-09-29 02:58:28327 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57328 &transport_security_state_, /*ssl_config_service=*/nullptr,
danakjad1777e2016-04-16 00:56:42329 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
Paul Jensen8e3c5d32018-02-19 17:06:33330 QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
331 PRIVACY_MODE_DISABLED, SocketTag()),
Bence Béky1ceba552019-07-19 17:11:05332 /*require_confirmation=*/false,
333 /*max_allowed_push_id=*/0,
334 /*migrate_session_early_v2=*/false,
Zhongyi Shi757fcce2018-06-27 05:41:27335 /*migrate_session_on_network_change_v2=*/false,
336 /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shie01f2db2019-02-22 19:53:23337 quic::QuicTime::Delta::FromMilliseconds(
Ryan Sleevi2e8255b2019-07-17 21:02:21338 kDefaultRetransmittableOnWireTimeout.InMilliseconds()),
Zhongyi Shiaf38c4e42019-08-29 22:49:05339 /*migrate_idle_session=*/false, /*allow_port_migration=*/false,
340 kDefaultIdleSessionMigrationPeriod, kMaxTimeOnNonDefaultNetwork,
Zhongyi Shiee760762018-08-01 00:54:29341 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30342 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17343 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52344 quic::QuicTime::Delta::FromMilliseconds(
345 kQuicYieldAfterDurationMilliseconds),
Zhongyi Shidbce7f412019-02-01 23:16:29346 /*go_away_on_path_degrading*/ false,
Yixin Wang079ad542018-01-11 04:06:05347 client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52348 quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
349 dns_start, dns_end, &push_promise_index_, nullptr,
Zhongyi Shic16b4102019-02-12 00:37:40350 base::DefaultTickClock::GetInstance(),
xunjieli84adaab2016-09-20 01:12:28351 base::ThreadTaskRunnerHandle::Get().get(),
xunjieli5fafe142016-03-23 23:32:54352 /*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));
rtennetid39bd762015-06-12 01:05:52353 session_->Initialize();
xunjieli100937eb52016-09-15 20:09:37354 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57355
rch433bf5f2017-02-14 04:10:47356 session_->CryptoConnect(callback.callback());
Ryan Hamilton6c2a2a82017-12-15 02:06:28357 stream_ = std::make_unique<QuicHttpStream>(
358 session_->CreateHandle(HostPortPair("www.example.org", 443)));
359 promised_stream_ = std::make_unique<QuicHttpStream>(
360 session_->CreateHandle(HostPortPair("www.example.org", 443)));
ckrasic3865ee0f2016-02-29 22:04:56361 push_promise_[":path"] = "/bar";
362 push_promise_[":authority"] = "www.example.org";
363 push_promise_[":version"] = "HTTP/1.1";
364 push_promise_[":method"] = "GET";
365 push_promise_[":scheme"] = "https";
366
367 promised_response_[":status"] = "200 OK";
368 promised_response_[":version"] = "HTTP/1.1";
369 promised_response_["content-type"] = "text/plain";
370
David Schinazi3f7465c2019-07-12 01:57:05371 promise_url_ =
372 quic::SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
[email protected]6cca996b2013-01-25 07:43:36373 }
374
bnc614a92d32016-04-04 13:56:07375 void SetRequest(const string& method,
376 const string& path,
[email protected]1e960032013-12-20 19:00:20377 RequestPriority priority) {
rchcd379012017-04-12 21:53:32378 request_headers_ = client_maker_.GetRequestHeaders(method, "https", path);
[email protected]6cca996b2013-01-25 07:43:36379 }
380
bnc614a92d32016-04-04 13:56:07381 void SetResponse(const string& status, const string& body) {
alyssar2adf3ac2016-05-03 17:12:58382 response_headers_ = server_maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03383 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36384 }
[email protected]f702d572012-12-04 15:56:20385
Ryan Hamilton8d9ee76e2018-05-29 23:52:52386 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructDataPacket(
Fan Yangac867502019-01-28 21:10:23387 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52388 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56389 bool should_include_version,
390 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52391 quic::QuicStringPiece data,
alyssar2adf3ac2016-05-03 17:12:58392 QuicTestPacketMaker* maker) {
393 return maker->MakeDataPacket(packet_number, stream_id,
Ryan Hamilton7505eb92019-06-08 00:22:17394 should_include_version, fin, data);
ckrasic3865ee0f2016-02-29 22:04:56395 }
396
Ryan Hamilton8d9ee76e2018-05-29 23:52:52397 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23398 uint64_t packet_number,
[email protected]e8ff26842013-03-22 21:02:05399 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20400 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52401 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17402 return client_maker_.MakeDataPacket(packet_number, stream_id_,
403 should_include_version, fin, data);
alyssar2adf3ac2016-05-03 17:12:58404 }
405
Renjief49758b2019-01-11 23:32:41406 std::unique_ptr<quic::QuicReceivedPacket>
407 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23408 uint64_t packet_number,
Renjief49758b2019-01-11 23:32:41409 bool should_include_version,
410 bool fin,
Renjief49758b2019-01-11 23:32:41411 const std::vector<std::string>& data) {
412 return client_maker_.MakeMultipleDataFramesPacket(
Ryan Hamilton7505eb92019-06-08 00:22:17413 packet_number, stream_id_, should_include_version, fin, data);
Renjief49758b2019-01-11 23:32:41414 }
415
Ryan Hamilton8d9ee76e2018-05-29 23:52:52416 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23417 uint64_t packet_number,
alyssar2adf3ac2016-05-03 17:12:58418 bool should_include_version,
419 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52420 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17421 return server_maker_.MakeDataPacket(packet_number, stream_id_,
422 should_include_version, fin, data);
ckrasic3865ee0f2016-02-29 22:04:56423 }
424
Ryan Hamilton8d9ee76e2018-05-29 23:52:52425 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23426 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52427 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56428 bool should_include_version,
429 bool fin,
430 RequestPriority request_priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02431 size_t* spdy_headers_frame_length) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48432 return InnerConstructRequestHeadersPacket(
433 packet_number, stream_id, should_include_version, fin, request_priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02434 0, spdy_headers_frame_length);
Yixin Wang7a3f1b8d2018-01-17 21:40:48435 }
436
Ryan Hamilton8d9ee76e2018-05-29 23:52:52437 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23438 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52439 quic::QuicStreamId stream_id,
Yixin Wang7a3f1b8d2018-01-17 21:40:48440 bool should_include_version,
441 bool fin,
442 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52443 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02444 size_t* spdy_headers_frame_length) {
Ryan Hamilton0239aac2018-05-19 00:03:13445 spdy::SpdyPriority priority =
ckrasic3865ee0f2016-02-29 22:04:56446 ConvertRequestPriorityToQuicPriority(request_priority);
alyssar2adf3ac2016-05-03 17:12:58447 return client_maker_.MakeRequestHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56448 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48449 std::move(request_headers_), parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02450 spdy_headers_frame_length);
[email protected]f702d572012-12-04 15:56:20451 }
452
Ryan Hamilton8d9ee76e2018-05-29 23:52:52453 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25454 ConstructRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23455 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52456 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25457 bool should_include_version,
458 bool fin,
459 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52460 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25461 size_t* spdy_headers_frame_length,
462 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13463 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25464 ConvertRequestPriorityToQuicPriority(request_priority);
465 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
466 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02467 std::move(request_headers_), parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25468 spdy_headers_frame_length, data_writes);
469 }
470
Ryan Hamilton8d9ee76e2018-05-29 23:52:52471 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestAndRstPacket(
Fan Yangac867502019-01-28 21:10:23472 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52473 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25474 bool should_include_version,
475 bool fin,
476 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52477 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25478 size_t* spdy_headers_frame_length,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41479 quic::QuicRstStreamErrorCode error_code) {
Ryan Hamilton0239aac2018-05-19 00:03:13480 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25481 ConvertRequestPriorityToQuicPriority(request_priority);
482 return client_maker_.MakeRequestHeadersAndRstPacket(
483 packet_number, stream_id, should_include_version, fin, priority,
484 std::move(request_headers_), parent_stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41485 spdy_headers_frame_length, error_code);
Yixin Wange7ecc472018-03-06 19:00:25486 }
487
Ryan Hamilton8d9ee76e2018-05-29 23:52:52488 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23489 uint64_t packet_number,
rtennetif4bdb542015-01-21 14:33:05490 bool fin,
sclittlec4dc1a32015-09-24 00:15:45491 RequestPriority request_priority,
492 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56493 return InnerConstructRequestHeadersPacket(
494 packet_number, stream_id_, kIncludeVersion, fin, request_priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02495 spdy_headers_frame_length);
ckrasic3865ee0f2016-02-29 22:04:56496 }
497
Ryan Hamilton8d9ee76e2018-05-29 23:52:52498 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructResponseHeadersPacket(
Fan Yangac867502019-01-28 21:10:23499 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52500 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56501 bool fin,
502 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58503 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26504 packet_number, stream_id, !kIncludeVersion, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02505 std::move(response_headers_), spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20506 }
507
Ryan Hamilton8d9ee76e2018-05-29 23:52:52508 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseHeadersPacket(
Fan Yangac867502019-01-28 21:10:23509 uint64_t packet_number,
sclittlec4dc1a32015-09-24 00:15:45510 bool fin,
511 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56512 return InnerConstructResponseHeadersPacket(packet_number, stream_id_, fin,
513 spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20514 }
515
Ryan Hamilton8d9ee76e2018-05-29 23:52:52516 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseTrailersPacket(
Fan Yangac867502019-01-28 21:10:23517 uint64_t packet_number,
xunjieli34291fe12016-03-02 13:58:38518 bool fin,
Ryan Hamilton0239aac2018-05-19 00:03:13519 spdy::SpdyHeaderBlock trailers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02520 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58521 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26522 packet_number, stream_id_, !kIncludeVersion, fin, std::move(trailers),
Ryan Hamilton0d65a8c2019-06-07 00:46:02523 spdy_headers_frame_length);
xunjieli34291fe12016-03-02 13:58:38524 }
525
Ryan Hamilton8d9ee76e2018-05-29 23:52:52526 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23527 uint64_t packet_number) {
alyssara72f5352016-10-20 12:45:16528 return client_maker_.MakeRstPacket(packet_number, true, stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52529 quic::QUIC_RST_ACKNOWLEDGEMENT);
[email protected]06ff5152013-08-29 01:03:05530 }
531
Ryan Hamilton8d9ee76e2018-05-29 23:52:52532 std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23533 ConstructClientRstStreamCancelledPacket(uint64_t packet_number) {
alyssar2adf3ac2016-05-03 17:12:58534 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52535 stream_id_, quic::QUIC_STREAM_CANCELLED);
rtenneti6bd660b2015-07-18 00:19:53536 }
537
Ryan Hamilton8d9ee76e2018-05-29 23:52:52538 std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23539 ConstructClientRstStreamVaryMismatchPacket(uint64_t packet_number) {
alyssar2adf3ac2016-05-03 17:12:58540 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52541 promise_id_,
542 quic::QUIC_PROMISE_VARY_MISMATCH);
ckrasic3865ee0f2016-02-29 22:04:56543 }
544
Fan Yang550c6282018-06-22 18:53:25545 std::unique_ptr<quic::QuicReceivedPacket>
546 ConstructClientRstStreamVaryMismatchAndRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23547 uint64_t packet_number,
Fan Yang550c6282018-06-22 18:53:25548 quic::QuicStreamId stream_id,
549 bool should_include_version,
550 bool fin,
551 RequestPriority request_priority,
552 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02553 size_t* spdy_headers_frame_length) {
Fan Yang550c6282018-06-22 18:53:25554 spdy::SpdyPriority priority =
555 ConvertRequestPriorityToQuicPriority(request_priority);
556 return client_maker_.MakeRstAndRequestHeadersPacket(
557 packet_number, should_include_version, promise_id_,
558 quic::QUIC_PROMISE_VARY_MISMATCH, stream_id, fin, priority,
559 std::move(request_headers_), parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02560 spdy_headers_frame_length);
Fan Yang550c6282018-06-22 18:53:25561 }
562
Ryan Hamilton8d9ee76e2018-05-29 23:52:52563 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23564 uint64_t packet_number,
565 uint64_t largest_received,
566 uint64_t smallest_received,
567 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58568 return client_maker_.MakeAckAndRstPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52569 packet_number, !kIncludeVersion, stream_id_,
570 quic::QUIC_STREAM_CANCELLED, largest_received, smallest_received,
571 least_unacked, !kIncludeCongestionFeedback);
xunjieli34291fe12016-03-02 13:58:38572 }
573
Ryan Hamilton8d9ee76e2018-05-29 23:52:52574 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamErrorPacket(
Fan Yangac867502019-01-28 21:10:23575 uint64_t packet_number,
maksim.sisov84e20c92016-06-23 08:49:34576 bool include_version) {
577 return client_maker_.MakeRstPacket(packet_number, include_version,
578 stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52579 quic::QUIC_ERROR_PROCESSING_STREAM);
maksim.sisov84e20c92016-06-23 08:49:34580 }
581
Ryan Hamilton8d9ee76e2018-05-29 23:52:52582 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23583 uint64_t packet_number) {
Renjie90e808e2019-01-24 07:24:04584 return ConstructAckAndRstStreamPacket(packet_number, 2, 1, 2);
[email protected]c5e1aca2014-01-30 04:03:04585 }
586
Ryan Hamilton8d9ee76e2018-05-29 23:52:52587 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23588 uint64_t packet_number,
589 uint64_t largest_received,
590 uint64_t smallest_received,
591 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58592 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49593 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58594 !kIncludeCongestionFeedback);
595 }
596
Ryan Hamilton8d9ee76e2018-05-29 23:52:52597 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23598 uint64_t packet_number,
599 uint64_t largest_received,
600 uint64_t smallest_received,
601 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58602 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49603 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58604 !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00605 }
606
Ryan Hamilton8d9ee76e2018-05-29 23:52:52607 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23608 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57609 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52610 quic::QuicStreamId id,
611 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02612 RequestPriority request_priority) {
Yixin Wangb470bc882018-02-15 18:43:57613 return client_maker_.MakePriorityPacket(
614 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02615 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wangb470bc882018-02-15 18:43:57616 }
617
Ryan Hamilton0d65a8c2019-06-07 00:46:02618 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket() {
619 return client_maker_.MakeInitialSettingsPacket(1);
fayang3bcb8b502016-12-07 21:44:37620 }
621
Renjie Tangaadb84b2019-08-31 01:00:23622 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
623 int packet_number) {
624 return client_maker_.MakeInitialSettingsPacket(packet_number);
625 }
626
Victor Vasiliev076657c2019-03-12 02:46:43627 std::string ConstructDataHeader(size_t body_len) {
Nick Harper23290b82019-05-02 00:02:56628 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41629 return "";
630 }
631 quic::HttpEncoder encoder;
632 std::unique_ptr<char[]> buffer;
633 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43634 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41635 }
636
Ryan Hamilton8d9ee76e2018-05-29 23:52:52637 void ReceivePromise(quic::QuicStreamId id) {
638 auto headers = quic::test::AsHeaderList(push_promise_);
rch08e198572017-05-09 16:56:55639 QuicChromiumClientStream::Handle* stream =
ckrasic3865ee0f2016-02-29 22:04:56640 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
ckrasic32b17dcd2016-10-31 06:15:35641 stream->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
642 headers);
ckrasic3865ee0f2016-02-29 22:04:56643 }
644
xunjieli84adaab2016-09-20 01:12:28645 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info,
xunjieli100937eb52016-09-15 20:09:37646 bool session_reused) {
647 EXPECT_EQ(session_reused, load_timing_info.socket_reused);
xunjieli84adaab2016-09-20 01:12:28648 if (session_reused) {
649 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
650 } else {
651 ExpectConnectTimingHasTimes(
652 load_timing_info.connect_timing,
653 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
654 }
655 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
xunjieli100937eb52016-09-15 20:09:37656 }
657
Fan Yang32c5a112018-12-10 20:06:33658 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56659 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
660 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36661 }
662
Fan Yang32c5a112018-12-10 20:06:33663 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56664 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
665 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36666 }
667
Ryan Hamiltona1d1f4a2019-06-26 14:43:04668 QuicFlagSaver saver_;
669
Nick Harper23290b82019-05-02 00:02:56670 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05671 const bool client_headers_include_h2_stream_dependency_;
672
xunjieli5fafe142016-03-23 23:32:54673 BoundTestNetLog net_log_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52674 quic::test::MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20675 scoped_refptr<TestTaskRunner> runner_;
danakjad1777e2016-04-16 00:56:42676 std::unique_ptr<MockWrite[]> mock_writes_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52677 quic::MockClock clock_;
[email protected]f702d572012-12-04 15:56:20678 TestQuicConnection* connection_;
danakjad1777e2016-04-16 00:56:42679 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
rch16c74d1d2016-04-22 06:14:07680 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52681 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
rch97827ee2017-05-24 23:49:12682 std::unique_ptr<UploadDataStream> upload_data_stream_;
danakjad1777e2016-04-16 00:56:42683 std::unique_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15684 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42685 std::unique_ptr<QuicChromiumClientSession> session_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52686 quic::QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20687 TestCompletionCallback callback_;
688 HttpRequestInfo request_;
689 HttpRequestHeaders headers_;
690 HttpResponseInfo response_;
691 scoped_refptr<IOBufferWithSize> read_buffer_;
Ryan Hamilton0239aac2018-05-19 00:03:13692 spdy::SpdyHeaderBlock request_headers_;
693 spdy::SpdyHeaderBlock response_headers_;
bnc614a92d32016-04-04 13:56:07694 string request_data_;
695 string response_data_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52696 quic::QuicClientPushPromiseIndex push_promise_index_;
[email protected]f702d572012-12-04 15:56:20697
ckrasic3865ee0f2016-02-29 22:04:56698 // For server push testing
danakjad1777e2016-04-16 00:56:42699 std::unique_ptr<QuicHttpStream> promised_stream_;
Ryan Hamilton0239aac2018-05-19 00:03:13700 spdy::SpdyHeaderBlock push_promise_;
701 spdy::SpdyHeaderBlock promised_response_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52702 const quic::QuicStreamId promise_id_;
ckrasic3865ee0f2016-02-29 22:04:56703 string promise_url_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52704 const quic::QuicStreamId stream_id_;
ckrasic3865ee0f2016-02-29 22:04:56705
Ryan Hamilton8d9ee76e2018-05-29 23:52:52706 const quic::QuicConnectionId connection_id_;
alyssar2adf3ac2016-05-03 17:12:58707 QuicTestPacketMaker client_maker_;
708 QuicTestPacketMaker server_maker_;
[email protected]f702d572012-12-04 15:56:20709 IPEndPoint self_addr_;
710 IPEndPoint peer_addr_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52711 quic::test::MockRandom random_generator_;
rch03b7a202016-02-05 00:54:20712 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05713 MockCryptoClientStreamFactory crypto_client_stream_factory_;
danakjad1777e2016-04-16 00:56:42714 std::unique_ptr<StaticSocketDataProvider> socket_data_;
Ryan Hamilton0d65a8c2019-06-07 00:46:02715 QuicPacketPrinter printer_;
[email protected]f702d572012-12-04 15:56:20716 std::vector<PacketToWrite> writes_;
717};
718
Victor Costane635086f2019-01-27 05:20:30719INSTANTIATE_TEST_SUITE_P(
Bence Békyce380cb2018-04-26 23:39:55720 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05721 QuicHttpStreamTest,
Ryan Hamilton93424eb82019-08-23 04:28:40722 ::testing::Combine(::testing::ValuesIn(quic::AllSupportedVersions()),
Nick Harper23290b82019-05-02 00:02:56723 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20724
725TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44726 Initialize();
rtennetibe635732014-10-02 22:51:42727 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20728}
729
mmenkebd84c392015-09-02 14:12:34730TEST_P(QuicHttpStreamTest, CanReuseConnection) {
[email protected]ed3fc15d2013-03-08 18:37:44731 Initialize();
mmenkebd84c392015-09-02 14:12:34732 EXPECT_FALSE(stream_->CanReuseConnection());
[email protected]f702d572012-12-04 15:56:20733}
734
jri231c2972016-03-08 19:50:11735TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
Zhongyi Shibb28b1f2018-07-18 02:41:26736 request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri231c2972016-03-08 19:50:11737 Initialize();
xunjieli5fafe142016-03-23 23:32:54738 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27739 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54740 net_log_.bound(), callback_.callback()));
rch08e198572017-05-09 16:56:55741 QuicChromiumClientStream::Handle* client_stream =
jri231c2972016-03-08 19:50:11742 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
Zhongyi Shibb28b1f2018-07-18 02:41:26743 EXPECT_FALSE(client_stream->can_migrate_to_cellular_network());
jri231c2972016-03-08 19:50:11744}
745
[email protected]1e960032013-12-20 19:00:20746TEST_P(QuicHttpStreamTest, GetRequest) {
747 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45748 size_t spdy_request_header_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:23749 int packet_number = 1;
750 if (VersionUsesQpack(version_.transport_version))
751 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:37752 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:23753 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
754 kIncludeVersion, kFin, DEFAULT_PRIORITY,
755 &spdy_request_header_frame_length));
fayang3bcb8b502016-12-07 21:44:37756
[email protected]f702d572012-12-04 15:56:20757 Initialize();
758
759 request_.method = "GET";
rchcd379012017-04-12 21:53:32760 request_.url = GURL("https://www.example.org/");
[email protected]f702d572012-12-04 15:56:20761
xunjieli100937eb52016-09-15 20:09:37762 // Make sure getting load timing from the stream early does not crash.
763 LoadTimingInfo load_timing_info;
764 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
765
xunjieli5fafe142016-03-23 23:32:54766 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27767 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54768 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02769 EXPECT_EQ(OK,
770 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20771
772 // Ack the request.
Renjie90e808e2019-01-24 07:24:04773 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]f702d572012-12-04 15:56:20774
robpercival214763f2016-07-01 23:27:01775 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
776 IsError(ERR_IO_PENDING));
[email protected]f702d572012-12-04 15:56:20777
bnc614a92d32016-04-04 13:56:07778 SetResponse("404 Not Found", string());
sclittlec4dc1a32015-09-24 00:15:45779 size_t spdy_response_header_frame_length;
780 ProcessPacket(ConstructResponseHeadersPacket(
781 2, kFin, &spdy_response_header_frame_length));
[email protected]f702d572012-12-04 15:56:20782
783 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01784 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]cadac622013-06-11 16:46:36785 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20786 EXPECT_EQ(404, response_.headers->response_code());
787 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53788 EXPECT_FALSE(response_.response_time.is_null());
789 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20790
791 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02792 EXPECT_EQ(0,
793 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
794 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20795 EXPECT_TRUE(stream_->IsResponseBodyComplete());
796 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10797
xunjieli100937eb52016-09-15 20:09:37798 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28799 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37800
sclittle1edeeb22015-09-02 20:46:10801 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45802 // headers and payload.
803 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
804 stream_->GetTotalSentBytes());
805 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
806 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20807}
808
xunjieli100937eb52016-09-15 20:09:37809TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
810 SetRequest("GET", "/", DEFAULT_PRIORITY);
811 size_t spdy_request_header_frame_length;
812
Renjie Tangaadb84b2019-08-31 01:00:23813 int packet_number = 1;
814 if (VersionUsesQpack(version_.transport_version))
815 AddWrite(ConstructInitialSettingsPacket(packet_number++));
xunjieli100937eb52016-09-15 20:09:37816 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:23817 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
818 kIncludeVersion, kFin, DEFAULT_PRIORITY,
819 &spdy_request_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37820
821 // SetRequest() again for second request as |request_headers_| was moved.
822 SetRequest("GET", "/", DEFAULT_PRIORITY);
823 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:23824 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
825 kIncludeVersion, kFin, DEFAULT_PRIORITY,
826 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:02827 &spdy_request_header_frame_length));
Renjie Tangaadb84b2019-08-31 01:00:23828 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1,
829 2)); // Ack the responses.
xunjieli100937eb52016-09-15 20:09:37830
831 Initialize();
832
833 request_.method = "GET";
rchcd379012017-04-12 21:53:32834 request_.url = GURL("https://www.example.org/");
xunjieli100937eb52016-09-15 20:09:37835 // Start first request.
836 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27837 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37838 net_log_.bound(), callback_.callback()));
839 EXPECT_EQ(OK,
840 stream_->SendRequest(headers_, &response_, callback_.callback()));
841
842 // Start a second request.
Ryan Hamilton6c2a2a82017-12-15 02:06:28843 QuicHttpStream stream2(
844 session_->CreateHandle(HostPortPair("www.example.org", 443)));
xunjieli100937eb52016-09-15 20:09:37845 TestCompletionCallback callback2;
846 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27847 stream2.InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37848 net_log_.bound(), callback2.callback()));
849 EXPECT_EQ(OK,
850 stream2.SendRequest(headers_, &response_, callback2.callback()));
851
852 // Ack both requests.
Renjie90e808e2019-01-24 07:24:04853 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
xunjieli100937eb52016-09-15 20:09:37854
855 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
856 IsError(ERR_IO_PENDING));
857 size_t spdy_response_header_frame_length;
858 SetResponse("200 OK", string());
859 ProcessPacket(InnerConstructResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33860 2, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
ckrasicbf2f59c2017-05-04 23:54:36861 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37862
863 // Now that the headers have been processed, the callback will return.
864 EXPECT_THAT(callback_.WaitForResult(), IsOk());
865 EXPECT_EQ(200, response_.headers->response_code());
866
867 // There is no body, so this should return immediately.
868 EXPECT_EQ(0,
869 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
870 callback_.callback()));
871 EXPECT_TRUE(stream_->IsResponseBodyComplete());
872
873 LoadTimingInfo load_timing_info;
874 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28875 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37876
877 // SetResponse() again for second request as |response_headers_| was moved.
878 SetResponse("200 OK", string());
879 EXPECT_THAT(stream2.ReadResponseHeaders(callback2.callback()),
880 IsError(ERR_IO_PENDING));
881
882 ProcessPacket(InnerConstructResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33883 3, GetNthClientInitiatedBidirectionalStreamId(1), kFin,
ckrasicbf2f59c2017-05-04 23:54:36884 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37885
886 EXPECT_THAT(callback2.WaitForResult(), IsOk());
887
888 // There is no body, so this should return immediately.
889 EXPECT_EQ(0,
890 stream2.ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
891 callback2.callback()));
892 EXPECT_TRUE(stream2.IsResponseBodyComplete());
893
894 LoadTimingInfo load_timing_info2;
895 EXPECT_TRUE(stream2.GetLoadTimingInfo(&load_timing_info2));
xunjieli84adaab2016-09-20 01:12:28896 ExpectLoadTimingValid(load_timing_info2, /*session_reused=*/true);
xunjieli100937eb52016-09-15 20:09:37897}
898
xunjieli34291fe12016-03-02 13:58:38899// QuicHttpStream does not currently support trailers. It should ignore
900// trailers upon receiving them.
901TEST_P(QuicHttpStreamTest, GetRequestWithTrailers) {
902 SetRequest("GET", "/", DEFAULT_PRIORITY);
903 size_t spdy_request_header_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:23904 int packet_number = 1;
905 if (VersionUsesQpack(version_.transport_version))
906 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:37907 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:23908 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
909 kIncludeVersion, kFin, DEFAULT_PRIORITY,
910 &spdy_request_header_frame_length));
911 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1,
912 2)); // Ack the data packet.
xunjieli34291fe12016-03-02 13:58:38913
914 Initialize();
915
916 request_.method = "GET";
rchcd379012017-04-12 21:53:32917 request_.url = GURL("https://www.example.org/");
xunjieli34291fe12016-03-02 13:58:38918
xunjieli5fafe142016-03-23 23:32:54919 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27920 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54921 net_log_.bound(), callback_.callback()));
922
xunjieli34291fe12016-03-02 13:58:38923 EXPECT_EQ(OK,
924 stream_->SendRequest(headers_, &response_, callback_.callback()));
xunjieli34291fe12016-03-02 13:58:38925 // Ack the request.
Renjie90e808e2019-01-24 07:24:04926 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
xunjieli34291fe12016-03-02 13:58:38927
robpercival214763f2016-07-01 23:27:01928 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
929 IsError(ERR_IO_PENDING));
xunjieli34291fe12016-03-02 13:58:38930
bnc614a92d32016-04-04 13:56:07931 SetResponse("200 OK", string());
xunjieli34291fe12016-03-02 13:58:38932
933 // Send the response headers.
934 size_t spdy_response_header_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:02935 ProcessPacket(ConstructResponseHeadersPacket(
936 2, !kFin, &spdy_response_header_frame_length));
xunjieli34291fe12016-03-02 13:58:38937 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01938 EXPECT_THAT(callback_.WaitForResult(), IsOk());
xunjieli34291fe12016-03-02 13:58:38939 ASSERT_TRUE(response_.headers.get());
940 EXPECT_EQ(200, response_.headers->response_code());
941 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
942 EXPECT_FALSE(response_.response_time.is_null());
943 EXPECT_FALSE(response_.request_time.is_null());
944
945 // Send the response body.
946 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:43947 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:17948 ProcessPacket(
949 ConstructServerDataPacket(3, false, !kFin, header + kResponseBody));
Ryan Hamilton0239aac2018-05-19 00:03:13950 spdy::SpdyHeaderBlock trailers;
xunjieli34291fe12016-03-02 13:58:38951 size_t spdy_trailers_frame_length;
952 trailers["foo"] = "bar";
Ryan Hamiltona1d1f4a2019-06-26 14:43:04953 if (!quic::VersionUsesQpack(version_.transport_version)) {
954 trailers[quic::kFinalOffsetHeaderKey] =
955 base::NumberToString(strlen(kResponseBody) + header.length());
956 }
Ryan Hamilton0d65a8c2019-06-07 00:46:02957 ProcessPacket(ConstructResponseTrailersPacket(4, kFin, std::move(trailers),
958 &spdy_trailers_frame_length));
xunjieli34291fe12016-03-02 13:58:38959
960 // Make sure trailers are processed.
fdoray92e35a72016-06-10 15:54:55961 base::RunLoop().RunUntilIdle();
xunjieli34291fe12016-03-02 13:58:38962
963 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
964 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
965 callback_.callback()));
966 EXPECT_TRUE(stream_->IsResponseBodyComplete());
967
968 EXPECT_EQ(OK,
969 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
970 callback_.callback()));
971
972 EXPECT_TRUE(stream_->IsResponseBodyComplete());
973 EXPECT_TRUE(AtEof());
974
975 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
976 // headers and payload.
977 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
978 stream_->GetTotalSentBytes());
Renjief49758b2019-01-11 23:32:41979 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length +
980 strlen(kResponseBody) + header.length() +
981 +spdy_trailers_frame_length),
982 stream_->GetTotalReceivedBytes());
xunjieli5fafe142016-03-23 23:32:54983 // Check that NetLog was filled as expected.
Eric Roman79cc7552019-07-19 02:17:54984 auto entries = net_log_.GetEntries();
xunjieli5fafe142016-03-23 23:32:54985 size_t pos = ExpectLogContainsSomewhere(
986 entries, /*min_offset=*/0,
mikecirone8b85c432016-09-08 19:11:00987 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
988 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54989 pos = ExpectLogContainsSomewhere(
990 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00991 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
992 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54993 ExpectLogContainsSomewhere(
994 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00995 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
996 NetLogEventPhase::NONE);
xunjieli34291fe12016-03-02 13:58:38997}
998
[email protected]3e7dca62013-09-10 16:14:23999// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:201000TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
1001 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451002 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231003 int packet_number = 1;
1004 if (VersionUsesQpack(version_.transport_version))
1005 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371006 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231007 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1008 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1009 &spdy_request_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:231010 Initialize();
1011
1012 request_.method = "GET";
rchcd379012017-04-12 21:53:321013 request_.url = GURL("https://www.example.org/");
[email protected]3e7dca62013-09-10 16:14:231014
xunjieli5fafe142016-03-23 23:32:541015 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271016 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541017 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021018 EXPECT_EQ(OK,
1019 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:231020
1021 // Ack the request.
Renjie90e808e2019-01-24 07:24:041022 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]3e7dca62013-09-10 16:14:231023
robpercival214763f2016-07-01 23:27:011024 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1025 IsError(ERR_IO_PENDING));
[email protected]3e7dca62013-09-10 16:14:231026
bnc086b39e12016-06-24 13:05:261027 response_headers_[":status"] = "200 OK";
1028 response_headers_[":version"] = "HTTP/1.1";
1029 response_headers_["content-type"] = "text/plain";
1030 response_headers_["big6"] = string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:231031
sclittlec4dc1a32015-09-24 00:15:451032 size_t spdy_response_headers_frame_length;
1033 ProcessPacket(ConstructResponseHeadersPacket(
1034 2, kFin, &spdy_response_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:231035
1036 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:011037 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]3e7dca62013-09-10 16:14:231038 ASSERT_TRUE(response_.headers.get());
1039 EXPECT_EQ(200, response_.headers->response_code());
1040 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1041
1042 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:021043 EXPECT_EQ(0,
1044 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1045 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:231046 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1047 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101048
1049 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451050 // headers and payload.
1051 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1052 stream_->GetTotalSentBytes());
1053 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
1054 stream_->GetTotalReceivedBytes());
[email protected]3e7dca62013-09-10 16:14:231055}
1056
rchf9f103cbc2014-08-30 05:28:041057// Regression test for http://crbug.com/409101
1058TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
1059 SetRequest("GET", "/", DEFAULT_PRIORITY);
1060 Initialize();
1061
1062 request_.method = "GET";
rchcd379012017-04-12 21:53:321063 request_.url = GURL("https://www.example.org/");
rchf9f103cbc2014-08-30 05:28:041064
xunjieli5fafe142016-03-23 23:32:541065 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271066 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541067 net_log_.bound(), callback_.callback()));
rchf9f103cbc2014-08-30 05:28:041068
jri78ec06a2016-03-31 18:19:401069 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521070 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchf9f103cbc2014-08-30 05:28:041071
1072 EXPECT_EQ(ERR_CONNECTION_CLOSED,
rjshaded5ced072015-12-18 19:26:021073 stream_->SendRequest(headers_, &response_, callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101074
1075 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1076 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rchf9f103cbc2014-08-30 05:28:041077}
1078
rch03b7a202016-02-05 00:54:201079// Regression test for http://crbug.com/584441
1080TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
1081 SetRequest("GET", "/", DEFAULT_PRIORITY);
1082 Initialize();
1083
1084 request_.method = "GET";
rchcd379012017-04-12 21:53:321085 request_.url = GURL("https://www.example.org/");
rch03b7a202016-02-05 00:54:201086
xunjieli5fafe142016-03-23 23:32:541087 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271088 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541089 net_log_.bound(), callback_.callback()));
rch03b7a202016-02-05 00:54:201090
1091 SSLInfo ssl_info;
rch11565e02016-02-09 20:13:471092 EXPECT_FALSE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201093 stream_->GetSSLInfo(&ssl_info);
rch11565e02016-02-09 20:13:471094 EXPECT_TRUE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201095
jri78ec06a2016-03-31 18:19:401096 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521097 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch03b7a202016-02-05 00:54:201098
rch11565e02016-02-09 20:13:471099 SSLInfo ssl_info2;
1100 stream_->GetSSLInfo(&ssl_info2);
1101 EXPECT_TRUE(ssl_info2.is_valid());
rch03b7a202016-02-05 00:54:201102}
1103
rchcd379012017-04-12 21:53:321104TEST_P(QuicHttpStreamTest, GetAlternativeService) {
1105 SetRequest("GET", "/", DEFAULT_PRIORITY);
1106 Initialize();
1107
1108 request_.method = "GET";
1109 request_.url = GURL("https://www.example.org/");
1110
1111 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271112 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
rchcd379012017-04-12 21:53:321113 net_log_.bound(), callback_.callback()));
1114
1115 AlternativeService alternative_service;
1116 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service));
1117 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1118 alternative_service);
1119
1120 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521121 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchcd379012017-04-12 21:53:321122
1123 AlternativeService alternative_service2;
1124 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service2));
1125 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1126 alternative_service2);
1127}
1128
zhongyica364fbb2015-12-12 03:39:121129TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
1130 SetRequest("GET", "/", DEFAULT_PRIORITY);
1131 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231132 int packet_number = 1;
1133 if (VersionUsesQpack(version_.transport_version))
1134 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371135 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231136 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1137 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1138 &spdy_request_headers_frame_length));
fayang3bcb8b502016-12-07 21:44:371139 AddWrite(ConstructAckAndRstStreamPacket(3));
zhongyica364fbb2015-12-12 03:39:121140 Initialize();
1141
1142 request_.method = "GET";
rchcd379012017-04-12 21:53:321143 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121144
xunjieli5fafe142016-03-23 23:32:541145 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271146 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541147 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121148 EXPECT_EQ(OK,
1149 stream_->SendRequest(headers_, &response_, callback_.callback()));
1150
1151 // Ack the request.
Renjie90e808e2019-01-24 07:24:041152 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011153 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1154 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121155
Ryan Hamilton8d9ee76e2018-05-29 23:52:521156 quic::QuicConnectionCloseFrame frame;
Zhongyi Shica576df2019-04-12 17:43:401157 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
Renjie Tangdb47d4c2019-08-27 18:56:231158 frame.extracted_error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551159 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121160
1161 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521162 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121163 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521164 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121165}
1166
Ryan Hamiltone316e482017-08-17 02:48:531167TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
Ryan Hamiltona1d1f4a2019-06-26 14:43:041168 // TODO(nharper): Figure out why this test does not send packets
1169 // when TLS is used.
1170 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
1171 Initialize();
1172
1173 return;
1174 }
1175
rch617e0652017-04-26 17:57:511176 // By default the test setup defaults handshake to be confirmed. Manually set
1177 // it to be not confirmed.
rch617e0652017-04-26 17:57:511178 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271179 MockCryptoClientStream::ZERO_RTT);
rch617e0652017-04-26 17:57:511180
zhongyica364fbb2015-12-12 03:39:121181 SetRequest("GET", "/", DEFAULT_PRIORITY);
1182 size_t spdy_request_headers_frame_length;
Michael Warres167db3e2019-03-01 21:38:031183 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
fayang3bcb8b502016-12-07 21:44:371184 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331185 1, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:021186 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
zhongyica364fbb2015-12-12 03:39:121187 Initialize();
1188
1189 request_.method = "GET";
rchcd379012017-04-12 21:53:321190 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121191
xunjieli5fafe142016-03-23 23:32:541192 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271193 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541194 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121195 EXPECT_EQ(OK,
1196 stream_->SendRequest(headers_, &response_, callback_.callback()));
1197
1198 // Ack the request.
Renjie90e808e2019-01-24 07:24:041199 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011200 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1201 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121202
Ryan Hamilton8d9ee76e2018-05-29 23:52:521203 quic::QuicConnectionCloseFrame frame;
Zhongyi Shica576df2019-04-12 17:43:401204 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
Renjie Tangdb47d4c2019-08-27 18:56:231205 frame.extracted_error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551206 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121207
1208 NetErrorDetails details;
zhongyica364fbb2015-12-12 03:39:121209 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521210 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121211}
1212
rch11a114a2014-09-04 23:41:591213// Regression test for http://crbug.com/409871
1214TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
1215 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451216 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231217 int packet_number = 1;
1218 if (VersionUsesQpack(version_.transport_version))
1219 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371220 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231221 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1222 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1223 &spdy_request_headers_frame_length));
rch11a114a2014-09-04 23:41:591224 Initialize();
1225
1226 request_.method = "GET";
rchcd379012017-04-12 21:53:321227 request_.url = GURL("https://www.example.org/");
rch11a114a2014-09-04 23:41:591228
xunjieli5fafe142016-03-23 23:32:541229 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271230 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541231 net_log_.bound(), callback_.callback()));
rch11a114a2014-09-04 23:41:591232
rjshaded5ced072015-12-18 19:26:021233 EXPECT_EQ(OK,
1234 stream_->SendRequest(headers_, &response_, callback_.callback()));
rch11a114a2014-09-04 23:41:591235
jri78ec06a2016-03-31 18:19:401236 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521237 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch11a114a2014-09-04 23:41:591238
1239 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101240
1241 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451242 // headers and payload.
1243 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1244 stream_->GetTotalSentBytes());
sclittle1edeeb22015-09-02 20:46:101245 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rch11a114a2014-09-04 23:41:591246}
1247
[email protected]1e960032013-12-20 19:00:201248TEST_P(QuicHttpStreamTest, SendPostRequest) {
1249 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451250 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231251 int packet_number = 1;
1252 if (VersionUsesQpack(version_.transport_version))
1253 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Yixin Wange7ecc472018-03-06 19:00:251254
Victor Vasiliev076657c2019-03-12 02:46:431255 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harper23290b82019-05-02 00:02:561256 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411257 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231258 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1259 kIncludeVersion, kFin, DEFAULT_PRIORITY, 0,
1260 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411261 } else {
1262 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231263 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1264 kIncludeVersion, kFin, DEFAULT_PRIORITY, 0,
1265 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411266 }
Yixin Wange7ecc472018-03-06 19:00:251267
Renjie Tangaadb84b2019-08-31 01:00:231268 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1, 2));
[email protected]f702d572012-12-04 15:56:201269
1270 Initialize();
1271
danakjad1777e2016-04-16 00:56:421272 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191273 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
ricea2deef682016-09-09 08:04:071274 kUploadData, strlen(kUploadData)));
rch97827ee2017-05-24 23:49:121275 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191276 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
[email protected]f702d572012-12-04 15:56:201277 request_.method = "POST";
rchcd379012017-04-12 21:53:321278 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121279 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581280 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
tfarina42834112016-09-22 13:38:201281 NetLogWithSource()),
1282 IsOk());
[email protected]f702d572012-12-04 15:56:201283
xunjieli5fafe142016-03-23 23:32:541284 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271285 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541286 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021287 EXPECT_EQ(OK,
1288 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:201289
1290 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041291 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]f702d572012-12-04 15:56:201292
1293 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071294 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451295 size_t spdy_response_headers_frame_length;
1296 ProcessPacket(ConstructResponseHeadersPacket(
1297 2, !kFin, &spdy_response_headers_frame_length));
[email protected]f702d572012-12-04 15:56:201298
rchfb47f712017-05-21 03:24:001299 // The headers have already arrived.
1300 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361301 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:201302 EXPECT_EQ(200, response_.headers->response_code());
1303 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1304
1305 // Send the response body.
1306 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431307 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:411308 ProcessPacket(
Ryan Hamilton7505eb92019-06-08 00:22:171309 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
[email protected]f702d572012-12-04 15:56:201310 // Since the body has already arrived, this should return immediately.
1311 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1312 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1313 callback_.callback()));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291314 EXPECT_EQ(0,
1315 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1316 callback_.callback()));
1317
1318 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1319 EXPECT_TRUE(AtEof());
1320
1321 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1322 // headers and payload.
1323 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411324 strlen(kUploadData) + header.length()),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291325 stream_->GetTotalSentBytes());
1326 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411327 strlen(kResponseBody) + header2.length()),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291328 stream_->GetTotalReceivedBytes());
1329}
1330
1331TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
1332 SetRequest("POST", "/", DEFAULT_PRIORITY);
1333 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231334 int packet_number = 1;
1335 if (VersionUsesQpack(version_.transport_version))
1336 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431337 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harper23290b82019-05-02 00:02:561338 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411339 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231340 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1341 kIncludeVersion, kFin, DEFAULT_PRIORITY, 0,
1342 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411343 } else {
1344 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231345 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1346 kIncludeVersion, kFin, DEFAULT_PRIORITY, 0,
1347 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411348 }
1349
Renjie Tangaadb84b2019-08-31 01:00:231350 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1, 2));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291351
1352 Initialize();
1353
1354 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191355 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
Ryan Hamilton2ef0a9c2017-07-25 03:18:291356 kUploadData, strlen(kUploadData)));
1357 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191358 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
Ryan Hamilton2ef0a9c2017-07-25 03:18:291359 request_.method = "POST";
1360 request_.url = GURL("https://www.example.org/");
1361 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581362 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291363 NetLogWithSource()),
1364 IsOk());
1365
1366 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271367 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
Ryan Hamilton2ef0a9c2017-07-25 03:18:291368 net_log_.bound(), callback_.callback()));
1369 EXPECT_EQ(OK,
1370 stream_->SendRequest(headers_, &response_, callback_.callback()));
1371
1372 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041373 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291374
1375 // Send the response headers (but not the body).
1376 SetResponse("200 OK", string());
1377 size_t spdy_response_headers_frame_length;
1378 ProcessPacket(ConstructResponseHeadersPacket(
1379 2, !kFin, &spdy_response_headers_frame_length));
1380
1381 // The headers have already arrived.
1382 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1383 ASSERT_TRUE(response_.headers.get());
1384 EXPECT_EQ(200, response_.headers->response_code());
1385 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1386
1387 // Send the response body.
1388 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431389 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:411390 ProcessPacket(
Ryan Hamilton7505eb92019-06-08 00:22:171391 ConstructServerDataPacket(3, false, !kFin, header2 + kResponseBody));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291392 // Since the body has already arrived, this should return immediately.
1393 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1394 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1395 callback_.callback()));
Ryan Hamilton7505eb92019-06-08 00:22:171396 ProcessPacket(ConstructServerDataPacket(4, false, kFin, ""));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291397 EXPECT_EQ(0,
1398 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1399 callback_.callback()));
[email protected]f702d572012-12-04 15:56:201400
1401 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1402 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101403
1404 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451405 // headers and payload.
1406 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411407 strlen(kUploadData) + header.length()),
sclittle1edeeb22015-09-02 20:46:101408 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451409 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411410 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101411 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:201412}
1413
[email protected]1e960032013-12-20 19:00:201414TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
1415 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:471416 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451417 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231418 int packet_number = 1;
1419 if (VersionUsesQpack(version_.transport_version))
1420 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431421 std::string header = ConstructDataHeader(chunk_size);
Nick Harper23290b82019-05-02 00:02:561422 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411423 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231424 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1425 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1426 &spdy_request_headers_frame_length, {header, kUploadData}));
1427 AddWrite(ConstructClientMultipleDataFramesPacket(
1428 packet_number++, kIncludeVersion, kFin, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411429 } else {
1430 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231431 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1432 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1433 &spdy_request_headers_frame_length, {kUploadData}));
1434 AddWrite(ConstructClientDataPacket(packet_number++, kIncludeVersion, kFin,
1435 kUploadData));
Renjief49758b2019-01-11 23:32:411436 }
1437
Renjie Tangaadb84b2019-08-31 01:00:231438 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1, 2));
[email protected]c9e49a02013-02-26 05:56:471439 Initialize();
1440
Jeremy Roman0579ed62017-08-29 15:56:191441 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121442 auto* chunked_upload_stream =
1443 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1444 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:471445
1446 request_.method = "POST";
rchcd379012017-04-12 21:53:321447 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121448 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071449 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201450 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]c9e49a02013-02-26 05:56:471451
xunjieli5fafe142016-03-23 23:32:541452 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271453 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541454 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021455 ASSERT_EQ(ERR_IO_PENDING,
1456 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:471457
rch97827ee2017-05-24 23:49:121458 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
robpercival214763f2016-07-01 23:27:011459 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]c9e49a02013-02-26 05:56:471460
1461 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041462 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]c9e49a02013-02-26 05:56:471463
1464 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071465 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451466 size_t spdy_response_headers_frame_length;
1467 ProcessPacket(ConstructResponseHeadersPacket(
1468 2, !kFin, &spdy_response_headers_frame_length));
[email protected]c9e49a02013-02-26 05:56:471469
rchfb47f712017-05-21 03:24:001470 // The headers have already arrived.
1471 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361472 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:471473 EXPECT_EQ(200, response_.headers->response_code());
1474 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1475
1476 // Send the response body.
1477 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431478 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171479 ProcessPacket(
1480 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
[email protected]c9e49a02013-02-26 05:56:471481
1482 // Since the body has already arrived, this should return immediately.
1483 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1484 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1485 callback_.callback()));
1486
1487 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1488 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101489
1490 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451491 // headers and payload.
1492 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411493 strlen(kUploadData) * 2 + header.length() * 2),
sclittle1edeeb22015-09-02 20:46:101494 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451495 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411496 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101497 stream_->GetTotalReceivedBytes());
[email protected]c9e49a02013-02-26 05:56:471498}
1499
[email protected]16ba7742014-08-22 00:57:251500TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
1501 SetRequest("POST", "/", DEFAULT_PRIORITY);
1502 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451503 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231504 int packet_number = 1;
1505 if (VersionUsesQpack(version_.transport_version))
1506 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431507 std::string header = ConstructDataHeader(chunk_size);
Renjief49758b2019-01-11 23:32:411508
Nick Harper23290b82019-05-02 00:02:561509 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411510 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231511 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1512 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1513 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411514 } else {
1515 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231516 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1517 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1518 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411519 }
Renjie Tangaadb84b2019-08-31 01:00:231520 AddWrite(
1521 ConstructClientDataPacket(packet_number++, kIncludeVersion, kFin, ""));
1522 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1, 2));
[email protected]16ba7742014-08-22 00:57:251523 Initialize();
1524
Jeremy Roman0579ed62017-08-29 15:56:191525 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121526 auto* chunked_upload_stream =
1527 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1528 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:251529
1530 request_.method = "POST";
rchcd379012017-04-12 21:53:321531 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121532 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071533 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201534 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251535
xunjieli5fafe142016-03-23 23:32:541536 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271537 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541538 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021539 ASSERT_EQ(ERR_IO_PENDING,
1540 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251541
rch97827ee2017-05-24 23:49:121542 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011543 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251544
Renjie90e808e2019-01-24 07:24:041545 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]16ba7742014-08-22 00:57:251546
1547 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071548 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451549 size_t spdy_response_headers_frame_length;
1550 ProcessPacket(ConstructResponseHeadersPacket(
1551 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251552
rchfb47f712017-05-21 03:24:001553 // The headers have already arrived.
1554 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251555 ASSERT_TRUE(response_.headers.get());
1556 EXPECT_EQ(200, response_.headers->response_code());
1557 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1558
1559 // Send the response body.
1560 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431561 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171562 ProcessPacket(
1563 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
[email protected]16ba7742014-08-22 00:57:251564
rchb27683c2015-07-29 23:53:501565 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251566 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1567 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1568 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251569 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1570 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101571
1572 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451573 // headers and payload.
1574 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411575 strlen(kUploadData) + header.length()),
sclittle1edeeb22015-09-02 20:46:101576 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451577 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411578 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101579 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251580}
1581
1582TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
1583 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451584 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231585 int packet_number = 1;
1586 if (VersionUsesQpack(version_.transport_version))
1587 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371588 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231589 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1590 kIncludeVersion, !kFin, DEFAULT_PRIORITY,
1591 &spdy_request_headers_frame_length));
1592 AddWrite(
1593 ConstructClientDataPacket(packet_number++, kIncludeVersion, kFin, ""));
1594 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1, 2));
[email protected]16ba7742014-08-22 00:57:251595 Initialize();
1596
Jeremy Roman0579ed62017-08-29 15:56:191597 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121598 auto* chunked_upload_stream =
1599 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
[email protected]16ba7742014-08-22 00:57:251600
1601 request_.method = "POST";
rchcd379012017-04-12 21:53:321602 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121603 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071604 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201605 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251606
xunjieli5fafe142016-03-23 23:32:541607 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271608 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541609 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021610 ASSERT_EQ(ERR_IO_PENDING,
1611 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251612
rch97827ee2017-05-24 23:49:121613 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011614 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251615
Renjie90e808e2019-01-24 07:24:041616 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]16ba7742014-08-22 00:57:251617
1618 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071619 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451620 size_t spdy_response_headers_frame_length;
1621 ProcessPacket(ConstructResponseHeadersPacket(
1622 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251623
rchfb47f712017-05-21 03:24:001624 // The headers have already arrived.
1625 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251626 ASSERT_TRUE(response_.headers.get());
1627 EXPECT_EQ(200, response_.headers->response_code());
1628 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1629
1630 // Send the response body.
1631 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431632 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171633 ProcessPacket(
1634 ConstructServerDataPacket(3, false, kFin, header + kResponseBody));
[email protected]16ba7742014-08-22 00:57:251635
rchb27683c2015-07-29 23:53:501636 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251637 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1638 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1639 callback_.callback()));
1640
1641 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1642 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101643
1644 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451645 // headers and payload.
1646 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1647 stream_->GetTotalSentBytes());
1648 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411649 strlen(kResponseBody) + header.length()),
sclittle1edeeb22015-09-02 20:46:101650 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251651}
1652
[email protected]1e960032013-12-20 19:00:201653TEST_P(QuicHttpStreamTest, DestroyedEarly) {
1654 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451655 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231656 int packet_number = 1;
1657 if (VersionUsesQpack(version_.transport_version))
1658 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371659 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231660 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1661 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1662 &spdy_request_headers_frame_length));
1663 AddWrite(ConstructAckAndRstStreamPacket(packet_number++));
[email protected]63534512012-12-23 18:49:001664 Initialize();
1665
1666 request_.method = "GET";
rchcd379012017-04-12 21:53:321667 request_.url = GURL("https://www.example.org/");
[email protected]63534512012-12-23 18:49:001668
xunjieli5fafe142016-03-23 23:32:541669 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271670 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541671 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021672 EXPECT_EQ(OK,
1673 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]63534512012-12-23 18:49:001674
1675 // Ack the request.
Renjie90e808e2019-01-24 07:24:041676 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
rchfb47f712017-05-21 03:24:001677 EXPECT_THAT(stream_->ReadResponseHeaders(
Yannic Bonenberger3c96beb2019-09-03 20:41:371678 base::BindOnce(&QuicHttpStreamTest::CloseStream,
1679 base::Unretained(this), stream_.get())),
robpercival214763f2016-07-01 23:27:011680 IsError(ERR_IO_PENDING));
[email protected]63534512012-12-23 18:49:001681
1682 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201683 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:001684 // In the course of processing this packet, the QuicHttpStream close itself.
rchfb47f712017-05-21 03:24:001685 size_t response_size = 0;
rch1bcfddf22017-06-03 00:26:291686 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin, &response_size));
[email protected]63534512012-12-23 18:49:001687
fdoray92e35a72016-06-10 15:54:551688 base::RunLoop().RunUntilIdle();
rchb27683c2015-07-29 23:53:501689
[email protected]63534512012-12-23 18:49:001690 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101691
1692 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451693 // headers and payload.
1694 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1695 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001696 // The stream was closed after receiving the headers.
1697 EXPECT_EQ(static_cast<int64_t>(response_size),
1698 stream_->GetTotalReceivedBytes());
[email protected]63534512012-12-23 18:49:001699}
1700
[email protected]1e960032013-12-20 19:00:201701TEST_P(QuicHttpStreamTest, Priority) {
1702 SetRequest("GET", "/", MEDIUM);
sclittlec4dc1a32015-09-24 00:15:451703 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231704 int packet_number = 1;
1705 if (VersionUsesQpack(version_.transport_version))
1706 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371707 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231708 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1709 kIncludeVersion, kFin, MEDIUM, &spdy_request_headers_frame_length));
[email protected]24e5bc52013-09-18 15:36:581710 Initialize();
1711
1712 request_.method = "GET";
rchcd379012017-04-12 21:53:321713 request_.url = GURL("https://www.example.org/");
[email protected]24e5bc52013-09-18 15:36:581714
Steven Valdezb4ff0412018-01-18 22:39:271715 EXPECT_EQ(OK,
1716 stream_->InitializeStream(&request_, true, MEDIUM, net_log_.bound(),
1717 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581718
rjshaded5ced072015-12-18 19:26:021719 EXPECT_EQ(OK,
1720 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581721
[email protected]24e5bc52013-09-18 15:36:581722 // Ack the request.
Renjie90e808e2019-01-24 07:24:041723 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011724 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1725 IsError(ERR_IO_PENDING));
[email protected]24e5bc52013-09-18 15:36:581726
1727 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201728 SetResponse("404 OK", "hello world!");
rchfb47f712017-05-21 03:24:001729 size_t response_size = 0;
1730 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, &response_size));
[email protected]24e5bc52013-09-18 15:36:581731
rchfb47f712017-05-21 03:24:001732 EXPECT_EQ(OK, callback_.WaitForResult());
rchb27683c2015-07-29 23:53:501733
[email protected]24e5bc52013-09-18 15:36:581734 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101735
1736 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451737 // headers and payload.
1738 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1739 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001740 EXPECT_EQ(static_cast<int64_t>(response_size),
1741 stream_->GetTotalReceivedBytes());
[email protected]24e5bc52013-09-18 15:36:581742}
1743
xunjieli8dff50b2016-07-22 14:19:061744TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
1745 SetRequest("POST", "/", DEFAULT_PRIORITY);
1746 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231747 int packet_number = 1;
1748 if (VersionUsesQpack(version_.transport_version))
1749 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431750 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harper23290b82019-05-02 00:02:561751 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411752 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231753 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1754 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1755 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411756 } else {
1757 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231758 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1759 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1760 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411761 }
1762
xunjieli8dff50b2016-07-22 14:19:061763 // Second data write will result in a synchronous failure which will close
1764 // the session.
1765 AddWrite(SYNCHRONOUS, ERR_FAILED);
1766 Initialize();
1767
Jeremy Roman0579ed62017-08-29 15:56:191768 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121769 auto* chunked_upload_stream =
1770 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
xunjieli8dff50b2016-07-22 14:19:061771
1772 request_.method = "POST";
rchcd379012017-04-12 21:53:321773 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121774 request_.upload_data_stream = upload_data_stream_.get();
xunjieli8dff50b2016-07-22 14:19:061775 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201776 TestCompletionCallback().callback(), NetLogWithSource()));
xunjieli8dff50b2016-07-22 14:19:061777
1778 size_t chunk_size = strlen(kUploadData);
rch97827ee2017-05-24 23:49:121779 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
xunjieli8dff50b2016-07-22 14:19:061780 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271781 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli8dff50b2016-07-22 14:19:061782 net_log_.bound(), callback_.callback()));
1783 QuicHttpStream* stream = stream_.get();
1784 DeleteStreamCallback delete_stream_callback(std::move(stream_));
1785 // SendRequest() completes asynchronously after the final chunk is added.
Yixin Wange7ecc472018-03-06 19:00:251786 // Error does not surface yet since packet write is triggered by a packet
1787 // flusher that tries to bundle request body writes.
xunjieli8dff50b2016-07-22 14:19:061788 ASSERT_EQ(ERR_IO_PENDING,
1789 stream->SendRequest(headers_, &response_, callback_.callback()));
rch97827ee2017-05-24 23:49:121790 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
xunjieli8dff50b2016-07-22 14:19:061791 int rv = callback_.WaitForResult();
Yixin Wange7ecc472018-03-06 19:00:251792 EXPECT_EQ(OK, rv);
1793 // Error will be surfaced once an attempt to read the response occurs.
1794 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1795 stream->ReadResponseHeaders(callback_.callback()));
xunjieli8dff50b2016-07-22 14:19:061796}
1797
rtenneti15656ae2016-01-23 03:05:031798TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
1799 SetRequest("POST", "/", DEFAULT_PRIORITY);
Renjie Tangaadb84b2019-08-31 01:00:231800 if (VersionUsesQpack(version_.transport_version))
1801 AddWrite(ConstructInitialSettingsPacket());
rtenneti15656ae2016-01-23 03:05:031802 AddWrite(SYNCHRONOUS, ERR_FAILED);
1803 Initialize();
1804
Jeremy Roman0579ed62017-08-29 15:56:191805 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
Yixin Wange7ecc472018-03-06 19:00:251806 auto* chunked_upload_stream =
1807 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031808
1809 request_.method = "POST";
rchcd379012017-04-12 21:53:321810 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121811 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031812 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201813 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031814
xunjieli5fafe142016-03-23 23:32:541815 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271816 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541817 net_log_.bound(), callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251818 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:031819 stream_->SendRequest(headers_, &response_, callback_.callback()));
mmenkeffff3642017-06-15 17:37:241820
Yixin Wange7ecc472018-03-06 19:00:251821 // Error will be surfaced once |upload_data_stream| triggers the next write.
1822 size_t chunk_size = strlen(kUploadData);
1823 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1824 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
1825
1826 EXPECT_LE(0, stream_->GetTotalSentBytes());
1827 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1828}
1829
1830TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersCompleteReadResponse) {
1831 SetRequest("POST", "/", DEFAULT_PRIORITY);
Renjie Tangaadb84b2019-08-31 01:00:231832 if (VersionUsesQpack(version_.transport_version))
1833 AddWrite(ConstructInitialSettingsPacket());
Yixin Wange7ecc472018-03-06 19:00:251834 AddWrite(SYNCHRONOUS, ERR_FAILED);
1835 Initialize();
1836
1837 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1838 auto* chunked_upload_stream =
1839 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1840
1841 request_.method = "POST";
1842 request_.url = GURL("https://www.example.org/");
1843 request_.upload_data_stream = upload_data_stream_.get();
1844
1845 size_t chunk_size = strlen(kUploadData);
1846 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1847
1848 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1849 TestCompletionCallback().callback(), NetLogWithSource()));
1850
1851 ASSERT_EQ(OK,
1852 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
1853 net_log_.bound(), callback_.callback()));
1854 ASSERT_EQ(OK,
1855 stream_->SendRequest(headers_, &response_, callback_.callback()));
1856
1857 // Error will be surfaced once an attempt to read the response occurs.
1858 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1859 stream_->ReadResponseHeaders(callback_.callback()));
1860
mmenkeffff3642017-06-15 17:37:241861 EXPECT_LE(0, stream_->GetTotalSentBytes());
1862 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031863}
1864
1865TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
1866 SetRequest("POST", "/", DEFAULT_PRIORITY);
1867 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231868 int packet_number = 1;
1869 if (VersionUsesQpack(version_.transport_version))
1870 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371871 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231872 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1873 kIncludeVersion, !kFin, DEFAULT_PRIORITY,
1874 &spdy_request_headers_frame_length));
rtenneti15656ae2016-01-23 03:05:031875 AddWrite(SYNCHRONOUS, ERR_FAILED);
1876 Initialize();
1877
Jeremy Roman0579ed62017-08-29 15:56:191878 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121879 auto* chunked_upload_stream =
1880 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031881
1882 request_.method = "POST";
rchcd379012017-04-12 21:53:321883 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121884 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031885 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201886 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031887
xunjieli5fafe142016-03-23 23:32:541888 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271889 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541890 net_log_.bound(), callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251891 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:031892 stream_->SendRequest(headers_, &response_, callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251893
1894 size_t chunk_size = strlen(kUploadData);
1895 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1896 // Error does not surface yet since packet write is triggered by a packet
1897 // flusher that tries to bundle request body writes.
1898 ASSERT_EQ(OK, callback_.WaitForResult());
1899 // Error will be surfaced once an attempt to read the response occurs.
1900 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1901 stream_->ReadResponseHeaders(callback_.callback()));
1902
1903 EXPECT_LE(0, stream_->GetTotalSentBytes());
1904 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1905}
1906
1907TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBundledBodyComplete) {
1908 SetRequest("POST", "/", DEFAULT_PRIORITY);
1909 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231910 int packet_number = 1;
1911 if (VersionUsesQpack(version_.transport_version))
1912 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431913 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harper23290b82019-05-02 00:02:561914 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411915 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231916 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1917 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1918 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411919 } else {
1920 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231921 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1922 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1923 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411924 }
1925
Yixin Wange7ecc472018-03-06 19:00:251926 AddWrite(SYNCHRONOUS, ERR_FAILED);
1927 Initialize();
1928
1929 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1930 auto* chunked_upload_stream =
1931 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1932
1933 request_.method = "POST";
1934 request_.url = GURL("https://www.example.org/");
1935 request_.upload_data_stream = upload_data_stream_.get();
1936
1937 size_t chunk_size = strlen(kUploadData);
1938 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
1939
1940 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1941 TestCompletionCallback().callback(), NetLogWithSource()));
1942
1943 ASSERT_EQ(OK,
1944 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
1945 net_log_.bound(), callback_.callback()));
1946 ASSERT_EQ(ERR_IO_PENDING,
1947 stream_->SendRequest(headers_, &response_, callback_.callback()));
1948
1949 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1950
1951 // Error does not surface yet since packet write is triggered by a packet
1952 // flusher that tries to bundle request body writes.
1953 ASSERT_EQ(OK, callback_.WaitForResult());
1954 // Error will be surfaced once an attempt to read the response occurs.
1955 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1956 stream_->ReadResponseHeaders(callback_.callback()));
1957
1958 EXPECT_LE(0, stream_->GetTotalSentBytes());
1959 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031960}
1961
ckrasic3865ee0f2016-02-29 22:04:561962TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
1963 SetRequest("GET", "/", DEFAULT_PRIORITY);
1964 Initialize();
1965
1966 // Initialize the first stream, for receiving the promise on.
1967 request_.method = "GET";
rchcd379012017-04-12 21:53:321968 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561969
xunjieli5fafe142016-03-23 23:32:541970 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271971 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541972 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:231973 ASSERT_EQ(OK,
1974 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561975
1976 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1977 // packet, but does it matter?
1978 ReceivePromise(promise_id_);
1979 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1980
1981 request_.url = GURL(promise_url_);
1982
1983 // Make the second stream that will exercise the first step of the
1984 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271985 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1986 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1987 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561988
1989 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251990 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561991 size_t spdy_response_headers_frame_length;
1992 ProcessPacket(InnerConstructResponseHeadersPacket(
1993 1, promise_id_, false, &spdy_response_headers_frame_length));
1994
1995 // Receive the promised response body.
1996 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431997 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171998 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
1999 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562000
2001 // Now sending a matching request will have successful rendezvous
2002 // with the promised stream.
Ryan Hamiltona1d1f4a2019-06-26 14:43:042003 ASSERT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
ckrasic3865ee0f2016-02-29 22:04:562004 callback_.callback()));
2005
2006 EXPECT_EQ(
2007 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2008 ->id(),
2009 promise_id_);
2010
2011 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:012012 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2013 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562014
2015 // As will be the body.
2016 EXPECT_EQ(
2017 static_cast<int>(strlen(kResponseBody)),
2018 promised_stream_->ReadResponseBody(
2019 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2020 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2021 EXPECT_TRUE(AtEof());
2022
ckrasic3865ee0f2016-02-29 22:04:562023 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2024 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412025 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562026 promised_stream_->GetTotalReceivedBytes());
2027}
2028
2029TEST_P(QuicHttpStreamTest, ServerPushGetRequestSlowResponse) {
2030 SetRequest("GET", "/", DEFAULT_PRIORITY);
2031 Initialize();
2032
2033 // Initialize the first stream, for receiving the promise on.
2034 request_.method = "GET";
rchcd379012017-04-12 21:53:322035 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562036
xunjieli5fafe142016-03-23 23:32:542037 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272038 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542039 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232040 ASSERT_EQ(OK,
2041 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562042
2043 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2044 // packet, but does it matter?
2045 ReceivePromise(promise_id_);
2046 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2047
2048 request_.url = GURL(promise_url_);
2049
2050 // Make the second stream that will exercise the first step of the
2051 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272052 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2053 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2054 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562055
2056 // Now sending a matching request will rendezvous with the promised
2057 // stream, but pending secondary validation.
2058 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2059 headers_, &response_, callback_.callback()));
2060
2061 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252062 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562063 size_t spdy_response_headers_frame_length;
2064 ProcessPacket(InnerConstructResponseHeadersPacket(
2065 1, promise_id_, false, &spdy_response_headers_frame_length));
2066
2067 // Receive the promised response body.
2068 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432069 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172070 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2071 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562072
fdoray92e35a72016-06-10 15:54:552073 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562074
2075 // Rendezvous should have succeeded now, so the promised stream
2076 // should point at our push stream, and we should be able read
2077 // headers and data from it.
robpercival214763f2016-07-01 23:27:012078 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562079
2080 EXPECT_EQ(
2081 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2082 ->id(),
2083 promise_id_);
2084
robpercival214763f2016-07-01 23:27:012085 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2086 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562087
2088 EXPECT_EQ(
2089 static_cast<int>(strlen(kResponseBody)),
2090 promised_stream_->ReadResponseBody(
2091 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2092
2093 // Callback should return
2094 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2095 EXPECT_TRUE(AtEof());
2096
ckrasic3865ee0f2016-02-29 22:04:562097 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2098 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412099 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562100 promised_stream_->GetTotalReceivedBytes());
2101}
2102
ckrasic2c63f9b2016-08-16 23:54:072103// Verify fix for crbug.com/637349
2104TEST_P(QuicHttpStreamTest, ServerPushCancelHttpStreamBeforeResponse) {
2105 SetRequest("GET", "/", DEFAULT_PRIORITY);
2106 Initialize();
2107
2108 // Initialize the first stream, for receiving the promise on.
2109 request_.method = "GET";
rchcd379012017-04-12 21:53:322110 request_.url = GURL("https://www.example.org/");
ckrasic2c63f9b2016-08-16 23:54:072111
2112 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272113 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
ckrasic2c63f9b2016-08-16 23:54:072114 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232115 ASSERT_EQ(OK,
2116 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic2c63f9b2016-08-16 23:54:072117
2118 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2119 // packet, but does it matter?
2120 ReceivePromise(promise_id_);
2121 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2122
2123 request_.url = GURL(promise_url_);
2124
2125 // Make the second stream that will exercise the first step of the
2126 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272127 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2128 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2129 callback_.callback()));
ckrasic2c63f9b2016-08-16 23:54:072130
2131 // Now sending a matching request will rendezvous with the promised
2132 // stream, but pending secondary validation.
2133 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2134 headers_, &response_, callback_.callback()));
2135
2136 base::RunLoop().RunUntilIdle();
2137
2138 // Cause of FinalValidation() crash as per bug.
2139 promised_stream_.reset();
2140
2141 // Receive the promised response headers.
2142 response_headers_ = promised_response_.Clone();
2143 size_t spdy_response_headers_frame_length;
2144 ProcessPacket(InnerConstructResponseHeadersPacket(
2145 1, promise_id_, false, &spdy_response_headers_frame_length));
2146}
2147
ckrasic3865ee0f2016-02-29 22:04:562148TEST_P(QuicHttpStreamTest, ServerPushCrossOriginOK) {
2149 SetRequest("GET", "/", DEFAULT_PRIORITY);
2150 Initialize();
2151
2152 // Initialize the first stream, for receiving the promise on.
2153 request_.method = "GET";
rchcd379012017-04-12 21:53:322154 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562155
xunjieli5fafe142016-03-23 23:32:542156 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272157 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542158 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232159 ASSERT_EQ(OK,
2160 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562161
2162 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2163 // packet, but does it matter?
2164
2165 push_promise_[":authority"] = "mail.example.org";
David Schinazi3f7465c2019-07-12 01:57:052166 promise_url_ =
2167 quic::SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562168
2169 ReceivePromise(promise_id_);
2170 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2171
2172 request_.url = GURL(promise_url_);
2173
2174 // Make the second stream that will exercise the first step of the
2175 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272176 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2177 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2178 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562179
2180 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252181 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562182 size_t spdy_response_headers_frame_length;
2183 ProcessPacket(InnerConstructResponseHeadersPacket(
2184 1, promise_id_, false, &spdy_response_headers_frame_length));
2185
2186 // Receive the promised response body.
2187 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432188 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172189 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2190 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562191
2192 // Now sending a matching request will have successful rendezvous
2193 // with the promised stream.
2194 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
2195 callback_.callback()));
2196
2197 EXPECT_EQ(
2198 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2199 ->id(),
2200 promise_id_);
2201
2202 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:012203 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2204 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562205
2206 // As will be the body.
2207 EXPECT_EQ(
2208 static_cast<int>(strlen(kResponseBody)),
2209 promised_stream_->ReadResponseBody(
2210 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2211 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2212 EXPECT_TRUE(AtEof());
2213
ckrasic3865ee0f2016-02-29 22:04:562214 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2215 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412216 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562217 promised_stream_->GetTotalReceivedBytes());
2218}
2219
2220TEST_P(QuicHttpStreamTest, ServerPushCrossOriginFail) {
2221 SetRequest("GET", "/", DEFAULT_PRIORITY);
2222 Initialize();
2223
2224 // Initialize the first stream, for receiving the promise on.
2225 request_.method = "GET";
rchcd379012017-04-12 21:53:322226 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562227
xunjieli5fafe142016-03-23 23:32:542228 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272229 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542230 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232231 ASSERT_EQ(OK,
2232 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562233
2234 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2235 // packet, but does it matter?
2236 push_promise_[":authority"] = "www.notexample.org";
David Schinazi3f7465c2019-07-12 01:57:052237 promise_url_ =
2238 quic::SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562239
2240 ReceivePromise(promise_id_);
2241 // The promise will have been rejected because the cert doesn't
2242 // match.
2243 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2244}
2245
2246TEST_P(QuicHttpStreamTest, ServerPushVaryCheckOK) {
2247 SetRequest("GET", "/", DEFAULT_PRIORITY);
2248 Initialize();
2249
2250 // Initialize the first stream, for receiving the promise on.
2251 request_.method = "GET";
rchcd379012017-04-12 21:53:322252 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562253
xunjieli5fafe142016-03-23 23:32:542254 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272255 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542256 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232257 ASSERT_EQ(OK,
2258 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562259
2260 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562261
2262 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2263 // packet, but does it matter?
2264 ReceivePromise(promise_id_);
2265 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2266
2267 request_.url = GURL(promise_url_);
2268
2269 // Make the second stream that will exercise the first step of the
2270 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272271 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2272 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2273 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562274
2275 headers_.SetHeader("accept-encoding", "gzip");
2276
2277 // Now sending a matching request will rendezvous with the promised
2278 // stream, but pending secondary validation.
2279 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2280 headers_, &response_, callback_.callback()));
2281
2282 // Receive the promised response headers.
2283 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252284 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562285 size_t spdy_response_headers_frame_length;
2286 ProcessPacket(InnerConstructResponseHeadersPacket(
2287 1, promise_id_, false, &spdy_response_headers_frame_length));
2288
2289 // Receive the promised response body.
2290 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432291 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172292 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2293 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562294
fdoray92e35a72016-06-10 15:54:552295 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562296
2297 // Rendezvous should have succeeded now, so the promised stream
2298 // should point at our push stream, and we should be able read
2299 // headers and data from it.
robpercival214763f2016-07-01 23:27:012300 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562301
2302 EXPECT_EQ(
2303 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2304 ->id(),
2305 promise_id_);
2306
robpercival214763f2016-07-01 23:27:012307 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2308 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562309
2310 EXPECT_EQ(
2311 static_cast<int>(strlen(kResponseBody)),
2312 promised_stream_->ReadResponseBody(
2313 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2314
2315 // Callback should return
2316 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2317 EXPECT_TRUE(AtEof());
2318
ckrasic3865ee0f2016-02-29 22:04:562319 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2320 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412321 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562322 promised_stream_->GetTotalReceivedBytes());
2323}
2324
2325TEST_P(QuicHttpStreamTest, ServerPushVaryCheckFail) {
2326 SetRequest("GET", "/", DEFAULT_PRIORITY);
2327 request_headers_[":scheme"] = "https";
2328 request_headers_[":path"] = "/bar";
2329 request_headers_["accept-encoding"] = "sdch";
2330
ckrasic3865ee0f2016-02-29 22:04:562331 Initialize();
2332
2333 // Initialize the first stream, for receiving the promise on.
2334 request_.method = "GET";
rchcd379012017-04-12 21:53:322335 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562336
xunjieli5fafe142016-03-23 23:32:542337 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272338 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542339 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232340 ASSERT_EQ(OK,
2341 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562342
2343 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562344
2345 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2346 // packet, but does it matter?
2347 ReceivePromise(promise_id_);
2348 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2349
2350 request_.url = GURL(promise_url_);
2351
2352 // Make the second stream that will exercise the first step of the
2353 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272354 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2355 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2356 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562357
2358 headers_.SetHeader("accept-encoding", "sdch");
2359
2360 // Now sending a matching request will rendezvous with the promised
2361 // stream, but pending secondary validation.
2362 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2363 headers_, &response_, callback_.callback()));
2364
2365 // Receive the promised response headers.
2366 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252367 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562368 size_t spdy_response_headers_frame_length;
2369 ProcessPacket(InnerConstructResponseHeadersPacket(
2370 1, promise_id_, false, &spdy_response_headers_frame_length));
2371
fdoray92e35a72016-06-10 15:54:552372 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562373
2374 // Rendezvous should have failed due to vary mismatch, so the
2375 // promised stream should have been aborted, and instead we have a
2376 // new, regular client initiated stream.
robpercival214763f2016-07-01 23:27:012377 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562378
2379 // Not a server-initiated stream.
2380 EXPECT_NE(
2381 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2382 ->id(),
2383 promise_id_);
2384
2385 // Instead, a new client-initiated stream.
2386 EXPECT_EQ(
2387 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2388 ->id(),
Nick Harper23290b82019-05-02 00:02:562389 stream_id_ + quic::QuicUtils::StreamIdDelta(version_.transport_version));
ckrasic3865ee0f2016-02-29 22:04:562390
2391 // After rendezvous failure, the push stream has been cancelled.
2392 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2393
2394 // The rest of the test verifies that the retried as
2395 // client-initiated version of |promised_stream_| works as intended.
2396
2397 // Ack the request.
Renjie90e808e2019-01-24 07:24:042398 ProcessPacket(ConstructServerAckPacket(2, 1, 1, 1));
ckrasic3865ee0f2016-02-29 22:04:562399
bnc614a92d32016-04-04 13:56:072400 SetResponse("404 Not Found", string());
ckrasic3865ee0f2016-02-29 22:04:562401 size_t spdy_response_header_frame_length;
2402 ProcessPacket(InnerConstructResponseHeadersPacket(
Nick Harper23290b82019-05-02 00:02:562403 3,
2404 stream_id_ + quic::QuicUtils::StreamIdDelta(version_.transport_version),
2405 kFin, &spdy_response_header_frame_length));
ckrasic3865ee0f2016-02-29 22:04:562406
fdoray92e35a72016-06-10 15:54:552407 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562408
robpercival214763f2016-07-01 23:27:012409 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2410 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562411 ASSERT_TRUE(response_.headers.get());
2412 EXPECT_EQ(404, response_.headers->response_code());
2413 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
2414 EXPECT_FALSE(response_.response_time.is_null());
2415 EXPECT_FALSE(response_.request_time.is_null());
2416
2417 // There is no body, so this should return immediately.
2418 EXPECT_EQ(
2419 0, promised_stream_->ReadResponseBody(
2420 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2421 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2422
2423 stream_->Close(true);
2424
2425 EXPECT_TRUE(AtEof());
ckrasic3865ee0f2016-02-29 22:04:562426}
2427
maksim.sisov84e20c92016-06-23 08:49:342428TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
2429 SetRequest("POST", "/", DEFAULT_PRIORITY);
2430 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:232431 int packet_number = 1;
2432 if (VersionUsesQpack(version_.transport_version))
2433 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Yixin Wange7ecc472018-03-06 19:00:252434 AddWrite(ConstructRequestAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:232435 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
2436 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
2437 &spdy_request_headers_frame_length, quic::QUIC_ERROR_PROCESSING_STREAM));
maksim.sisov84e20c92016-06-23 08:49:342438
2439 Initialize();
2440
Jeremy Roman0579ed62017-08-29 15:56:192441 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342442 ReadErrorUploadDataStream::FailureMode::SYNC);
2443 request_.method = "POST";
rchcd379012017-04-12 21:53:322444 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122445 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342446 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202447 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342448
2449 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272450 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342451 net_log_.bound(), callback_.callback()));
2452
2453 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
robpercival214763f2016-07-01 23:27:012454 EXPECT_THAT(result, IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342455
2456 EXPECT_TRUE(AtEof());
2457
2458 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2459 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2460 stream_->GetTotalSentBytes());
2461 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2462}
2463
2464TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
2465 SetRequest("POST", "/", DEFAULT_PRIORITY);
2466 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:232467 int packet_number = 1;
2468 if (VersionUsesQpack(version_.transport_version))
2469 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:372470 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:232471 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
2472 kIncludeVersion, !kFin, DEFAULT_PRIORITY,
2473 &spdy_request_headers_frame_length));
2474 AddWrite(
2475 ConstructClientRstStreamErrorPacket(packet_number++, !kIncludeVersion));
maksim.sisov84e20c92016-06-23 08:49:342476
2477 Initialize();
2478
Jeremy Roman0579ed62017-08-29 15:56:192479 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342480 ReadErrorUploadDataStream::FailureMode::ASYNC);
2481 request_.method = "POST";
rchcd379012017-04-12 21:53:322482 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122483 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342484 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202485 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342486
2487 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272488 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342489 net_log_.bound(), callback_.callback()));
2490
2491 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2492
Renjie90e808e2019-01-24 07:24:042493 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
maksim.sisov84e20c92016-06-23 08:49:342494 SetResponse("200 OK", string());
2495
robpercival214763f2016-07-01 23:27:012496 EXPECT_THAT(result, IsError(ERR_IO_PENDING));
2497 EXPECT_THAT(callback_.GetResult(result), IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342498
2499 EXPECT_TRUE(AtEof());
2500
2501 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2502 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2503 stream_->GetTotalSentBytes());
2504 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2505}
2506
[email protected]f702d572012-12-04 15:56:202507} // namespace test
[email protected]f702d572012-12-04 15:56:202508} // namespace net