blob: 09b17f652664636d35c3c6bc3440e4699df573d7 [file] [log] [blame]
[email protected]f702d572012-12-04 15:56:201// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ryan Hamiltona3ee93a72018-08-01 22:03:085#include "net/quic/quic_http_stream.h"
[email protected]f702d572012-12-04 15:56:206
sclittle1edeeb22015-09-02 20:46:107#include <stdint.h>
8
danakjad1777e2016-04-16 00:56:429#include <memory>
bnc086b39e12016-06-24 13:05:2610#include <utility>
[email protected]f702d572012-12-04 15:56:2011
Sebastien Marchand6d0558fd2019-01-25 16:49:3712#include "base/bind.h"
danakjad1777e2016-04-16 00:56:4213#include "base/memory/ptr_util.h"
fdoray92e35a72016-06-10 15:54:5514#include "base/run_loop.h"
Avi Drissman4365a4782018-12-28 19:26:2415#include "base/stl_util.h"
xunjieli188bd402016-03-12 00:17:2516#include "base/strings/string_number_conversions.h"
gabf767595f2016-05-11 18:50:3517#include "base/threading/thread_task_runner_handle.h"
Zhongyi Shic16b4102019-02-12 00:37:4018#include "base/time/default_tick_clock.h"
xunjieli84adaab2016-09-20 01:12:2819#include "base/time/time.h"
mmenkecbc2b712014-10-09 20:29:0720#include "net/base/chunked_upload_data_stream.h"
21#include "net/base/elements_upload_data_stream.h"
David Benjamin0288768a2019-07-22 15:00:2622#include "net/base/load_flags.h"
xunjieli84adaab2016-09-20 01:12:2823#include "net/base/load_timing_info.h"
24#include "net/base/load_timing_info_test_util.h"
[email protected]f702d572012-12-04 15:56:2025#include "net/base/net_errors.h"
26#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0627#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2028#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1529#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0030#include "net/log/net_log_event_type.h"
xunjieli5fafe142016-03-23 23:32:5431#include "net/log/test_net_log.h"
32#include "net/log/test_net_log_util.h"
Victor Vasiliev4f6fb892019-05-31 16:58:3133#include "net/quic/address_utils.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0834#include "net/quic/crypto/proof_verifier_chromium.h"
35#include "net/quic/mock_crypto_client_stream_factory.h"
Ryan Hamiltona1d1f4a2019-06-26 14:43:0436#include "net/quic/platform/impl/quic_test_impl.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0837#include "net/quic/quic_chromium_alarm_factory.h"
38#include "net/quic/quic_chromium_connection_helper.h"
39#include "net/quic/quic_chromium_packet_reader.h"
40#include "net/quic/quic_chromium_packet_writer.h"
Matt Menkefca05b62019-09-20 23:15:5641#include "net/quic/quic_crypto_client_config_handle.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0842#include "net/quic/quic_http_utils.h"
43#include "net/quic/quic_server_info.h"
44#include "net/quic/quic_stream_factory.h"
45#include "net/quic/quic_test_packet_maker.h"
Ryan Hamilton0d65a8c2019-06-07 00:46:0246#include "net/quic/quic_test_packet_printer.h"
Matt Menkefca05b62019-09-20 23:15:5647#include "net/quic/test_quic_crypto_client_config_handle.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0848#include "net/quic/test_task_runner.h"
tbansalca83c002016-04-28 20:56:2849#include "net/socket/socket_performance_watcher.h"
[email protected]f702d572012-12-04 15:56:2050#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5851#include "net/spdy/spdy_http_utils.h"
rch03b7a202016-02-05 00:54:2052#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0153#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4354#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4055#include "net/test/test_with_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5156#include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h"
57#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
58#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
59#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
David Schinazi3f7465c2019-07-12 01:57:0560#include "net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5161#include "net/third_party/quiche/src/quic/core/quic_connection.h"
62#include "net/third_party/quiche/src/quic/core/quic_utils.h"
63#include "net/third_party/quiche/src/quic/core/quic_write_blocked_list.h"
Ryan Hamiltona1d1f4a2019-06-26 14:43:0464#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
65#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5166#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
67#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
68#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
69#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
70#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
71#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
72#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1473#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
74#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
75#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
Ramin Halavati683bcaa92018-02-14 08:42:3976#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]f702d572012-12-04 15:56:2077#include "testing/gmock/include/gmock/gmock.h"
78#include "testing/gtest/include/gtest/gtest.h"
79
bnc614a92d32016-04-04 13:56:0780using std::string;
[email protected]f702d572012-12-04 15:56:2081using testing::_;
[email protected]06ff5152013-08-29 01:03:0582using testing::AnyNumber;
83using testing::Return;
[email protected]f702d572012-12-04 15:56:2084
85namespace net {
[email protected]f702d572012-12-04 15:56:2086namespace test {
[email protected]f702d572012-12-04 15:56:2087namespace {
88
[email protected]16ba7742014-08-22 00:57:2589const char kUploadData[] = "Really nifty data!";
rch9ae5b3b2016-02-11 00:36:2990const char kDefaultServerHostName[] = "www.example.org";
rchcd379012017-04-12 21:53:3291const uint16_t kDefaultServerPort = 443;
[email protected]f702d572012-12-04 15:56:2092
David Schinazi09e9a6012019-10-03 17:37:5793struct TestParams {
94 quic::ParsedQuicVersion version;
95 bool client_headers_include_h2_stream_dependency;
96};
97
98// Used by ::testing::PrintToStringParamName().
99std::string PrintToString(const TestParams& p) {
100 return quic::QuicStrCat(
101 ParsedQuicVersionToString(p.version), "_",
102 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
103 "Dependency");
104}
105
106std::vector<TestParams> GetTestParams() {
107 std::vector<TestParams> params;
108 quic::ParsedQuicVersionVector all_supported_versions =
109 quic::AllSupportedVersions();
110 for (const auto& version : all_supported_versions) {
111 params.push_back(TestParams{version, false});
112 params.push_back(TestParams{version, true});
113 }
114 return params;
115}
116
Ryan Hamilton8d9ee76e2018-05-29 23:52:52117class TestQuicConnection : public quic::QuicConnection {
[email protected]f702d572012-12-04 15:56:20118 public:
Ryan Hamilton8d9ee76e2018-05-29 23:52:52119 TestQuicConnection(const quic::ParsedQuicVersionVector& versions,
120 quic::QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:20121 IPEndPoint address,
rch12fef552016-01-15 16:26:31122 QuicChromiumConnectionHelper* helper,
rch16c74d1d2016-04-22 06:14:07123 QuicChromiumAlarmFactory* alarm_factory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52124 quic::QuicPacketWriter* writer)
Victor Vasiliev4f6fb892019-05-31 16:58:31125 : quic::QuicConnection(connection_id,
126 ToQuicSocketAddress(address),
127 helper,
128 alarm_factory,
129 writer,
130 true /* owns_writer */,
131 quic::Perspective::IS_CLIENT,
132 versions) {}
[email protected]f702d572012-12-04 15:56:20133
Ryan Hamilton8d9ee76e2018-05-29 23:52:52134 void SetSendAlgorithm(quic::SendAlgorithmInterface* send_algorithm) {
135 quic::test::QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:20136 }
137};
138
maksim.sisov84e20c92016-06-23 08:49:34139// UploadDataStream that always returns errors on data read.
140class ReadErrorUploadDataStream : public UploadDataStream {
141 public:
142 enum class FailureMode { SYNC, ASYNC };
143
144 explicit ReadErrorUploadDataStream(FailureMode mode)
Jeremy Romand54000b22019-07-08 18:40:16145 : UploadDataStream(true, 0), async_(mode) {}
maksim.sisov84e20c92016-06-23 08:49:34146 ~ReadErrorUploadDataStream() override {}
147
148 private:
149 void CompleteRead() { UploadDataStream::OnReadCompleted(ERR_FAILED); }
150
151 // UploadDataStream implementation:
tfarina42834112016-09-22 13:38:20152 int InitInternal(const NetLogWithSource& net_log) override { return OK; }
maksim.sisov84e20c92016-06-23 08:49:34153
154 int ReadInternal(IOBuffer* buf, int buf_len) override {
155 if (async_ == FailureMode::ASYNC) {
156 base::ThreadTaskRunnerHandle::Get()->PostTask(
kylecharf4fe5172019-02-15 18:53:49157 FROM_HERE, base::BindOnce(&ReadErrorUploadDataStream::CompleteRead,
158 weak_factory_.GetWeakPtr()));
maksim.sisov84e20c92016-06-23 08:49:34159 return ERR_IO_PENDING;
160 }
161 return ERR_FAILED;
162 }
163
164 void ResetInternal() override {}
165
166 const FailureMode async_;
167
Jeremy Romand54000b22019-07-08 18:40:16168 base::WeakPtrFactory<ReadErrorUploadDataStream> weak_factory_{this};
maksim.sisov84e20c92016-06-23 08:49:34169
170 DISALLOW_COPY_AND_ASSIGN(ReadErrorUploadDataStream);
171};
172
Bence Béky8ddc2492018-06-13 01:02:04173// A helper class that will delete |stream| when the callback is invoked.
xunjieli8dff50b2016-07-22 14:19:06174class DeleteStreamCallback : public TestCompletionCallbackBase {
175 public:
Bence Béky8ddc2492018-06-13 01:02:04176 explicit DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)
177 : stream_(std::move(stream)) {}
xunjieli8dff50b2016-07-22 14:19:06178
Bence Béky8ddc2492018-06-13 01:02:04179 CompletionOnceCallback callback() {
180 return base::BindOnce(&DeleteStreamCallback::DeleteStream,
181 base::Unretained(this));
182 }
xunjieli8dff50b2016-07-22 14:19:06183
184 private:
185 void DeleteStream(int result) {
186 stream_.reset();
187 SetResult(result);
188 }
189
190 std::unique_ptr<QuicHttpStream> stream_;
xunjieli8dff50b2016-07-22 14:19:06191};
192
[email protected]f702d572012-12-04 15:56:20193} // namespace
194
[email protected]24e5bc52013-09-18 15:36:58195class QuicHttpStreamPeer {
196 public:
rch08e198572017-05-09 16:56:55197 static QuicChromiumClientStream::Handle* GetQuicChromiumClientStream(
[email protected]24e5bc52013-09-18 15:36:58198 QuicHttpStream* stream) {
rch08e198572017-05-09 16:56:55199 return stream->stream_.get();
[email protected]24e5bc52013-09-18 15:36:58200 }
201};
202
David Schinazi09e9a6012019-10-03 17:37:57203class QuicHttpStreamTest : public ::testing::TestWithParam<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05204 public WithTaskEnvironment {
rchfb47f712017-05-21 03:24:00205 public:
206 void CloseStream(QuicHttpStream* stream, int /*rv*/) { stream->Close(false); }
207
[email protected]f702d572012-12-04 15:56:20208 protected:
[email protected]1e960032013-12-20 19:00:20209 static const bool kFin = true;
210 static const bool kIncludeVersion = true;
211 static const bool kIncludeCongestionFeedback = true;
212
[email protected]f702d572012-12-04 15:56:20213 // Holds a packet to be written to the wire, and the IO mode that should
214 // be used by the mock socket when performing the write.
215 struct PacketToWrite {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52216 PacketToWrite(IoMode mode, quic::QuicReceivedPacket* packet)
rjshaded5ced072015-12-18 19:26:02217 : mode(mode), packet(packet) {}
rtenneti15656ae2016-01-23 03:05:03218 PacketToWrite(IoMode mode, int rv) : mode(mode), packet(nullptr), rv(rv) {}
[email protected]f702d572012-12-04 15:56:20219 IoMode mode;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52220 quic::QuicReceivedPacket* packet;
rtenneti15656ae2016-01-23 03:05:03221 int rv;
[email protected]f702d572012-12-04 15:56:20222 };
223
224 QuicHttpStreamTest()
David Schinazi09e9a6012019-10-03 17:37:57225 : version_(GetParam().version),
226 client_headers_include_h2_stream_dependency_(
227 GetParam().client_headers_include_h2_stream_dependency),
Nick Harpera598fc5f2019-06-21 08:46:50228 crypto_config_(
229 quic::test::crypto_test_utils::ProofVerifierForTesting()),
Victor Costan9c7302b2018-08-27 16:39:44230 read_buffer_(base::MakeRefCounted<IOBufferWithSize>(4096)),
Fan Yang32c5a112018-12-10 20:06:33231 promise_id_(GetNthServerInitiatedUnidirectionalStreamId(0)),
232 stream_id_(GetNthClientInitiatedBidirectionalStreamId(0)),
David Schinazic8281052019-01-24 06:14:17233 connection_id_(quic::test::TestConnectionId(2)),
Yixin Wang079ad542018-01-11 04:06:05234 client_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58235 connection_id_,
236 &clock_,
237 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52238 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05239 client_headers_include_h2_stream_dependency_),
240 server_maker_(version_,
zhongyi5dbfdd42017-06-20 05:22:15241 connection_id_,
alyssar2adf3ac2016-05-03 17:12:58242 &clock_,
243 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52244 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05245 false),
ckrasic3865ee0f2016-02-29 22:04:56246 random_generator_(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:02247 printer_(version_) {
Zhongyi Shi49f8ad2fd2019-12-13 01:20:31248 quic::QuicEnableVersion(version_);
martijn21968ea2016-02-24 18:46:20249 IPAddress ip(192, 0, 2, 33);
[email protected]f702d572012-12-04 15:56:20250 peer_addr_ = IPEndPoint(ip, 443);
251 self_addr_ = IPEndPoint(ip, 8435);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52252 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
Ramin Halavati683bcaa92018-02-14 08:42:39253 request_.traffic_annotation =
254 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f702d572012-12-04 15:56:20255 }
256
257 ~QuicHttpStreamTest() {
Renjieba55fae2018-09-20 03:05:16258 session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
259 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]f702d572012-12-04 15:56:20260 for (size_t i = 0; i < writes_.size(); i++) {
261 delete writes_[i].packet;
262 }
263 }
264
265 // Adds a packet to the list of expected writes.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52266 void AddWrite(std::unique_ptr<quic::QuicReceivedPacket> packet) {
[email protected]1e960032013-12-20 19:00:20267 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20268 }
269
rtenneti15656ae2016-01-23 03:05:03270 void AddWrite(IoMode mode, int rv) {
271 writes_.push_back(PacketToWrite(mode, rv));
272 }
273
[email protected]f702d572012-12-04 15:56:20274 // Returns the packet to be written at position |pos|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52275 quic::QuicReceivedPacket* GetWrite(size_t pos) { return writes_[pos].packet; }
[email protected]f702d572012-12-04 15:56:20276
277 bool AtEof() {
rch37de576c2015-05-17 20:28:17278 return socket_data_->AllReadDataConsumed() &&
279 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20280 }
281
Ryan Hamilton8d9ee76e2018-05-29 23:52:52282 void ProcessPacket(std::unique_ptr<quic::QuicReceivedPacket> packet) {
Victor Vasiliev4f6fb892019-05-31 16:58:31283 connection_->ProcessUdpPacket(ToQuicSocketAddress(self_addr_),
284 ToQuicSocketAddress(peer_addr_), *packet);
[email protected]f702d572012-12-04 15:56:20285 }
286
287 // Configures the test fixture to use the list of expected writes.
288 void Initialize() {
289 mock_writes_.reset(new MockWrite[writes_.size()]);
290 for (size_t i = 0; i < writes_.size(); i++) {
rtenneti15656ae2016-01-23 03:05:03291 if (writes_[i].packet == nullptr) {
292 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
293 } else {
294 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
295 writes_[i].packet->length());
296 }
bnc614a92d32016-04-04 13:56:07297 }
[email protected]f702d572012-12-04 15:56:20298
rtennetibe635732014-10-02 22:51:42299 socket_data_.reset(new StaticSocketDataProvider(
Ryan Sleevib8d7ea02018-05-07 20:01:01300 base::span<MockRead>(),
301 base::make_span(mock_writes_.get(), writes_.size())));
Ryan Hamilton0d65a8c2019-06-07 00:46:02302 socket_data_->set_printer(&printer_);
[email protected]f702d572012-12-04 15:56:20303
danakjad1777e2016-04-16 00:56:42304 std::unique_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
xunjielib53b38c2016-03-24 15:54:36305 socket_data_.get(), net_log_.bound().net_log()));
[email protected]e13201d82012-12-12 05:00:32306 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20307 runner_ = new TestTaskRunner(&clock_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52308 send_algorithm_ = new quic::test::MockSendAlgorithm();
rch7dd15702015-07-01 18:57:57309 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
310 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
Victor Vasiliev7da08172019-10-14 06:04:25311 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:23312 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
313 .Times(testing::AtLeast(1));
314 }
Ryan Hamiltona1d1f4a2019-06-26 14:43:04315 EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
316 .Times(AnyNumber());
rtenneti44f4a2e2015-08-07 14:00:07317 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
Zhongyi Shica576df2019-04-12 17:43:40318 .WillRepeatedly(Return(quic::kMaxOutgoingPacketSize));
jokulik0e0a00c32016-06-13 21:51:58319 EXPECT_CALL(*send_algorithm_, PacingRate(_))
Ryan Hamilton8d9ee76e2018-05-29 23:52:52320 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Michael Warres74ee3ce2017-10-09 15:26:37321 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
rtenneti44f4a2e2015-08-07 14:00:07322 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52323 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40324 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
rch08cae032017-03-29 00:59:15325 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
rch0d5bcf62017-05-24 22:48:45326 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
327 .Times(AnyNumber());
rch16c74d1d2016-04-22 06:14:07328 helper_.reset(
329 new QuicChromiumConnectionHelper(&clock_, &random_generator_));
330 alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
331
Michael Warres74ee3ce2017-10-09 15:26:37332 connection_ = new TestQuicConnection(
Nick Harper23290b82019-05-02 00:02:56333 quic::test::SupportedVersions(version_), connection_id_, peer_addr_,
334 helper_.get(), alarm_factory_.get(),
Ryan Hamilton9edcf1a2017-11-22 05:55:17335 new QuicChromiumPacketWriter(
336 socket.get(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]f702d572012-12-04 15:56:20337 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41338 connection_->SetSendAlgorithm(send_algorithm_);
rch03b7a202016-02-05 00:54:20339
340 // Load a certificate that is valid for *.example.org
341 scoped_refptr<X509Certificate> test_cert(
342 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
343 EXPECT_TRUE(test_cert.get());
344
345 verify_details_.cert_verify_result.verified_cert = test_cert;
346 verify_details_.cert_verify_result.is_issued_by_known_root = true;
347 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
348
xunjieli84adaab2016-09-20 01:12:28349 base::TimeTicks dns_end = base::TimeTicks::Now();
350 base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);
ckrasic4f9d88d2015-07-22 22:23:16351 session_.reset(new QuicChromiumClientSession(
xunjielib53b38c2016-03-24 15:54:36352 connection_, std::move(socket),
rtenneti1cd3b162015-09-29 02:58:28353 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57354 &transport_security_state_, /*ssl_config_service=*/nullptr,
danakjad1777e2016-04-16 00:56:42355 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
Paul Jensen8e3c5d32018-02-19 17:06:33356 QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
dalyk51ab46b2019-10-15 15:14:34357 PRIVACY_MODE_DISABLED, SocketTag(),
358 NetworkIsolationKey(), false /* disable_secure_dns */),
Bence Béky1ceba552019-07-19 17:11:05359 /*require_confirmation=*/false,
360 /*max_allowed_push_id=*/0,
361 /*migrate_session_early_v2=*/false,
Zhongyi Shi757fcce2018-06-27 05:41:27362 /*migrate_session_on_network_change_v2=*/false,
363 /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shie01f2db2019-02-22 19:53:23364 quic::QuicTime::Delta::FromMilliseconds(
Ryan Sleevi2e8255b2019-07-17 21:02:21365 kDefaultRetransmittableOnWireTimeout.InMilliseconds()),
Zhongyi Shiaf38c4e42019-08-29 22:49:05366 /*migrate_idle_session=*/false, /*allow_port_migration=*/false,
367 kDefaultIdleSessionMigrationPeriod, kMaxTimeOnNonDefaultNetwork,
Zhongyi Shiee760762018-08-01 00:54:29368 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30369 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17370 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52371 quic::QuicTime::Delta::FromMilliseconds(
372 kQuicYieldAfterDurationMilliseconds),
Zhongyi Shidbce7f412019-02-01 23:16:29373 /*go_away_on_path_degrading*/ false,
Yixin Wang079ad542018-01-11 04:06:05374 client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
Matt Menkefca05b62019-09-20 23:15:56375 quic::test::DefaultQuicConfig(),
376 std::make_unique<TestQuicCryptoClientConfigHandle>(&crypto_config_),
377 "CONNECTION_UNKNOWN", dns_start, dns_end, &push_promise_index_, nullptr,
Zhongyi Shic16b4102019-02-12 00:37:40378 base::DefaultTickClock::GetInstance(),
xunjieli84adaab2016-09-20 01:12:28379 base::ThreadTaskRunnerHandle::Get().get(),
xunjieli5fafe142016-03-23 23:32:54380 /*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));
rtennetid39bd762015-06-12 01:05:52381 session_->Initialize();
xunjieli100937eb52016-09-15 20:09:37382 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57383
rch433bf5f2017-02-14 04:10:47384 session_->CryptoConnect(callback.callback());
Ryan Hamilton6c2a2a82017-12-15 02:06:28385 stream_ = std::make_unique<QuicHttpStream>(
386 session_->CreateHandle(HostPortPair("www.example.org", 443)));
387 promised_stream_ = std::make_unique<QuicHttpStream>(
388 session_->CreateHandle(HostPortPair("www.example.org", 443)));
ckrasic3865ee0f2016-02-29 22:04:56389 push_promise_[":path"] = "/bar";
390 push_promise_[":authority"] = "www.example.org";
391 push_promise_[":version"] = "HTTP/1.1";
392 push_promise_[":method"] = "GET";
393 push_promise_[":scheme"] = "https";
394
395 promised_response_[":status"] = "200 OK";
396 promised_response_[":version"] = "HTTP/1.1";
397 promised_response_["content-type"] = "text/plain";
398
David Schinazi3f7465c2019-07-12 01:57:05399 promise_url_ =
400 quic::SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
[email protected]6cca996b2013-01-25 07:43:36401 }
402
bnc614a92d32016-04-04 13:56:07403 void SetRequest(const string& method,
404 const string& path,
[email protected]1e960032013-12-20 19:00:20405 RequestPriority priority) {
rchcd379012017-04-12 21:53:32406 request_headers_ = client_maker_.GetRequestHeaders(method, "https", path);
[email protected]6cca996b2013-01-25 07:43:36407 }
408
bnc614a92d32016-04-04 13:56:07409 void SetResponse(const string& status, const string& body) {
alyssar2adf3ac2016-05-03 17:12:58410 response_headers_ = server_maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03411 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36412 }
[email protected]f702d572012-12-04 15:56:20413
Ryan Hamilton8d9ee76e2018-05-29 23:52:52414 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructDataPacket(
Fan Yangac867502019-01-28 21:10:23415 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52416 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56417 bool should_include_version,
418 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52419 quic::QuicStringPiece data,
alyssar2adf3ac2016-05-03 17:12:58420 QuicTestPacketMaker* maker) {
421 return maker->MakeDataPacket(packet_number, stream_id,
Ryan Hamilton7505eb92019-06-08 00:22:17422 should_include_version, fin, data);
ckrasic3865ee0f2016-02-29 22:04:56423 }
424
Ryan Hamilton8d9ee76e2018-05-29 23:52:52425 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23426 uint64_t packet_number,
[email protected]e8ff26842013-03-22 21:02:05427 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20428 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52429 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17430 return client_maker_.MakeDataPacket(packet_number, stream_id_,
431 should_include_version, fin, data);
alyssar2adf3ac2016-05-03 17:12:58432 }
433
Ryan Hamilton8d9ee76e2018-05-29 23:52:52434 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23435 uint64_t packet_number,
alyssar2adf3ac2016-05-03 17:12:58436 bool should_include_version,
437 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52438 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17439 return server_maker_.MakeDataPacket(packet_number, stream_id_,
440 should_include_version, fin, data);
ckrasic3865ee0f2016-02-29 22:04:56441 }
442
Ryan Hamilton8d9ee76e2018-05-29 23:52:52443 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23444 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52445 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56446 bool should_include_version,
447 bool fin,
448 RequestPriority request_priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02449 size_t* spdy_headers_frame_length) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48450 return InnerConstructRequestHeadersPacket(
451 packet_number, stream_id, should_include_version, fin, request_priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02452 0, spdy_headers_frame_length);
Yixin Wang7a3f1b8d2018-01-17 21:40:48453 }
454
Ryan Hamilton8d9ee76e2018-05-29 23:52:52455 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23456 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52457 quic::QuicStreamId stream_id,
Yixin Wang7a3f1b8d2018-01-17 21:40:48458 bool should_include_version,
459 bool fin,
460 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52461 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02462 size_t* spdy_headers_frame_length) {
Ryan Hamilton0239aac2018-05-19 00:03:13463 spdy::SpdyPriority priority =
ckrasic3865ee0f2016-02-29 22:04:56464 ConvertRequestPriorityToQuicPriority(request_priority);
alyssar2adf3ac2016-05-03 17:12:58465 return client_maker_.MakeRequestHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56466 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48467 std::move(request_headers_), parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02468 spdy_headers_frame_length);
[email protected]f702d572012-12-04 15:56:20469 }
470
Ryan Hamilton8d9ee76e2018-05-29 23:52:52471 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25472 ConstructRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23473 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52474 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25475 bool should_include_version,
476 bool fin,
477 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52478 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25479 size_t* spdy_headers_frame_length,
480 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13481 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25482 ConvertRequestPriorityToQuicPriority(request_priority);
483 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
484 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02485 std::move(request_headers_), parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25486 spdy_headers_frame_length, data_writes);
487 }
488
Ryan Hamilton8d9ee76e2018-05-29 23:52:52489 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestAndRstPacket(
Fan Yangac867502019-01-28 21:10:23490 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52491 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25492 bool should_include_version,
493 bool fin,
494 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52495 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25496 size_t* spdy_headers_frame_length,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41497 quic::QuicRstStreamErrorCode error_code) {
Ryan Hamilton0239aac2018-05-19 00:03:13498 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25499 ConvertRequestPriorityToQuicPriority(request_priority);
500 return client_maker_.MakeRequestHeadersAndRstPacket(
501 packet_number, stream_id, should_include_version, fin, priority,
502 std::move(request_headers_), parent_stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41503 spdy_headers_frame_length, error_code);
Yixin Wange7ecc472018-03-06 19:00:25504 }
505
Ryan Hamilton8d9ee76e2018-05-29 23:52:52506 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23507 uint64_t packet_number,
rtennetif4bdb542015-01-21 14:33:05508 bool fin,
sclittlec4dc1a32015-09-24 00:15:45509 RequestPriority request_priority,
510 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56511 return InnerConstructRequestHeadersPacket(
512 packet_number, stream_id_, kIncludeVersion, fin, request_priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02513 spdy_headers_frame_length);
ckrasic3865ee0f2016-02-29 22:04:56514 }
515
Ryan Hamilton8d9ee76e2018-05-29 23:52:52516 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructResponseHeadersPacket(
Fan Yangac867502019-01-28 21:10:23517 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52518 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56519 bool fin,
520 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58521 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26522 packet_number, stream_id, !kIncludeVersion, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02523 std::move(response_headers_), spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20524 }
525
Ryan Hamilton8d9ee76e2018-05-29 23:52:52526 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseHeadersPacket(
Fan Yangac867502019-01-28 21:10:23527 uint64_t packet_number,
sclittlec4dc1a32015-09-24 00:15:45528 bool fin,
529 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56530 return InnerConstructResponseHeadersPacket(packet_number, stream_id_, fin,
531 spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20532 }
533
Ryan Hamilton8d9ee76e2018-05-29 23:52:52534 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseTrailersPacket(
Fan Yangac867502019-01-28 21:10:23535 uint64_t packet_number,
xunjieli34291fe12016-03-02 13:58:38536 bool fin,
Ryan Hamilton0239aac2018-05-19 00:03:13537 spdy::SpdyHeaderBlock trailers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02538 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58539 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26540 packet_number, stream_id_, !kIncludeVersion, fin, std::move(trailers),
Ryan Hamilton0d65a8c2019-06-07 00:46:02541 spdy_headers_frame_length);
xunjieli34291fe12016-03-02 13:58:38542 }
543
Ryan Hamilton8d9ee76e2018-05-29 23:52:52544 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23545 uint64_t packet_number) {
alyssara72f5352016-10-20 12:45:16546 return client_maker_.MakeRstPacket(packet_number, true, stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52547 quic::QUIC_RST_ACKNOWLEDGEMENT);
[email protected]06ff5152013-08-29 01:03:05548 }
549
Ryan Hamilton8d9ee76e2018-05-29 23:52:52550 std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23551 ConstructClientRstStreamCancelledPacket(uint64_t packet_number) {
alyssar2adf3ac2016-05-03 17:12:58552 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52553 stream_id_, quic::QUIC_STREAM_CANCELLED);
rtenneti6bd660b2015-07-18 00:19:53554 }
555
Ryan Hamilton8d9ee76e2018-05-29 23:52:52556 std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23557 ConstructClientRstStreamVaryMismatchPacket(uint64_t packet_number) {
alyssar2adf3ac2016-05-03 17:12:58558 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52559 promise_id_,
560 quic::QUIC_PROMISE_VARY_MISMATCH);
ckrasic3865ee0f2016-02-29 22:04:56561 }
562
Fan Yang550c6282018-06-22 18:53:25563 std::unique_ptr<quic::QuicReceivedPacket>
564 ConstructClientRstStreamVaryMismatchAndRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23565 uint64_t packet_number,
Fan Yang550c6282018-06-22 18:53:25566 quic::QuicStreamId stream_id,
567 bool should_include_version,
568 bool fin,
569 RequestPriority request_priority,
570 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02571 size_t* spdy_headers_frame_length) {
Fan Yang550c6282018-06-22 18:53:25572 spdy::SpdyPriority priority =
573 ConvertRequestPriorityToQuicPriority(request_priority);
574 return client_maker_.MakeRstAndRequestHeadersPacket(
575 packet_number, should_include_version, promise_id_,
576 quic::QUIC_PROMISE_VARY_MISMATCH, stream_id, fin, priority,
577 std::move(request_headers_), parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02578 spdy_headers_frame_length);
Fan Yang550c6282018-06-22 18:53:25579 }
580
Ryan Hamilton8d9ee76e2018-05-29 23:52:52581 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23582 uint64_t packet_number,
583 uint64_t largest_received,
584 uint64_t smallest_received,
585 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58586 return client_maker_.MakeAckAndRstPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52587 packet_number, !kIncludeVersion, stream_id_,
588 quic::QUIC_STREAM_CANCELLED, largest_received, smallest_received,
589 least_unacked, !kIncludeCongestionFeedback);
xunjieli34291fe12016-03-02 13:58:38590 }
591
Ryan Hamilton8d9ee76e2018-05-29 23:52:52592 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamErrorPacket(
Fan Yangac867502019-01-28 21:10:23593 uint64_t packet_number,
maksim.sisov84e20c92016-06-23 08:49:34594 bool include_version) {
595 return client_maker_.MakeRstPacket(packet_number, include_version,
596 stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52597 quic::QUIC_ERROR_PROCESSING_STREAM);
maksim.sisov84e20c92016-06-23 08:49:34598 }
599
Ryan Hamilton8d9ee76e2018-05-29 23:52:52600 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23601 uint64_t packet_number) {
Renjie90e808e2019-01-24 07:24:04602 return ConstructAckAndRstStreamPacket(packet_number, 2, 1, 2);
[email protected]c5e1aca2014-01-30 04:03:04603 }
604
Ryan Hamilton8d9ee76e2018-05-29 23:52:52605 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckPacket(
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 client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49611 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58612 !kIncludeCongestionFeedback);
613 }
614
Ryan Hamilton8d9ee76e2018-05-29 23:52:52615 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23616 uint64_t packet_number,
617 uint64_t largest_received,
618 uint64_t smallest_received,
619 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58620 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49621 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58622 !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00623 }
624
Ryan Hamilton8d9ee76e2018-05-29 23:52:52625 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23626 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57627 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52628 quic::QuicStreamId id,
629 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02630 RequestPriority request_priority) {
Yixin Wangb470bc882018-02-15 18:43:57631 return client_maker_.MakePriorityPacket(
632 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02633 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wangb470bc882018-02-15 18:43:57634 }
635
Ryan Hamilton0d65a8c2019-06-07 00:46:02636 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket() {
637 return client_maker_.MakeInitialSettingsPacket(1);
fayang3bcb8b502016-12-07 21:44:37638 }
639
Renjie Tangaadb84b2019-08-31 01:00:23640 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
641 int packet_number) {
642 return client_maker_.MakeInitialSettingsPacket(packet_number);
643 }
644
Victor Vasiliev076657c2019-03-12 02:46:43645 std::string ConstructDataHeader(size_t body_len) {
Nick Harper23290b82019-05-02 00:02:56646 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41647 return "";
648 }
Renjief49758b2019-01-11 23:32:41649 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:57650 auto header_length =
651 quic::HttpEncoder::SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43652 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41653 }
654
Ryan Hamilton8d9ee76e2018-05-29 23:52:52655 void ReceivePromise(quic::QuicStreamId id) {
656 auto headers = quic::test::AsHeaderList(push_promise_);
rch08e198572017-05-09 16:56:55657 QuicChromiumClientStream::Handle* stream =
ckrasic3865ee0f2016-02-29 22:04:56658 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
ckrasic32b17dcd2016-10-31 06:15:35659 stream->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
660 headers);
ckrasic3865ee0f2016-02-29 22:04:56661 }
662
xunjieli84adaab2016-09-20 01:12:28663 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info,
xunjieli100937eb52016-09-15 20:09:37664 bool session_reused) {
665 EXPECT_EQ(session_reused, load_timing_info.socket_reused);
xunjieli84adaab2016-09-20 01:12:28666 if (session_reused) {
667 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
668 } else {
669 ExpectConnectTimingHasTimes(
670 load_timing_info.connect_timing,
671 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
672 }
673 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
xunjieli100937eb52016-09-15 20:09:37674 }
675
Fan Yang32c5a112018-12-10 20:06:33676 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56677 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
678 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36679 }
680
Fan Yang32c5a112018-12-10 20:06:33681 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56682 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
683 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36684 }
685
Ryan Hamiltona1d1f4a2019-06-26 14:43:04686 QuicFlagSaver saver_;
687
Nick Harper23290b82019-05-02 00:02:56688 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05689 const bool client_headers_include_h2_stream_dependency_;
690
Matt Muellerd9342e3a2019-11-26 01:41:14691 RecordingBoundTestNetLog net_log_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52692 quic::test::MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20693 scoped_refptr<TestTaskRunner> runner_;
danakjad1777e2016-04-16 00:56:42694 std::unique_ptr<MockWrite[]> mock_writes_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52695 quic::MockClock clock_;
[email protected]f702d572012-12-04 15:56:20696 TestQuicConnection* connection_;
danakjad1777e2016-04-16 00:56:42697 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
rch16c74d1d2016-04-22 06:14:07698 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52699 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
rch97827ee2017-05-24 23:49:12700 std::unique_ptr<UploadDataStream> upload_data_stream_;
danakjad1777e2016-04-16 00:56:42701 std::unique_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15702 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42703 std::unique_ptr<QuicChromiumClientSession> session_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52704 quic::QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20705 TestCompletionCallback callback_;
706 HttpRequestInfo request_;
707 HttpRequestHeaders headers_;
708 HttpResponseInfo response_;
709 scoped_refptr<IOBufferWithSize> read_buffer_;
Ryan Hamilton0239aac2018-05-19 00:03:13710 spdy::SpdyHeaderBlock request_headers_;
711 spdy::SpdyHeaderBlock response_headers_;
bnc614a92d32016-04-04 13:56:07712 string request_data_;
713 string response_data_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52714 quic::QuicClientPushPromiseIndex push_promise_index_;
[email protected]f702d572012-12-04 15:56:20715
ckrasic3865ee0f2016-02-29 22:04:56716 // For server push testing
danakjad1777e2016-04-16 00:56:42717 std::unique_ptr<QuicHttpStream> promised_stream_;
Ryan Hamilton0239aac2018-05-19 00:03:13718 spdy::SpdyHeaderBlock push_promise_;
719 spdy::SpdyHeaderBlock promised_response_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52720 const quic::QuicStreamId promise_id_;
ckrasic3865ee0f2016-02-29 22:04:56721 string promise_url_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52722 const quic::QuicStreamId stream_id_;
ckrasic3865ee0f2016-02-29 22:04:56723
Ryan Hamilton8d9ee76e2018-05-29 23:52:52724 const quic::QuicConnectionId connection_id_;
alyssar2adf3ac2016-05-03 17:12:58725 QuicTestPacketMaker client_maker_;
726 QuicTestPacketMaker server_maker_;
[email protected]f702d572012-12-04 15:56:20727 IPEndPoint self_addr_;
728 IPEndPoint peer_addr_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52729 quic::test::MockRandom random_generator_;
rch03b7a202016-02-05 00:54:20730 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05731 MockCryptoClientStreamFactory crypto_client_stream_factory_;
danakjad1777e2016-04-16 00:56:42732 std::unique_ptr<StaticSocketDataProvider> socket_data_;
Ryan Hamilton0d65a8c2019-06-07 00:46:02733 QuicPacketPrinter printer_;
[email protected]f702d572012-12-04 15:56:20734 std::vector<PacketToWrite> writes_;
735};
736
David Schinazi09e9a6012019-10-03 17:37:57737INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
738 QuicHttpStreamTest,
739 ::testing::ValuesIn(GetTestParams()),
740 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:20741
742TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44743 Initialize();
rtennetibe635732014-10-02 22:51:42744 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20745}
746
mmenkebd84c392015-09-02 14:12:34747TEST_P(QuicHttpStreamTest, CanReuseConnection) {
[email protected]ed3fc15d2013-03-08 18:37:44748 Initialize();
mmenkebd84c392015-09-02 14:12:34749 EXPECT_FALSE(stream_->CanReuseConnection());
[email protected]f702d572012-12-04 15:56:20750}
751
jri231c2972016-03-08 19:50:11752TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
Zhongyi Shibb28b1f2018-07-18 02:41:26753 request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri231c2972016-03-08 19:50:11754 Initialize();
xunjieli5fafe142016-03-23 23:32:54755 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27756 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54757 net_log_.bound(), callback_.callback()));
rch08e198572017-05-09 16:56:55758 QuicChromiumClientStream::Handle* client_stream =
jri231c2972016-03-08 19:50:11759 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
Zhongyi Shibb28b1f2018-07-18 02:41:26760 EXPECT_FALSE(client_stream->can_migrate_to_cellular_network());
jri231c2972016-03-08 19:50:11761}
762
[email protected]1e960032013-12-20 19:00:20763TEST_P(QuicHttpStreamTest, GetRequest) {
764 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45765 size_t spdy_request_header_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:23766 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25767 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:23768 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:37769 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:23770 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
771 kIncludeVersion, kFin, DEFAULT_PRIORITY,
772 &spdy_request_header_frame_length));
fayang3bcb8b502016-12-07 21:44:37773
[email protected]f702d572012-12-04 15:56:20774 Initialize();
775
776 request_.method = "GET";
rchcd379012017-04-12 21:53:32777 request_.url = GURL("https://www.example.org/");
[email protected]f702d572012-12-04 15:56:20778
xunjieli100937eb52016-09-15 20:09:37779 // Make sure getting load timing from the stream early does not crash.
780 LoadTimingInfo load_timing_info;
781 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
782
xunjieli5fafe142016-03-23 23:32:54783 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27784 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54785 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02786 EXPECT_EQ(OK,
787 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20788
789 // Ack the request.
Renjie90e808e2019-01-24 07:24:04790 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]f702d572012-12-04 15:56:20791
robpercival214763f2016-07-01 23:27:01792 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
793 IsError(ERR_IO_PENDING));
[email protected]f702d572012-12-04 15:56:20794
bnc614a92d32016-04-04 13:56:07795 SetResponse("404 Not Found", string());
sclittlec4dc1a32015-09-24 00:15:45796 size_t spdy_response_header_frame_length;
797 ProcessPacket(ConstructResponseHeadersPacket(
798 2, kFin, &spdy_response_header_frame_length));
[email protected]f702d572012-12-04 15:56:20799
800 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01801 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]cadac622013-06-11 16:46:36802 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20803 EXPECT_EQ(404, response_.headers->response_code());
804 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53805 EXPECT_FALSE(response_.response_time.is_null());
806 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20807
808 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02809 EXPECT_EQ(0,
810 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
811 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20812 EXPECT_TRUE(stream_->IsResponseBodyComplete());
813 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10814
xunjieli100937eb52016-09-15 20:09:37815 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28816 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37817
sclittle1edeeb22015-09-02 20:46:10818 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45819 // headers and payload.
820 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
821 stream_->GetTotalSentBytes());
822 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
823 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20824}
825
xunjieli100937eb52016-09-15 20:09:37826TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
827 SetRequest("GET", "/", DEFAULT_PRIORITY);
828 size_t spdy_request_header_frame_length;
829
Renjie Tangaadb84b2019-08-31 01:00:23830 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25831 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:23832 AddWrite(ConstructInitialSettingsPacket(packet_number++));
xunjieli100937eb52016-09-15 20:09:37833 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:23834 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
835 kIncludeVersion, kFin, DEFAULT_PRIORITY,
836 &spdy_request_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37837
838 // SetRequest() again for second request as |request_headers_| was moved.
839 SetRequest("GET", "/", DEFAULT_PRIORITY);
840 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:23841 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
842 kIncludeVersion, kFin, DEFAULT_PRIORITY,
843 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:02844 &spdy_request_header_frame_length));
Renjie Tangaadb84b2019-08-31 01:00:23845 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1,
846 2)); // Ack the responses.
xunjieli100937eb52016-09-15 20:09:37847
848 Initialize();
849
850 request_.method = "GET";
rchcd379012017-04-12 21:53:32851 request_.url = GURL("https://www.example.org/");
xunjieli100937eb52016-09-15 20:09:37852 // Start first request.
853 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27854 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37855 net_log_.bound(), callback_.callback()));
856 EXPECT_EQ(OK,
857 stream_->SendRequest(headers_, &response_, callback_.callback()));
858
859 // Start a second request.
Ryan Hamilton6c2a2a82017-12-15 02:06:28860 QuicHttpStream stream2(
861 session_->CreateHandle(HostPortPair("www.example.org", 443)));
xunjieli100937eb52016-09-15 20:09:37862 TestCompletionCallback callback2;
863 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27864 stream2.InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37865 net_log_.bound(), callback2.callback()));
866 EXPECT_EQ(OK,
867 stream2.SendRequest(headers_, &response_, callback2.callback()));
868
869 // Ack both requests.
Renjie90e808e2019-01-24 07:24:04870 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
xunjieli100937eb52016-09-15 20:09:37871
872 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
873 IsError(ERR_IO_PENDING));
874 size_t spdy_response_header_frame_length;
875 SetResponse("200 OK", string());
876 ProcessPacket(InnerConstructResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33877 2, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
ckrasicbf2f59c2017-05-04 23:54:36878 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37879
880 // Now that the headers have been processed, the callback will return.
881 EXPECT_THAT(callback_.WaitForResult(), IsOk());
882 EXPECT_EQ(200, response_.headers->response_code());
883
884 // There is no body, so this should return immediately.
885 EXPECT_EQ(0,
886 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
887 callback_.callback()));
888 EXPECT_TRUE(stream_->IsResponseBodyComplete());
889
890 LoadTimingInfo load_timing_info;
891 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28892 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37893
894 // SetResponse() again for second request as |response_headers_| was moved.
895 SetResponse("200 OK", string());
896 EXPECT_THAT(stream2.ReadResponseHeaders(callback2.callback()),
897 IsError(ERR_IO_PENDING));
898
899 ProcessPacket(InnerConstructResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33900 3, GetNthClientInitiatedBidirectionalStreamId(1), kFin,
ckrasicbf2f59c2017-05-04 23:54:36901 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37902
903 EXPECT_THAT(callback2.WaitForResult(), IsOk());
904
905 // There is no body, so this should return immediately.
906 EXPECT_EQ(0,
907 stream2.ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
908 callback2.callback()));
909 EXPECT_TRUE(stream2.IsResponseBodyComplete());
910
911 LoadTimingInfo load_timing_info2;
912 EXPECT_TRUE(stream2.GetLoadTimingInfo(&load_timing_info2));
xunjieli84adaab2016-09-20 01:12:28913 ExpectLoadTimingValid(load_timing_info2, /*session_reused=*/true);
xunjieli100937eb52016-09-15 20:09:37914}
915
xunjieli34291fe12016-03-02 13:58:38916// QuicHttpStream does not currently support trailers. It should ignore
917// trailers upon receiving them.
918TEST_P(QuicHttpStreamTest, GetRequestWithTrailers) {
919 SetRequest("GET", "/", DEFAULT_PRIORITY);
920 size_t spdy_request_header_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:23921 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25922 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:23923 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:37924 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:23925 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
926 kIncludeVersion, kFin, DEFAULT_PRIORITY,
927 &spdy_request_header_frame_length));
928 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1,
929 2)); // Ack the data packet.
xunjieli34291fe12016-03-02 13:58:38930
931 Initialize();
932
933 request_.method = "GET";
rchcd379012017-04-12 21:53:32934 request_.url = GURL("https://www.example.org/");
xunjieli34291fe12016-03-02 13:58:38935
xunjieli5fafe142016-03-23 23:32:54936 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27937 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54938 net_log_.bound(), callback_.callback()));
939
xunjieli34291fe12016-03-02 13:58:38940 EXPECT_EQ(OK,
941 stream_->SendRequest(headers_, &response_, callback_.callback()));
xunjieli34291fe12016-03-02 13:58:38942 // Ack the request.
Renjie90e808e2019-01-24 07:24:04943 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
xunjieli34291fe12016-03-02 13:58:38944
robpercival214763f2016-07-01 23:27:01945 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
946 IsError(ERR_IO_PENDING));
xunjieli34291fe12016-03-02 13:58:38947
bnc614a92d32016-04-04 13:56:07948 SetResponse("200 OK", string());
xunjieli34291fe12016-03-02 13:58:38949
950 // Send the response headers.
951 size_t spdy_response_header_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:02952 ProcessPacket(ConstructResponseHeadersPacket(
953 2, !kFin, &spdy_response_header_frame_length));
xunjieli34291fe12016-03-02 13:58:38954 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01955 EXPECT_THAT(callback_.WaitForResult(), IsOk());
xunjieli34291fe12016-03-02 13:58:38956 ASSERT_TRUE(response_.headers.get());
957 EXPECT_EQ(200, response_.headers->response_code());
958 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
959 EXPECT_FALSE(response_.response_time.is_null());
960 EXPECT_FALSE(response_.request_time.is_null());
961
962 // Send the response body.
963 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:43964 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:17965 ProcessPacket(
966 ConstructServerDataPacket(3, false, !kFin, header + kResponseBody));
Ryan Hamilton0239aac2018-05-19 00:03:13967 spdy::SpdyHeaderBlock trailers;
xunjieli34291fe12016-03-02 13:58:38968 size_t spdy_trailers_frame_length;
969 trailers["foo"] = "bar";
Victor Vasiliev7da08172019-10-14 06:04:25970 if (!quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltona1d1f4a2019-06-26 14:43:04971 trailers[quic::kFinalOffsetHeaderKey] =
972 base::NumberToString(strlen(kResponseBody) + header.length());
973 }
Ryan Hamilton0d65a8c2019-06-07 00:46:02974 ProcessPacket(ConstructResponseTrailersPacket(4, kFin, std::move(trailers),
975 &spdy_trailers_frame_length));
xunjieli34291fe12016-03-02 13:58:38976
977 // Make sure trailers are processed.
fdoray92e35a72016-06-10 15:54:55978 base::RunLoop().RunUntilIdle();
xunjieli34291fe12016-03-02 13:58:38979
980 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
981 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
982 callback_.callback()));
983 EXPECT_TRUE(stream_->IsResponseBodyComplete());
984
985 EXPECT_EQ(OK,
986 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
987 callback_.callback()));
988
989 EXPECT_TRUE(stream_->IsResponseBodyComplete());
990 EXPECT_TRUE(AtEof());
991
992 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
993 // headers and payload.
994 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
995 stream_->GetTotalSentBytes());
Renjief49758b2019-01-11 23:32:41996 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length +
997 strlen(kResponseBody) + header.length() +
998 +spdy_trailers_frame_length),
999 stream_->GetTotalReceivedBytes());
xunjieli5fafe142016-03-23 23:32:541000 // Check that NetLog was filled as expected.
Eric Roman79cc7552019-07-19 02:17:541001 auto entries = net_log_.GetEntries();
xunjieli5fafe142016-03-23 23:32:541002 size_t pos = ExpectLogContainsSomewhere(
1003 entries, /*min_offset=*/0,
mikecirone8b85c432016-09-08 19:11:001004 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
1005 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:541006 pos = ExpectLogContainsSomewhere(
1007 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:001008 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
1009 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:541010 ExpectLogContainsSomewhere(
1011 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:001012 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
1013 NetLogEventPhase::NONE);
xunjieli34291fe12016-03-02 13:58:381014}
1015
[email protected]3e7dca62013-09-10 16:14:231016// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:201017TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
1018 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451019 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231020 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251021 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231022 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371023 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231024 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1025 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1026 &spdy_request_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:231027 Initialize();
1028
1029 request_.method = "GET";
rchcd379012017-04-12 21:53:321030 request_.url = GURL("https://www.example.org/");
[email protected]3e7dca62013-09-10 16:14:231031
xunjieli5fafe142016-03-23 23:32:541032 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271033 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541034 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021035 EXPECT_EQ(OK,
1036 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:231037
1038 // Ack the request.
Renjie90e808e2019-01-24 07:24:041039 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]3e7dca62013-09-10 16:14:231040
robpercival214763f2016-07-01 23:27:011041 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1042 IsError(ERR_IO_PENDING));
[email protected]3e7dca62013-09-10 16:14:231043
bnc086b39e12016-06-24 13:05:261044 response_headers_[":status"] = "200 OK";
1045 response_headers_[":version"] = "HTTP/1.1";
1046 response_headers_["content-type"] = "text/plain";
1047 response_headers_["big6"] = string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:231048
sclittlec4dc1a32015-09-24 00:15:451049 size_t spdy_response_headers_frame_length;
1050 ProcessPacket(ConstructResponseHeadersPacket(
1051 2, kFin, &spdy_response_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:231052
1053 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:011054 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]3e7dca62013-09-10 16:14:231055 ASSERT_TRUE(response_.headers.get());
1056 EXPECT_EQ(200, response_.headers->response_code());
1057 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1058
1059 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:021060 EXPECT_EQ(0,
1061 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1062 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:231063 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1064 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101065
1066 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451067 // headers and payload.
1068 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1069 stream_->GetTotalSentBytes());
1070 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
1071 stream_->GetTotalReceivedBytes());
[email protected]3e7dca62013-09-10 16:14:231072}
1073
rchf9f103cbc2014-08-30 05:28:041074// Regression test for http://crbug.com/409101
1075TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
1076 SetRequest("GET", "/", DEFAULT_PRIORITY);
1077 Initialize();
1078
1079 request_.method = "GET";
rchcd379012017-04-12 21:53:321080 request_.url = GURL("https://www.example.org/");
rchf9f103cbc2014-08-30 05:28:041081
xunjieli5fafe142016-03-23 23:32:541082 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271083 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541084 net_log_.bound(), callback_.callback()));
rchf9f103cbc2014-08-30 05:28:041085
jri78ec06a2016-03-31 18:19:401086 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521087 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchf9f103cbc2014-08-30 05:28:041088
1089 EXPECT_EQ(ERR_CONNECTION_CLOSED,
rjshaded5ced072015-12-18 19:26:021090 stream_->SendRequest(headers_, &response_, callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101091
1092 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1093 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rchf9f103cbc2014-08-30 05:28:041094}
1095
rch03b7a202016-02-05 00:54:201096// Regression test for http://crbug.com/584441
1097TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
1098 SetRequest("GET", "/", DEFAULT_PRIORITY);
1099 Initialize();
1100
1101 request_.method = "GET";
rchcd379012017-04-12 21:53:321102 request_.url = GURL("https://www.example.org/");
rch03b7a202016-02-05 00:54:201103
xunjieli5fafe142016-03-23 23:32:541104 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271105 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541106 net_log_.bound(), callback_.callback()));
rch03b7a202016-02-05 00:54:201107
1108 SSLInfo ssl_info;
rch11565e02016-02-09 20:13:471109 EXPECT_FALSE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201110 stream_->GetSSLInfo(&ssl_info);
rch11565e02016-02-09 20:13:471111 EXPECT_TRUE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201112
jri78ec06a2016-03-31 18:19:401113 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521114 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch03b7a202016-02-05 00:54:201115
rch11565e02016-02-09 20:13:471116 SSLInfo ssl_info2;
1117 stream_->GetSSLInfo(&ssl_info2);
1118 EXPECT_TRUE(ssl_info2.is_valid());
rch03b7a202016-02-05 00:54:201119}
1120
rchcd379012017-04-12 21:53:321121TEST_P(QuicHttpStreamTest, GetAlternativeService) {
1122 SetRequest("GET", "/", DEFAULT_PRIORITY);
1123 Initialize();
1124
1125 request_.method = "GET";
1126 request_.url = GURL("https://www.example.org/");
1127
1128 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271129 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
rchcd379012017-04-12 21:53:321130 net_log_.bound(), callback_.callback()));
1131
1132 AlternativeService alternative_service;
1133 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service));
1134 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1135 alternative_service);
1136
1137 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521138 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchcd379012017-04-12 21:53:321139
1140 AlternativeService alternative_service2;
1141 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service2));
1142 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1143 alternative_service2);
1144}
1145
zhongyica364fbb2015-12-12 03:39:121146TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
1147 SetRequest("GET", "/", DEFAULT_PRIORITY);
1148 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231149 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251150 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231151 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371152 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231153 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1154 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1155 &spdy_request_headers_frame_length));
fayang3bcb8b502016-12-07 21:44:371156 AddWrite(ConstructAckAndRstStreamPacket(3));
zhongyica364fbb2015-12-12 03:39:121157 Initialize();
1158
1159 request_.method = "GET";
rchcd379012017-04-12 21:53:321160 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121161
xunjieli5fafe142016-03-23 23:32:541162 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271163 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541164 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121165 EXPECT_EQ(OK,
1166 stream_->SendRequest(headers_, &response_, callback_.callback()));
1167
1168 // Ack the request.
Renjie90e808e2019-01-24 07:24:041169 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011170 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1171 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121172
Ryan Hamilton8d9ee76e2018-05-29 23:52:521173 quic::QuicConnectionCloseFrame frame;
Zhongyi Shica576df2019-04-12 17:43:401174 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
Renjie Tangdb47d4c2019-08-27 18:56:231175 frame.extracted_error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551176 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121177
1178 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521179 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121180 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521181 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121182}
1183
Ryan Hamiltone316e482017-08-17 02:48:531184TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
Ryan Hamiltona1d1f4a2019-06-26 14:43:041185 // TODO(nharper): Figure out why this test does not send packets
1186 // when TLS is used.
1187 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
1188 Initialize();
1189
1190 return;
1191 }
1192
rch617e0652017-04-26 17:57:511193 // By default the test setup defaults handshake to be confirmed. Manually set
1194 // it to be not confirmed.
rch617e0652017-04-26 17:57:511195 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271196 MockCryptoClientStream::ZERO_RTT);
rch617e0652017-04-26 17:57:511197
zhongyica364fbb2015-12-12 03:39:121198 SetRequest("GET", "/", DEFAULT_PRIORITY);
1199 size_t spdy_request_headers_frame_length;
Michael Warres167db3e2019-03-01 21:38:031200 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:491201 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
1202 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251203 if (VersionUsesHttp3(version_.transport_version))
Nick Harper057264a82019-09-12 23:33:491204 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371205 AddWrite(InnerConstructRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:491206 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1207 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1208 &spdy_request_headers_frame_length));
zhongyica364fbb2015-12-12 03:39:121209 Initialize();
1210
1211 request_.method = "GET";
rchcd379012017-04-12 21:53:321212 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121213
xunjieli5fafe142016-03-23 23:32:541214 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271215 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541216 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121217 EXPECT_EQ(OK,
1218 stream_->SendRequest(headers_, &response_, callback_.callback()));
1219
1220 // Ack the request.
Renjie90e808e2019-01-24 07:24:041221 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011222 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1223 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121224
Ryan Hamilton8d9ee76e2018-05-29 23:52:521225 quic::QuicConnectionCloseFrame frame;
Zhongyi Shica576df2019-04-12 17:43:401226 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
Renjie Tangdb47d4c2019-08-27 18:56:231227 frame.extracted_error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551228 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121229
1230 NetErrorDetails details;
zhongyica364fbb2015-12-12 03:39:121231 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521232 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121233}
1234
rch11a114a2014-09-04 23:41:591235// Regression test for http://crbug.com/409871
1236TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
1237 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451238 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231239 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251240 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231241 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371242 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231243 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1244 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1245 &spdy_request_headers_frame_length));
rch11a114a2014-09-04 23:41:591246 Initialize();
1247
1248 request_.method = "GET";
rchcd379012017-04-12 21:53:321249 request_.url = GURL("https://www.example.org/");
rch11a114a2014-09-04 23:41:591250
xunjieli5fafe142016-03-23 23:32:541251 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271252 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541253 net_log_.bound(), callback_.callback()));
rch11a114a2014-09-04 23:41:591254
rjshaded5ced072015-12-18 19:26:021255 EXPECT_EQ(OK,
1256 stream_->SendRequest(headers_, &response_, callback_.callback()));
rch11a114a2014-09-04 23:41:591257
jri78ec06a2016-03-31 18:19:401258 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521259 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch11a114a2014-09-04 23:41:591260
1261 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101262
1263 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451264 // headers and payload.
1265 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1266 stream_->GetTotalSentBytes());
sclittle1edeeb22015-09-02 20:46:101267 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rch11a114a2014-09-04 23:41:591268}
1269
[email protected]1e960032013-12-20 19:00:201270TEST_P(QuicHttpStreamTest, SendPostRequest) {
1271 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451272 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231273 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251274 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231275 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Yixin Wange7ecc472018-03-06 19:00:251276
Victor Vasiliev076657c2019-03-12 02:46:431277 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harper23290b82019-05-02 00:02:561278 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411279 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231280 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1281 kIncludeVersion, kFin, DEFAULT_PRIORITY, 0,
1282 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411283 } else {
1284 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231285 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1286 kIncludeVersion, kFin, DEFAULT_PRIORITY, 0,
1287 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411288 }
Yixin Wange7ecc472018-03-06 19:00:251289
Renjie Tangaadb84b2019-08-31 01:00:231290 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1, 2));
[email protected]f702d572012-12-04 15:56:201291
1292 Initialize();
1293
danakjad1777e2016-04-16 00:56:421294 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191295 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
ricea2deef682016-09-09 08:04:071296 kUploadData, strlen(kUploadData)));
rch97827ee2017-05-24 23:49:121297 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191298 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
[email protected]f702d572012-12-04 15:56:201299 request_.method = "POST";
rchcd379012017-04-12 21:53:321300 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121301 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581302 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
tfarina42834112016-09-22 13:38:201303 NetLogWithSource()),
1304 IsOk());
[email protected]f702d572012-12-04 15:56:201305
xunjieli5fafe142016-03-23 23:32:541306 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271307 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541308 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021309 EXPECT_EQ(OK,
1310 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:201311
1312 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041313 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]f702d572012-12-04 15:56:201314
1315 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071316 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451317 size_t spdy_response_headers_frame_length;
1318 ProcessPacket(ConstructResponseHeadersPacket(
1319 2, !kFin, &spdy_response_headers_frame_length));
[email protected]f702d572012-12-04 15:56:201320
rchfb47f712017-05-21 03:24:001321 // The headers have already arrived.
1322 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361323 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:201324 EXPECT_EQ(200, response_.headers->response_code());
1325 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1326
1327 // Send the response body.
1328 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431329 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:411330 ProcessPacket(
Ryan Hamilton7505eb92019-06-08 00:22:171331 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
[email protected]f702d572012-12-04 15:56:201332 // Since the body has already arrived, this should return immediately.
1333 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1334 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1335 callback_.callback()));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291336 EXPECT_EQ(0,
1337 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1338 callback_.callback()));
1339
1340 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1341 EXPECT_TRUE(AtEof());
1342
1343 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1344 // headers and payload.
1345 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411346 strlen(kUploadData) + header.length()),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291347 stream_->GetTotalSentBytes());
1348 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411349 strlen(kResponseBody) + header2.length()),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291350 stream_->GetTotalReceivedBytes());
1351}
1352
1353TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
1354 SetRequest("POST", "/", DEFAULT_PRIORITY);
1355 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231356 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251357 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231358 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431359 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harper23290b82019-05-02 00:02:561360 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411361 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231362 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1363 kIncludeVersion, kFin, DEFAULT_PRIORITY, 0,
1364 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411365 } else {
1366 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231367 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1368 kIncludeVersion, kFin, DEFAULT_PRIORITY, 0,
1369 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411370 }
1371
Renjie Tangaadb84b2019-08-31 01:00:231372 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1, 2));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291373
1374 Initialize();
1375
1376 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191377 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
Ryan Hamilton2ef0a9c2017-07-25 03:18:291378 kUploadData, strlen(kUploadData)));
1379 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191380 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
Ryan Hamilton2ef0a9c2017-07-25 03:18:291381 request_.method = "POST";
1382 request_.url = GURL("https://www.example.org/");
1383 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581384 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291385 NetLogWithSource()),
1386 IsOk());
1387
1388 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271389 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
Ryan Hamilton2ef0a9c2017-07-25 03:18:291390 net_log_.bound(), callback_.callback()));
1391 EXPECT_EQ(OK,
1392 stream_->SendRequest(headers_, &response_, callback_.callback()));
1393
1394 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041395 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291396
1397 // Send the response headers (but not the body).
1398 SetResponse("200 OK", string());
1399 size_t spdy_response_headers_frame_length;
1400 ProcessPacket(ConstructResponseHeadersPacket(
1401 2, !kFin, &spdy_response_headers_frame_length));
1402
1403 // The headers have already arrived.
1404 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1405 ASSERT_TRUE(response_.headers.get());
1406 EXPECT_EQ(200, response_.headers->response_code());
1407 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1408
1409 // Send the response body.
1410 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431411 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:411412 ProcessPacket(
Ryan Hamilton7505eb92019-06-08 00:22:171413 ConstructServerDataPacket(3, false, !kFin, header2 + kResponseBody));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291414 // Since the body has already arrived, this should return immediately.
1415 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1416 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1417 callback_.callback()));
Ryan Hamilton7505eb92019-06-08 00:22:171418 ProcessPacket(ConstructServerDataPacket(4, false, kFin, ""));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291419 EXPECT_EQ(0,
1420 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1421 callback_.callback()));
[email protected]f702d572012-12-04 15:56:201422
1423 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1424 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101425
1426 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451427 // headers and payload.
1428 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411429 strlen(kUploadData) + header.length()),
sclittle1edeeb22015-09-02 20:46:101430 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451431 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411432 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101433 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:201434}
1435
[email protected]1e960032013-12-20 19:00:201436TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
1437 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:471438 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451439 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231440 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251441 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231442 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431443 std::string header = ConstructDataHeader(chunk_size);
Nick Harper23290b82019-05-02 00:02:561444 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411445 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231446 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1447 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1448 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjie Tangd5133972019-12-06 00:20:281449 AddWrite(ConstructClientDataPacket(packet_number++, kIncludeVersion, kFin,
1450 {header + 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, {kUploadData}));
1456 AddWrite(ConstructClientDataPacket(packet_number++, kIncludeVersion, kFin,
1457 kUploadData));
Renjief49758b2019-01-11 23:32:411458 }
1459
Renjie Tangaadb84b2019-08-31 01:00:231460 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1, 2));
[email protected]c9e49a02013-02-26 05:56:471461 Initialize();
1462
Jeremy Roman0579ed62017-08-29 15:56:191463 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121464 auto* chunked_upload_stream =
1465 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1466 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:471467
1468 request_.method = "POST";
rchcd379012017-04-12 21:53:321469 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121470 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071471 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201472 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]c9e49a02013-02-26 05:56:471473
xunjieli5fafe142016-03-23 23:32:541474 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271475 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541476 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021477 ASSERT_EQ(ERR_IO_PENDING,
1478 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:471479
rch97827ee2017-05-24 23:49:121480 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
robpercival214763f2016-07-01 23:27:011481 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]c9e49a02013-02-26 05:56:471482
1483 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041484 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]c9e49a02013-02-26 05:56:471485
1486 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071487 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451488 size_t spdy_response_headers_frame_length;
1489 ProcessPacket(ConstructResponseHeadersPacket(
1490 2, !kFin, &spdy_response_headers_frame_length));
[email protected]c9e49a02013-02-26 05:56:471491
rchfb47f712017-05-21 03:24:001492 // The headers have already arrived.
1493 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361494 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:471495 EXPECT_EQ(200, response_.headers->response_code());
1496 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1497
1498 // Send the response body.
1499 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431500 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171501 ProcessPacket(
1502 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
[email protected]c9e49a02013-02-26 05:56:471503
1504 // Since the body has already arrived, this should return immediately.
1505 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1506 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1507 callback_.callback()));
1508
1509 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1510 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101511
1512 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451513 // headers and payload.
1514 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411515 strlen(kUploadData) * 2 + header.length() * 2),
sclittle1edeeb22015-09-02 20:46:101516 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451517 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411518 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101519 stream_->GetTotalReceivedBytes());
[email protected]c9e49a02013-02-26 05:56:471520}
1521
[email protected]16ba7742014-08-22 00:57:251522TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
1523 SetRequest("POST", "/", DEFAULT_PRIORITY);
1524 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451525 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231526 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251527 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231528 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431529 std::string header = ConstructDataHeader(chunk_size);
Renjief49758b2019-01-11 23:32:411530
Nick Harper23290b82019-05-02 00:02:561531 if (version_.transport_version != quic::QUIC_VERSION_99) {
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, {kUploadData}));
Renjief49758b2019-01-11 23:32:411536 } else {
1537 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231538 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1539 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1540 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411541 }
Renjie Tangaadb84b2019-08-31 01:00:231542 AddWrite(
1543 ConstructClientDataPacket(packet_number++, kIncludeVersion, kFin, ""));
1544 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1, 2));
[email protected]16ba7742014-08-22 00:57:251545 Initialize();
1546
Jeremy Roman0579ed62017-08-29 15:56:191547 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121548 auto* chunked_upload_stream =
1549 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1550 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:251551
1552 request_.method = "POST";
rchcd379012017-04-12 21:53:321553 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121554 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071555 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201556 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251557
xunjieli5fafe142016-03-23 23:32:541558 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271559 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541560 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021561 ASSERT_EQ(ERR_IO_PENDING,
1562 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251563
rch97827ee2017-05-24 23:49:121564 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011565 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251566
Renjie90e808e2019-01-24 07:24:041567 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]16ba7742014-08-22 00:57:251568
1569 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071570 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451571 size_t spdy_response_headers_frame_length;
1572 ProcessPacket(ConstructResponseHeadersPacket(
1573 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251574
rchfb47f712017-05-21 03:24:001575 // The headers have already arrived.
1576 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251577 ASSERT_TRUE(response_.headers.get());
1578 EXPECT_EQ(200, response_.headers->response_code());
1579 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1580
1581 // Send the response body.
1582 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431583 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171584 ProcessPacket(
1585 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
[email protected]16ba7742014-08-22 00:57:251586
rchb27683c2015-07-29 23:53:501587 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251588 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1589 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1590 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251591 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1592 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101593
1594 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451595 // headers and payload.
1596 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411597 strlen(kUploadData) + header.length()),
sclittle1edeeb22015-09-02 20:46:101598 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451599 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411600 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101601 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251602}
1603
1604TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
1605 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451606 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231607 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251608 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231609 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371610 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231611 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1612 kIncludeVersion, !kFin, DEFAULT_PRIORITY,
1613 &spdy_request_headers_frame_length));
1614 AddWrite(
1615 ConstructClientDataPacket(packet_number++, kIncludeVersion, kFin, ""));
1616 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1, 2));
[email protected]16ba7742014-08-22 00:57:251617 Initialize();
1618
Jeremy Roman0579ed62017-08-29 15:56:191619 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121620 auto* chunked_upload_stream =
1621 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
[email protected]16ba7742014-08-22 00:57:251622
1623 request_.method = "POST";
rchcd379012017-04-12 21:53:321624 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121625 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071626 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201627 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251628
xunjieli5fafe142016-03-23 23:32:541629 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271630 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541631 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021632 ASSERT_EQ(ERR_IO_PENDING,
1633 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251634
rch97827ee2017-05-24 23:49:121635 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011636 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251637
Renjie90e808e2019-01-24 07:24:041638 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]16ba7742014-08-22 00:57:251639
1640 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071641 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451642 size_t spdy_response_headers_frame_length;
1643 ProcessPacket(ConstructResponseHeadersPacket(
1644 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251645
rchfb47f712017-05-21 03:24:001646 // The headers have already arrived.
1647 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251648 ASSERT_TRUE(response_.headers.get());
1649 EXPECT_EQ(200, response_.headers->response_code());
1650 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1651
1652 // Send the response body.
1653 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431654 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171655 ProcessPacket(
1656 ConstructServerDataPacket(3, false, kFin, header + kResponseBody));
[email protected]16ba7742014-08-22 00:57:251657
rchb27683c2015-07-29 23:53:501658 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251659 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1660 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1661 callback_.callback()));
1662
1663 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1664 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101665
1666 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451667 // headers and payload.
1668 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1669 stream_->GetTotalSentBytes());
1670 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411671 strlen(kResponseBody) + header.length()),
sclittle1edeeb22015-09-02 20:46:101672 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251673}
1674
[email protected]1e960032013-12-20 19:00:201675TEST_P(QuicHttpStreamTest, DestroyedEarly) {
1676 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451677 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231678 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251679 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231680 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371681 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231682 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1683 kIncludeVersion, kFin, DEFAULT_PRIORITY,
1684 &spdy_request_headers_frame_length));
1685 AddWrite(ConstructAckAndRstStreamPacket(packet_number++));
[email protected]63534512012-12-23 18:49:001686 Initialize();
1687
1688 request_.method = "GET";
rchcd379012017-04-12 21:53:321689 request_.url = GURL("https://www.example.org/");
[email protected]63534512012-12-23 18:49:001690
xunjieli5fafe142016-03-23 23:32:541691 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271692 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541693 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021694 EXPECT_EQ(OK,
1695 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]63534512012-12-23 18:49:001696
1697 // Ack the request.
Renjie90e808e2019-01-24 07:24:041698 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
rchfb47f712017-05-21 03:24:001699 EXPECT_THAT(stream_->ReadResponseHeaders(
Yannic Bonenberger3c96beb2019-09-03 20:41:371700 base::BindOnce(&QuicHttpStreamTest::CloseStream,
1701 base::Unretained(this), stream_.get())),
robpercival214763f2016-07-01 23:27:011702 IsError(ERR_IO_PENDING));
[email protected]63534512012-12-23 18:49:001703
1704 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201705 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:001706 // In the course of processing this packet, the QuicHttpStream close itself.
rchfb47f712017-05-21 03:24:001707 size_t response_size = 0;
rch1bcfddf22017-06-03 00:26:291708 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin, &response_size));
[email protected]63534512012-12-23 18:49:001709
fdoray92e35a72016-06-10 15:54:551710 base::RunLoop().RunUntilIdle();
rchb27683c2015-07-29 23:53:501711
[email protected]63534512012-12-23 18:49:001712 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101713
1714 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451715 // headers and payload.
1716 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1717 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001718 // The stream was closed after receiving the headers.
1719 EXPECT_EQ(static_cast<int64_t>(response_size),
1720 stream_->GetTotalReceivedBytes());
[email protected]63534512012-12-23 18:49:001721}
1722
[email protected]1e960032013-12-20 19:00:201723TEST_P(QuicHttpStreamTest, Priority) {
1724 SetRequest("GET", "/", MEDIUM);
sclittlec4dc1a32015-09-24 00:15:451725 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231726 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251727 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231728 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371729 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231730 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1731 kIncludeVersion, kFin, MEDIUM, &spdy_request_headers_frame_length));
[email protected]24e5bc52013-09-18 15:36:581732 Initialize();
1733
1734 request_.method = "GET";
rchcd379012017-04-12 21:53:321735 request_.url = GURL("https://www.example.org/");
[email protected]24e5bc52013-09-18 15:36:581736
Steven Valdezb4ff0412018-01-18 22:39:271737 EXPECT_EQ(OK,
1738 stream_->InitializeStream(&request_, true, MEDIUM, net_log_.bound(),
1739 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581740
rjshaded5ced072015-12-18 19:26:021741 EXPECT_EQ(OK,
1742 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581743
[email protected]24e5bc52013-09-18 15:36:581744 // Ack the request.
Renjie90e808e2019-01-24 07:24:041745 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011746 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1747 IsError(ERR_IO_PENDING));
[email protected]24e5bc52013-09-18 15:36:581748
1749 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201750 SetResponse("404 OK", "hello world!");
rchfb47f712017-05-21 03:24:001751 size_t response_size = 0;
1752 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, &response_size));
[email protected]24e5bc52013-09-18 15:36:581753
rchfb47f712017-05-21 03:24:001754 EXPECT_EQ(OK, callback_.WaitForResult());
rchb27683c2015-07-29 23:53:501755
[email protected]24e5bc52013-09-18 15:36:581756 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101757
1758 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451759 // headers and payload.
1760 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1761 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001762 EXPECT_EQ(static_cast<int64_t>(response_size),
1763 stream_->GetTotalReceivedBytes());
[email protected]24e5bc52013-09-18 15:36:581764}
1765
xunjieli8dff50b2016-07-22 14:19:061766TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
1767 SetRequest("POST", "/", DEFAULT_PRIORITY);
1768 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231769 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251770 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231771 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431772 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harper23290b82019-05-02 00:02:561773 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411774 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231775 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1776 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1777 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411778 } else {
1779 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231780 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1781 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1782 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411783 }
1784
xunjieli8dff50b2016-07-22 14:19:061785 // Second data write will result in a synchronous failure which will close
1786 // the session.
1787 AddWrite(SYNCHRONOUS, ERR_FAILED);
1788 Initialize();
1789
Jeremy Roman0579ed62017-08-29 15:56:191790 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121791 auto* chunked_upload_stream =
1792 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
xunjieli8dff50b2016-07-22 14:19:061793
1794 request_.method = "POST";
rchcd379012017-04-12 21:53:321795 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121796 request_.upload_data_stream = upload_data_stream_.get();
xunjieli8dff50b2016-07-22 14:19:061797 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201798 TestCompletionCallback().callback(), NetLogWithSource()));
xunjieli8dff50b2016-07-22 14:19:061799
1800 size_t chunk_size = strlen(kUploadData);
rch97827ee2017-05-24 23:49:121801 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
xunjieli8dff50b2016-07-22 14:19:061802 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271803 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli8dff50b2016-07-22 14:19:061804 net_log_.bound(), callback_.callback()));
1805 QuicHttpStream* stream = stream_.get();
1806 DeleteStreamCallback delete_stream_callback(std::move(stream_));
1807 // SendRequest() completes asynchronously after the final chunk is added.
Yixin Wange7ecc472018-03-06 19:00:251808 // Error does not surface yet since packet write is triggered by a packet
1809 // flusher that tries to bundle request body writes.
xunjieli8dff50b2016-07-22 14:19:061810 ASSERT_EQ(ERR_IO_PENDING,
1811 stream->SendRequest(headers_, &response_, callback_.callback()));
rch97827ee2017-05-24 23:49:121812 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
xunjieli8dff50b2016-07-22 14:19:061813 int rv = callback_.WaitForResult();
Yixin Wange7ecc472018-03-06 19:00:251814 EXPECT_EQ(OK, rv);
1815 // Error will be surfaced once an attempt to read the response occurs.
1816 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1817 stream->ReadResponseHeaders(callback_.callback()));
xunjieli8dff50b2016-07-22 14:19:061818}
1819
rtenneti15656ae2016-01-23 03:05:031820TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
1821 SetRequest("POST", "/", DEFAULT_PRIORITY);
Victor Vasiliev7da08172019-10-14 06:04:251822 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231823 AddWrite(ConstructInitialSettingsPacket());
rtenneti15656ae2016-01-23 03:05:031824 AddWrite(SYNCHRONOUS, ERR_FAILED);
1825 Initialize();
1826
Jeremy Roman0579ed62017-08-29 15:56:191827 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
Yixin Wange7ecc472018-03-06 19:00:251828 auto* chunked_upload_stream =
1829 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031830
1831 request_.method = "POST";
rchcd379012017-04-12 21:53:321832 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121833 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031834 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201835 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031836
xunjieli5fafe142016-03-23 23:32:541837 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271838 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541839 net_log_.bound(), callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251840 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:031841 stream_->SendRequest(headers_, &response_, callback_.callback()));
mmenkeffff3642017-06-15 17:37:241842
Yixin Wange7ecc472018-03-06 19:00:251843 // Error will be surfaced once |upload_data_stream| triggers the next write.
1844 size_t chunk_size = strlen(kUploadData);
1845 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1846 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
1847
1848 EXPECT_LE(0, stream_->GetTotalSentBytes());
1849 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1850}
1851
1852TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersCompleteReadResponse) {
1853 SetRequest("POST", "/", DEFAULT_PRIORITY);
Victor Vasiliev7da08172019-10-14 06:04:251854 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231855 AddWrite(ConstructInitialSettingsPacket());
Yixin Wange7ecc472018-03-06 19:00:251856 AddWrite(SYNCHRONOUS, ERR_FAILED);
1857 Initialize();
1858
1859 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1860 auto* chunked_upload_stream =
1861 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1862
1863 request_.method = "POST";
1864 request_.url = GURL("https://www.example.org/");
1865 request_.upload_data_stream = upload_data_stream_.get();
1866
1867 size_t chunk_size = strlen(kUploadData);
1868 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1869
1870 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1871 TestCompletionCallback().callback(), NetLogWithSource()));
1872
1873 ASSERT_EQ(OK,
1874 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
1875 net_log_.bound(), callback_.callback()));
1876 ASSERT_EQ(OK,
1877 stream_->SendRequest(headers_, &response_, callback_.callback()));
1878
1879 // Error will be surfaced once an attempt to read the response occurs.
1880 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1881 stream_->ReadResponseHeaders(callback_.callback()));
1882
mmenkeffff3642017-06-15 17:37:241883 EXPECT_LE(0, stream_->GetTotalSentBytes());
1884 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031885}
1886
1887TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
1888 SetRequest("POST", "/", DEFAULT_PRIORITY);
1889 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231890 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251891 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231892 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:371893 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:231894 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1895 kIncludeVersion, !kFin, DEFAULT_PRIORITY,
1896 &spdy_request_headers_frame_length));
rtenneti15656ae2016-01-23 03:05:031897 AddWrite(SYNCHRONOUS, ERR_FAILED);
1898 Initialize();
1899
Jeremy Roman0579ed62017-08-29 15:56:191900 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121901 auto* chunked_upload_stream =
1902 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031903
1904 request_.method = "POST";
rchcd379012017-04-12 21:53:321905 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121906 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031907 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201908 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031909
xunjieli5fafe142016-03-23 23:32:541910 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271911 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541912 net_log_.bound(), callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251913 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:031914 stream_->SendRequest(headers_, &response_, callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251915
1916 size_t chunk_size = strlen(kUploadData);
1917 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1918 // Error does not surface yet since packet write is triggered by a packet
1919 // flusher that tries to bundle request body writes.
1920 ASSERT_EQ(OK, callback_.WaitForResult());
1921 // Error will be surfaced once an attempt to read the response occurs.
1922 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1923 stream_->ReadResponseHeaders(callback_.callback()));
1924
1925 EXPECT_LE(0, stream_->GetTotalSentBytes());
1926 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1927}
1928
1929TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBundledBodyComplete) {
1930 SetRequest("POST", "/", DEFAULT_PRIORITY);
1931 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:231932 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251933 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231934 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Victor Vasiliev076657c2019-03-12 02:46:431935 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harper23290b82019-05-02 00:02:561936 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411937 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231938 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1939 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1940 &spdy_request_headers_frame_length, {kUploadData}));
Renjief49758b2019-01-11 23:32:411941 } else {
1942 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:231943 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
1944 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
1945 &spdy_request_headers_frame_length, {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411946 }
1947
Yixin Wange7ecc472018-03-06 19:00:251948 AddWrite(SYNCHRONOUS, ERR_FAILED);
1949 Initialize();
1950
1951 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1952 auto* chunked_upload_stream =
1953 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1954
1955 request_.method = "POST";
1956 request_.url = GURL("https://www.example.org/");
1957 request_.upload_data_stream = upload_data_stream_.get();
1958
1959 size_t chunk_size = strlen(kUploadData);
1960 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
1961
1962 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1963 TestCompletionCallback().callback(), NetLogWithSource()));
1964
1965 ASSERT_EQ(OK,
1966 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
1967 net_log_.bound(), callback_.callback()));
1968 ASSERT_EQ(ERR_IO_PENDING,
1969 stream_->SendRequest(headers_, &response_, callback_.callback()));
1970
1971 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1972
1973 // Error does not surface yet since packet write is triggered by a packet
1974 // flusher that tries to bundle request body writes.
1975 ASSERT_EQ(OK, callback_.WaitForResult());
1976 // Error will be surfaced once an attempt to read the response occurs.
1977 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1978 stream_->ReadResponseHeaders(callback_.callback()));
1979
1980 EXPECT_LE(0, stream_->GetTotalSentBytes());
1981 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031982}
1983
ckrasic3865ee0f2016-02-29 22:04:561984TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
1985 SetRequest("GET", "/", DEFAULT_PRIORITY);
1986 Initialize();
1987
1988 // Initialize the first stream, for receiving the promise on.
1989 request_.method = "GET";
rchcd379012017-04-12 21:53:321990 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561991
xunjieli5fafe142016-03-23 23:32:541992 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271993 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541994 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:231995 ASSERT_EQ(OK,
1996 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561997
1998 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1999 // packet, but does it matter?
2000 ReceivePromise(promise_id_);
2001 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2002
2003 request_.url = GURL(promise_url_);
2004
2005 // Make the second stream that will exercise the first step of the
2006 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272007 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2008 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2009 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562010
2011 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252012 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562013 size_t spdy_response_headers_frame_length;
2014 ProcessPacket(InnerConstructResponseHeadersPacket(
2015 1, promise_id_, false, &spdy_response_headers_frame_length));
2016
2017 // Receive the promised response body.
2018 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432019 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172020 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2021 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562022
2023 // Now sending a matching request will have successful rendezvous
2024 // with the promised stream.
Ryan Hamiltona1d1f4a2019-06-26 14:43:042025 ASSERT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
ckrasic3865ee0f2016-02-29 22:04:562026 callback_.callback()));
2027
2028 EXPECT_EQ(
2029 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2030 ->id(),
2031 promise_id_);
2032
2033 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:012034 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2035 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562036
2037 // As will be the body.
2038 EXPECT_EQ(
2039 static_cast<int>(strlen(kResponseBody)),
2040 promised_stream_->ReadResponseBody(
2041 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2042 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2043 EXPECT_TRUE(AtEof());
2044
ckrasic3865ee0f2016-02-29 22:04:562045 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2046 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412047 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562048 promised_stream_->GetTotalReceivedBytes());
2049}
2050
2051TEST_P(QuicHttpStreamTest, ServerPushGetRequestSlowResponse) {
2052 SetRequest("GET", "/", DEFAULT_PRIORITY);
2053 Initialize();
2054
2055 // Initialize the first stream, for receiving the promise on.
2056 request_.method = "GET";
rchcd379012017-04-12 21:53:322057 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562058
xunjieli5fafe142016-03-23 23:32:542059 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272060 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542061 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232062 ASSERT_EQ(OK,
2063 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562064
2065 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2066 // packet, but does it matter?
2067 ReceivePromise(promise_id_);
2068 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2069
2070 request_.url = GURL(promise_url_);
2071
2072 // Make the second stream that will exercise the first step of the
2073 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272074 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2075 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2076 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562077
2078 // Now sending a matching request will rendezvous with the promised
2079 // stream, but pending secondary validation.
2080 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2081 headers_, &response_, callback_.callback()));
2082
2083 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252084 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562085 size_t spdy_response_headers_frame_length;
2086 ProcessPacket(InnerConstructResponseHeadersPacket(
2087 1, promise_id_, false, &spdy_response_headers_frame_length));
2088
2089 // Receive the promised response body.
2090 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432091 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172092 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2093 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562094
fdoray92e35a72016-06-10 15:54:552095 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562096
2097 // Rendezvous should have succeeded now, so the promised stream
2098 // should point at our push stream, and we should be able read
2099 // headers and data from it.
robpercival214763f2016-07-01 23:27:012100 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562101
2102 EXPECT_EQ(
2103 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2104 ->id(),
2105 promise_id_);
2106
robpercival214763f2016-07-01 23:27:012107 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2108 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562109
2110 EXPECT_EQ(
2111 static_cast<int>(strlen(kResponseBody)),
2112 promised_stream_->ReadResponseBody(
2113 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2114
2115 // Callback should return
2116 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2117 EXPECT_TRUE(AtEof());
2118
ckrasic3865ee0f2016-02-29 22:04:562119 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2120 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412121 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562122 promised_stream_->GetTotalReceivedBytes());
2123}
2124
ckrasic2c63f9b2016-08-16 23:54:072125// Verify fix for crbug.com/637349
2126TEST_P(QuicHttpStreamTest, ServerPushCancelHttpStreamBeforeResponse) {
2127 SetRequest("GET", "/", DEFAULT_PRIORITY);
2128 Initialize();
2129
2130 // Initialize the first stream, for receiving the promise on.
2131 request_.method = "GET";
rchcd379012017-04-12 21:53:322132 request_.url = GURL("https://www.example.org/");
ckrasic2c63f9b2016-08-16 23:54:072133
2134 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272135 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
ckrasic2c63f9b2016-08-16 23:54:072136 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232137 ASSERT_EQ(OK,
2138 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic2c63f9b2016-08-16 23:54:072139
2140 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2141 // packet, but does it matter?
2142 ReceivePromise(promise_id_);
2143 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2144
2145 request_.url = GURL(promise_url_);
2146
2147 // Make the second stream that will exercise the first step of the
2148 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272149 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2150 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2151 callback_.callback()));
ckrasic2c63f9b2016-08-16 23:54:072152
2153 // Now sending a matching request will rendezvous with the promised
2154 // stream, but pending secondary validation.
2155 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2156 headers_, &response_, callback_.callback()));
2157
2158 base::RunLoop().RunUntilIdle();
2159
2160 // Cause of FinalValidation() crash as per bug.
2161 promised_stream_.reset();
2162
2163 // Receive the promised response headers.
2164 response_headers_ = promised_response_.Clone();
2165 size_t spdy_response_headers_frame_length;
2166 ProcessPacket(InnerConstructResponseHeadersPacket(
2167 1, promise_id_, false, &spdy_response_headers_frame_length));
2168}
2169
ckrasic3865ee0f2016-02-29 22:04:562170TEST_P(QuicHttpStreamTest, ServerPushCrossOriginOK) {
2171 SetRequest("GET", "/", DEFAULT_PRIORITY);
2172 Initialize();
2173
2174 // Initialize the first stream, for receiving the promise on.
2175 request_.method = "GET";
rchcd379012017-04-12 21:53:322176 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562177
xunjieli5fafe142016-03-23 23:32:542178 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272179 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542180 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232181 ASSERT_EQ(OK,
2182 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562183
2184 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2185 // packet, but does it matter?
2186
2187 push_promise_[":authority"] = "mail.example.org";
David Schinazi3f7465c2019-07-12 01:57:052188 promise_url_ =
2189 quic::SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562190
2191 ReceivePromise(promise_id_);
2192 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2193
2194 request_.url = GURL(promise_url_);
2195
2196 // Make the second stream that will exercise the first step of the
2197 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272198 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2199 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2200 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562201
2202 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252203 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562204 size_t spdy_response_headers_frame_length;
2205 ProcessPacket(InnerConstructResponseHeadersPacket(
2206 1, promise_id_, false, &spdy_response_headers_frame_length));
2207
2208 // Receive the promised response body.
2209 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432210 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172211 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2212 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562213
2214 // Now sending a matching request will have successful rendezvous
2215 // with the promised stream.
2216 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
2217 callback_.callback()));
2218
2219 EXPECT_EQ(
2220 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2221 ->id(),
2222 promise_id_);
2223
2224 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:012225 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2226 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562227
2228 // As will be the body.
2229 EXPECT_EQ(
2230 static_cast<int>(strlen(kResponseBody)),
2231 promised_stream_->ReadResponseBody(
2232 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2233 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2234 EXPECT_TRUE(AtEof());
2235
ckrasic3865ee0f2016-02-29 22:04:562236 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2237 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412238 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562239 promised_stream_->GetTotalReceivedBytes());
2240}
2241
2242TEST_P(QuicHttpStreamTest, ServerPushCrossOriginFail) {
2243 SetRequest("GET", "/", DEFAULT_PRIORITY);
2244 Initialize();
2245
2246 // Initialize the first stream, for receiving the promise on.
2247 request_.method = "GET";
rchcd379012017-04-12 21:53:322248 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562249
xunjieli5fafe142016-03-23 23:32:542250 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272251 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542252 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232253 ASSERT_EQ(OK,
2254 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562255
2256 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2257 // packet, but does it matter?
2258 push_promise_[":authority"] = "www.notexample.org";
David Schinazi3f7465c2019-07-12 01:57:052259 promise_url_ =
2260 quic::SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562261
2262 ReceivePromise(promise_id_);
2263 // The promise will have been rejected because the cert doesn't
2264 // match.
2265 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2266}
2267
2268TEST_P(QuicHttpStreamTest, ServerPushVaryCheckOK) {
2269 SetRequest("GET", "/", DEFAULT_PRIORITY);
2270 Initialize();
2271
2272 // Initialize the first stream, for receiving the promise on.
2273 request_.method = "GET";
rchcd379012017-04-12 21:53:322274 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562275
xunjieli5fafe142016-03-23 23:32:542276 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272277 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542278 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232279 ASSERT_EQ(OK,
2280 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562281
2282 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562283
2284 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2285 // packet, but does it matter?
2286 ReceivePromise(promise_id_);
2287 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2288
2289 request_.url = GURL(promise_url_);
2290
2291 // Make the second stream that will exercise the first step of the
2292 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272293 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2294 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2295 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562296
2297 headers_.SetHeader("accept-encoding", "gzip");
2298
2299 // Now sending a matching request will rendezvous with the promised
2300 // stream, but pending secondary validation.
2301 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2302 headers_, &response_, callback_.callback()));
2303
2304 // Receive the promised response headers.
2305 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252306 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562307 size_t spdy_response_headers_frame_length;
2308 ProcessPacket(InnerConstructResponseHeadersPacket(
2309 1, promise_id_, false, &spdy_response_headers_frame_length));
2310
2311 // Receive the promised response body.
2312 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432313 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172314 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2315 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562316
fdoray92e35a72016-06-10 15:54:552317 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562318
2319 // Rendezvous should have succeeded now, so the promised stream
2320 // should point at our push stream, and we should be able read
2321 // headers and data from it.
robpercival214763f2016-07-01 23:27:012322 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562323
2324 EXPECT_EQ(
2325 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2326 ->id(),
2327 promise_id_);
2328
robpercival214763f2016-07-01 23:27:012329 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2330 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562331
2332 EXPECT_EQ(
2333 static_cast<int>(strlen(kResponseBody)),
2334 promised_stream_->ReadResponseBody(
2335 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2336
2337 // Callback should return
2338 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2339 EXPECT_TRUE(AtEof());
2340
ckrasic3865ee0f2016-02-29 22:04:562341 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2342 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412343 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562344 promised_stream_->GetTotalReceivedBytes());
2345}
2346
2347TEST_P(QuicHttpStreamTest, ServerPushVaryCheckFail) {
2348 SetRequest("GET", "/", DEFAULT_PRIORITY);
2349 request_headers_[":scheme"] = "https";
2350 request_headers_[":path"] = "/bar";
2351 request_headers_["accept-encoding"] = "sdch";
2352
ckrasic3865ee0f2016-02-29 22:04:562353 Initialize();
2354
2355 // Initialize the first stream, for receiving the promise on.
2356 request_.method = "GET";
rchcd379012017-04-12 21:53:322357 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562358
xunjieli5fafe142016-03-23 23:32:542359 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272360 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542361 net_log_.bound(), callback_.callback()));
Renjie Tangaadb84b2019-08-31 01:00:232362 ASSERT_EQ(OK,
2363 stream_->SendRequest(headers_, &response_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562364
2365 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562366
2367 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2368 // packet, but does it matter?
2369 ReceivePromise(promise_id_);
2370 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2371
2372 request_.url = GURL(promise_url_);
2373
2374 // Make the second stream that will exercise the first step of the
2375 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272376 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2377 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2378 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562379
2380 headers_.SetHeader("accept-encoding", "sdch");
2381
2382 // Now sending a matching request will rendezvous with the promised
2383 // stream, but pending secondary validation.
2384 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2385 headers_, &response_, callback_.callback()));
2386
2387 // Receive the promised response headers.
2388 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252389 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562390 size_t spdy_response_headers_frame_length;
2391 ProcessPacket(InnerConstructResponseHeadersPacket(
2392 1, promise_id_, false, &spdy_response_headers_frame_length));
2393
fdoray92e35a72016-06-10 15:54:552394 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562395
2396 // Rendezvous should have failed due to vary mismatch, so the
2397 // promised stream should have been aborted, and instead we have a
2398 // new, regular client initiated stream.
robpercival214763f2016-07-01 23:27:012399 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562400
2401 // Not a server-initiated stream.
2402 EXPECT_NE(
2403 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2404 ->id(),
2405 promise_id_);
2406
2407 // Instead, a new client-initiated stream.
2408 EXPECT_EQ(
2409 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2410 ->id(),
Nick Harper23290b82019-05-02 00:02:562411 stream_id_ + quic::QuicUtils::StreamIdDelta(version_.transport_version));
ckrasic3865ee0f2016-02-29 22:04:562412
2413 // After rendezvous failure, the push stream has been cancelled.
2414 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2415
2416 // The rest of the test verifies that the retried as
2417 // client-initiated version of |promised_stream_| works as intended.
2418
2419 // Ack the request.
Renjie90e808e2019-01-24 07:24:042420 ProcessPacket(ConstructServerAckPacket(2, 1, 1, 1));
ckrasic3865ee0f2016-02-29 22:04:562421
bnc614a92d32016-04-04 13:56:072422 SetResponse("404 Not Found", string());
ckrasic3865ee0f2016-02-29 22:04:562423 size_t spdy_response_header_frame_length;
2424 ProcessPacket(InnerConstructResponseHeadersPacket(
Nick Harper23290b82019-05-02 00:02:562425 3,
2426 stream_id_ + quic::QuicUtils::StreamIdDelta(version_.transport_version),
2427 kFin, &spdy_response_header_frame_length));
ckrasic3865ee0f2016-02-29 22:04:562428
fdoray92e35a72016-06-10 15:54:552429 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562430
robpercival214763f2016-07-01 23:27:012431 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2432 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562433 ASSERT_TRUE(response_.headers.get());
2434 EXPECT_EQ(404, response_.headers->response_code());
2435 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
2436 EXPECT_FALSE(response_.response_time.is_null());
2437 EXPECT_FALSE(response_.request_time.is_null());
2438
2439 // There is no body, so this should return immediately.
2440 EXPECT_EQ(
2441 0, promised_stream_->ReadResponseBody(
2442 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2443 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2444
2445 stream_->Close(true);
2446
2447 EXPECT_TRUE(AtEof());
ckrasic3865ee0f2016-02-29 22:04:562448}
2449
maksim.sisov84e20c92016-06-23 08:49:342450TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
2451 SetRequest("POST", "/", DEFAULT_PRIORITY);
2452 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:232453 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:252454 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232455 AddWrite(ConstructInitialSettingsPacket(packet_number++));
Yixin Wange7ecc472018-03-06 19:00:252456 AddWrite(ConstructRequestAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:232457 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
2458 kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
2459 &spdy_request_headers_frame_length, quic::QUIC_ERROR_PROCESSING_STREAM));
maksim.sisov84e20c92016-06-23 08:49:342460
2461 Initialize();
2462
Jeremy Roman0579ed62017-08-29 15:56:192463 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342464 ReadErrorUploadDataStream::FailureMode::SYNC);
2465 request_.method = "POST";
rchcd379012017-04-12 21:53:322466 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122467 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342468 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202469 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342470
2471 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272472 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342473 net_log_.bound(), callback_.callback()));
2474
2475 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
robpercival214763f2016-07-01 23:27:012476 EXPECT_THAT(result, IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342477
2478 EXPECT_TRUE(AtEof());
2479
2480 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2481 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2482 stream_->GetTotalSentBytes());
2483 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2484}
2485
2486TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
2487 SetRequest("POST", "/", DEFAULT_PRIORITY);
2488 size_t spdy_request_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:232489 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:252490 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232491 AddWrite(ConstructInitialSettingsPacket(packet_number++));
fayang3bcb8b502016-12-07 21:44:372492 AddWrite(InnerConstructRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:232493 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
2494 kIncludeVersion, !kFin, DEFAULT_PRIORITY,
2495 &spdy_request_headers_frame_length));
2496 AddWrite(
2497 ConstructClientRstStreamErrorPacket(packet_number++, !kIncludeVersion));
maksim.sisov84e20c92016-06-23 08:49:342498
2499 Initialize();
2500
Jeremy Roman0579ed62017-08-29 15:56:192501 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342502 ReadErrorUploadDataStream::FailureMode::ASYNC);
2503 request_.method = "POST";
rchcd379012017-04-12 21:53:322504 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122505 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342506 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202507 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342508
2509 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272510 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342511 net_log_.bound(), callback_.callback()));
2512
2513 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2514
Renjie90e808e2019-01-24 07:24:042515 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
maksim.sisov84e20c92016-06-23 08:49:342516 SetResponse("200 OK", string());
2517
robpercival214763f2016-07-01 23:27:012518 EXPECT_THAT(result, IsError(ERR_IO_PENDING));
2519 EXPECT_THAT(callback_.GetResult(result), IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342520
2521 EXPECT_TRUE(AtEof());
2522
2523 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2524 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2525 stream_->GetTotalSentBytes());
2526 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2527}
2528
[email protected]f702d572012-12-04 15:56:202529} // namespace test
[email protected]f702d572012-12-04 15:56:202530} // namespace net