blob: fbd891c9ef20aea9e14c07b69390823d9362448a [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"
Keishi Hattori0e45c022021-11-27 09:25:5214#include "base/memory/raw_ptr.h"
fdoray92e35a72016-06-10 15:54:5515#include "base/run_loop.h"
Bence Békye0d3747d2020-08-28 23:16:4016#include "base/strings/strcat.h"
xunjieli188bd402016-03-12 00:17:2517#include "base/strings/string_number_conversions.h"
Bence Béky97ec688c2021-03-16 13:48:5018#include "base/test/metrics/histogram_tester.h"
gabf767595f2016-05-11 18:50:3519#include "base/threading/thread_task_runner_handle.h"
Zhongyi Shic16b4102019-02-12 00:37:4020#include "base/time/default_tick_clock.h"
xunjieli84adaab2016-09-20 01:12:2821#include "base/time/time.h"
mmenkecbc2b712014-10-09 20:29:0722#include "net/base/chunked_upload_data_stream.h"
23#include "net/base/elements_upload_data_stream.h"
David Benjamin0288768a2019-07-22 15:00:2624#include "net/base/load_flags.h"
xunjieli84adaab2016-09-20 01:12:2825#include "net/base/load_timing_info.h"
26#include "net/base/load_timing_info_test_util.h"
[email protected]f702d572012-12-04 15:56:2027#include "net/base/net_errors.h"
28#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0629#include "net/base/upload_bytes_element_reader.h"
Ben Schwartz3ff4dc1e62021-04-27 21:15:2330#include "net/dns/public/secure_dns_policy.h"
[email protected]f702d572012-12-04 15:56:2031#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1532#include "net/http/transport_security_state.h"
Matt Reichhoff0049a0b72021-10-20 20:44:2633#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0034#include "net/log/net_log_event_type.h"
xunjieli5fafe142016-03-23 23:32:5435#include "net/log/test_net_log.h"
36#include "net/log/test_net_log_util.h"
Victor Vasiliev4f6fb892019-05-31 16:58:3137#include "net/quic/address_utils.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0838#include "net/quic/crypto/proof_verifier_chromium.h"
39#include "net/quic/mock_crypto_client_stream_factory.h"
40#include "net/quic/quic_chromium_alarm_factory.h"
41#include "net/quic/quic_chromium_connection_helper.h"
42#include "net/quic/quic_chromium_packet_reader.h"
43#include "net/quic/quic_chromium_packet_writer.h"
Matt Menkefca05b62019-09-20 23:15:5644#include "net/quic/quic_crypto_client_config_handle.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0845#include "net/quic/quic_http_utils.h"
46#include "net/quic/quic_server_info.h"
47#include "net/quic/quic_stream_factory.h"
48#include "net/quic/quic_test_packet_maker.h"
Ryan Hamilton0d65a8c2019-06-07 00:46:0249#include "net/quic/quic_test_packet_printer.h"
Matt Menkefca05b62019-09-20 23:15:5650#include "net/quic/test_quic_crypto_client_config_handle.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0851#include "net/quic/test_task_runner.h"
tbansalca83c002016-04-28 20:56:2852#include "net/socket/socket_performance_watcher.h"
[email protected]f702d572012-12-04 15:56:2053#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5854#include "net/spdy/spdy_http_utils.h"
rch03b7a202016-02-05 00:54:2055#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0156#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4357#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4058#include "net/test/test_with_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5159#include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h"
60#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
61#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
62#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
David Schinazi3f7465c2019-07-12 01:57:0563#include "net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5164#include "net/third_party/quiche/src/quic/core/quic_connection.h"
65#include "net/third_party/quiche/src/quic/core/quic_utils.h"
66#include "net/third_party/quiche/src/quic/core/quic_write_blocked_list.h"
Ryan Hamiltona1d1f4a2019-06-26 14:43:0467#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
68#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5169#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
70#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
71#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
Bence Béky6e243aa2019-12-13 19:01:0772#include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5173#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
74#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
75#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1476#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
77#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
78#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
Ramin Halavati683bcaa92018-02-14 08:42:3979#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]f702d572012-12-04 15:56:2080#include "testing/gmock/include/gmock/gmock.h"
81#include "testing/gtest/include/gtest/gtest.h"
Dan McArdle68a5f622021-07-09 20:56:5382#include "url/scheme_host_port.h"
83#include "url/url_constants.h"
[email protected]f702d572012-12-04 15:56:2084
bnc614a92d32016-04-04 13:56:0785using std::string;
[email protected]f702d572012-12-04 15:56:2086using testing::_;
[email protected]06ff5152013-08-29 01:03:0587using testing::AnyNumber;
88using testing::Return;
[email protected]f702d572012-12-04 15:56:2089
90namespace net {
[email protected]f702d572012-12-04 15:56:2091namespace test {
[email protected]f702d572012-12-04 15:56:2092namespace {
93
[email protected]16ba7742014-08-22 00:57:2594const char kUploadData[] = "Really nifty data!";
rch9ae5b3b2016-02-11 00:36:2995const char kDefaultServerHostName[] = "www.example.org";
rchcd379012017-04-12 21:53:3296const uint16_t kDefaultServerPort = 443;
[email protected]f702d572012-12-04 15:56:2097
David Schinazi09e9a6012019-10-03 17:37:5798struct TestParams {
99 quic::ParsedQuicVersion version;
100 bool client_headers_include_h2_stream_dependency;
101};
102
103// Used by ::testing::PrintToStringParamName().
104std::string PrintToString(const TestParams& p) {
Victor Vasiliev62c09dc2020-11-06 18:18:29105 return base::StrCat(
106 {ParsedQuicVersionToString(p.version), "_",
107 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
108 "Dependency"});
David Schinazi09e9a6012019-10-03 17:37:57109}
110
111std::vector<TestParams> GetTestParams() {
112 std::vector<TestParams> params;
113 quic::ParsedQuicVersionVector all_supported_versions =
114 quic::AllSupportedVersions();
115 for (const auto& version : all_supported_versions) {
116 params.push_back(TestParams{version, false});
117 params.push_back(TestParams{version, true});
118 }
119 return params;
120}
121
Bence Békye0d3747d2020-08-28 23:16:40122// Returns true if |params| is a dict, has an entry with key "headers", that
123// entry is a list of strings, which when interpreted as colon-separated
124// key-value pairs has exactly one entry with |key| and that entry has value
125// |expected_value|.
126bool CheckHeader(const base::Value& params,
127 base::StringPiece key,
128 base::StringPiece expected_value) {
129 if (!params.is_dict()) {
130 return false;
131 }
132 const base::Value* headers = params.FindListKey("headers");
133 if (!headers) {
134 return false;
135 }
136
137 std::string header_prefix = base::StrCat({key, ": "});
138 std::string expected_header = base::StrCat({header_prefix, expected_value});
139
Daniel Cheng354945d2022-02-02 23:39:17140 auto header_list = headers->GetListDeprecated();
Bence Békye0d3747d2020-08-28 23:16:40141 auto header_it = header_list.begin();
142 bool header_found = false;
143 while (header_it != header_list.end()) {
144 if (!header_it->is_string()) {
145 return false;
146 }
147 const std::string& header = header_it->GetString();
148 if (base::StartsWith(header, header_prefix)) {
149 if (header_found) {
150 return false;
151 }
152 if (header != expected_header) {
153 return false;
154 }
155 header_found = true;
156 }
157 ++header_it;
158 }
159 return header_found;
160}
161
Ryan Hamilton8d9ee76e2018-05-29 23:52:52162class TestQuicConnection : public quic::QuicConnection {
[email protected]f702d572012-12-04 15:56:20163 public:
Ryan Hamilton8d9ee76e2018-05-29 23:52:52164 TestQuicConnection(const quic::ParsedQuicVersionVector& versions,
165 quic::QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:20166 IPEndPoint address,
rch12fef552016-01-15 16:26:31167 QuicChromiumConnectionHelper* helper,
rch16c74d1d2016-04-22 06:14:07168 QuicChromiumAlarmFactory* alarm_factory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52169 quic::QuicPacketWriter* writer)
Victor Vasiliev4f6fb892019-05-31 16:58:31170 : quic::QuicConnection(connection_id,
Nick Harperd049f192020-10-02 02:56:10171 quic::QuicSocketAddress(),
Victor Vasiliev4f6fb892019-05-31 16:58:31172 ToQuicSocketAddress(address),
173 helper,
174 alarm_factory,
175 writer,
176 true /* owns_writer */,
177 quic::Perspective::IS_CLIENT,
178 versions) {}
[email protected]f702d572012-12-04 15:56:20179
Ryan Hamilton8d9ee76e2018-05-29 23:52:52180 void SetSendAlgorithm(quic::SendAlgorithmInterface* send_algorithm) {
181 quic::test::QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:20182 }
183};
184
maksim.sisov84e20c92016-06-23 08:49:34185// UploadDataStream that always returns errors on data read.
186class ReadErrorUploadDataStream : public UploadDataStream {
187 public:
188 enum class FailureMode { SYNC, ASYNC };
189
190 explicit ReadErrorUploadDataStream(FailureMode mode)
Jeremy Romand54000b22019-07-08 18:40:16191 : UploadDataStream(true, 0), async_(mode) {}
Peter Boström293b1342021-09-22 17:31:43192
193 ReadErrorUploadDataStream(const ReadErrorUploadDataStream&) = delete;
194 ReadErrorUploadDataStream& operator=(const ReadErrorUploadDataStream&) =
195 delete;
196
maksim.sisov84e20c92016-06-23 08:49:34197 ~ReadErrorUploadDataStream() override {}
198
199 private:
200 void CompleteRead() { UploadDataStream::OnReadCompleted(ERR_FAILED); }
201
202 // UploadDataStream implementation:
tfarina42834112016-09-22 13:38:20203 int InitInternal(const NetLogWithSource& net_log) override { return OK; }
maksim.sisov84e20c92016-06-23 08:49:34204
205 int ReadInternal(IOBuffer* buf, int buf_len) override {
206 if (async_ == FailureMode::ASYNC) {
207 base::ThreadTaskRunnerHandle::Get()->PostTask(
kylecharf4fe5172019-02-15 18:53:49208 FROM_HERE, base::BindOnce(&ReadErrorUploadDataStream::CompleteRead,
209 weak_factory_.GetWeakPtr()));
maksim.sisov84e20c92016-06-23 08:49:34210 return ERR_IO_PENDING;
211 }
212 return ERR_FAILED;
213 }
214
215 void ResetInternal() override {}
216
217 const FailureMode async_;
218
Jeremy Romand54000b22019-07-08 18:40:16219 base::WeakPtrFactory<ReadErrorUploadDataStream> weak_factory_{this};
maksim.sisov84e20c92016-06-23 08:49:34220};
221
Bence Béky8ddc2492018-06-13 01:02:04222// A helper class that will delete |stream| when the callback is invoked.
xunjieli8dff50b2016-07-22 14:19:06223class DeleteStreamCallback : public TestCompletionCallbackBase {
224 public:
Bence Béky8ddc2492018-06-13 01:02:04225 explicit DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)
226 : stream_(std::move(stream)) {}
xunjieli8dff50b2016-07-22 14:19:06227
Bence Béky8ddc2492018-06-13 01:02:04228 CompletionOnceCallback callback() {
229 return base::BindOnce(&DeleteStreamCallback::DeleteStream,
230 base::Unretained(this));
231 }
xunjieli8dff50b2016-07-22 14:19:06232
233 private:
234 void DeleteStream(int result) {
235 stream_.reset();
236 SetResult(result);
237 }
238
239 std::unique_ptr<QuicHttpStream> stream_;
xunjieli8dff50b2016-07-22 14:19:06240};
241
[email protected]f702d572012-12-04 15:56:20242} // namespace
243
[email protected]24e5bc52013-09-18 15:36:58244class QuicHttpStreamPeer {
245 public:
rch08e198572017-05-09 16:56:55246 static QuicChromiumClientStream::Handle* GetQuicChromiumClientStream(
[email protected]24e5bc52013-09-18 15:36:58247 QuicHttpStream* stream) {
rch08e198572017-05-09 16:56:55248 return stream->stream_.get();
[email protected]24e5bc52013-09-18 15:36:58249 }
250};
251
David Schinazi09e9a6012019-10-03 17:37:57252class QuicHttpStreamTest : public ::testing::TestWithParam<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05253 public WithTaskEnvironment {
rchfb47f712017-05-21 03:24:00254 public:
255 void CloseStream(QuicHttpStream* stream, int /*rv*/) { stream->Close(false); }
256
[email protected]f702d572012-12-04 15:56:20257 protected:
[email protected]1e960032013-12-20 19:00:20258 static const bool kFin = true;
259 static const bool kIncludeVersion = true;
[email protected]1e960032013-12-20 19:00:20260
[email protected]f702d572012-12-04 15:56:20261 // Holds a packet to be written to the wire, and the IO mode that should
262 // be used by the mock socket when performing the write.
263 struct PacketToWrite {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52264 PacketToWrite(IoMode mode, quic::QuicReceivedPacket* packet)
rjshaded5ced072015-12-18 19:26:02265 : mode(mode), packet(packet) {}
rtenneti15656ae2016-01-23 03:05:03266 PacketToWrite(IoMode mode, int rv) : mode(mode), packet(nullptr), rv(rv) {}
[email protected]f702d572012-12-04 15:56:20267 IoMode mode;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52268 quic::QuicReceivedPacket* packet;
rtenneti15656ae2016-01-23 03:05:03269 int rv;
[email protected]f702d572012-12-04 15:56:20270 };
271
272 QuicHttpStreamTest()
David Schinazi09e9a6012019-10-03 17:37:57273 : version_(GetParam().version),
274 client_headers_include_h2_stream_dependency_(
275 GetParam().client_headers_include_h2_stream_dependency),
Nick Harpera598fc5f2019-06-21 08:46:50276 crypto_config_(
277 quic::test::crypto_test_utils::ProofVerifierForTesting()),
Victor Costan9c7302b2018-08-27 16:39:44278 read_buffer_(base::MakeRefCounted<IOBufferWithSize>(4096)),
Fan Yang32c5a112018-12-10 20:06:33279 promise_id_(GetNthServerInitiatedUnidirectionalStreamId(0)),
280 stream_id_(GetNthClientInitiatedBidirectionalStreamId(0)),
David Schinazic8281052019-01-24 06:14:17281 connection_id_(quic::test::TestConnectionId(2)),
Yixin Wang079ad542018-01-11 04:06:05282 client_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58283 connection_id_,
284 &clock_,
285 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52286 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05287 client_headers_include_h2_stream_dependency_),
288 server_maker_(version_,
zhongyi5dbfdd42017-06-20 05:22:15289 connection_id_,
alyssar2adf3ac2016-05-03 17:12:58290 &clock_,
291 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52292 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05293 false),
ckrasic3865ee0f2016-02-29 22:04:56294 random_generator_(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:02295 printer_(version_) {
Renjie Tang98b4d512020-02-08 01:24:19296 FLAGS_quic_enable_http3_grease_randomness = false;
Zhongyi Shi49f8ad2fd2019-12-13 01:20:31297 quic::QuicEnableVersion(version_);
martijn21968ea2016-02-24 18:46:20298 IPAddress ip(192, 0, 2, 33);
[email protected]f702d572012-12-04 15:56:20299 peer_addr_ = IPEndPoint(ip, 443);
300 self_addr_ = IPEndPoint(ip, 8435);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52301 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
Ramin Halavati683bcaa92018-02-14 08:42:39302 request_.traffic_annotation =
303 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f702d572012-12-04 15:56:20304 }
305
306 ~QuicHttpStreamTest() {
Renjieba55fae2018-09-20 03:05:16307 session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
308 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]f702d572012-12-04 15:56:20309 for (size_t i = 0; i < writes_.size(); i++) {
310 delete writes_[i].packet;
311 }
312 }
313
314 // Adds a packet to the list of expected writes.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52315 void AddWrite(std::unique_ptr<quic::QuicReceivedPacket> packet) {
[email protected]1e960032013-12-20 19:00:20316 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20317 }
318
rtenneti15656ae2016-01-23 03:05:03319 void AddWrite(IoMode mode, int rv) {
320 writes_.push_back(PacketToWrite(mode, rv));
321 }
322
[email protected]f702d572012-12-04 15:56:20323 // Returns the packet to be written at position |pos|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52324 quic::QuicReceivedPacket* GetWrite(size_t pos) { return writes_[pos].packet; }
[email protected]f702d572012-12-04 15:56:20325
326 bool AtEof() {
rch37de576c2015-05-17 20:28:17327 return socket_data_->AllReadDataConsumed() &&
328 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20329 }
330
Ryan Hamilton8d9ee76e2018-05-29 23:52:52331 void ProcessPacket(std::unique_ptr<quic::QuicReceivedPacket> packet) {
Victor Vasiliev4f6fb892019-05-31 16:58:31332 connection_->ProcessUdpPacket(ToQuicSocketAddress(self_addr_),
333 ToQuicSocketAddress(peer_addr_), *packet);
[email protected]f702d572012-12-04 15:56:20334 }
335
336 // Configures the test fixture to use the list of expected writes.
337 void Initialize() {
Renjie Tang6ff9a9b2021-02-03 22:11:09338 mock_writes_ = std::make_unique<MockWrite[]>(writes_.size());
[email protected]f702d572012-12-04 15:56:20339 for (size_t i = 0; i < writes_.size(); i++) {
rtenneti15656ae2016-01-23 03:05:03340 if (writes_[i].packet == nullptr) {
341 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
342 } else {
343 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
344 writes_[i].packet->length());
345 }
bnc614a92d32016-04-04 13:56:07346 }
[email protected]f702d572012-12-04 15:56:20347
Renjie Tang6ff9a9b2021-02-03 22:11:09348 socket_data_ = std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:01349 base::span<MockRead>(),
Renjie Tang6ff9a9b2021-02-03 22:11:09350 base::make_span(mock_writes_.get(), writes_.size()));
Ryan Hamilton0d65a8c2019-06-07 00:46:02351 socket_data_->set_printer(&printer_);
[email protected]f702d572012-12-04 15:56:20352
Matt Reichhoff0049a0b72021-10-20 20:44:26353 std::unique_ptr<MockUDPClientSocket> socket(
354 new MockUDPClientSocket(socket_data_.get(), NetLog::Get()));
[email protected]e13201d82012-12-12 05:00:32355 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20356 runner_ = new TestTaskRunner(&clock_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52357 send_algorithm_ = new quic::test::MockSendAlgorithm();
rch7dd15702015-07-01 18:57:57358 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
359 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
Victor Vasiliev7da08172019-10-14 06:04:25360 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:23361 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
362 .Times(testing::AtLeast(1));
363 }
Ryan Hamiltona1d1f4a2019-06-26 14:43:04364 EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
365 .Times(AnyNumber());
rtenneti44f4a2e2015-08-07 14:00:07366 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
Zhongyi Shica576df2019-04-12 17:43:40367 .WillRepeatedly(Return(quic::kMaxOutgoingPacketSize));
jokulik0e0a00c32016-06-13 21:51:58368 EXPECT_CALL(*send_algorithm_, PacingRate(_))
Ryan Hamilton8d9ee76e2018-05-29 23:52:52369 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Michael Warres74ee3ce2017-10-09 15:26:37370 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
rtenneti44f4a2e2015-08-07 14:00:07371 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52372 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40373 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
rch08cae032017-03-29 00:59:15374 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
rch0d5bcf62017-05-24 22:48:45375 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
376 .Times(AnyNumber());
Renjie Tang6ff9a9b2021-02-03 22:11:09377 helper_ = std::make_unique<QuicChromiumConnectionHelper>(
378 &clock_, &random_generator_);
379 alarm_factory_ =
380 std::make_unique<QuicChromiumAlarmFactory>(runner_.get(), &clock_);
rch16c74d1d2016-04-22 06:14:07381
Michael Warres74ee3ce2017-10-09 15:26:37382 connection_ = new TestQuicConnection(
Nick Harper23290b82019-05-02 00:02:56383 quic::test::SupportedVersions(version_), connection_id_, peer_addr_,
384 helper_.get(), alarm_factory_.get(),
Ryan Hamilton9edcf1a2017-11-22 05:55:17385 new QuicChromiumPacketWriter(
386 socket.get(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]f702d572012-12-04 15:56:20387 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41388 connection_->SetSendAlgorithm(send_algorithm_);
rch03b7a202016-02-05 00:54:20389
390 // Load a certificate that is valid for *.example.org
391 scoped_refptr<X509Certificate> test_cert(
392 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
393 EXPECT_TRUE(test_cert.get());
394
395 verify_details_.cert_verify_result.verified_cert = test_cert;
396 verify_details_.cert_verify_result.is_issued_by_known_root = true;
397 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
398
xunjieli84adaab2016-09-20 01:12:28399 base::TimeTicks dns_end = base::TimeTicks::Now();
Peter Kastinge5a38ed2021-10-02 03:06:35400 base::TimeTicks dns_start = dns_end - base::Milliseconds(1);
Renjie Tang6ff9a9b2021-02-03 22:11:09401 session_ = std::make_unique<QuicChromiumClientSession>(
xunjielib53b38c2016-03-24 15:54:36402 connection_, std::move(socket),
rtenneti1cd3b162015-09-29 02:58:28403 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57404 &transport_security_state_, /*ssl_config_service=*/nullptr,
danakjad1777e2016-04-16 00:56:42405 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
Paul Jensen8e3c5d32018-02-19 17:06:33406 QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
dalyk51ab46b2019-10-15 15:14:34407 PRIVACY_MODE_DISABLED, SocketTag(),
Ben Schwartz3ff4dc1e62021-04-27 21:15:23408 NetworkIsolationKey(), SecureDnsPolicy::kAllow),
Bence Béky1ceba552019-07-19 17:11:05409 /*require_confirmation=*/false,
Bence Béky1ceba552019-07-19 17:11:05410 /*migrate_session_early_v2=*/false,
Zhongyi Shi757fcce2018-06-27 05:41:27411 /*migrate_session_on_network_change_v2=*/false,
412 /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shie01f2db2019-02-22 19:53:23413 quic::QuicTime::Delta::FromMilliseconds(
Ryan Sleevi2e8255b2019-07-17 21:02:21414 kDefaultRetransmittableOnWireTimeout.InMilliseconds()),
Zhongyi Shiaf38c4e42019-08-29 22:49:05415 /*migrate_idle_session=*/false, /*allow_port_migration=*/false,
416 kDefaultIdleSessionMigrationPeriod, kMaxTimeOnNonDefaultNetwork,
Zhongyi Shiee760762018-08-01 00:54:29417 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30418 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17419 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52420 quic::QuicTime::Delta::FromMilliseconds(
421 kQuicYieldAfterDurationMilliseconds),
Yixin Wang079ad542018-01-11 04:06:05422 client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
Matt Menkefca05b62019-09-20 23:15:56423 quic::test::DefaultQuicConfig(),
424 std::make_unique<TestQuicCryptoClientConfigHandle>(&crypto_config_),
Matt Menked804aaf2020-07-21 21:25:48425 "CONNECTION_UNKNOWN", dns_start, dns_end,
426 std::make_unique<quic::QuicClientPushPromiseIndex>(), nullptr,
Zhongyi Shic16b4102019-02-12 00:37:40427 base::DefaultTickClock::GetInstance(),
xunjieli84adaab2016-09-20 01:12:28428 base::ThreadTaskRunnerHandle::Get().get(),
Matt Reichhoff0049a0b72021-10-20 20:44:26429 /*socket_performance_watcher=*/nullptr, NetLog::Get());
rtennetid39bd762015-06-12 01:05:52430 session_->Initialize();
rchf0b18c8a2017-05-05 19:31:57431
Bence Béky6e243aa2019-12-13 19:01:07432 // Blackhole QPACK decoder stream instead of constructing mock writes.
433 if (VersionUsesHttp3(version_.transport_version)) {
434 session_->qpack_decoder()->set_qpack_stream_sender_delegate(
435 &noop_qpack_stream_sender_delegate_);
436 }
437
438 TestCompletionCallback callback;
rch433bf5f2017-02-14 04:10:47439 session_->CryptoConnect(callback.callback());
Ryan Hamilton6c2a2a82017-12-15 02:06:28440 stream_ = std::make_unique<QuicHttpStream>(
Dan McArdle68a5f622021-07-09 20:56:53441 session_->CreateHandle(
442 url::SchemeHostPort(url::kHttpsScheme, "www.example.org", 443)),
Eric Orthac661912022-01-10 21:44:17443 /*dns_aliases=*/std::set<std::string>());
Ryan Hamilton6c2a2a82017-12-15 02:06:28444 promised_stream_ = std::make_unique<QuicHttpStream>(
Dan McArdle68a5f622021-07-09 20:56:53445 session_->CreateHandle(
446 url::SchemeHostPort(url::kHttpsScheme, "www.example.org", 443)),
Eric Orthac661912022-01-10 21:44:17447 /*dns_aliases=*/std::set<std::string>());
ckrasic3865ee0f2016-02-29 22:04:56448 push_promise_[":path"] = "/bar";
449 push_promise_[":authority"] = "www.example.org";
450 push_promise_[":version"] = "HTTP/1.1";
451 push_promise_[":method"] = "GET";
452 push_promise_[":scheme"] = "https";
453
Kenichi Ishibashif8634ab2021-03-16 23:41:28454 promised_response_[":status"] = "200";
ckrasic3865ee0f2016-02-29 22:04:56455 promised_response_[":version"] = "HTTP/1.1";
456 promised_response_["content-type"] = "text/plain";
457
David Schinazi3f7465c2019-07-12 01:57:05458 promise_url_ =
459 quic::SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
[email protected]6cca996b2013-01-25 07:43:36460 }
461
bnc614a92d32016-04-04 13:56:07462 void SetRequest(const string& method,
463 const string& path,
[email protected]1e960032013-12-20 19:00:20464 RequestPriority priority) {
rchcd379012017-04-12 21:53:32465 request_headers_ = client_maker_.GetRequestHeaders(method, "https", path);
[email protected]6cca996b2013-01-25 07:43:36466 }
467
bnc614a92d32016-04-04 13:56:07468 void SetResponse(const string& status, const string& body) {
alyssar2adf3ac2016-05-03 17:12:58469 response_headers_ = server_maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03470 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36471 }
[email protected]f702d572012-12-04 15:56:20472
Ryan Hamilton8d9ee76e2018-05-29 23:52:52473 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23474 uint64_t packet_number,
[email protected]e8ff26842013-03-22 21:02:05475 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20476 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10477 absl::string_view data) {
Ryan Hamilton7505eb92019-06-08 00:22:17478 return client_maker_.MakeDataPacket(packet_number, stream_id_,
479 should_include_version, fin, data);
alyssar2adf3ac2016-05-03 17:12:58480 }
481
Ryan Hamilton8d9ee76e2018-05-29 23:52:52482 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23483 uint64_t packet_number,
alyssar2adf3ac2016-05-03 17:12:58484 bool should_include_version,
485 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10486 absl::string_view data) {
Ryan Hamilton7505eb92019-06-08 00:22:17487 return server_maker_.MakeDataPacket(packet_number, stream_id_,
488 should_include_version, fin, data);
ckrasic3865ee0f2016-02-29 22:04:56489 }
490
Ryan Hamilton8d9ee76e2018-05-29 23:52:52491 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23492 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52493 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56494 bool should_include_version,
495 bool fin,
496 RequestPriority request_priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02497 size_t* spdy_headers_frame_length) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48498 return InnerConstructRequestHeadersPacket(
499 packet_number, stream_id, should_include_version, fin, request_priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02500 0, spdy_headers_frame_length);
Yixin Wang7a3f1b8d2018-01-17 21:40:48501 }
502
Ryan Hamilton8d9ee76e2018-05-29 23:52:52503 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23504 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52505 quic::QuicStreamId stream_id,
Yixin Wang7a3f1b8d2018-01-17 21:40:48506 bool should_include_version,
507 bool fin,
508 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52509 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02510 size_t* spdy_headers_frame_length) {
Ryan Hamilton0239aac2018-05-19 00:03:13511 spdy::SpdyPriority priority =
ckrasic3865ee0f2016-02-29 22:04:56512 ConvertRequestPriorityToQuicPriority(request_priority);
alyssar2adf3ac2016-05-03 17:12:58513 return client_maker_.MakeRequestHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56514 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48515 std::move(request_headers_), parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02516 spdy_headers_frame_length);
[email protected]f702d572012-12-04 15:56:20517 }
518
Ryan Hamilton8d9ee76e2018-05-29 23:52:52519 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25520 ConstructRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23521 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52522 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25523 bool should_include_version,
524 bool fin,
525 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52526 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25527 size_t* spdy_headers_frame_length,
528 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13529 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25530 ConvertRequestPriorityToQuicPriority(request_priority);
531 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
532 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02533 std::move(request_headers_), parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25534 spdy_headers_frame_length, data_writes);
535 }
536
Ryan Hamilton8d9ee76e2018-05-29 23:52:52537 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestAndRstPacket(
Fan Yangac867502019-01-28 21:10:23538 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52539 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25540 bool should_include_version,
541 bool fin,
542 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52543 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25544 size_t* spdy_headers_frame_length,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41545 quic::QuicRstStreamErrorCode error_code) {
Ryan Hamilton0239aac2018-05-19 00:03:13546 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25547 ConvertRequestPriorityToQuicPriority(request_priority);
548 return client_maker_.MakeRequestHeadersAndRstPacket(
549 packet_number, stream_id, should_include_version, fin, priority,
550 std::move(request_headers_), parent_stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41551 spdy_headers_frame_length, error_code);
Yixin Wange7ecc472018-03-06 19:00:25552 }
553
Ryan Hamilton8d9ee76e2018-05-29 23:52:52554 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructResponseHeadersPacket(
Fan Yangac867502019-01-28 21:10:23555 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52556 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56557 bool fin,
558 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58559 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26560 packet_number, stream_id, !kIncludeVersion, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02561 std::move(response_headers_), spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20562 }
563
Ryan Hamilton8d9ee76e2018-05-29 23:52:52564 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseHeadersPacket(
Fan Yangac867502019-01-28 21:10:23565 uint64_t packet_number,
sclittlec4dc1a32015-09-24 00:15:45566 bool fin,
567 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56568 return InnerConstructResponseHeadersPacket(packet_number, stream_id_, fin,
569 spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20570 }
571
Ryan Hamilton8d9ee76e2018-05-29 23:52:52572 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseTrailersPacket(
Fan Yangac867502019-01-28 21:10:23573 uint64_t packet_number,
xunjieli34291fe12016-03-02 13:58:38574 bool fin,
Bence Béky4c325e52020-10-22 20:48:01575 spdy::Http2HeaderBlock trailers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02576 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58577 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26578 packet_number, stream_id_, !kIncludeVersion, fin, std::move(trailers),
Ryan Hamilton0d65a8c2019-06-07 00:46:02579 spdy_headers_frame_length);
xunjieli34291fe12016-03-02 13:58:38580 }
581
Ryan Hamilton8d9ee76e2018-05-29 23:52:52582 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamErrorPacket(
Fan Yangac867502019-01-28 21:10:23583 uint64_t packet_number,
maksim.sisov84e20c92016-06-23 08:49:34584 bool include_version) {
585 return client_maker_.MakeRstPacket(packet_number, include_version,
586 stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52587 quic::QUIC_ERROR_PROCESSING_STREAM);
maksim.sisov84e20c92016-06-23 08:49:34588 }
589
Ryan Hamilton8d9ee76e2018-05-29 23:52:52590 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23591 uint64_t packet_number) {
Renjie Tangcd594f32020-07-11 20:18:34592 return client_maker_.MakeAckAndRstPacket(packet_number, !kIncludeVersion,
593 stream_id_,
594 quic::QUIC_STREAM_CANCELLED, 2, 1);
[email protected]c5e1aca2014-01-30 04:03:04595 }
596
Ryan Hamilton8d9ee76e2018-05-29 23:52:52597 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23598 uint64_t packet_number,
599 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34600 uint64_t smallest_received) {
alyssar2adf3ac2016-05-03 17:12:58601 return client_maker_.MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34602 smallest_received);
alyssar2adf3ac2016-05-03 17:12:58603 }
604
Ryan Hamilton8d9ee76e2018-05-29 23:52:52605 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23606 uint64_t packet_number,
607 uint64_t largest_received,
608 uint64_t smallest_received,
609 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58610 return server_maker_.MakeAckPacket(packet_number, largest_received,
Bence Béky7a45d4d2020-05-08 01:59:23611 smallest_received, least_unacked);
[email protected]63534512012-12-23 18:49:00612 }
613
Ryan Hamilton0d65a8c2019-06-07 00:46:02614 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket() {
615 return client_maker_.MakeInitialSettingsPacket(1);
fayang3bcb8b502016-12-07 21:44:37616 }
617
Renjie Tangaadb84b2019-08-31 01:00:23618 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
619 int packet_number) {
620 return client_maker_.MakeInitialSettingsPacket(packet_number);
621 }
622
Victor Vasiliev076657c2019-03-12 02:46:43623 std::string ConstructDataHeader(size_t body_len) {
Nick Harperc6cb7a612020-02-24 20:03:32624 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:41625 return "";
626 }
Victor Vasilievc617d452022-03-07 15:54:25627 quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
628 body_len, quiche::SimpleBufferAllocator::Get());
Ian Swett17d4d1c02021-06-08 19:52:41629 return std::string(buffer.data(), buffer.size());
Renjief49758b2019-01-11 23:32:41630 }
631
Ryan Hamilton8d9ee76e2018-05-29 23:52:52632 void ReceivePromise(quic::QuicStreamId id) {
633 auto headers = quic::test::AsHeaderList(push_promise_);
rch08e198572017-05-09 16:56:55634 QuicChromiumClientStream::Handle* stream =
ckrasic3865ee0f2016-02-29 22:04:56635 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
ckrasic32b17dcd2016-10-31 06:15:35636 stream->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
637 headers);
ckrasic3865ee0f2016-02-29 22:04:56638 }
639
xunjieli84adaab2016-09-20 01:12:28640 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info,
xunjieli100937eb52016-09-15 20:09:37641 bool session_reused) {
642 EXPECT_EQ(session_reused, load_timing_info.socket_reused);
xunjieli84adaab2016-09-20 01:12:28643 if (session_reused) {
644 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
645 } else {
646 ExpectConnectTimingHasTimes(
647 load_timing_info.connect_timing,
648 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
649 }
650 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
xunjieli100937eb52016-09-15 20:09:37651 }
652
Fan Yang32c5a112018-12-10 20:06:33653 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56654 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
655 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36656 }
657
Fan Yang32c5a112018-12-10 20:06:33658 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56659 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
660 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36661 }
662
Ryan Hamiltona1d1f4a2019-06-26 14:43:04663 QuicFlagSaver saver_;
664
Nick Harper23290b82019-05-02 00:02:56665 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05666 const bool client_headers_include_h2_stream_dependency_;
667
Matt Reichhoff0049a0b72021-10-20 20:44:26668 NetLogWithSource net_log_with_source_{
669 NetLogWithSource::Make(NetLog::Get(), NetLogSourceType::NONE)};
670 RecordingNetLogObserver net_log_observer_;
Keishi Hattori0e45c022021-11-27 09:25:52671 raw_ptr<quic::test::MockSendAlgorithm> send_algorithm_;
[email protected]f702d572012-12-04 15:56:20672 scoped_refptr<TestTaskRunner> runner_;
danakjad1777e2016-04-16 00:56:42673 std::unique_ptr<MockWrite[]> mock_writes_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52674 quic::MockClock clock_;
Keishi Hattori0e45c022021-11-27 09:25:52675 raw_ptr<TestQuicConnection> connection_;
danakjad1777e2016-04-16 00:56:42676 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
rch16c74d1d2016-04-22 06:14:07677 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52678 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
rch97827ee2017-05-24 23:49:12679 std::unique_ptr<UploadDataStream> upload_data_stream_;
danakjad1777e2016-04-16 00:56:42680 std::unique_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15681 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42682 std::unique_ptr<QuicChromiumClientSession> session_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52683 quic::QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20684 TestCompletionCallback callback_;
685 HttpRequestInfo request_;
686 HttpRequestHeaders headers_;
687 HttpResponseInfo response_;
688 scoped_refptr<IOBufferWithSize> read_buffer_;
Bence Béky4c325e52020-10-22 20:48:01689 spdy::Http2HeaderBlock request_headers_;
690 spdy::Http2HeaderBlock response_headers_;
bnc614a92d32016-04-04 13:56:07691 string request_data_;
692 string response_data_;
[email protected]f702d572012-12-04 15:56:20693
ckrasic3865ee0f2016-02-29 22:04:56694 // For server push testing
danakjad1777e2016-04-16 00:56:42695 std::unique_ptr<QuicHttpStream> promised_stream_;
Bence Béky4c325e52020-10-22 20:48:01696 spdy::Http2HeaderBlock push_promise_;
697 spdy::Http2HeaderBlock promised_response_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52698 const quic::QuicStreamId promise_id_;
ckrasic3865ee0f2016-02-29 22:04:56699 string promise_url_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52700 const quic::QuicStreamId stream_id_;
ckrasic3865ee0f2016-02-29 22:04:56701
Ryan Hamilton8d9ee76e2018-05-29 23:52:52702 const quic::QuicConnectionId connection_id_;
alyssar2adf3ac2016-05-03 17:12:58703 QuicTestPacketMaker client_maker_;
704 QuicTestPacketMaker server_maker_;
[email protected]f702d572012-12-04 15:56:20705 IPEndPoint self_addr_;
706 IPEndPoint peer_addr_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52707 quic::test::MockRandom random_generator_;
rch03b7a202016-02-05 00:54:20708 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05709 MockCryptoClientStreamFactory crypto_client_stream_factory_;
danakjad1777e2016-04-16 00:56:42710 std::unique_ptr<StaticSocketDataProvider> socket_data_;
Ryan Hamilton0d65a8c2019-06-07 00:46:02711 QuicPacketPrinter printer_;
[email protected]f702d572012-12-04 15:56:20712 std::vector<PacketToWrite> writes_;
Bence Béky6e243aa2019-12-13 19:01:07713 quic::test::NoopQpackStreamSenderDelegate noop_qpack_stream_sender_delegate_;
[email protected]f702d572012-12-04 15:56:20714};
715
David Schinazi09e9a6012019-10-03 17:37:57716INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
717 QuicHttpStreamTest,
718 ::testing::ValuesIn(GetTestParams()),
719 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:20720
721TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44722 Initialize();
rtennetibe635732014-10-02 22:51:42723 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20724}
725
mmenkebd84c392015-09-02 14:12:34726TEST_P(QuicHttpStreamTest, CanReuseConnection) {
[email protected]ed3fc15d2013-03-08 18:37:44727 Initialize();
mmenkebd84c392015-09-02 14:12:34728 EXPECT_FALSE(stream_->CanReuseConnection());
[email protected]f702d572012-12-04 15:56:20729}
730
jri231c2972016-03-08 19:50:11731TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
Zhongyi Shibb28b1f2018-07-18 02:41:26732 request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri231c2972016-03-08 19:50:11733 Initialize();
Ali Beyada0b1a1c2022-04-08 20:08:14734 stream_->RegisterRequest(&request_);
735 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:26736 net_log_with_source_,
737 callback_.callback()));
rch08e198572017-05-09 16:56:55738 QuicChromiumClientStream::Handle* client_stream =
jri231c2972016-03-08 19:50:11739 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
Zhongyi Shibb28b1f2018-07-18 02:41:26740 EXPECT_FALSE(client_stream->can_migrate_to_cellular_network());
jri231c2972016-03-08 19:50:11741}
742
[email protected]1e960032013-12-20 19:00:20743TEST_P(QuicHttpStreamTest, GetRequest) {
744 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45745 size_t spdy_request_header_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:23746 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25747 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:23748 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:37749 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:23750 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
751 kIncludeVersion, kFin, DEFAULT_PRIORITY,
752 &spdy_request_header_frame_length));
fayang3bcb8b502016-12-07 21:44:37753
[email protected]f702d572012-12-04 15:56:20754 Initialize();
755
756 request_.method = "GET";
rchcd379012017-04-12 21:53:32757 request_.url = GURL("https://www.example.org/");
[email protected]f702d572012-12-04 15:56:20758
xunjieli100937eb52016-09-15 20:09:37759 // Make sure getting load timing from the stream early does not crash.
760 LoadTimingInfo load_timing_info;
761 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
Ali Beyada0b1a1c2022-04-08 20:08:14762 stream_->RegisterRequest(&request_);
763 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:26764 net_log_with_source_,
765 callback_.callback()));
rjshaded5ced072015-12-18 19:26:02766 EXPECT_EQ(OK,
767 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20768
769 // Ack the request.
Renjie90e808e2019-01-24 07:24:04770 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]f702d572012-12-04 15:56:20771
robpercival214763f2016-07-01 23:27:01772 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
773 IsError(ERR_IO_PENDING));
[email protected]f702d572012-12-04 15:56:20774
Kenichi Ishibashif8634ab2021-03-16 23:41:28775 SetResponse("404", string());
sclittlec4dc1a32015-09-24 00:15:45776 size_t spdy_response_header_frame_length;
777 ProcessPacket(ConstructResponseHeadersPacket(
778 2, kFin, &spdy_response_header_frame_length));
[email protected]f702d572012-12-04 15:56:20779
780 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01781 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]cadac622013-06-11 16:46:36782 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20783 EXPECT_EQ(404, response_.headers->response_code());
784 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53785 EXPECT_FALSE(response_.response_time.is_null());
786 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20787
788 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02789 EXPECT_EQ(0,
790 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
791 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20792 EXPECT_TRUE(stream_->IsResponseBodyComplete());
793 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10794
xunjieli100937eb52016-09-15 20:09:37795 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28796 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37797
sclittle1edeeb22015-09-02 20:46:10798 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45799 // headers and payload.
800 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
801 stream_->GetTotalSentBytes());
802 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
803 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20804}
805
xunjieli100937eb52016-09-15 20:09:37806TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
807 SetRequest("GET", "/", DEFAULT_PRIORITY);
808 size_t spdy_request_header_frame_length;
809
Renjie Tangaadb84b2019-08-31 01:00:23810 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25811 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:23812 AddWrite(ConstructInitialSettingsPacket(packet_number++));
xunjieli100937eb52016-09-15 20:09:37813 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:23814 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
815 kIncludeVersion, kFin, DEFAULT_PRIORITY,
816 &spdy_request_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37817
818 // SetRequest() again for second request as |request_headers_| was moved.
819 SetRequest("GET", "/", DEFAULT_PRIORITY);
820 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:23821 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
822 kIncludeVersion, kFin, DEFAULT_PRIORITY,
823 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:02824 &spdy_request_header_frame_length));
Renjie Tangcd594f32020-07-11 20:18:34825 AddWrite(
826 ConstructClientAckPacket(packet_number++, 3, 1)); // Ack the responses.
xunjieli100937eb52016-09-15 20:09:37827
828 Initialize();
829
830 request_.method = "GET";
rchcd379012017-04-12 21:53:32831 request_.url = GURL("https://www.example.org/");
xunjieli100937eb52016-09-15 20:09:37832 // Start first request.
Ali Beyada0b1a1c2022-04-08 20:08:14833 stream_->RegisterRequest(&request_);
834 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:26835 net_log_with_source_,
836 callback_.callback()));
xunjieli100937eb52016-09-15 20:09:37837 EXPECT_EQ(OK,
838 stream_->SendRequest(headers_, &response_, callback_.callback()));
839
840 // Start a second request.
Dan McArdle68a5f622021-07-09 20:56:53841 QuicHttpStream stream2(session_->CreateHandle(url::SchemeHostPort(
842 url::kHttpsScheme, "www.example.org", 443)),
843 {} /* dns_aliases */);
xunjieli100937eb52016-09-15 20:09:37844 TestCompletionCallback callback2;
Ali Beyada0b1a1c2022-04-08 20:08:14845 stream2.RegisterRequest(&request_);
Matt Reichhoff0049a0b72021-10-20 20:44:26846 EXPECT_EQ(
Ali Beyada0b1a1c2022-04-08 20:08:14847 OK, stream2.InitializeStream(true, DEFAULT_PRIORITY, net_log_with_source_,
848 callback2.callback()));
xunjieli100937eb52016-09-15 20:09:37849 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;
Kenichi Ishibashif8634ab2021-03-16 23:41:28858 SetResponse("200", string());
xunjieli100937eb52016-09-15 20:09:37859 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.
Kenichi Ishibashif8634ab2021-03-16 23:41:28878 SetResponse("200", string());
xunjieli100937eb52016-09-15 20:09:37879 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;
Victor Vasiliev7da08172019-10-14 06:04:25905 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:23906 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));
Renjie Tangcd594f32020-07-11 20:18:34911 AddWrite(
912 ConstructClientAckPacket(packet_number++, 3, 1)); // 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/");
Ali Beyada0b1a1c2022-04-08 20:08:14918 stream_->RegisterRequest(&request_);
919 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:26920 net_log_with_source_,
921 callback_.callback()));
xunjieli5fafe142016-03-23 23:32:54922
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
Kenichi Ishibashif8634ab2021-03-16 23:41:28931 SetResponse("200", 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));
Bence Béky4c325e52020-10-22 20:48:01950 spdy::Http2HeaderBlock trailers;
xunjieli34291fe12016-03-02 13:58:38951 size_t spdy_trailers_frame_length;
952 trailers["foo"] = "bar";
Victor Vasiliev7da08172019-10-14 06:04:25953 if (!quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltona1d1f4a2019-06-26 14:43:04954 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.
Matt Reichhoff0049a0b72021-10-20 20:44:26984 auto entries = net_log_observer_.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
Bence Béky6c2c78f2020-08-28 16:49:06999TEST_P(QuicHttpStreamTest, ElideHeadersInNetLog) {
1000 Initialize();
1001
1002 // QuicHttp3Logger is only used with HTTP/3.
1003 if (!VersionUsesHttp3(version_.transport_version)) {
1004 return;
1005 }
1006
Matt Reichhoff0049a0b72021-10-20 20:44:261007 net_log_observer_.SetObserverCaptureMode(NetLogCaptureMode::kDefault);
Bence Béky6c2c78f2020-08-28 16:49:061008
Bence Békye0d3747d2020-08-28 23:16:401009 // Send first request.
Bence Béky6c2c78f2020-08-28 16:49:061010 SetRequest("GET", "/", DEFAULT_PRIORITY);
1011 request_.method = "GET";
1012 request_.url = GURL("https://www.example.org/");
1013 headers_.SetHeader(HttpRequestHeaders::kCookie, "secret");
1014
1015 size_t spdy_request_header_frame_length;
Bence Békye0d3747d2020-08-28 23:16:401016 int outgoing_packet_number = 1;
1017 AddWrite(ConstructInitialSettingsPacket(outgoing_packet_number++));
Bence Béky6c2c78f2020-08-28 16:49:061018 AddWrite(InnerConstructRequestHeadersPacket(
Bence Békye0d3747d2020-08-28 23:16:401019 outgoing_packet_number++, stream_id_, kIncludeVersion, kFin,
1020 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
Bence Béky6c2c78f2020-08-28 16:49:061021
Ali Beyada0b1a1c2022-04-08 20:08:141022 stream_->RegisterRequest(&request_);
Matt Reichhoff0049a0b72021-10-20 20:44:261023 EXPECT_THAT(
Ali Beyada0b1a1c2022-04-08 20:08:141024 stream_->InitializeStream(true, DEFAULT_PRIORITY, net_log_with_source_,
1025 callback_.callback()),
Matt Reichhoff0049a0b72021-10-20 20:44:261026 IsOk());
Bence Béky6c2c78f2020-08-28 16:49:061027 EXPECT_THAT(stream_->SendRequest(headers_, &response_, callback_.callback()),
1028 IsOk());
Bence Békye0d3747d2020-08-28 23:16:401029 int incoming_packet_number = 1;
1030 ProcessPacket(ConstructServerAckPacket(incoming_packet_number++, 1, 1,
1031 1)); // Ack the request.
Bence Béky6c2c78f2020-08-28 16:49:061032
Bence Békye0d3747d2020-08-28 23:16:401033 // Process first response.
Kenichi Ishibashif8634ab2021-03-16 23:41:281034 SetResponse("200", string());
Bence Béky6c2c78f2020-08-28 16:49:061035 response_headers_["set-cookie"] = "secret";
1036 size_t spdy_response_header_frame_length;
1037 ProcessPacket(ConstructResponseHeadersPacket(
Bence Békye0d3747d2020-08-28 23:16:401038 incoming_packet_number++, kFin, &spdy_response_header_frame_length));
Bence Béky6c2c78f2020-08-28 16:49:061039 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
Bence Béky6c2c78f2020-08-28 16:49:061040
1041 ASSERT_TRUE(response_.headers.get());
1042 EXPECT_EQ(200, response_.headers->response_code());
1043 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1044 EXPECT_TRUE(response_.headers->HasHeaderValue("set-cookie", "secret"));
1045
Matt Reichhoff0049a0b72021-10-20 20:44:261046 net_log_observer_.SetObserverCaptureMode(
1047 NetLogCaptureMode::kIncludeSensitive);
Bence Béky6c2c78f2020-08-28 16:49:061048
Bence Békye0d3747d2020-08-28 23:16:401049 // Send second request.
1050 quic::QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(1);
1051 request_.url = GURL("https://www.example.org/foo");
Bence Béky6c2c78f2020-08-28 16:49:061052
Bence Békye0d3747d2020-08-28 23:16:401053 AddWrite(InnerConstructRequestHeadersPacket(
1054 outgoing_packet_number++, stream_id, kIncludeVersion, kFin,
1055 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
Bence Béky6c2c78f2020-08-28 16:49:061056
Bence Békye0d3747d2020-08-28 23:16:401057 auto stream = std::make_unique<QuicHttpStream>(
Dan McArdle68a5f622021-07-09 20:56:531058 session_->CreateHandle(
1059 url::SchemeHostPort(url::kHttpsScheme, "www.example.org/foo", 443)),
Eric Orthac661912022-01-10 21:44:171060 /*dns_aliases=*/std::set<std::string>());
Ali Beyada0b1a1c2022-04-08 20:08:141061 stream->RegisterRequest(&request_);
Matt Reichhoff0049a0b72021-10-20 20:44:261062 EXPECT_THAT(
Ali Beyada0b1a1c2022-04-08 20:08:141063 stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_with_source_,
1064 callback_.callback()),
Matt Reichhoff0049a0b72021-10-20 20:44:261065 IsOk());
Bence Békye0d3747d2020-08-28 23:16:401066 EXPECT_THAT(stream->SendRequest(headers_, &response_, callback_.callback()),
1067 IsOk());
1068 ProcessPacket(ConstructServerAckPacket(incoming_packet_number++, 1, 1,
1069 1)); // Ack the request.
Bence Béky6c2c78f2020-08-28 16:49:061070
Bence Békye0d3747d2020-08-28 23:16:401071 // Process second response.
Kenichi Ishibashif8634ab2021-03-16 23:41:281072 SetResponse("200", string());
Bence Békye0d3747d2020-08-28 23:16:401073 response_headers_["set-cookie"] = "secret";
1074 ProcessPacket(InnerConstructResponseHeadersPacket(
1075 incoming_packet_number++, stream_id, kFin,
1076 &spdy_response_header_frame_length));
1077 EXPECT_THAT(stream->ReadResponseHeaders(callback_.callback()), IsOk());
Bence Béky6c2c78f2020-08-28 16:49:061078
Bence Békye0d3747d2020-08-28 23:16:401079 ASSERT_TRUE(response_.headers.get());
1080 EXPECT_EQ(200, response_.headers->response_code());
1081 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1082 EXPECT_TRUE(response_.headers->HasHeaderValue("set-cookie", "secret"));
1083
1084 EXPECT_TRUE(AtEof());
1085
1086 // Check that sensitive header value were stripped
1087 // for the first transaction (logged with NetLogCaptureMode::kDefault)
1088 // but not for the second (logged with NetLogCaptureMode::kIncludeSensitive).
1089 auto entries =
Matt Reichhoff0049a0b72021-10-20 20:44:261090 net_log_observer_.GetEntriesWithType(NetLogEventType::HTTP3_HEADERS_SENT);
Bence Békye0d3747d2020-08-28 23:16:401091 ASSERT_EQ(2u, entries.size());
1092 EXPECT_TRUE(
1093 CheckHeader(entries[0].params, "cookie", "[6 bytes were stripped]"));
1094 EXPECT_TRUE(CheckHeader(entries[1].params, "cookie", "secret"));
1095
Matt Reichhoff0049a0b72021-10-20 20:44:261096 entries = net_log_observer_.GetEntriesWithType(
1097 NetLogEventType::HTTP3_HEADERS_DECODED);
Bence Békye0d3747d2020-08-28 23:16:401098 ASSERT_EQ(2u, entries.size());
1099 EXPECT_TRUE(
1100 CheckHeader(entries[0].params, "set-cookie", "[6 bytes were stripped]"));
1101 EXPECT_TRUE(CheckHeader(entries[1].params, "set-cookie", "secret"));
Bence Béky6c2c78f2020-08-28 16:49:061102}
1103
[email protected]3e7dca62013-09-10 16:14:231104// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:201105TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
1106 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451107 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231108 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251109 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231110 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371111 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231112 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1113 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1114 &spdy_request_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:231115 Initialize();
1116
1117 request_.method = "GET";
rchcd379012017-04-12 21:53:321118 request_.url = GURL("https://www.example.org/");
[email protected]3e7dca62013-09-10 16:14:231119
Ali Beyada0b1a1c2022-04-08 20:08:141120 stream_->RegisterRequest(&request_);
1121 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261122 net_log_with_source_,
1123 callback_.callback()));
rjshaded5ced072015-12-18 19:26:021124 EXPECT_EQ(OK,
1125 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:231126
1127 // Ack the request.
Renjie90e808e2019-01-24 07:24:041128 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]3e7dca62013-09-10 16:14:231129
robpercival214763f2016-07-01 23:27:011130 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1131 IsError(ERR_IO_PENDING));
[email protected]3e7dca62013-09-10 16:14:231132
Kenichi Ishibashif8634ab2021-03-16 23:41:281133 response_headers_[":status"] = "200";
bnc086b39e12016-06-24 13:05:261134 response_headers_[":version"] = "HTTP/1.1";
1135 response_headers_["content-type"] = "text/plain";
1136 response_headers_["big6"] = string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:231137
sclittlec4dc1a32015-09-24 00:15:451138 size_t spdy_response_headers_frame_length;
1139 ProcessPacket(ConstructResponseHeadersPacket(
1140 2, kFin, &spdy_response_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:231141
1142 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:011143 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]3e7dca62013-09-10 16:14:231144 ASSERT_TRUE(response_.headers.get());
1145 EXPECT_EQ(200, response_.headers->response_code());
1146 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1147
1148 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:021149 EXPECT_EQ(0,
1150 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1151 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:231152 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1153 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101154
1155 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451156 // headers and payload.
1157 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1158 stream_->GetTotalSentBytes());
1159 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
1160 stream_->GetTotalReceivedBytes());
[email protected]3e7dca62013-09-10 16:14:231161}
1162
rchf9f103cbc2014-08-30 05:28:041163// Regression test for http://crbug.com/409101
1164TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
1165 SetRequest("GET", "/", DEFAULT_PRIORITY);
1166 Initialize();
1167
1168 request_.method = "GET";
rchcd379012017-04-12 21:53:321169 request_.url = GURL("https://www.example.org/");
rchf9f103cbc2014-08-30 05:28:041170
Ali Beyada0b1a1c2022-04-08 20:08:141171 stream_->RegisterRequest(&request_);
1172 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261173 net_log_with_source_,
1174 callback_.callback()));
rchf9f103cbc2014-08-30 05:28:041175
jri78ec06a2016-03-31 18:19:401176 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521177 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchf9f103cbc2014-08-30 05:28:041178
1179 EXPECT_EQ(ERR_CONNECTION_CLOSED,
rjshaded5ced072015-12-18 19:26:021180 stream_->SendRequest(headers_, &response_, callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101181
1182 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1183 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rchf9f103cbc2014-08-30 05:28:041184}
1185
rch03b7a202016-02-05 00:54:201186// Regression test for http://crbug.com/584441
1187TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
1188 SetRequest("GET", "/", DEFAULT_PRIORITY);
1189 Initialize();
1190
1191 request_.method = "GET";
rchcd379012017-04-12 21:53:321192 request_.url = GURL("https://www.example.org/");
rch03b7a202016-02-05 00:54:201193
Ali Beyada0b1a1c2022-04-08 20:08:141194 stream_->RegisterRequest(&request_);
1195 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261196 net_log_with_source_,
1197 callback_.callback()));
rch03b7a202016-02-05 00:54:201198
1199 SSLInfo ssl_info;
rch11565e02016-02-09 20:13:471200 EXPECT_FALSE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201201 stream_->GetSSLInfo(&ssl_info);
rch11565e02016-02-09 20:13:471202 EXPECT_TRUE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201203
jri78ec06a2016-03-31 18:19:401204 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521205 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch03b7a202016-02-05 00:54:201206
rch11565e02016-02-09 20:13:471207 SSLInfo ssl_info2;
1208 stream_->GetSSLInfo(&ssl_info2);
1209 EXPECT_TRUE(ssl_info2.is_valid());
rch03b7a202016-02-05 00:54:201210}
1211
rchcd379012017-04-12 21:53:321212TEST_P(QuicHttpStreamTest, GetAlternativeService) {
1213 SetRequest("GET", "/", DEFAULT_PRIORITY);
1214 Initialize();
1215
1216 request_.method = "GET";
1217 request_.url = GURL("https://www.example.org/");
1218
Ali Beyada0b1a1c2022-04-08 20:08:141219 stream_->RegisterRequest(&request_);
1220 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261221 net_log_with_source_,
1222 callback_.callback()));
rchcd379012017-04-12 21:53:321223
1224 AlternativeService alternative_service;
1225 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service));
1226 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1227 alternative_service);
1228
1229 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521230 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchcd379012017-04-12 21:53:321231
1232 AlternativeService alternative_service2;
1233 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service2));
1234 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1235 alternative_service2);
1236}
1237
zhongyica364fbb2015-12-12 03:39:121238TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
1239 SetRequest("GET", "/", DEFAULT_PRIORITY);
1240 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231241 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251242 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231243 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371244 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231245 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1246 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1247 &spdy_request_headers_frame_length));
fayang3bcb8b502016-12-07 21:44:371248 AddWrite(ConstructAckAndRstStreamPacket(3));
zhongyica364fbb2015-12-12 03:39:121249 Initialize();
1250
1251 request_.method = "GET";
rchcd379012017-04-12 21:53:321252 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121253
Ali Beyada0b1a1c2022-04-08 20:08:141254 stream_->RegisterRequest(&request_);
1255 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261256 net_log_with_source_,
1257 callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121258 EXPECT_EQ(OK,
1259 stream_->SendRequest(headers_, &response_, callback_.callback()));
1260
1261 // Ack the request.
Renjie90e808e2019-01-24 07:24:041262 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011263 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1264 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121265
Ryan Hamilton8d9ee76e2018-05-29 23:52:521266 quic::QuicConnectionCloseFrame frame;
Zhongyi Shica576df2019-04-12 17:43:401267 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551268 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121269
1270 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521271 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121272 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521273 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121274}
1275
Ryan Hamiltone316e482017-08-17 02:48:531276TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
rch617e0652017-04-26 17:57:511277 // By default the test setup defaults handshake to be confirmed. Manually set
1278 // it to be not confirmed.
rch617e0652017-04-26 17:57:511279 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271280 MockCryptoClientStream::ZERO_RTT);
rch617e0652017-04-26 17:57:511281
zhongyica364fbb2015-12-12 03:39:121282 SetRequest("GET", "/", DEFAULT_PRIORITY);
1283 size_t spdy_request_headers_frame_length;
Michael Warres167db3e2019-03-01 21:38:031284 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:491285 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
1286 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251287 if (VersionUsesHttp3(version_.transport_version))
Nick Harper057264a82019-09-12 23:33:491288 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371289 AddWrite(InnerConstructRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:491290 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1291 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1292 &spdy_request_headers_frame_length));
zhongyica364fbb2015-12-12 03:39:121293 Initialize();
1294
1295 request_.method = "GET";
rchcd379012017-04-12 21:53:321296 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121297
Ali Beyada0b1a1c2022-04-08 20:08:141298 stream_->RegisterRequest(&request_);
1299 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261300 net_log_with_source_,
1301 callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121302 EXPECT_EQ(OK,
1303 stream_->SendRequest(headers_, &response_, callback_.callback()));
1304
1305 // Ack the request.
Renjie90e808e2019-01-24 07:24:041306 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011307 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1308 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121309
Ryan Hamilton8d9ee76e2018-05-29 23:52:521310 quic::QuicConnectionCloseFrame frame;
Zhongyi Shica576df2019-04-12 17:43:401311 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551312 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121313
1314 NetErrorDetails details;
zhongyica364fbb2015-12-12 03:39:121315 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521316 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121317}
1318
rch11a114a2014-09-04 23:41:591319// Regression test for http://crbug.com/409871
1320TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
1321 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451322 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231323 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251324 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231325 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371326 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231327 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1328 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1329 &spdy_request_headers_frame_length));
rch11a114a2014-09-04 23:41:591330 Initialize();
1331
1332 request_.method = "GET";
rchcd379012017-04-12 21:53:321333 request_.url = GURL("https://www.example.org/");
rch11a114a2014-09-04 23:41:591334
Ali Beyada0b1a1c2022-04-08 20:08:141335 stream_->RegisterRequest(&request_);
1336 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261337 net_log_with_source_,
1338 callback_.callback()));
rch11a114a2014-09-04 23:41:591339
rjshaded5ced072015-12-18 19:26:021340 EXPECT_EQ(OK,
1341 stream_->SendRequest(headers_, &response_, callback_.callback()));
rch11a114a2014-09-04 23:41:591342
jri78ec06a2016-03-31 18:19:401343 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521344 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch11a114a2014-09-04 23:41:591345
1346 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101347
1348 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451349 // headers and payload.
1350 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1351 stream_->GetTotalSentBytes());
sclittle1edeeb22015-09-02 20:46:101352 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rch11a114a2014-09-04 23:41:591353}
1354
[email protected]1e960032013-12-20 19:00:201355TEST_P(QuicHttpStreamTest, SendPostRequest) {
1356 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451357 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231358 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251359 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231360 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Yixin Wange7ecc472018-03-06 19:00:251361
Victor Vasiliev076657c2019-03-12 02:46:431362 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harperc6cb7a612020-02-24 20:03:321363 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:411364 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231365 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1366 kIncludeVersion, kFin, DEFAULT_PRIORITY, 0,
1367 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411368 } else {
1369 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231370 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1371 kIncludeVersion, kFin, DEFAULT_PRIORITY, 0,
1372 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411373 }
Yixin Wange7ecc472018-03-06 19:00:251374
Renjie Tangcd594f32020-07-11 20:18:341375 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
[email protected]f702d572012-12-04 15:56:201376
1377 Initialize();
1378
danakjad1777e2016-04-16 00:56:421379 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191380 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
ricea2deef682016-09-09 08:04:071381 kUploadData, strlen(kUploadData)));
rch97827ee2017-05-24 23:49:121382 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191383 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
[email protected]f702d572012-12-04 15:56:201384 request_.method = "POST";
rchcd379012017-04-12 21:53:321385 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121386 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581387 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
tfarina42834112016-09-22 13:38:201388 NetLogWithSource()),
1389 IsOk());
[email protected]f702d572012-12-04 15:56:201390
Ali Beyada0b1a1c2022-04-08 20:08:141391 stream_->RegisterRequest(&request_);
1392 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261393 net_log_with_source_,
1394 callback_.callback()));
rjshaded5ced072015-12-18 19:26:021395 EXPECT_EQ(OK,
1396 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:201397
1398 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041399 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]f702d572012-12-04 15:56:201400
1401 // Send the response headers (but not the body).
Kenichi Ishibashif8634ab2021-03-16 23:41:281402 SetResponse("200", string());
sclittlec4dc1a32015-09-24 00:15:451403 size_t spdy_response_headers_frame_length;
1404 ProcessPacket(ConstructResponseHeadersPacket(
1405 2, !kFin, &spdy_response_headers_frame_length));
[email protected]f702d572012-12-04 15:56:201406
rchfb47f712017-05-21 03:24:001407 // The headers have already arrived.
1408 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361409 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:201410 EXPECT_EQ(200, response_.headers->response_code());
1411 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1412
1413 // Send the response body.
1414 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431415 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:411416 ProcessPacket(
Ryan Hamilton7505eb92019-06-08 00:22:171417 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
[email protected]f702d572012-12-04 15:56:201418 // Since the body has already arrived, this should return immediately.
1419 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1420 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1421 callback_.callback()));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291422 EXPECT_EQ(0,
1423 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1424 callback_.callback()));
1425
1426 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1427 EXPECT_TRUE(AtEof());
1428
1429 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1430 // headers and payload.
1431 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411432 strlen(kUploadData) + header.length()),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291433 stream_->GetTotalSentBytes());
1434 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411435 strlen(kResponseBody) + header2.length()),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291436 stream_->GetTotalReceivedBytes());
1437}
1438
1439TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
1440 SetRequest("POST", "/", DEFAULT_PRIORITY);
1441 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231442 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251443 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231444 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431445 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harperc6cb7a612020-02-24 20:03:321446 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:411447 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231448 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1449 kIncludeVersion, kFin, DEFAULT_PRIORITY, 0,
1450 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411451 } else {
1452 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231453 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1454 kIncludeVersion, kFin, DEFAULT_PRIORITY, 0,
1455 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411456 }
1457
Renjie Tangcd594f32020-07-11 20:18:341458 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291459
1460 Initialize();
1461
1462 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191463 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
Ryan Hamilton2ef0a9c2017-07-25 03:18:291464 kUploadData, strlen(kUploadData)));
1465 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191466 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
Ryan Hamilton2ef0a9c2017-07-25 03:18:291467 request_.method = "POST";
1468 request_.url = GURL("https://www.example.org/");
1469 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581470 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291471 NetLogWithSource()),
1472 IsOk());
1473
Ali Beyada0b1a1c2022-04-08 20:08:141474 stream_->RegisterRequest(&request_);
1475 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261476 net_log_with_source_,
1477 callback_.callback()));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291478 EXPECT_EQ(OK,
1479 stream_->SendRequest(headers_, &response_, callback_.callback()));
1480
1481 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041482 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291483
1484 // Send the response headers (but not the body).
Kenichi Ishibashif8634ab2021-03-16 23:41:281485 SetResponse("200", string());
Ryan Hamilton2ef0a9c2017-07-25 03:18:291486 size_t spdy_response_headers_frame_length;
1487 ProcessPacket(ConstructResponseHeadersPacket(
1488 2, !kFin, &spdy_response_headers_frame_length));
1489
1490 // The headers have already arrived.
1491 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1492 ASSERT_TRUE(response_.headers.get());
1493 EXPECT_EQ(200, response_.headers->response_code());
1494 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1495
1496 // Send the response body.
1497 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431498 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:411499 ProcessPacket(
Ryan Hamilton7505eb92019-06-08 00:22:171500 ConstructServerDataPacket(3, false, !kFin, header2 + kResponseBody));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291501 // Since the body has already arrived, this should return immediately.
1502 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1503 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1504 callback_.callback()));
Ryan Hamilton7505eb92019-06-08 00:22:171505 ProcessPacket(ConstructServerDataPacket(4, false, kFin, ""));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291506 EXPECT_EQ(0,
1507 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1508 callback_.callback()));
[email protected]f702d572012-12-04 15:56:201509
1510 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1511 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101512
1513 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451514 // headers and payload.
1515 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411516 strlen(kUploadData) + header.length()),
sclittle1edeeb22015-09-02 20:46:101517 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451518 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411519 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101520 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:201521}
1522
[email protected]1e960032013-12-20 19:00:201523TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
1524 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:471525 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451526 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231527 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251528 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231529 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431530 std::string header = ConstructDataHeader(chunk_size);
Nick Harperc6cb7a612020-02-24 20:03:321531 if (version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:411532 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231533 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1534 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1535 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjie Tangd5133972019-12-06 00:20:281536 AddWrite(ConstructClientDataPacket(packet_number++, kIncludeVersion, kFin,
1537 {header + kUploadData}));
Renjief49758b2019-01-11 23:32:411538 } else {
1539 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231540 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1541 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1542 &spdy_request_headers_frame_length, {kUploadData}));
1543 AddWrite(ConstructClientDataPacket(packet_number++, kIncludeVersion, kFin,
1544 kUploadData));
Renjief49758b2019-01-11 23:32:411545 }
1546
Renjie Tangcd594f32020-07-11 20:18:341547 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
[email protected]c9e49a02013-02-26 05:56:471548 Initialize();
1549
Jeremy Roman0579ed62017-08-29 15:56:191550 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121551 auto* chunked_upload_stream =
1552 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1553 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:471554
1555 request_.method = "POST";
rchcd379012017-04-12 21:53:321556 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121557 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071558 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201559 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]c9e49a02013-02-26 05:56:471560
Ali Beyada0b1a1c2022-04-08 20:08:141561 stream_->RegisterRequest(&request_);
1562 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261563 net_log_with_source_,
1564 callback_.callback()));
rjshaded5ced072015-12-18 19:26:021565 ASSERT_EQ(ERR_IO_PENDING,
1566 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:471567
rch97827ee2017-05-24 23:49:121568 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
robpercival214763f2016-07-01 23:27:011569 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]c9e49a02013-02-26 05:56:471570
1571 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041572 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]c9e49a02013-02-26 05:56:471573
1574 // Send the response headers (but not the body).
Kenichi Ishibashif8634ab2021-03-16 23:41:281575 SetResponse("200", string());
sclittlec4dc1a32015-09-24 00:15:451576 size_t spdy_response_headers_frame_length;
1577 ProcessPacket(ConstructResponseHeadersPacket(
1578 2, !kFin, &spdy_response_headers_frame_length));
[email protected]c9e49a02013-02-26 05:56:471579
rchfb47f712017-05-21 03:24:001580 // The headers have already arrived.
1581 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361582 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:471583 EXPECT_EQ(200, response_.headers->response_code());
1584 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1585
1586 // Send the response body.
1587 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431588 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171589 ProcessPacket(
1590 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
[email protected]c9e49a02013-02-26 05:56:471591
1592 // Since the body has already arrived, this should return immediately.
1593 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1594 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1595 callback_.callback()));
1596
1597 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1598 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101599
1600 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451601 // headers and payload.
1602 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411603 strlen(kUploadData) * 2 + header.length() * 2),
sclittle1edeeb22015-09-02 20:46:101604 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451605 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411606 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101607 stream_->GetTotalReceivedBytes());
[email protected]c9e49a02013-02-26 05:56:471608}
1609
[email protected]16ba7742014-08-22 00:57:251610TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
1611 SetRequest("POST", "/", DEFAULT_PRIORITY);
1612 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451613 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231614 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251615 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231616 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431617 std::string header = ConstructDataHeader(chunk_size);
Renjief49758b2019-01-11 23:32:411618
Nick Harperc6cb7a612020-02-24 20:03:321619 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:411620 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231621 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1622 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1623 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411624 } else {
1625 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231626 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1627 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1628 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411629 }
Renjie Tangaadb84b2019-08-31 01:00:231630 AddWrite(
1631 ConstructClientDataPacket(packet_number++, kIncludeVersion, kFin, ""));
Renjie Tangcd594f32020-07-11 20:18:341632 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
[email protected]16ba7742014-08-22 00:57:251633 Initialize();
1634
Jeremy Roman0579ed62017-08-29 15:56:191635 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121636 auto* chunked_upload_stream =
1637 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1638 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:251639
1640 request_.method = "POST";
rchcd379012017-04-12 21:53:321641 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121642 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071643 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201644 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251645
Ali Beyada0b1a1c2022-04-08 20:08:141646 stream_->RegisterRequest(&request_);
1647 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261648 net_log_with_source_,
1649 callback_.callback()));
rjshaded5ced072015-12-18 19:26:021650 ASSERT_EQ(ERR_IO_PENDING,
1651 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251652
rch97827ee2017-05-24 23:49:121653 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011654 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251655
Renjie90e808e2019-01-24 07:24:041656 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]16ba7742014-08-22 00:57:251657
1658 // Send the response headers (but not the body).
Kenichi Ishibashif8634ab2021-03-16 23:41:281659 SetResponse("200", string());
sclittlec4dc1a32015-09-24 00:15:451660 size_t spdy_response_headers_frame_length;
1661 ProcessPacket(ConstructResponseHeadersPacket(
1662 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251663
rchfb47f712017-05-21 03:24:001664 // The headers have already arrived.
1665 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251666 ASSERT_TRUE(response_.headers.get());
1667 EXPECT_EQ(200, response_.headers->response_code());
1668 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1669
1670 // Send the response body.
1671 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431672 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171673 ProcessPacket(
1674 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
[email protected]16ba7742014-08-22 00:57:251675
rchb27683c2015-07-29 23:53:501676 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251677 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1678 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1679 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251680 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1681 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101682
1683 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451684 // headers and payload.
1685 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411686 strlen(kUploadData) + header.length()),
sclittle1edeeb22015-09-02 20:46:101687 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451688 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411689 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101690 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251691}
1692
1693TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
1694 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451695 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231696 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251697 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231698 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371699 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231700 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1701 kIncludeVersion, !kFin, DEFAULT_PRIORITY,
1702 &spdy_request_headers_frame_length));
1703 AddWrite(
1704 ConstructClientDataPacket(packet_number++, kIncludeVersion, kFin, ""));
Renjie Tangcd594f32020-07-11 20:18:341705 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
[email protected]16ba7742014-08-22 00:57:251706 Initialize();
1707
Jeremy Roman0579ed62017-08-29 15:56:191708 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121709 auto* chunked_upload_stream =
1710 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
[email protected]16ba7742014-08-22 00:57:251711
1712 request_.method = "POST";
rchcd379012017-04-12 21:53:321713 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121714 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071715 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201716 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251717
Ali Beyada0b1a1c2022-04-08 20:08:141718 stream_->RegisterRequest(&request_);
1719 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261720 net_log_with_source_,
1721 callback_.callback()));
rjshaded5ced072015-12-18 19:26:021722 ASSERT_EQ(ERR_IO_PENDING,
1723 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251724
rch97827ee2017-05-24 23:49:121725 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011726 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251727
Renjie90e808e2019-01-24 07:24:041728 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]16ba7742014-08-22 00:57:251729
1730 // Send the response headers (but not the body).
Kenichi Ishibashif8634ab2021-03-16 23:41:281731 SetResponse("200", string());
sclittlec4dc1a32015-09-24 00:15:451732 size_t spdy_response_headers_frame_length;
1733 ProcessPacket(ConstructResponseHeadersPacket(
1734 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251735
rchfb47f712017-05-21 03:24:001736 // The headers have already arrived.
1737 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251738 ASSERT_TRUE(response_.headers.get());
1739 EXPECT_EQ(200, response_.headers->response_code());
1740 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1741
1742 // Send the response body.
1743 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431744 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171745 ProcessPacket(
1746 ConstructServerDataPacket(3, false, kFin, header + kResponseBody));
[email protected]16ba7742014-08-22 00:57:251747
rchb27683c2015-07-29 23:53:501748 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251749 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1750 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1751 callback_.callback()));
1752
1753 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1754 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101755
1756 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451757 // headers and payload.
1758 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1759 stream_->GetTotalSentBytes());
1760 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411761 strlen(kResponseBody) + header.length()),
sclittle1edeeb22015-09-02 20:46:101762 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251763}
1764
Bence Békye3c6f122020-05-08 01:09:471765TEST_P(QuicHttpStreamTest, SendChunkedPostRequestAbortedByResetStream) {
1766 SetRequest("POST", "/", DEFAULT_PRIORITY);
1767 size_t chunk_size = strlen(kUploadData);
1768 size_t spdy_request_headers_frame_length;
1769 int packet_number = 1;
1770
1771 if (version_.UsesHttp3()) {
1772 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1773 }
1774
1775 std::string header = ConstructDataHeader(chunk_size);
1776 if (version_.HasIetfQuicFrames()) {
1777 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1778 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1779 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1780 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjie Tangcd594f32020-07-11 20:18:341781 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
Fan Yang8d4177792021-07-16 17:48:531782 AddWrite(client_maker_.MakeAckAndRstPacket(
1783 packet_number++, true, stream_id_, quic::QUIC_STREAM_NO_ERROR, 4, 1,
Renjie Tangcd594f32020-07-11 20:18:341784 /* include_stop_sending_if_v99 = */ false));
Bence Békye3c6f122020-05-08 01:09:471785 } else {
1786 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1787 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1788 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1789 &spdy_request_headers_frame_length, {kUploadData}));
Renjie Tangcd594f32020-07-11 20:18:341790 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
Bence Békye3c6f122020-05-08 01:09:471791 AddWrite(client_maker_.MakeAckAndRstPacket(
1792 packet_number++,
1793 /* include_version = */ false, stream_id_,
Renjie Tangcd594f32020-07-11 20:18:341794 quic::QUIC_RST_ACKNOWLEDGEMENT, 4, 1,
Bence Békye3c6f122020-05-08 01:09:471795 /* include_stop_sending_if_v99 = */ false));
1796 }
1797
1798 Initialize();
1799
1800 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1801 auto* chunked_upload_stream =
1802 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1803 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
1804
1805 request_.method = "POST";
1806 request_.url = GURL("https://www.example.org/");
1807 request_.upload_data_stream = upload_data_stream_.get();
1808 ASSERT_THAT(request_.upload_data_stream->Init(
1809 TestCompletionCallback().callback(), NetLogWithSource()),
1810 IsOk());
Ali Beyada0b1a1c2022-04-08 20:08:141811 stream_->RegisterRequest(&request_);
Matt Reichhoff0049a0b72021-10-20 20:44:261812 ASSERT_THAT(
Ali Beyada0b1a1c2022-04-08 20:08:141813 stream_->InitializeStream(false, DEFAULT_PRIORITY, net_log_with_source_,
1814 callback_.callback()),
Matt Reichhoff0049a0b72021-10-20 20:44:261815 IsOk());
Bence Békye3c6f122020-05-08 01:09:471816 ASSERT_THAT(stream_->SendRequest(headers_, &response_, callback_.callback()),
1817 IsError(ERR_IO_PENDING));
1818
1819 // Ack both packets in the request.
1820 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1821
1822 // Send the response headers (but not the body).
Kenichi Ishibashif8634ab2021-03-16 23:41:281823 SetResponse("200", string());
Bence Békye3c6f122020-05-08 01:09:471824 size_t spdy_response_headers_frame_length;
1825 ProcessPacket(ConstructResponseHeadersPacket(
1826 2, !kFin, &spdy_response_headers_frame_length));
1827
1828 // Send the response body.
1829 const char kResponseBody[] = "Hello world!";
1830 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
1831 ProcessPacket(
1832 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
1833
Bence Béky050ec6d2021-02-25 22:07:051834 if (version_.HasIetfQuicFrames()) {
1835 // In IETF QUIC, the server uses a STOP_SENDING frame to notify the client
1836 // that it does not need any further data to fully process the request.
1837 ProcessPacket(server_maker_.MakeStopSendingPacket(
1838 4, /* include_version = */ false, stream_id_,
1839 quic::QUIC_STREAM_NO_ERROR));
1840 } else {
1841 // Server resets stream with H3_NO_ERROR before request body is complete.
1842 ProcessPacket(server_maker_.MakeRstPacket(4, /* include_version = */ false,
1843 stream_id_,
1844 quic::QUIC_STREAM_NO_ERROR));
1845 }
Bence Békye3c6f122020-05-08 01:09:471846
1847 // Finish feeding request body to QuicHttpStream. Data will be discarded.
1848 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1849 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1850
1851 // Verify response.
1852 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1853 ASSERT_TRUE(response_.headers.get());
1854 EXPECT_EQ(200, response_.headers->response_code());
1855 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1856 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1857 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1858 callback_.callback()));
1859 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1860 EXPECT_TRUE(AtEof());
1861
1862 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1863 // headers and payload.
1864 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1865 strlen(kUploadData) + header.length()),
1866 stream_->GetTotalSentBytes());
1867 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1868 strlen(kResponseBody) + header2.length()),
1869 stream_->GetTotalReceivedBytes());
1870}
1871
[email protected]1e960032013-12-20 19:00:201872TEST_P(QuicHttpStreamTest, DestroyedEarly) {
1873 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451874 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231875 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251876 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231877 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371878 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231879 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1880 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1881 &spdy_request_headers_frame_length));
1882 AddWrite(ConstructAckAndRstStreamPacket(packet_number++));
[email protected]63534512012-12-23 18:49:001883 Initialize();
1884
1885 request_.method = "GET";
rchcd379012017-04-12 21:53:321886 request_.url = GURL("https://www.example.org/");
[email protected]63534512012-12-23 18:49:001887
Ali Beyada0b1a1c2022-04-08 20:08:141888 stream_->RegisterRequest(&request_);
1889 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:261890 net_log_with_source_,
1891 callback_.callback()));
rjshaded5ced072015-12-18 19:26:021892 EXPECT_EQ(OK,
1893 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]63534512012-12-23 18:49:001894
1895 // Ack the request.
Renjie90e808e2019-01-24 07:24:041896 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
rchfb47f712017-05-21 03:24:001897 EXPECT_THAT(stream_->ReadResponseHeaders(
Yannic Bonenberger3c96beb2019-09-03 20:41:371898 base::BindOnce(&QuicHttpStreamTest::CloseStream,
1899 base::Unretained(this), stream_.get())),
robpercival214763f2016-07-01 23:27:011900 IsError(ERR_IO_PENDING));
[email protected]63534512012-12-23 18:49:001901
1902 // Send the response with a body.
Kenichi Ishibashif8634ab2021-03-16 23:41:281903 SetResponse("404", "hello world!");
[email protected]63534512012-12-23 18:49:001904 // In the course of processing this packet, the QuicHttpStream close itself.
rchfb47f712017-05-21 03:24:001905 size_t response_size = 0;
rch1bcfddf22017-06-03 00:26:291906 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin, &response_size));
[email protected]63534512012-12-23 18:49:001907
fdoray92e35a72016-06-10 15:54:551908 base::RunLoop().RunUntilIdle();
rchb27683c2015-07-29 23:53:501909
[email protected]63534512012-12-23 18:49:001910 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101911
1912 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451913 // headers and payload.
1914 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1915 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001916 // The stream was closed after receiving the headers.
1917 EXPECT_EQ(static_cast<int64_t>(response_size),
1918 stream_->GetTotalReceivedBytes());
[email protected]63534512012-12-23 18:49:001919}
1920
[email protected]1e960032013-12-20 19:00:201921TEST_P(QuicHttpStreamTest, Priority) {
1922 SetRequest("GET", "/", MEDIUM);
sclittlec4dc1a32015-09-24 00:15:451923 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231924 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251925 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231926 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371927 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231928 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1929 kIncludeVersion, kFin, MEDIUM, &spdy_request_headers_frame_length));
[email protected]24e5bc52013-09-18 15:36:581930 Initialize();
1931
1932 request_.method = "GET";
rchcd379012017-04-12 21:53:321933 request_.url = GURL("https://www.example.org/");
[email protected]24e5bc52013-09-18 15:36:581934
Ali Beyada0b1a1c2022-04-08 20:08:141935 stream_->RegisterRequest(&request_);
1936 EXPECT_EQ(OK, stream_->InitializeStream(true, MEDIUM, net_log_with_source_,
Matt Reichhoff0049a0b72021-10-20 20:44:261937 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581938
rjshaded5ced072015-12-18 19:26:021939 EXPECT_EQ(OK,
1940 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581941
[email protected]24e5bc52013-09-18 15:36:581942 // Ack the request.
Renjie90e808e2019-01-24 07:24:041943 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011944 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1945 IsError(ERR_IO_PENDING));
[email protected]24e5bc52013-09-18 15:36:581946
1947 // Send the response with a body.
Kenichi Ishibashif8634ab2021-03-16 23:41:281948 SetResponse("404", "hello world!");
rchfb47f712017-05-21 03:24:001949 size_t response_size = 0;
1950 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, &response_size));
[email protected]24e5bc52013-09-18 15:36:581951
rchfb47f712017-05-21 03:24:001952 EXPECT_EQ(OK, callback_.WaitForResult());
rchb27683c2015-07-29 23:53:501953
[email protected]24e5bc52013-09-18 15:36:581954 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101955
1956 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451957 // headers and payload.
1958 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1959 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001960 EXPECT_EQ(static_cast<int64_t>(response_size),
1961 stream_->GetTotalReceivedBytes());
[email protected]24e5bc52013-09-18 15:36:581962}
1963
xunjieli8dff50b2016-07-22 14:19:061964TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
1965 SetRequest("POST", "/", DEFAULT_PRIORITY);
1966 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231967 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251968 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231969 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431970 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harperc6cb7a612020-02-24 20:03:321971 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:411972 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231973 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1974 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1975 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411976 } else {
1977 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231978 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1979 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1980 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411981 }
1982
xunjieli8dff50b2016-07-22 14:19:061983 // Second data write will result in a synchronous failure which will close
1984 // the session.
1985 AddWrite(SYNCHRONOUS, ERR_FAILED);
1986 Initialize();
1987
Jeremy Roman0579ed62017-08-29 15:56:191988 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121989 auto* chunked_upload_stream =
1990 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
xunjieli8dff50b2016-07-22 14:19:061991
1992 request_.method = "POST";
rchcd379012017-04-12 21:53:321993 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121994 request_.upload_data_stream = upload_data_stream_.get();
xunjieli8dff50b2016-07-22 14:19:061995 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201996 TestCompletionCallback().callback(), NetLogWithSource()));
xunjieli8dff50b2016-07-22 14:19:061997
1998 size_t chunk_size = strlen(kUploadData);
rch97827ee2017-05-24 23:49:121999 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
Ali Beyada0b1a1c2022-04-08 20:08:142000 stream_->RegisterRequest(&request_);
2001 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262002 net_log_with_source_,
2003 callback_.callback()));
xunjieli8dff50b2016-07-22 14:19:062004 QuicHttpStream* stream = stream_.get();
2005 DeleteStreamCallback delete_stream_callback(std::move(stream_));
2006 // SendRequest() completes asynchronously after the final chunk is added.
Yixin Wange7ecc472018-03-06 19:00:252007 // Error does not surface yet since packet write is triggered by a packet
2008 // flusher that tries to bundle request body writes.
xunjieli8dff50b2016-07-22 14:19:062009 ASSERT_EQ(ERR_IO_PENDING,
2010 stream->SendRequest(headers_, &response_, callback_.callback()));
rch97827ee2017-05-24 23:49:122011 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
xunjieli8dff50b2016-07-22 14:19:062012 int rv = callback_.WaitForResult();
Yixin Wange7ecc472018-03-06 19:00:252013 EXPECT_EQ(OK, rv);
2014 // Error will be surfaced once an attempt to read the response occurs.
2015 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
2016 stream->ReadResponseHeaders(callback_.callback()));
xunjieli8dff50b2016-07-22 14:19:062017}
2018
rtenneti15656ae2016-01-23 03:05:032019TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
2020 SetRequest("POST", "/", DEFAULT_PRIORITY);
Victor Vasiliev7da08172019-10-14 06:04:252021 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232022 AddWrite(ConstructInitialSettingsPacket());
rtenneti15656ae2016-01-23 03:05:032023 AddWrite(SYNCHRONOUS, ERR_FAILED);
2024 Initialize();
2025
Jeremy Roman0579ed62017-08-29 15:56:192026 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
Yixin Wange7ecc472018-03-06 19:00:252027 auto* chunked_upload_stream =
2028 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:032029
2030 request_.method = "POST";
rchcd379012017-04-12 21:53:322031 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122032 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:032033 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202034 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:032035
Ali Beyada0b1a1c2022-04-08 20:08:142036 stream_->RegisterRequest(&request_);
2037 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262038 net_log_with_source_,
2039 callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:252040 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:032041 stream_->SendRequest(headers_, &response_, callback_.callback()));
mmenkeffff3642017-06-15 17:37:242042
Yixin Wange7ecc472018-03-06 19:00:252043 // Error will be surfaced once |upload_data_stream| triggers the next write.
2044 size_t chunk_size = strlen(kUploadData);
2045 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
2046 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
2047
2048 EXPECT_LE(0, stream_->GetTotalSentBytes());
2049 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2050}
2051
2052TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersCompleteReadResponse) {
2053 SetRequest("POST", "/", DEFAULT_PRIORITY);
Victor Vasiliev7da08172019-10-14 06:04:252054 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232055 AddWrite(ConstructInitialSettingsPacket());
Yixin Wange7ecc472018-03-06 19:00:252056 AddWrite(SYNCHRONOUS, ERR_FAILED);
2057 Initialize();
2058
2059 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
2060 auto* chunked_upload_stream =
2061 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
2062
2063 request_.method = "POST";
2064 request_.url = GURL("https://www.example.org/");
2065 request_.upload_data_stream = upload_data_stream_.get();
2066
2067 size_t chunk_size = strlen(kUploadData);
2068 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
2069
2070 ASSERT_EQ(OK, request_.upload_data_stream->Init(
2071 TestCompletionCallback().callback(), NetLogWithSource()));
2072
Ali Beyada0b1a1c2022-04-08 20:08:142073 stream_->RegisterRequest(&request_);
2074 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262075 net_log_with_source_,
2076 callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:252077 ASSERT_EQ(OK,
2078 stream_->SendRequest(headers_, &response_, callback_.callback()));
2079
2080 // Error will be surfaced once an attempt to read the response occurs.
2081 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
2082 stream_->ReadResponseHeaders(callback_.callback()));
2083
mmenkeffff3642017-06-15 17:37:242084 EXPECT_LE(0, stream_->GetTotalSentBytes());
2085 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:032086}
2087
2088TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
2089 SetRequest("POST", "/", DEFAULT_PRIORITY);
2090 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:232091 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:252092 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232093 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:372094 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:232095 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
2096 kIncludeVersion, !kFin, DEFAULT_PRIORITY,
2097 &spdy_request_headers_frame_length));
rtenneti15656ae2016-01-23 03:05:032098 AddWrite(SYNCHRONOUS, ERR_FAILED);
2099 Initialize();
2100
Jeremy Roman0579ed62017-08-29 15:56:192101 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:122102 auto* chunked_upload_stream =
2103 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:032104
2105 request_.method = "POST";
rchcd379012017-04-12 21:53:322106 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122107 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:032108 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202109 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:032110
Ali Beyada0b1a1c2022-04-08 20:08:142111 stream_->RegisterRequest(&request_);
2112 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262113 net_log_with_source_,
2114 callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:252115 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:032116 stream_->SendRequest(headers_, &response_, callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:252117
2118 size_t chunk_size = strlen(kUploadData);
2119 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
2120 // Error does not surface yet since packet write is triggered by a packet
2121 // flusher that tries to bundle request body writes.
2122 ASSERT_EQ(OK, callback_.WaitForResult());
2123 // Error will be surfaced once an attempt to read the response occurs.
2124 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
2125 stream_->ReadResponseHeaders(callback_.callback()));
2126
2127 EXPECT_LE(0, stream_->GetTotalSentBytes());
2128 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2129}
2130
2131TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBundledBodyComplete) {
2132 SetRequest("POST", "/", DEFAULT_PRIORITY);
2133 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:232134 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:252135 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232136 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:432137 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harperc6cb7a612020-02-24 20:03:322138 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:412139 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:232140 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
2141 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
2142 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:412143 } else {
2144 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:232145 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
2146 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
2147 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:412148 }
2149
Yixin Wange7ecc472018-03-06 19:00:252150 AddWrite(SYNCHRONOUS, ERR_FAILED);
2151 Initialize();
2152
2153 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
2154 auto* chunked_upload_stream =
2155 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
2156
2157 request_.method = "POST";
2158 request_.url = GURL("https://www.example.org/");
2159 request_.upload_data_stream = upload_data_stream_.get();
2160
2161 size_t chunk_size = strlen(kUploadData);
2162 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
2163
2164 ASSERT_EQ(OK, request_.upload_data_stream->Init(
2165 TestCompletionCallback().callback(), NetLogWithSource()));
2166
Ali Beyada0b1a1c2022-04-08 20:08:142167 stream_->RegisterRequest(&request_);
2168 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262169 net_log_with_source_,
2170 callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:252171 ASSERT_EQ(ERR_IO_PENDING,
2172 stream_->SendRequest(headers_, &response_, callback_.callback()));
2173
2174 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
2175
2176 // Error does not surface yet since packet write is triggered by a packet
2177 // flusher that tries to bundle request body writes.
2178 ASSERT_EQ(OK, callback_.WaitForResult());
2179 // Error will be surfaced once an attempt to read the response occurs.
2180 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
2181 stream_->ReadResponseHeaders(callback_.callback()));
2182
2183 EXPECT_LE(0, stream_->GetTotalSentBytes());
2184 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:032185}
2186
ckrasic3865ee0f2016-02-29 22:04:562187TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
2188 SetRequest("GET", "/", DEFAULT_PRIORITY);
2189 Initialize();
2190
Bin Wue8408792021-08-24 23:25:162191 // Server push is not supported in HTTP/3.
2192 if (version_.UsesHttp3())
2193 return;
2194
ckrasic3865ee0f2016-02-29 22:04:562195 // Initialize the first stream, for receiving the promise on.
2196 request_.method = "GET";
rchcd379012017-04-12 21:53:322197 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562198
Ali Beyada0b1a1c2022-04-08 20:08:142199 stream_->RegisterRequest(&request_);
2200 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262201 net_log_with_source_,
2202 callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232203 ASSERT_EQ(OK,
2204 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562205
2206 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2207 // packet, but does it matter?
2208 ReceivePromise(promise_id_);
2209 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2210
2211 request_.url = GURL(promise_url_);
2212
2213 // Make the second stream that will exercise the first step of the
2214 // server push rendezvous mechanism.
Ali Beyada0b1a1c2022-04-08 20:08:142215 promised_stream_->RegisterRequest(&request_);
2216 EXPECT_EQ(OK, promised_stream_->InitializeStream(true, DEFAULT_PRIORITY,
2217 net_log_with_source_,
2218 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562219
2220 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252221 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562222 size_t spdy_response_headers_frame_length;
2223 ProcessPacket(InnerConstructResponseHeadersPacket(
2224 1, promise_id_, false, &spdy_response_headers_frame_length));
2225
2226 // Receive the promised response body.
2227 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432228 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172229 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2230 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562231
2232 // Now sending a matching request will have successful rendezvous
2233 // with the promised stream.
Ryan Hamiltona1d1f4a2019-06-26 14:43:042234 ASSERT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
ckrasic3865ee0f2016-02-29 22:04:562235 callback_.callback()));
2236
2237 EXPECT_EQ(
2238 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2239 ->id(),
2240 promise_id_);
2241
2242 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:012243 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2244 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562245
2246 // As will be the body.
2247 EXPECT_EQ(
2248 static_cast<int>(strlen(kResponseBody)),
2249 promised_stream_->ReadResponseBody(
2250 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2251 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2252 EXPECT_TRUE(AtEof());
2253
ckrasic3865ee0f2016-02-29 22:04:562254 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2255 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412256 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562257 promised_stream_->GetTotalReceivedBytes());
2258}
2259
2260TEST_P(QuicHttpStreamTest, ServerPushGetRequestSlowResponse) {
2261 SetRequest("GET", "/", DEFAULT_PRIORITY);
2262 Initialize();
2263
Bin Wue8408792021-08-24 23:25:162264 // Server push is not supported in HTTP/3.
2265 if (version_.UsesHttp3())
2266 return;
2267
ckrasic3865ee0f2016-02-29 22:04:562268 // Initialize the first stream, for receiving the promise on.
2269 request_.method = "GET";
rchcd379012017-04-12 21:53:322270 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562271
Ali Beyada0b1a1c2022-04-08 20:08:142272 stream_->RegisterRequest(&request_);
2273 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262274 net_log_with_source_,
2275 callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232276 ASSERT_EQ(OK,
2277 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562278
2279 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2280 // packet, but does it matter?
2281 ReceivePromise(promise_id_);
2282 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2283
2284 request_.url = GURL(promise_url_);
2285
2286 // Make the second stream that will exercise the first step of the
2287 // server push rendezvous mechanism.
Ali Beyada0b1a1c2022-04-08 20:08:142288 promised_stream_->RegisterRequest(&request_);
2289 EXPECT_EQ(OK, promised_stream_->InitializeStream(true, DEFAULT_PRIORITY,
2290 net_log_with_source_,
2291 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562292
2293 // Now sending a matching request will rendezvous with the promised
2294 // stream, but pending secondary validation.
2295 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2296 headers_, &response_, callback_.callback()));
2297
2298 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252299 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562300 size_t spdy_response_headers_frame_length;
2301 ProcessPacket(InnerConstructResponseHeadersPacket(
2302 1, promise_id_, false, &spdy_response_headers_frame_length));
2303
2304 // Receive the promised response body.
2305 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432306 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172307 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2308 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562309
fdoray92e35a72016-06-10 15:54:552310 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562311
2312 // Rendezvous should have succeeded now, so the promised stream
2313 // should point at our push stream, and we should be able read
2314 // headers and data from it.
robpercival214763f2016-07-01 23:27:012315 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562316
2317 EXPECT_EQ(
2318 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2319 ->id(),
2320 promise_id_);
2321
robpercival214763f2016-07-01 23:27:012322 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2323 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562324
2325 EXPECT_EQ(
2326 static_cast<int>(strlen(kResponseBody)),
2327 promised_stream_->ReadResponseBody(
2328 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2329
2330 // Callback should return
2331 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2332 EXPECT_TRUE(AtEof());
2333
ckrasic3865ee0f2016-02-29 22:04:562334 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2335 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412336 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562337 promised_stream_->GetTotalReceivedBytes());
2338}
2339
ckrasic2c63f9b2016-08-16 23:54:072340// Verify fix for crbug.com/637349
2341TEST_P(QuicHttpStreamTest, ServerPushCancelHttpStreamBeforeResponse) {
2342 SetRequest("GET", "/", DEFAULT_PRIORITY);
2343 Initialize();
2344
Bin Wue8408792021-08-24 23:25:162345 // Server push is not supported in HTTP/3.
2346 if (version_.UsesHttp3())
2347 return;
2348
ckrasic2c63f9b2016-08-16 23:54:072349 // Initialize the first stream, for receiving the promise on.
2350 request_.method = "GET";
rchcd379012017-04-12 21:53:322351 request_.url = GURL("https://www.example.org/");
ckrasic2c63f9b2016-08-16 23:54:072352
Ali Beyada0b1a1c2022-04-08 20:08:142353 stream_->RegisterRequest(&request_);
2354 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262355 net_log_with_source_,
2356 callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232357 ASSERT_EQ(OK,
2358 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic2c63f9b2016-08-16 23:54:072359
2360 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2361 // packet, but does it matter?
2362 ReceivePromise(promise_id_);
2363 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2364
2365 request_.url = GURL(promise_url_);
2366
2367 // Make the second stream that will exercise the first step of the
2368 // server push rendezvous mechanism.
Ali Beyada0b1a1c2022-04-08 20:08:142369 promised_stream_->RegisterRequest(&request_);
2370 EXPECT_EQ(OK, promised_stream_->InitializeStream(true, DEFAULT_PRIORITY,
2371 net_log_with_source_,
2372 callback_.callback()));
ckrasic2c63f9b2016-08-16 23:54:072373
2374 // Now sending a matching request will rendezvous with the promised
2375 // stream, but pending secondary validation.
2376 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2377 headers_, &response_, callback_.callback()));
2378
2379 base::RunLoop().RunUntilIdle();
2380
2381 // Cause of FinalValidation() crash as per bug.
2382 promised_stream_.reset();
2383
2384 // Receive the promised response headers.
2385 response_headers_ = promised_response_.Clone();
2386 size_t spdy_response_headers_frame_length;
2387 ProcessPacket(InnerConstructResponseHeadersPacket(
2388 1, promise_id_, false, &spdy_response_headers_frame_length));
2389}
2390
ckrasic3865ee0f2016-02-29 22:04:562391TEST_P(QuicHttpStreamTest, ServerPushCrossOriginOK) {
2392 SetRequest("GET", "/", DEFAULT_PRIORITY);
2393 Initialize();
2394
Bin Wue8408792021-08-24 23:25:162395 // Server push is not supported in HTTP/3.
2396 if (version_.UsesHttp3())
2397 return;
2398
ckrasic3865ee0f2016-02-29 22:04:562399 // Initialize the first stream, for receiving the promise on.
2400 request_.method = "GET";
rchcd379012017-04-12 21:53:322401 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562402
Ali Beyada0b1a1c2022-04-08 20:08:142403 stream_->RegisterRequest(&request_);
2404 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262405 net_log_with_source_,
2406 callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232407 ASSERT_EQ(OK,
2408 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562409
2410 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2411 // packet, but does it matter?
2412
2413 push_promise_[":authority"] = "mail.example.org";
David Schinazi3f7465c2019-07-12 01:57:052414 promise_url_ =
2415 quic::SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562416
2417 ReceivePromise(promise_id_);
2418 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2419
2420 request_.url = GURL(promise_url_);
2421
2422 // Make the second stream that will exercise the first step of the
2423 // server push rendezvous mechanism.
Ali Beyada0b1a1c2022-04-08 20:08:142424 promised_stream_->RegisterRequest(&request_);
2425 EXPECT_EQ(OK, promised_stream_->InitializeStream(true, DEFAULT_PRIORITY,
2426 net_log_with_source_,
2427 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562428
2429 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252430 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562431 size_t spdy_response_headers_frame_length;
2432 ProcessPacket(InnerConstructResponseHeadersPacket(
2433 1, promise_id_, false, &spdy_response_headers_frame_length));
2434
2435 // Receive the promised response body.
2436 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432437 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172438 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2439 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562440
2441 // Now sending a matching request will have successful rendezvous
2442 // with the promised stream.
2443 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
2444 callback_.callback()));
2445
2446 EXPECT_EQ(
2447 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2448 ->id(),
2449 promise_id_);
2450
2451 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:012452 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2453 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562454
2455 // As will be the body.
2456 EXPECT_EQ(
2457 static_cast<int>(strlen(kResponseBody)),
2458 promised_stream_->ReadResponseBody(
2459 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2460 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2461 EXPECT_TRUE(AtEof());
2462
ckrasic3865ee0f2016-02-29 22:04:562463 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2464 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412465 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562466 promised_stream_->GetTotalReceivedBytes());
2467}
2468
2469TEST_P(QuicHttpStreamTest, ServerPushCrossOriginFail) {
2470 SetRequest("GET", "/", DEFAULT_PRIORITY);
2471 Initialize();
2472
Bin Wue8408792021-08-24 23:25:162473 // Server push is not supported in HTTP/3.
2474 if (version_.UsesHttp3())
2475 return;
2476
ckrasic3865ee0f2016-02-29 22:04:562477 // Initialize the first stream, for receiving the promise on.
2478 request_.method = "GET";
rchcd379012017-04-12 21:53:322479 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562480
Ali Beyada0b1a1c2022-04-08 20:08:142481 stream_->RegisterRequest(&request_);
2482 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262483 net_log_with_source_,
2484 callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232485 ASSERT_EQ(OK,
2486 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562487
2488 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2489 // packet, but does it matter?
2490 push_promise_[":authority"] = "www.notexample.org";
David Schinazi3f7465c2019-07-12 01:57:052491 promise_url_ =
2492 quic::SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562493
2494 ReceivePromise(promise_id_);
2495 // The promise will have been rejected because the cert doesn't
2496 // match.
2497 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2498}
2499
2500TEST_P(QuicHttpStreamTest, ServerPushVaryCheckOK) {
2501 SetRequest("GET", "/", DEFAULT_PRIORITY);
2502 Initialize();
2503
Bin Wue8408792021-08-24 23:25:162504 // Server push is not supported in HTTP/3.
2505 if (version_.UsesHttp3())
2506 return;
2507
ckrasic3865ee0f2016-02-29 22:04:562508 // Initialize the first stream, for receiving the promise on.
2509 request_.method = "GET";
rchcd379012017-04-12 21:53:322510 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562511
Ali Beyada0b1a1c2022-04-08 20:08:142512 stream_->RegisterRequest(&request_);
2513 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262514 net_log_with_source_,
2515 callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232516 ASSERT_EQ(OK,
2517 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562518
2519 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562520
2521 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2522 // packet, but does it matter?
2523 ReceivePromise(promise_id_);
2524 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2525
2526 request_.url = GURL(promise_url_);
2527
2528 // Make the second stream that will exercise the first step of the
2529 // server push rendezvous mechanism.
Ali Beyada0b1a1c2022-04-08 20:08:142530 promised_stream_->RegisterRequest(&request_);
2531 EXPECT_EQ(OK, promised_stream_->InitializeStream(true, DEFAULT_PRIORITY,
2532 net_log_with_source_,
2533 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562534
2535 headers_.SetHeader("accept-encoding", "gzip");
2536
2537 // Now sending a matching request will rendezvous with the promised
2538 // stream, but pending secondary validation.
2539 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2540 headers_, &response_, callback_.callback()));
2541
2542 // Receive the promised response headers.
2543 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252544 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562545 size_t spdy_response_headers_frame_length;
2546 ProcessPacket(InnerConstructResponseHeadersPacket(
2547 1, promise_id_, false, &spdy_response_headers_frame_length));
2548
2549 // Receive the promised response body.
2550 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432551 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172552 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2553 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562554
fdoray92e35a72016-06-10 15:54:552555 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562556
2557 // Rendezvous should have succeeded now, so the promised stream
2558 // should point at our push stream, and we should be able read
2559 // headers and data from it.
robpercival214763f2016-07-01 23:27:012560 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562561
2562 EXPECT_EQ(
2563 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2564 ->id(),
2565 promise_id_);
2566
robpercival214763f2016-07-01 23:27:012567 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2568 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562569
2570 EXPECT_EQ(
2571 static_cast<int>(strlen(kResponseBody)),
2572 promised_stream_->ReadResponseBody(
2573 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2574
2575 // Callback should return
2576 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2577 EXPECT_TRUE(AtEof());
2578
ckrasic3865ee0f2016-02-29 22:04:562579 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2580 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412581 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562582 promised_stream_->GetTotalReceivedBytes());
2583}
2584
2585TEST_P(QuicHttpStreamTest, ServerPushVaryCheckFail) {
2586 SetRequest("GET", "/", DEFAULT_PRIORITY);
2587 request_headers_[":scheme"] = "https";
2588 request_headers_[":path"] = "/bar";
2589 request_headers_["accept-encoding"] = "sdch";
2590
ckrasic3865ee0f2016-02-29 22:04:562591 Initialize();
2592
Bin Wue8408792021-08-24 23:25:162593 // Server push is not supported in HTTP/3.
2594 if (version_.UsesHttp3())
2595 return;
2596
ckrasic3865ee0f2016-02-29 22:04:562597 // Initialize the first stream, for receiving the promise on.
2598 request_.method = "GET";
rchcd379012017-04-12 21:53:322599 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562600
Ali Beyada0b1a1c2022-04-08 20:08:142601 stream_->RegisterRequest(&request_);
2602 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262603 net_log_with_source_,
2604 callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232605 ASSERT_EQ(OK,
2606 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562607
2608 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562609
2610 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2611 // packet, but does it matter?
2612 ReceivePromise(promise_id_);
2613 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2614
2615 request_.url = GURL(promise_url_);
2616
2617 // Make the second stream that will exercise the first step of the
2618 // server push rendezvous mechanism.
Ali Beyada0b1a1c2022-04-08 20:08:142619 promised_stream_->RegisterRequest(&request_);
2620 EXPECT_EQ(OK, promised_stream_->InitializeStream(true, DEFAULT_PRIORITY,
2621 net_log_with_source_,
2622 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562623
2624 headers_.SetHeader("accept-encoding", "sdch");
2625
2626 // Now sending a matching request will rendezvous with the promised
2627 // stream, but pending secondary validation.
2628 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2629 headers_, &response_, callback_.callback()));
2630
2631 // Receive the promised response headers.
2632 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252633 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562634 size_t spdy_response_headers_frame_length;
2635 ProcessPacket(InnerConstructResponseHeadersPacket(
2636 1, promise_id_, false, &spdy_response_headers_frame_length));
2637
fdoray92e35a72016-06-10 15:54:552638 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562639
2640 // Rendezvous should have failed due to vary mismatch, so the
2641 // promised stream should have been aborted, and instead we have a
2642 // new, regular client initiated stream.
robpercival214763f2016-07-01 23:27:012643 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562644
2645 // Not a server-initiated stream.
2646 EXPECT_NE(
2647 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2648 ->id(),
2649 promise_id_);
2650
2651 // Instead, a new client-initiated stream.
2652 EXPECT_EQ(
2653 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2654 ->id(),
Nick Harper23290b82019-05-02 00:02:562655 stream_id_ + quic::QuicUtils::StreamIdDelta(version_.transport_version));
ckrasic3865ee0f2016-02-29 22:04:562656
2657 // After rendezvous failure, the push stream has been cancelled.
2658 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2659
2660 // The rest of the test verifies that the retried as
2661 // client-initiated version of |promised_stream_| works as intended.
2662
2663 // Ack the request.
Renjie90e808e2019-01-24 07:24:042664 ProcessPacket(ConstructServerAckPacket(2, 1, 1, 1));
ckrasic3865ee0f2016-02-29 22:04:562665
Kenichi Ishibashif8634ab2021-03-16 23:41:282666 SetResponse("404", string());
ckrasic3865ee0f2016-02-29 22:04:562667 size_t spdy_response_header_frame_length;
2668 ProcessPacket(InnerConstructResponseHeadersPacket(
Nick Harper23290b82019-05-02 00:02:562669 3,
2670 stream_id_ + quic::QuicUtils::StreamIdDelta(version_.transport_version),
2671 kFin, &spdy_response_header_frame_length));
ckrasic3865ee0f2016-02-29 22:04:562672
fdoray92e35a72016-06-10 15:54:552673 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562674
robpercival214763f2016-07-01 23:27:012675 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2676 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562677 ASSERT_TRUE(response_.headers.get());
2678 EXPECT_EQ(404, response_.headers->response_code());
2679 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
2680 EXPECT_FALSE(response_.response_time.is_null());
2681 EXPECT_FALSE(response_.request_time.is_null());
2682
2683 // There is no body, so this should return immediately.
2684 EXPECT_EQ(
2685 0, promised_stream_->ReadResponseBody(
2686 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2687 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2688
2689 stream_->Close(true);
2690
2691 EXPECT_TRUE(AtEof());
ckrasic3865ee0f2016-02-29 22:04:562692}
2693
maksim.sisov84e20c92016-06-23 08:49:342694TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
2695 SetRequest("POST", "/", DEFAULT_PRIORITY);
2696 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:232697 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:252698 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232699 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Yixin Wange7ecc472018-03-06 19:00:252700 AddWrite(ConstructRequestAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:232701 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
2702 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
2703 &spdy_request_headers_frame_length, quic::QUIC_ERROR_PROCESSING_STREAM));
maksim.sisov84e20c92016-06-23 08:49:342704
2705 Initialize();
2706
Jeremy Roman0579ed62017-08-29 15:56:192707 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342708 ReadErrorUploadDataStream::FailureMode::SYNC);
2709 request_.method = "POST";
rchcd379012017-04-12 21:53:322710 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122711 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342712 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202713 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342714
Ali Beyada0b1a1c2022-04-08 20:08:142715 stream_->RegisterRequest(&request_);
2716 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262717 net_log_with_source_,
2718 callback_.callback()));
maksim.sisov84e20c92016-06-23 08:49:342719
2720 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
robpercival214763f2016-07-01 23:27:012721 EXPECT_THAT(result, IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342722
2723 EXPECT_TRUE(AtEof());
2724
2725 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2726 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2727 stream_->GetTotalSentBytes());
2728 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2729}
2730
2731TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
2732 SetRequest("POST", "/", DEFAULT_PRIORITY);
2733 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:232734 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:252735 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232736 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:372737 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:232738 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
2739 kIncludeVersion, !kFin, DEFAULT_PRIORITY,
2740 &spdy_request_headers_frame_length));
2741 AddWrite(
2742 ConstructClientRstStreamErrorPacket(packet_number++, !kIncludeVersion));
maksim.sisov84e20c92016-06-23 08:49:342743
2744 Initialize();
2745
Jeremy Roman0579ed62017-08-29 15:56:192746 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342747 ReadErrorUploadDataStream::FailureMode::ASYNC);
2748 request_.method = "POST";
rchcd379012017-04-12 21:53:322749 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122750 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342751 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202752 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342753
Ali Beyada0b1a1c2022-04-08 20:08:142754 stream_->RegisterRequest(&request_);
2755 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262756 net_log_with_source_,
2757 callback_.callback()));
maksim.sisov84e20c92016-06-23 08:49:342758
2759 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2760
Renjie90e808e2019-01-24 07:24:042761 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
Kenichi Ishibashif8634ab2021-03-16 23:41:282762 SetResponse("200", string());
maksim.sisov84e20c92016-06-23 08:49:342763
robpercival214763f2016-07-01 23:27:012764 EXPECT_THAT(result, IsError(ERR_IO_PENDING));
2765 EXPECT_THAT(callback_.GetResult(result), IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342766
2767 EXPECT_TRUE(AtEof());
2768
2769 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2770 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2771 stream_->GetTotalSentBytes());
2772 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2773}
2774
Bence Béky97ec688c2021-03-16 13:48:502775TEST_P(QuicHttpStreamTest, GetAcceptChViaAlps) {
2776 AddWrite(ConstructInitialSettingsPacket());
2777 Initialize();
2778
2779 if (!VersionUsesHttp3(version_.transport_version)) {
2780 // ALPS is only implemented for HTTP/3.
2781 return;
2782 }
2783
2784 base::HistogramTester histogram_tester;
2785
2786 session_->OnAcceptChFrameReceivedViaAlps(
Bence Béky41a34f02021-05-07 00:27:482787 {{{"https://www.example.org", "Sec-CH-UA-Platform"}}});
Bence Béky97ec688c2021-03-16 13:48:502788
2789 request_.method = "GET";
2790 request_.url = GURL("https://www.example.org/foo");
2791
Ali Beyada0b1a1c2022-04-08 20:08:142792 stream_->RegisterRequest(&request_);
2793 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
Matt Reichhoff0049a0b72021-10-20 20:44:262794 net_log_with_source_,
2795 callback_.callback()));
Bence Béky41a34f02021-05-07 00:27:482796 EXPECT_EQ("Sec-CH-UA-Platform", stream_->GetAcceptChViaAlps());
Bence Béky97ec688c2021-03-16 13:48:502797 EXPECT_TRUE(AtEof());
2798
2799 histogram_tester.ExpectBucketCount(
2800 "Net.QuicSession.AcceptChFrameReceivedViaAlps", 1, 1);
2801 histogram_tester.ExpectTotalCount(
2802 "Net.QuicSession.AcceptChFrameReceivedViaAlps", 1);
2803 histogram_tester.ExpectBucketCount("Net.QuicSession.AcceptChForOrigin", 1, 1);
2804 histogram_tester.ExpectTotalCount("Net.QuicSession.AcceptChForOrigin", 1);
2805}
2806
[email protected]f702d572012-12-04 15:56:202807} // namespace test
[email protected]f702d572012-12-04 15:56:202808} // namespace net