blob: 7205e90d3ce817545a3872b4ea6982499709c839 [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"
xunjieli84adaab2016-09-20 01:12:2822#include "net/base/load_timing_info.h"
23#include "net/base/load_timing_info_test_util.h"
[email protected]f702d572012-12-04 15:56:2024#include "net/base/net_errors.h"
25#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0626#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2027#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1528#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0029#include "net/log/net_log_event_type.h"
xunjieli5fafe142016-03-23 23:32:5430#include "net/log/test_net_log.h"
31#include "net/log/test_net_log_util.h"
Victor Vasiliev4f6fb892019-05-31 16:58:3132#include "net/quic/address_utils.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0833#include "net/quic/crypto/proof_verifier_chromium.h"
34#include "net/quic/mock_crypto_client_stream_factory.h"
35#include "net/quic/quic_chromium_alarm_factory.h"
36#include "net/quic/quic_chromium_connection_helper.h"
37#include "net/quic/quic_chromium_packet_reader.h"
38#include "net/quic/quic_chromium_packet_writer.h"
39#include "net/quic/quic_http_utils.h"
40#include "net/quic/quic_server_info.h"
41#include "net/quic/quic_stream_factory.h"
42#include "net/quic/quic_test_packet_maker.h"
Ryan Hamilton0d65a8c2019-06-07 00:46:0243#include "net/quic/quic_test_packet_printer.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0844#include "net/quic/test_task_runner.h"
tbansalca83c002016-04-28 20:56:2845#include "net/socket/socket_performance_watcher.h"
[email protected]f702d572012-12-04 15:56:2046#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5847#include "net/spdy/spdy_http_utils.h"
rch03b7a202016-02-05 00:54:2048#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0149#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4350#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0151#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5152#include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h"
53#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
54#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
55#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
56#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
57#include "net/third_party/quiche/src/quic/core/quic_connection.h"
58#include "net/third_party/quiche/src/quic/core/quic_utils.h"
59#include "net/third_party/quiche/src/quic/core/quic_write_blocked_list.h"
60#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
61#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
62#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
63#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
64#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
65#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
66#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
67#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1468#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
69#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
70#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
Ramin Halavati683bcaa92018-02-14 08:42:3971#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]f702d572012-12-04 15:56:2072#include "testing/gmock/include/gmock/gmock.h"
73#include "testing/gtest/include/gtest/gtest.h"
74
bnc614a92d32016-04-04 13:56:0775using std::string;
[email protected]f702d572012-12-04 15:56:2076using testing::_;
[email protected]06ff5152013-08-29 01:03:0577using testing::AnyNumber;
78using testing::Return;
[email protected]f702d572012-12-04 15:56:2079
80namespace net {
[email protected]f702d572012-12-04 15:56:2081namespace test {
[email protected]f702d572012-12-04 15:56:2082namespace {
83
[email protected]16ba7742014-08-22 00:57:2584const char kUploadData[] = "Really nifty data!";
rch9ae5b3b2016-02-11 00:36:2985const char kDefaultServerHostName[] = "www.example.org";
rchcd379012017-04-12 21:53:3286const uint16_t kDefaultServerPort = 443;
[email protected]f702d572012-12-04 15:56:2087
Ryan Hamilton8d9ee76e2018-05-29 23:52:5288class TestQuicConnection : public quic::QuicConnection {
[email protected]f702d572012-12-04 15:56:2089 public:
Ryan Hamilton8d9ee76e2018-05-29 23:52:5290 TestQuicConnection(const quic::ParsedQuicVersionVector& versions,
91 quic::QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2092 IPEndPoint address,
rch12fef552016-01-15 16:26:3193 QuicChromiumConnectionHelper* helper,
rch16c74d1d2016-04-22 06:14:0794 QuicChromiumAlarmFactory* alarm_factory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5295 quic::QuicPacketWriter* writer)
Victor Vasiliev4f6fb892019-05-31 16:58:3196 : quic::QuicConnection(connection_id,
97 ToQuicSocketAddress(address),
98 helper,
99 alarm_factory,
100 writer,
101 true /* owns_writer */,
102 quic::Perspective::IS_CLIENT,
103 versions) {}
[email protected]f702d572012-12-04 15:56:20104
Ryan Hamilton8d9ee76e2018-05-29 23:52:52105 void SetSendAlgorithm(quic::SendAlgorithmInterface* send_algorithm) {
106 quic::test::QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:20107 }
108};
109
maksim.sisov84e20c92016-06-23 08:49:34110// UploadDataStream that always returns errors on data read.
111class ReadErrorUploadDataStream : public UploadDataStream {
112 public:
113 enum class FailureMode { SYNC, ASYNC };
114
115 explicit ReadErrorUploadDataStream(FailureMode mode)
116 : UploadDataStream(true, 0), async_(mode), weak_factory_(this) {}
117 ~ReadErrorUploadDataStream() override {}
118
119 private:
120 void CompleteRead() { UploadDataStream::OnReadCompleted(ERR_FAILED); }
121
122 // UploadDataStream implementation:
tfarina42834112016-09-22 13:38:20123 int InitInternal(const NetLogWithSource& net_log) override { return OK; }
maksim.sisov84e20c92016-06-23 08:49:34124
125 int ReadInternal(IOBuffer* buf, int buf_len) override {
126 if (async_ == FailureMode::ASYNC) {
127 base::ThreadTaskRunnerHandle::Get()->PostTask(
kylecharf4fe5172019-02-15 18:53:49128 FROM_HERE, base::BindOnce(&ReadErrorUploadDataStream::CompleteRead,
129 weak_factory_.GetWeakPtr()));
maksim.sisov84e20c92016-06-23 08:49:34130 return ERR_IO_PENDING;
131 }
132 return ERR_FAILED;
133 }
134
135 void ResetInternal() override {}
136
137 const FailureMode async_;
138
139 base::WeakPtrFactory<ReadErrorUploadDataStream> weak_factory_;
140
141 DISALLOW_COPY_AND_ASSIGN(ReadErrorUploadDataStream);
142};
143
Bence Béky8ddc2492018-06-13 01:02:04144// A helper class that will delete |stream| when the callback is invoked.
xunjieli8dff50b2016-07-22 14:19:06145class DeleteStreamCallback : public TestCompletionCallbackBase {
146 public:
Bence Béky8ddc2492018-06-13 01:02:04147 explicit DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)
148 : stream_(std::move(stream)) {}
xunjieli8dff50b2016-07-22 14:19:06149
Bence Béky8ddc2492018-06-13 01:02:04150 CompletionOnceCallback callback() {
151 return base::BindOnce(&DeleteStreamCallback::DeleteStream,
152 base::Unretained(this));
153 }
xunjieli8dff50b2016-07-22 14:19:06154
155 private:
156 void DeleteStream(int result) {
157 stream_.reset();
158 SetResult(result);
159 }
160
161 std::unique_ptr<QuicHttpStream> stream_;
xunjieli8dff50b2016-07-22 14:19:06162};
163
[email protected]f702d572012-12-04 15:56:20164} // namespace
165
[email protected]24e5bc52013-09-18 15:36:58166class QuicHttpStreamPeer {
167 public:
rch08e198572017-05-09 16:56:55168 static QuicChromiumClientStream::Handle* GetQuicChromiumClientStream(
[email protected]24e5bc52013-09-18 15:36:58169 QuicHttpStream* stream) {
rch08e198572017-05-09 16:56:55170 return stream->stream_.get();
[email protected]24e5bc52013-09-18 15:36:58171 }
172};
173
Ryan Hamilton8d9ee76e2018-05-29 23:52:52174class QuicHttpStreamTest : public ::testing::TestWithParam<
Nick Harper23290b82019-05-02 00:02:56175 std::tuple<quic::ParsedQuicVersion, bool>>,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52176 public WithScopedTaskEnvironment {
rchfb47f712017-05-21 03:24:00177 public:
178 void CloseStream(QuicHttpStream* stream, int /*rv*/) { stream->Close(false); }
179
[email protected]f702d572012-12-04 15:56:20180 protected:
[email protected]1e960032013-12-20 19:00:20181 static const bool kFin = true;
182 static const bool kIncludeVersion = true;
183 static const bool kIncludeCongestionFeedback = true;
184
[email protected]f702d572012-12-04 15:56:20185 // Holds a packet to be written to the wire, and the IO mode that should
186 // be used by the mock socket when performing the write.
187 struct PacketToWrite {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52188 PacketToWrite(IoMode mode, quic::QuicReceivedPacket* packet)
rjshaded5ced072015-12-18 19:26:02189 : mode(mode), packet(packet) {}
rtenneti15656ae2016-01-23 03:05:03190 PacketToWrite(IoMode mode, int rv) : mode(mode), packet(nullptr), rv(rv) {}
[email protected]f702d572012-12-04 15:56:20191 IoMode mode;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52192 quic::QuicReceivedPacket* packet;
rtenneti15656ae2016-01-23 03:05:03193 int rv;
[email protected]f702d572012-12-04 15:56:20194 };
195
196 QuicHttpStreamTest()
Yixin Wang079ad542018-01-11 04:06:05197 : version_(std::get<0>(GetParam())),
198 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52199 crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting(),
200 quic::TlsClientHandshaker::CreateSslCtx()),
Victor Costan9c7302b2018-08-27 16:39:44201 read_buffer_(base::MakeRefCounted<IOBufferWithSize>(4096)),
Fan Yang32c5a112018-12-10 20:06:33202 promise_id_(GetNthServerInitiatedUnidirectionalStreamId(0)),
203 stream_id_(GetNthClientInitiatedBidirectionalStreamId(0)),
David Schinazic8281052019-01-24 06:14:17204 connection_id_(quic::test::TestConnectionId(2)),
Yixin Wang079ad542018-01-11 04:06:05205 client_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58206 connection_id_,
207 &clock_,
208 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52209 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05210 client_headers_include_h2_stream_dependency_),
211 server_maker_(version_,
zhongyi5dbfdd42017-06-20 05:22:15212 connection_id_,
alyssar2adf3ac2016-05-03 17:12:58213 &clock_,
214 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52215 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05216 false),
ckrasic3865ee0f2016-02-29 22:04:56217 random_generator_(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:02218 printer_(version_) {
martijn21968ea2016-02-24 18:46:20219 IPAddress ip(192, 0, 2, 33);
[email protected]f702d572012-12-04 15:56:20220 peer_addr_ = IPEndPoint(ip, 443);
221 self_addr_ = IPEndPoint(ip, 8435);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52222 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
Ramin Halavati683bcaa92018-02-14 08:42:39223 request_.traffic_annotation =
224 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f702d572012-12-04 15:56:20225 }
226
227 ~QuicHttpStreamTest() {
Renjieba55fae2018-09-20 03:05:16228 session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
229 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]f702d572012-12-04 15:56:20230 for (size_t i = 0; i < writes_.size(); i++) {
231 delete writes_[i].packet;
232 }
233 }
234
235 // Adds a packet to the list of expected writes.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52236 void AddWrite(std::unique_ptr<quic::QuicReceivedPacket> packet) {
[email protected]1e960032013-12-20 19:00:20237 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20238 }
239
rtenneti15656ae2016-01-23 03:05:03240 void AddWrite(IoMode mode, int rv) {
241 writes_.push_back(PacketToWrite(mode, rv));
242 }
243
[email protected]f702d572012-12-04 15:56:20244 // Returns the packet to be written at position |pos|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52245 quic::QuicReceivedPacket* GetWrite(size_t pos) { return writes_[pos].packet; }
[email protected]f702d572012-12-04 15:56:20246
247 bool AtEof() {
rch37de576c2015-05-17 20:28:17248 return socket_data_->AllReadDataConsumed() &&
249 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20250 }
251
Ryan Hamilton8d9ee76e2018-05-29 23:52:52252 void ProcessPacket(std::unique_ptr<quic::QuicReceivedPacket> packet) {
Victor Vasiliev4f6fb892019-05-31 16:58:31253 connection_->ProcessUdpPacket(ToQuicSocketAddress(self_addr_),
254 ToQuicSocketAddress(peer_addr_), *packet);
[email protected]f702d572012-12-04 15:56:20255 }
256
257 // Configures the test fixture to use the list of expected writes.
258 void Initialize() {
259 mock_writes_.reset(new MockWrite[writes_.size()]);
260 for (size_t i = 0; i < writes_.size(); i++) {
rtenneti15656ae2016-01-23 03:05:03261 if (writes_[i].packet == nullptr) {
262 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
263 } else {
264 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
265 writes_[i].packet->length());
266 }
bnc614a92d32016-04-04 13:56:07267 }
[email protected]f702d572012-12-04 15:56:20268
rtennetibe635732014-10-02 22:51:42269 socket_data_.reset(new StaticSocketDataProvider(
Ryan Sleevib8d7ea02018-05-07 20:01:01270 base::span<MockRead>(),
271 base::make_span(mock_writes_.get(), writes_.size())));
Ryan Hamilton0d65a8c2019-06-07 00:46:02272 socket_data_->set_printer(&printer_);
[email protected]f702d572012-12-04 15:56:20273
danakjad1777e2016-04-16 00:56:42274 std::unique_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
xunjielib53b38c2016-03-24 15:54:36275 socket_data_.get(), net_log_.bound().net_log()));
[email protected]e13201d82012-12-12 05:00:32276 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20277 runner_ = new TestTaskRunner(&clock_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52278 send_algorithm_ = new quic::test::MockSendAlgorithm();
rch7dd15702015-07-01 18:57:57279 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
280 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
rjshaded5ced072015-12-18 19:26:02281 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
Dan Zhangf11470172017-09-18 22:02:09282 .Times(testing::AtLeast(1));
rtenneti44f4a2e2015-08-07 14:00:07283 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
Zhongyi Shica576df2019-04-12 17:43:40284 .WillRepeatedly(Return(quic::kMaxOutgoingPacketSize));
jokulik0e0a00c32016-06-13 21:51:58285 EXPECT_CALL(*send_algorithm_, PacingRate(_))
Ryan Hamilton8d9ee76e2018-05-29 23:52:52286 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Michael Warres74ee3ce2017-10-09 15:26:37287 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
rtenneti44f4a2e2015-08-07 14:00:07288 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52289 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40290 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
rch08cae032017-03-29 00:59:15291 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
rch0d5bcf62017-05-24 22:48:45292 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
293 .Times(AnyNumber());
rch16c74d1d2016-04-22 06:14:07294 helper_.reset(
295 new QuicChromiumConnectionHelper(&clock_, &random_generator_));
296 alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
297
Michael Warres74ee3ce2017-10-09 15:26:37298 connection_ = new TestQuicConnection(
Nick Harper23290b82019-05-02 00:02:56299 quic::test::SupportedVersions(version_), connection_id_, peer_addr_,
300 helper_.get(), alarm_factory_.get(),
Ryan Hamilton9edcf1a2017-11-22 05:55:17301 new QuicChromiumPacketWriter(
302 socket.get(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]f702d572012-12-04 15:56:20303 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41304 connection_->SetSendAlgorithm(send_algorithm_);
rch03b7a202016-02-05 00:54:20305
306 // Load a certificate that is valid for *.example.org
307 scoped_refptr<X509Certificate> test_cert(
308 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
309 EXPECT_TRUE(test_cert.get());
310
311 verify_details_.cert_verify_result.verified_cert = test_cert;
312 verify_details_.cert_verify_result.is_issued_by_known_root = true;
313 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
314
xunjieli84adaab2016-09-20 01:12:28315 base::TimeTicks dns_end = base::TimeTicks::Now();
316 base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);
ckrasic4f9d88d2015-07-22 22:23:16317 session_.reset(new QuicChromiumClientSession(
xunjielib53b38c2016-03-24 15:54:36318 connection_, std::move(socket),
rtenneti1cd3b162015-09-29 02:58:28319 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57320 &transport_security_state_, /*ssl_config_service=*/nullptr,
danakjad1777e2016-04-16 00:56:42321 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
Paul Jensen8e3c5d32018-02-19 17:06:33322 QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
323 PRIVACY_MODE_DISABLED, SocketTag()),
Zhongyi Shi757fcce2018-06-27 05:41:27324 /*require_confirmation=*/false, /*migrate_session_early_v2=*/false,
325 /*migrate_session_on_network_change_v2=*/false,
326 /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shie01f2db2019-02-22 19:53:23327 quic::QuicTime::Delta::FromMilliseconds(
328 kDefaultRetransmittableOnWireTimeoutMillisecs),
Zhongyi Shi32fe14d42019-02-28 00:25:36329 /*migrate_idle_session=*/false,
Zhongyi Shic16b4102019-02-12 00:37:40330 base::TimeDelta::FromSeconds(kDefaultIdleSessionMigrationPeriodSeconds),
Zhongyi Shi73f23ca872017-12-13 18:37:13331 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shiee760762018-08-01 00:54:29332 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30333 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17334 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52335 quic::QuicTime::Delta::FromMilliseconds(
336 kQuicYieldAfterDurationMilliseconds),
Zhongyi Shidbce7f412019-02-01 23:16:29337 /*go_away_on_path_degrading*/ false,
Yixin Wang079ad542018-01-11 04:06:05338 client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52339 quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
340 dns_start, dns_end, &push_promise_index_, nullptr,
Zhongyi Shic16b4102019-02-12 00:37:40341 base::DefaultTickClock::GetInstance(),
xunjieli84adaab2016-09-20 01:12:28342 base::ThreadTaskRunnerHandle::Get().get(),
xunjieli5fafe142016-03-23 23:32:54343 /*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));
rtennetid39bd762015-06-12 01:05:52344 session_->Initialize();
xunjieli100937eb52016-09-15 20:09:37345 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57346
rch433bf5f2017-02-14 04:10:47347 session_->CryptoConnect(callback.callback());
Ryan Hamilton6c2a2a82017-12-15 02:06:28348 stream_ = std::make_unique<QuicHttpStream>(
349 session_->CreateHandle(HostPortPair("www.example.org", 443)));
350 promised_stream_ = std::make_unique<QuicHttpStream>(
351 session_->CreateHandle(HostPortPair("www.example.org", 443)));
ckrasic3865ee0f2016-02-29 22:04:56352 push_promise_[":path"] = "/bar";
353 push_promise_[":authority"] = "www.example.org";
354 push_promise_[":version"] = "HTTP/1.1";
355 push_promise_[":method"] = "GET";
356 push_promise_[":scheme"] = "https";
357
358 promised_response_[":status"] = "200 OK";
359 promised_response_[":version"] = "HTTP/1.1";
360 promised_response_["content-type"] = "text/plain";
361
Ryan Hamilton8d9ee76e2018-05-29 23:52:52362 promise_url_ = quic::SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
[email protected]6cca996b2013-01-25 07:43:36363 }
364
bnc614a92d32016-04-04 13:56:07365 void SetRequest(const string& method,
366 const string& path,
[email protected]1e960032013-12-20 19:00:20367 RequestPriority priority) {
rchcd379012017-04-12 21:53:32368 request_headers_ = client_maker_.GetRequestHeaders(method, "https", path);
[email protected]6cca996b2013-01-25 07:43:36369 }
370
bnc614a92d32016-04-04 13:56:07371 void SetResponse(const string& status, const string& body) {
alyssar2adf3ac2016-05-03 17:12:58372 response_headers_ = server_maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03373 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36374 }
[email protected]f702d572012-12-04 15:56:20375
Ryan Hamilton8d9ee76e2018-05-29 23:52:52376 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructDataPacket(
Fan Yangac867502019-01-28 21:10:23377 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52378 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56379 bool should_include_version,
380 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52381 quic::QuicStringPiece data,
alyssar2adf3ac2016-05-03 17:12:58382 QuicTestPacketMaker* maker) {
383 return maker->MakeDataPacket(packet_number, stream_id,
Ryan Hamilton7505eb92019-06-08 00:22:17384 should_include_version, fin, data);
ckrasic3865ee0f2016-02-29 22:04:56385 }
386
Ryan Hamilton8d9ee76e2018-05-29 23:52:52387 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23388 uint64_t packet_number,
[email protected]e8ff26842013-03-22 21:02:05389 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20390 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52391 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17392 return client_maker_.MakeDataPacket(packet_number, stream_id_,
393 should_include_version, fin, data);
alyssar2adf3ac2016-05-03 17:12:58394 }
395
Renjief49758b2019-01-11 23:32:41396 std::unique_ptr<quic::QuicReceivedPacket>
397 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23398 uint64_t packet_number,
Renjief49758b2019-01-11 23:32:41399 bool should_include_version,
400 bool fin,
Renjief49758b2019-01-11 23:32:41401 const std::vector<std::string>& data) {
402 return client_maker_.MakeMultipleDataFramesPacket(
Ryan Hamilton7505eb92019-06-08 00:22:17403 packet_number, stream_id_, should_include_version, fin, data);
Renjief49758b2019-01-11 23:32:41404 }
405
Ryan Hamilton8d9ee76e2018-05-29 23:52:52406 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23407 uint64_t packet_number,
alyssar2adf3ac2016-05-03 17:12:58408 bool should_include_version,
409 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52410 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17411 return server_maker_.MakeDataPacket(packet_number, stream_id_,
412 should_include_version, fin, data);
ckrasic3865ee0f2016-02-29 22:04:56413 }
414
Ryan Hamilton8d9ee76e2018-05-29 23:52:52415 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23416 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52417 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56418 bool should_include_version,
419 bool fin,
420 RequestPriority request_priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02421 size_t* spdy_headers_frame_length) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48422 return InnerConstructRequestHeadersPacket(
423 packet_number, stream_id, should_include_version, fin, request_priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02424 0, spdy_headers_frame_length);
Yixin Wang7a3f1b8d2018-01-17 21:40:48425 }
426
Ryan Hamilton8d9ee76e2018-05-29 23:52:52427 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23428 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52429 quic::QuicStreamId stream_id,
Yixin Wang7a3f1b8d2018-01-17 21:40:48430 bool should_include_version,
431 bool fin,
432 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52433 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02434 size_t* spdy_headers_frame_length) {
Ryan Hamilton0239aac2018-05-19 00:03:13435 spdy::SpdyPriority priority =
ckrasic3865ee0f2016-02-29 22:04:56436 ConvertRequestPriorityToQuicPriority(request_priority);
alyssar2adf3ac2016-05-03 17:12:58437 return client_maker_.MakeRequestHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56438 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48439 std::move(request_headers_), parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02440 spdy_headers_frame_length);
[email protected]f702d572012-12-04 15:56:20441 }
442
Ryan Hamilton8d9ee76e2018-05-29 23:52:52443 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25444 ConstructRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23445 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52446 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25447 bool should_include_version,
448 bool fin,
449 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52450 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25451 size_t* spdy_headers_frame_length,
452 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13453 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25454 ConvertRequestPriorityToQuicPriority(request_priority);
455 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
456 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02457 std::move(request_headers_), parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25458 spdy_headers_frame_length, data_writes);
459 }
460
Ryan Hamilton8d9ee76e2018-05-29 23:52:52461 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestAndRstPacket(
Fan Yangac867502019-01-28 21:10:23462 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52463 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25464 bool should_include_version,
465 bool fin,
466 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52467 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25468 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52469 quic::QuicRstStreamErrorCode error_code,
Yixin Wange7ecc472018-03-06 19:00:25470 size_t bytes_written) {
Ryan Hamilton0239aac2018-05-19 00:03:13471 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25472 ConvertRequestPriorityToQuicPriority(request_priority);
473 return client_maker_.MakeRequestHeadersAndRstPacket(
474 packet_number, stream_id, should_include_version, fin, priority,
475 std::move(request_headers_), parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02476 spdy_headers_frame_length, error_code, bytes_written);
Yixin Wange7ecc472018-03-06 19:00:25477 }
478
Ryan Hamilton8d9ee76e2018-05-29 23:52:52479 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23480 uint64_t packet_number,
rtennetif4bdb542015-01-21 14:33:05481 bool fin,
sclittlec4dc1a32015-09-24 00:15:45482 RequestPriority request_priority,
483 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56484 return InnerConstructRequestHeadersPacket(
485 packet_number, stream_id_, kIncludeVersion, fin, request_priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02486 spdy_headers_frame_length);
ckrasic3865ee0f2016-02-29 22:04:56487 }
488
Ryan Hamilton8d9ee76e2018-05-29 23:52:52489 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructResponseHeadersPacket(
Fan Yangac867502019-01-28 21:10:23490 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52491 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56492 bool fin,
493 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58494 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26495 packet_number, stream_id, !kIncludeVersion, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02496 std::move(response_headers_), spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20497 }
498
Ryan Hamilton8d9ee76e2018-05-29 23:52:52499 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseHeadersPacket(
Fan Yangac867502019-01-28 21:10:23500 uint64_t packet_number,
sclittlec4dc1a32015-09-24 00:15:45501 bool fin,
502 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56503 return InnerConstructResponseHeadersPacket(packet_number, stream_id_, fin,
504 spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20505 }
506
Ryan Hamilton8d9ee76e2018-05-29 23:52:52507 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseTrailersPacket(
Fan Yangac867502019-01-28 21:10:23508 uint64_t packet_number,
xunjieli34291fe12016-03-02 13:58:38509 bool fin,
Ryan Hamilton0239aac2018-05-19 00:03:13510 spdy::SpdyHeaderBlock trailers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02511 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58512 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26513 packet_number, stream_id_, !kIncludeVersion, fin, std::move(trailers),
Ryan Hamilton0d65a8c2019-06-07 00:46:02514 spdy_headers_frame_length);
xunjieli34291fe12016-03-02 13:58:38515 }
516
Ryan Hamilton8d9ee76e2018-05-29 23:52:52517 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23518 uint64_t packet_number) {
alyssara72f5352016-10-20 12:45:16519 return client_maker_.MakeRstPacket(packet_number, true, stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52520 quic::QUIC_RST_ACKNOWLEDGEMENT);
[email protected]06ff5152013-08-29 01:03:05521 }
522
Ryan Hamilton8d9ee76e2018-05-29 23:52:52523 std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23524 ConstructClientRstStreamCancelledPacket(uint64_t packet_number) {
alyssar2adf3ac2016-05-03 17:12:58525 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52526 stream_id_, quic::QUIC_STREAM_CANCELLED);
rtenneti6bd660b2015-07-18 00:19:53527 }
528
Ryan Hamilton8d9ee76e2018-05-29 23:52:52529 std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23530 ConstructClientRstStreamVaryMismatchPacket(uint64_t packet_number) {
alyssar2adf3ac2016-05-03 17:12:58531 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52532 promise_id_,
533 quic::QUIC_PROMISE_VARY_MISMATCH);
ckrasic3865ee0f2016-02-29 22:04:56534 }
535
Fan Yang550c6282018-06-22 18:53:25536 std::unique_ptr<quic::QuicReceivedPacket>
537 ConstructClientRstStreamVaryMismatchAndRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23538 uint64_t packet_number,
Fan Yang550c6282018-06-22 18:53:25539 quic::QuicStreamId stream_id,
540 bool should_include_version,
541 bool fin,
542 RequestPriority request_priority,
543 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02544 size_t* spdy_headers_frame_length) {
Fan Yang550c6282018-06-22 18:53:25545 spdy::SpdyPriority priority =
546 ConvertRequestPriorityToQuicPriority(request_priority);
547 return client_maker_.MakeRstAndRequestHeadersPacket(
548 packet_number, should_include_version, promise_id_,
549 quic::QUIC_PROMISE_VARY_MISMATCH, stream_id, fin, priority,
550 std::move(request_headers_), parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02551 spdy_headers_frame_length);
Fan Yang550c6282018-06-22 18:53:25552 }
553
Ryan Hamilton8d9ee76e2018-05-29 23:52:52554 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23555 uint64_t packet_number,
556 uint64_t largest_received,
557 uint64_t smallest_received,
558 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58559 return client_maker_.MakeAckAndRstPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52560 packet_number, !kIncludeVersion, stream_id_,
561 quic::QUIC_STREAM_CANCELLED, largest_received, smallest_received,
562 least_unacked, !kIncludeCongestionFeedback);
xunjieli34291fe12016-03-02 13:58:38563 }
564
Ryan Hamilton8d9ee76e2018-05-29 23:52:52565 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamErrorPacket(
Fan Yangac867502019-01-28 21:10:23566 uint64_t packet_number,
maksim.sisov84e20c92016-06-23 08:49:34567 bool include_version) {
568 return client_maker_.MakeRstPacket(packet_number, include_version,
569 stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52570 quic::QUIC_ERROR_PROCESSING_STREAM);
maksim.sisov84e20c92016-06-23 08:49:34571 }
572
Ryan Hamilton8d9ee76e2018-05-29 23:52:52573 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23574 uint64_t packet_number) {
Renjie90e808e2019-01-24 07:24:04575 return ConstructAckAndRstStreamPacket(packet_number, 2, 1, 2);
[email protected]c5e1aca2014-01-30 04:03:04576 }
577
Ryan Hamilton8d9ee76e2018-05-29 23:52:52578 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23579 uint64_t packet_number,
580 uint64_t largest_received,
581 uint64_t smallest_received,
582 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58583 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49584 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58585 !kIncludeCongestionFeedback);
586 }
587
Ryan Hamilton8d9ee76e2018-05-29 23:52:52588 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23589 uint64_t packet_number,
590 uint64_t largest_received,
591 uint64_t smallest_received,
592 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58593 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49594 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58595 !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00596 }
597
Ryan Hamilton8d9ee76e2018-05-29 23:52:52598 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23599 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57600 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52601 quic::QuicStreamId id,
602 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02603 RequestPriority request_priority) {
Yixin Wangb470bc882018-02-15 18:43:57604 return client_maker_.MakePriorityPacket(
605 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02606 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wangb470bc882018-02-15 18:43:57607 }
608
Ryan Hamilton0d65a8c2019-06-07 00:46:02609 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket() {
610 return client_maker_.MakeInitialSettingsPacket(1);
fayang3bcb8b502016-12-07 21:44:37611 }
612
Victor Vasiliev076657c2019-03-12 02:46:43613 std::string ConstructDataHeader(size_t body_len) {
Nick Harper23290b82019-05-02 00:02:56614 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41615 return "";
616 }
617 quic::HttpEncoder encoder;
618 std::unique_ptr<char[]> buffer;
619 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43620 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41621 }
622
Ryan Hamilton8d9ee76e2018-05-29 23:52:52623 void ReceivePromise(quic::QuicStreamId id) {
624 auto headers = quic::test::AsHeaderList(push_promise_);
rch08e198572017-05-09 16:56:55625 QuicChromiumClientStream::Handle* stream =
ckrasic3865ee0f2016-02-29 22:04:56626 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
ckrasic32b17dcd2016-10-31 06:15:35627 stream->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
628 headers);
ckrasic3865ee0f2016-02-29 22:04:56629 }
630
xunjieli84adaab2016-09-20 01:12:28631 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info,
xunjieli100937eb52016-09-15 20:09:37632 bool session_reused) {
633 EXPECT_EQ(session_reused, load_timing_info.socket_reused);
xunjieli84adaab2016-09-20 01:12:28634 if (session_reused) {
635 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
636 } else {
637 ExpectConnectTimingHasTimes(
638 load_timing_info.connect_timing,
639 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
640 }
641 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
xunjieli100937eb52016-09-15 20:09:37642 }
643
Fan Yang32c5a112018-12-10 20:06:33644 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56645 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
646 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36647 }
648
Fan Yang32c5a112018-12-10 20:06:33649 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56650 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
651 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36652 }
653
Nick Harper23290b82019-05-02 00:02:56654 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05655 const bool client_headers_include_h2_stream_dependency_;
656
xunjieli5fafe142016-03-23 23:32:54657 BoundTestNetLog net_log_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52658 quic::test::MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20659 scoped_refptr<TestTaskRunner> runner_;
danakjad1777e2016-04-16 00:56:42660 std::unique_ptr<MockWrite[]> mock_writes_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52661 quic::MockClock clock_;
[email protected]f702d572012-12-04 15:56:20662 TestQuicConnection* connection_;
danakjad1777e2016-04-16 00:56:42663 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
rch16c74d1d2016-04-22 06:14:07664 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52665 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
rch97827ee2017-05-24 23:49:12666 std::unique_ptr<UploadDataStream> upload_data_stream_;
danakjad1777e2016-04-16 00:56:42667 std::unique_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15668 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42669 std::unique_ptr<QuicChromiumClientSession> session_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52670 quic::QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20671 TestCompletionCallback callback_;
672 HttpRequestInfo request_;
673 HttpRequestHeaders headers_;
674 HttpResponseInfo response_;
675 scoped_refptr<IOBufferWithSize> read_buffer_;
Ryan Hamilton0239aac2018-05-19 00:03:13676 spdy::SpdyHeaderBlock request_headers_;
677 spdy::SpdyHeaderBlock response_headers_;
bnc614a92d32016-04-04 13:56:07678 string request_data_;
679 string response_data_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52680 quic::QuicClientPushPromiseIndex push_promise_index_;
[email protected]f702d572012-12-04 15:56:20681
ckrasic3865ee0f2016-02-29 22:04:56682 // For server push testing
danakjad1777e2016-04-16 00:56:42683 std::unique_ptr<QuicHttpStream> promised_stream_;
Ryan Hamilton0239aac2018-05-19 00:03:13684 spdy::SpdyHeaderBlock push_promise_;
685 spdy::SpdyHeaderBlock promised_response_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52686 const quic::QuicStreamId promise_id_;
ckrasic3865ee0f2016-02-29 22:04:56687 string promise_url_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52688 const quic::QuicStreamId stream_id_;
ckrasic3865ee0f2016-02-29 22:04:56689
Ryan Hamilton8d9ee76e2018-05-29 23:52:52690 const quic::QuicConnectionId connection_id_;
alyssar2adf3ac2016-05-03 17:12:58691 QuicTestPacketMaker client_maker_;
692 QuicTestPacketMaker server_maker_;
[email protected]f702d572012-12-04 15:56:20693 IPEndPoint self_addr_;
694 IPEndPoint peer_addr_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52695 quic::test::MockRandom random_generator_;
rch03b7a202016-02-05 00:54:20696 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05697 MockCryptoClientStreamFactory crypto_client_stream_factory_;
danakjad1777e2016-04-16 00:56:42698 std::unique_ptr<StaticSocketDataProvider> socket_data_;
Ryan Hamilton0d65a8c2019-06-07 00:46:02699 QuicPacketPrinter printer_;
[email protected]f702d572012-12-04 15:56:20700 std::vector<PacketToWrite> writes_;
701};
702
Victor Costane635086f2019-01-27 05:20:30703INSTANTIATE_TEST_SUITE_P(
Bence Békyce380cb2018-04-26 23:39:55704 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05705 QuicHttpStreamTest,
Victor Vasiliev5d6cdc22019-05-28 20:37:43706 ::testing::Combine(::testing::ValuesIn(quic::AllVersionsExcept99()),
Nick Harper23290b82019-05-02 00:02:56707 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20708
709TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44710 Initialize();
rtennetibe635732014-10-02 22:51:42711 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20712}
713
mmenkebd84c392015-09-02 14:12:34714TEST_P(QuicHttpStreamTest, CanReuseConnection) {
[email protected]ed3fc15d2013-03-08 18:37:44715 Initialize();
mmenkebd84c392015-09-02 14:12:34716 EXPECT_FALSE(stream_->CanReuseConnection());
[email protected]f702d572012-12-04 15:56:20717}
718
jri231c2972016-03-08 19:50:11719TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
Zhongyi Shibb28b1f2018-07-18 02:41:26720 request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri231c2972016-03-08 19:50:11721 Initialize();
xunjieli5fafe142016-03-23 23:32:54722 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27723 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54724 net_log_.bound(), callback_.callback()));
rch08e198572017-05-09 16:56:55725 QuicChromiumClientStream::Handle* client_stream =
jri231c2972016-03-08 19:50:11726 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
Zhongyi Shibb28b1f2018-07-18 02:41:26727 EXPECT_FALSE(client_stream->can_migrate_to_cellular_network());
jri231c2972016-03-08 19:50:11728}
729
[email protected]1e960032013-12-20 19:00:20730TEST_P(QuicHttpStreamTest, GetRequest) {
731 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45732 size_t spdy_request_header_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:02733 AddWrite(ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:37734 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33735 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02736 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
fayang3bcb8b502016-12-07 21:44:37737
[email protected]f702d572012-12-04 15:56:20738 Initialize();
739
740 request_.method = "GET";
rchcd379012017-04-12 21:53:32741 request_.url = GURL("https://www.example.org/");
[email protected]f702d572012-12-04 15:56:20742
xunjieli100937eb52016-09-15 20:09:37743 // Make sure getting load timing from the stream early does not crash.
744 LoadTimingInfo load_timing_info;
745 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
746
xunjieli5fafe142016-03-23 23:32:54747 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27748 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54749 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02750 EXPECT_EQ(OK,
751 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20752
753 // Ack the request.
Renjie90e808e2019-01-24 07:24:04754 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]f702d572012-12-04 15:56:20755
robpercival214763f2016-07-01 23:27:01756 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
757 IsError(ERR_IO_PENDING));
[email protected]f702d572012-12-04 15:56:20758
bnc614a92d32016-04-04 13:56:07759 SetResponse("404 Not Found", string());
sclittlec4dc1a32015-09-24 00:15:45760 size_t spdy_response_header_frame_length;
761 ProcessPacket(ConstructResponseHeadersPacket(
762 2, kFin, &spdy_response_header_frame_length));
[email protected]f702d572012-12-04 15:56:20763
764 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01765 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]cadac622013-06-11 16:46:36766 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20767 EXPECT_EQ(404, response_.headers->response_code());
768 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53769 EXPECT_FALSE(response_.response_time.is_null());
770 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20771
772 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02773 EXPECT_EQ(0,
774 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
775 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20776 EXPECT_TRUE(stream_->IsResponseBodyComplete());
777 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10778
xunjieli100937eb52016-09-15 20:09:37779 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28780 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37781
sclittle1edeeb22015-09-02 20:46:10782 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45783 // headers and payload.
784 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
785 stream_->GetTotalSentBytes());
786 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
787 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20788}
789
xunjieli100937eb52016-09-15 20:09:37790TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
791 SetRequest("GET", "/", DEFAULT_PRIORITY);
792 size_t spdy_request_header_frame_length;
793
Ryan Hamilton0d65a8c2019-06-07 00:46:02794 AddWrite(ConstructInitialSettingsPacket());
xunjieli100937eb52016-09-15 20:09:37795 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33796 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02797 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37798
799 // SetRequest() again for second request as |request_headers_| was moved.
800 SetRequest("GET", "/", DEFAULT_PRIORITY);
801 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33802 3, GetNthClientInitiatedBidirectionalStreamId(1), kIncludeVersion, kFin,
803 DEFAULT_PRIORITY, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:02804 &spdy_request_header_frame_length));
Renjie90e808e2019-01-24 07:24:04805 AddWrite(ConstructClientAckPacket(4, 3, 1, 2)); // Ack the responses.
xunjieli100937eb52016-09-15 20:09:37806
807 Initialize();
808
809 request_.method = "GET";
rchcd379012017-04-12 21:53:32810 request_.url = GURL("https://www.example.org/");
xunjieli100937eb52016-09-15 20:09:37811 // Start first request.
812 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27813 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37814 net_log_.bound(), callback_.callback()));
815 EXPECT_EQ(OK,
816 stream_->SendRequest(headers_, &response_, callback_.callback()));
817
818 // Start a second request.
Ryan Hamilton6c2a2a82017-12-15 02:06:28819 QuicHttpStream stream2(
820 session_->CreateHandle(HostPortPair("www.example.org", 443)));
xunjieli100937eb52016-09-15 20:09:37821 TestCompletionCallback callback2;
822 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27823 stream2.InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37824 net_log_.bound(), callback2.callback()));
825 EXPECT_EQ(OK,
826 stream2.SendRequest(headers_, &response_, callback2.callback()));
827
828 // Ack both requests.
Renjie90e808e2019-01-24 07:24:04829 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
xunjieli100937eb52016-09-15 20:09:37830
831 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
832 IsError(ERR_IO_PENDING));
833 size_t spdy_response_header_frame_length;
834 SetResponse("200 OK", string());
835 ProcessPacket(InnerConstructResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33836 2, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
ckrasicbf2f59c2017-05-04 23:54:36837 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37838
839 // Now that the headers have been processed, the callback will return.
840 EXPECT_THAT(callback_.WaitForResult(), IsOk());
841 EXPECT_EQ(200, response_.headers->response_code());
842
843 // There is no body, so this should return immediately.
844 EXPECT_EQ(0,
845 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
846 callback_.callback()));
847 EXPECT_TRUE(stream_->IsResponseBodyComplete());
848
849 LoadTimingInfo load_timing_info;
850 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28851 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37852
853 // SetResponse() again for second request as |response_headers_| was moved.
854 SetResponse("200 OK", string());
855 EXPECT_THAT(stream2.ReadResponseHeaders(callback2.callback()),
856 IsError(ERR_IO_PENDING));
857
858 ProcessPacket(InnerConstructResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33859 3, GetNthClientInitiatedBidirectionalStreamId(1), kFin,
ckrasicbf2f59c2017-05-04 23:54:36860 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37861
862 EXPECT_THAT(callback2.WaitForResult(), IsOk());
863
864 // There is no body, so this should return immediately.
865 EXPECT_EQ(0,
866 stream2.ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
867 callback2.callback()));
868 EXPECT_TRUE(stream2.IsResponseBodyComplete());
869
870 LoadTimingInfo load_timing_info2;
871 EXPECT_TRUE(stream2.GetLoadTimingInfo(&load_timing_info2));
xunjieli84adaab2016-09-20 01:12:28872 ExpectLoadTimingValid(load_timing_info2, /*session_reused=*/true);
xunjieli100937eb52016-09-15 20:09:37873}
874
xunjieli34291fe12016-03-02 13:58:38875// QuicHttpStream does not currently support trailers. It should ignore
876// trailers upon receiving them.
877TEST_P(QuicHttpStreamTest, GetRequestWithTrailers) {
878 SetRequest("GET", "/", DEFAULT_PRIORITY);
879 size_t spdy_request_header_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:02880 AddWrite(ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:37881 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33882 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02883 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
Renjie90e808e2019-01-24 07:24:04884 AddWrite(ConstructClientAckPacket(3, 3, 1, 2)); // Ack the data packet.
xunjieli34291fe12016-03-02 13:58:38885
886 Initialize();
887
888 request_.method = "GET";
rchcd379012017-04-12 21:53:32889 request_.url = GURL("https://www.example.org/");
xunjieli34291fe12016-03-02 13:58:38890
xunjieli5fafe142016-03-23 23:32:54891 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27892 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54893 net_log_.bound(), callback_.callback()));
894
xunjieli34291fe12016-03-02 13:58:38895 EXPECT_EQ(OK,
896 stream_->SendRequest(headers_, &response_, callback_.callback()));
xunjieli34291fe12016-03-02 13:58:38897 // Ack the request.
Renjie90e808e2019-01-24 07:24:04898 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
xunjieli34291fe12016-03-02 13:58:38899
robpercival214763f2016-07-01 23:27:01900 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
901 IsError(ERR_IO_PENDING));
xunjieli34291fe12016-03-02 13:58:38902
bnc614a92d32016-04-04 13:56:07903 SetResponse("200 OK", string());
xunjieli34291fe12016-03-02 13:58:38904
905 // Send the response headers.
906 size_t spdy_response_header_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:02907 ProcessPacket(ConstructResponseHeadersPacket(
908 2, !kFin, &spdy_response_header_frame_length));
xunjieli34291fe12016-03-02 13:58:38909 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01910 EXPECT_THAT(callback_.WaitForResult(), IsOk());
xunjieli34291fe12016-03-02 13:58:38911 ASSERT_TRUE(response_.headers.get());
912 EXPECT_EQ(200, response_.headers->response_code());
913 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
914 EXPECT_FALSE(response_.response_time.is_null());
915 EXPECT_FALSE(response_.request_time.is_null());
916
917 // Send the response body.
918 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:43919 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:17920 ProcessPacket(
921 ConstructServerDataPacket(3, false, !kFin, header + kResponseBody));
Ryan Hamilton0239aac2018-05-19 00:03:13922 spdy::SpdyHeaderBlock trailers;
xunjieli34291fe12016-03-02 13:58:38923 size_t spdy_trailers_frame_length;
924 trailers["foo"] = "bar";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52925 trailers[quic::kFinalOffsetHeaderKey] =
Raul Tambre8c1981d2019-02-08 02:22:26926 base::NumberToString(strlen(kResponseBody) + header.length());
Ryan Hamilton0d65a8c2019-06-07 00:46:02927 ProcessPacket(ConstructResponseTrailersPacket(4, kFin, std::move(trailers),
928 &spdy_trailers_frame_length));
xunjieli34291fe12016-03-02 13:58:38929
930 // Make sure trailers are processed.
fdoray92e35a72016-06-10 15:54:55931 base::RunLoop().RunUntilIdle();
xunjieli34291fe12016-03-02 13:58:38932
933 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
934 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
935 callback_.callback()));
936 EXPECT_TRUE(stream_->IsResponseBodyComplete());
937
938 EXPECT_EQ(OK,
939 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
940 callback_.callback()));
941
942 EXPECT_TRUE(stream_->IsResponseBodyComplete());
943 EXPECT_TRUE(AtEof());
944
945 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
946 // headers and payload.
947 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
948 stream_->GetTotalSentBytes());
Renjief49758b2019-01-11 23:32:41949 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length +
950 strlen(kResponseBody) + header.length() +
951 +spdy_trailers_frame_length),
952 stream_->GetTotalReceivedBytes());
xunjieli5fafe142016-03-23 23:32:54953 // Check that NetLog was filled as expected.
954 TestNetLogEntry::List entries;
955 net_log_.GetEntries(&entries);
956 size_t pos = ExpectLogContainsSomewhere(
957 entries, /*min_offset=*/0,
mikecirone8b85c432016-09-08 19:11:00958 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
959 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54960 pos = ExpectLogContainsSomewhere(
961 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00962 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
963 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54964 ExpectLogContainsSomewhere(
965 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00966 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
967 NetLogEventPhase::NONE);
xunjieli34291fe12016-03-02 13:58:38968}
969
[email protected]3e7dca62013-09-10 16:14:23970// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20971TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
972 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45973 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:02974 AddWrite(ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:37975 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33976 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02977 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:23978 Initialize();
979
980 request_.method = "GET";
rchcd379012017-04-12 21:53:32981 request_.url = GURL("https://www.example.org/");
[email protected]3e7dca62013-09-10 16:14:23982
xunjieli5fafe142016-03-23 23:32:54983 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27984 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54985 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02986 EXPECT_EQ(OK,
987 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23988
989 // Ack the request.
Renjie90e808e2019-01-24 07:24:04990 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]3e7dca62013-09-10 16:14:23991
robpercival214763f2016-07-01 23:27:01992 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
993 IsError(ERR_IO_PENDING));
[email protected]3e7dca62013-09-10 16:14:23994
bnc086b39e12016-06-24 13:05:26995 response_headers_[":status"] = "200 OK";
996 response_headers_[":version"] = "HTTP/1.1";
997 response_headers_["content-type"] = "text/plain";
998 response_headers_["big6"] = string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:23999
sclittlec4dc1a32015-09-24 00:15:451000 size_t spdy_response_headers_frame_length;
1001 ProcessPacket(ConstructResponseHeadersPacket(
1002 2, kFin, &spdy_response_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:231003
1004 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:011005 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]3e7dca62013-09-10 16:14:231006 ASSERT_TRUE(response_.headers.get());
1007 EXPECT_EQ(200, response_.headers->response_code());
1008 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1009
1010 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:021011 EXPECT_EQ(0,
1012 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1013 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:231014 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1015 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101016
1017 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451018 // headers and payload.
1019 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1020 stream_->GetTotalSentBytes());
1021 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
1022 stream_->GetTotalReceivedBytes());
[email protected]3e7dca62013-09-10 16:14:231023}
1024
rchf9f103cbc2014-08-30 05:28:041025// Regression test for http://crbug.com/409101
1026TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
1027 SetRequest("GET", "/", DEFAULT_PRIORITY);
1028 Initialize();
1029
1030 request_.method = "GET";
rchcd379012017-04-12 21:53:321031 request_.url = GURL("https://www.example.org/");
rchf9f103cbc2014-08-30 05:28:041032
xunjieli5fafe142016-03-23 23:32:541033 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271034 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541035 net_log_.bound(), callback_.callback()));
rchf9f103cbc2014-08-30 05:28:041036
jri78ec06a2016-03-31 18:19:401037 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521038 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchf9f103cbc2014-08-30 05:28:041039
1040 EXPECT_EQ(ERR_CONNECTION_CLOSED,
rjshaded5ced072015-12-18 19:26:021041 stream_->SendRequest(headers_, &response_, callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101042
1043 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1044 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rchf9f103cbc2014-08-30 05:28:041045}
1046
rch03b7a202016-02-05 00:54:201047// Regression test for http://crbug.com/584441
1048TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
1049 SetRequest("GET", "/", DEFAULT_PRIORITY);
1050 Initialize();
1051
1052 request_.method = "GET";
rchcd379012017-04-12 21:53:321053 request_.url = GURL("https://www.example.org/");
rch03b7a202016-02-05 00:54:201054
xunjieli5fafe142016-03-23 23:32:541055 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271056 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541057 net_log_.bound(), callback_.callback()));
rch03b7a202016-02-05 00:54:201058
1059 SSLInfo ssl_info;
rch11565e02016-02-09 20:13:471060 EXPECT_FALSE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201061 stream_->GetSSLInfo(&ssl_info);
rch11565e02016-02-09 20:13:471062 EXPECT_TRUE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201063
jri78ec06a2016-03-31 18:19:401064 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521065 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch03b7a202016-02-05 00:54:201066
rch11565e02016-02-09 20:13:471067 SSLInfo ssl_info2;
1068 stream_->GetSSLInfo(&ssl_info2);
1069 EXPECT_TRUE(ssl_info2.is_valid());
rch03b7a202016-02-05 00:54:201070}
1071
rchcd379012017-04-12 21:53:321072TEST_P(QuicHttpStreamTest, GetAlternativeService) {
1073 SetRequest("GET", "/", DEFAULT_PRIORITY);
1074 Initialize();
1075
1076 request_.method = "GET";
1077 request_.url = GURL("https://www.example.org/");
1078
1079 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271080 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
rchcd379012017-04-12 21:53:321081 net_log_.bound(), callback_.callback()));
1082
1083 AlternativeService alternative_service;
1084 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service));
1085 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1086 alternative_service);
1087
1088 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521089 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchcd379012017-04-12 21:53:321090
1091 AlternativeService alternative_service2;
1092 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service2));
1093 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1094 alternative_service2);
1095}
1096
zhongyica364fbb2015-12-12 03:39:121097TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
1098 SetRequest("GET", "/", DEFAULT_PRIORITY);
1099 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:021100 AddWrite(ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:371101 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331102 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:021103 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
fayang3bcb8b502016-12-07 21:44:371104 AddWrite(ConstructAckAndRstStreamPacket(3));
zhongyica364fbb2015-12-12 03:39:121105 Initialize();
1106
1107 request_.method = "GET";
rchcd379012017-04-12 21:53:321108 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121109
xunjieli5fafe142016-03-23 23:32:541110 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271111 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541112 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121113 EXPECT_EQ(OK,
1114 stream_->SendRequest(headers_, &response_, callback_.callback()));
1115
1116 // Ack the request.
Renjie90e808e2019-01-24 07:24:041117 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011118 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1119 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121120
Ryan Hamilton8d9ee76e2018-05-29 23:52:521121 quic::QuicConnectionCloseFrame frame;
Zhongyi Shica576df2019-04-12 17:43:401122 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551123 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121124
1125 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521126 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121127 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521128 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121129}
1130
Ryan Hamiltone316e482017-08-17 02:48:531131TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
rch617e0652017-04-26 17:57:511132 // By default the test setup defaults handshake to be confirmed. Manually set
1133 // it to be not confirmed.
rch617e0652017-04-26 17:57:511134 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271135 MockCryptoClientStream::ZERO_RTT);
rch617e0652017-04-26 17:57:511136
zhongyica364fbb2015-12-12 03:39:121137 SetRequest("GET", "/", DEFAULT_PRIORITY);
1138 size_t spdy_request_headers_frame_length;
Michael Warres167db3e2019-03-01 21:38:031139 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
fayang3bcb8b502016-12-07 21:44:371140 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331141 1, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:021142 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
zhongyica364fbb2015-12-12 03:39:121143 Initialize();
1144
1145 request_.method = "GET";
rchcd379012017-04-12 21:53:321146 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121147
xunjieli5fafe142016-03-23 23:32:541148 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271149 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541150 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121151 EXPECT_EQ(OK,
1152 stream_->SendRequest(headers_, &response_, callback_.callback()));
1153
1154 // Ack the request.
Renjie90e808e2019-01-24 07:24:041155 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011156 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1157 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121158
Ryan Hamilton8d9ee76e2018-05-29 23:52:521159 quic::QuicConnectionCloseFrame frame;
Zhongyi Shica576df2019-04-12 17:43:401160 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551161 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121162
1163 NetErrorDetails details;
zhongyica364fbb2015-12-12 03:39:121164 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521165 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121166}
1167
rch11a114a2014-09-04 23:41:591168// Regression test for http://crbug.com/409871
1169TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
1170 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451171 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:021172 AddWrite(ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:371173 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331174 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:021175 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
rch11a114a2014-09-04 23:41:591176 Initialize();
1177
1178 request_.method = "GET";
rchcd379012017-04-12 21:53:321179 request_.url = GURL("https://www.example.org/");
rch11a114a2014-09-04 23:41:591180
xunjieli5fafe142016-03-23 23:32:541181 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271182 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541183 net_log_.bound(), callback_.callback()));
rch11a114a2014-09-04 23:41:591184
rjshaded5ced072015-12-18 19:26:021185 EXPECT_EQ(OK,
1186 stream_->SendRequest(headers_, &response_, callback_.callback()));
rch11a114a2014-09-04 23:41:591187
jri78ec06a2016-03-31 18:19:401188 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521189 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch11a114a2014-09-04 23:41:591190
1191 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101192
1193 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451194 // headers and payload.
1195 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1196 stream_->GetTotalSentBytes());
sclittle1edeeb22015-09-02 20:46:101197 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rch11a114a2014-09-04 23:41:591198}
1199
[email protected]1e960032013-12-20 19:00:201200TEST_P(QuicHttpStreamTest, SendPostRequest) {
1201 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451202 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:021203 AddWrite(ConstructInitialSettingsPacket());
Yixin Wange7ecc472018-03-06 19:00:251204
Victor Vasiliev076657c2019-03-12 02:46:431205 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harper23290b82019-05-02 00:02:561206 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411207 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1208 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:021209 DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
1210 {kUploadData}));
Renjief49758b2019-01-11 23:32:411211 } else {
1212 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1213 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:021214 DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
1215 {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411216 }
Yixin Wange7ecc472018-03-06 19:00:251217
Renjie90e808e2019-01-24 07:24:041218 AddWrite(ConstructClientAckPacket(3, 3, 1, 2));
[email protected]f702d572012-12-04 15:56:201219
1220 Initialize();
1221
danakjad1777e2016-04-16 00:56:421222 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191223 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
ricea2deef682016-09-09 08:04:071224 kUploadData, strlen(kUploadData)));
rch97827ee2017-05-24 23:49:121225 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191226 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
[email protected]f702d572012-12-04 15:56:201227 request_.method = "POST";
rchcd379012017-04-12 21:53:321228 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121229 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581230 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
tfarina42834112016-09-22 13:38:201231 NetLogWithSource()),
1232 IsOk());
[email protected]f702d572012-12-04 15:56:201233
xunjieli5fafe142016-03-23 23:32:541234 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271235 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541236 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021237 EXPECT_EQ(OK,
1238 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:201239
1240 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041241 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]f702d572012-12-04 15:56:201242
1243 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071244 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451245 size_t spdy_response_headers_frame_length;
1246 ProcessPacket(ConstructResponseHeadersPacket(
1247 2, !kFin, &spdy_response_headers_frame_length));
[email protected]f702d572012-12-04 15:56:201248
rchfb47f712017-05-21 03:24:001249 // The headers have already arrived.
1250 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361251 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:201252 EXPECT_EQ(200, response_.headers->response_code());
1253 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1254
1255 // Send the response body.
1256 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431257 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:411258 ProcessPacket(
Ryan Hamilton7505eb92019-06-08 00:22:171259 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
[email protected]f702d572012-12-04 15:56:201260 // Since the body has already arrived, this should return immediately.
1261 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1262 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1263 callback_.callback()));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291264 EXPECT_EQ(0,
1265 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1266 callback_.callback()));
1267
1268 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1269 EXPECT_TRUE(AtEof());
1270
1271 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1272 // headers and payload.
1273 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411274 strlen(kUploadData) + header.length()),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291275 stream_->GetTotalSentBytes());
1276 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411277 strlen(kResponseBody) + header2.length()),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291278 stream_->GetTotalReceivedBytes());
1279}
1280
1281TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
1282 SetRequest("POST", "/", DEFAULT_PRIORITY);
1283 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:021284 AddWrite(ConstructInitialSettingsPacket());
Victor Vasiliev076657c2019-03-12 02:46:431285 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harper23290b82019-05-02 00:02:561286 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411287 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1288 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:021289 DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
1290 {kUploadData}));
Renjief49758b2019-01-11 23:32:411291 } else {
1292 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1293 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:021294 DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
1295 {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411296 }
1297
Renjie90e808e2019-01-24 07:24:041298 AddWrite(ConstructClientAckPacket(3, 3, 1, 2));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291299
1300 Initialize();
1301
1302 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191303 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
Ryan Hamilton2ef0a9c2017-07-25 03:18:291304 kUploadData, strlen(kUploadData)));
1305 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191306 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
Ryan Hamilton2ef0a9c2017-07-25 03:18:291307 request_.method = "POST";
1308 request_.url = GURL("https://www.example.org/");
1309 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581310 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291311 NetLogWithSource()),
1312 IsOk());
1313
1314 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271315 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
Ryan Hamilton2ef0a9c2017-07-25 03:18:291316 net_log_.bound(), callback_.callback()));
1317 EXPECT_EQ(OK,
1318 stream_->SendRequest(headers_, &response_, callback_.callback()));
1319
1320 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041321 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291322
1323 // Send the response headers (but not the body).
1324 SetResponse("200 OK", string());
1325 size_t spdy_response_headers_frame_length;
1326 ProcessPacket(ConstructResponseHeadersPacket(
1327 2, !kFin, &spdy_response_headers_frame_length));
1328
1329 // The headers have already arrived.
1330 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1331 ASSERT_TRUE(response_.headers.get());
1332 EXPECT_EQ(200, response_.headers->response_code());
1333 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1334
1335 // Send the response body.
1336 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431337 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:411338 ProcessPacket(
Ryan Hamilton7505eb92019-06-08 00:22:171339 ConstructServerDataPacket(3, false, !kFin, header2 + kResponseBody));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291340 // Since the body has already arrived, this should return immediately.
1341 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1342 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1343 callback_.callback()));
Ryan Hamilton7505eb92019-06-08 00:22:171344 ProcessPacket(ConstructServerDataPacket(4, false, kFin, ""));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291345 EXPECT_EQ(0,
1346 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1347 callback_.callback()));
[email protected]f702d572012-12-04 15:56:201348
1349 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1350 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101351
1352 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451353 // headers and payload.
1354 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411355 strlen(kUploadData) + header.length()),
sclittle1edeeb22015-09-02 20:46:101356 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451357 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411358 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101359 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:201360}
1361
[email protected]1e960032013-12-20 19:00:201362TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
1363 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:471364 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451365 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:021366 AddWrite(ConstructInitialSettingsPacket());
Victor Vasiliev076657c2019-03-12 02:46:431367 std::string header = ConstructDataHeader(chunk_size);
Nick Harper23290b82019-05-02 00:02:561368 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411369 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1370 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
Ryan Hamilton0d65a8c2019-06-07 00:46:021371 !kFin, DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
1372 {header, kUploadData}));
Ryan Hamilton7505eb92019-06-08 00:22:171373 AddWrite(ConstructClientMultipleDataFramesPacket(3, kIncludeVersion, kFin,
1374 {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411375 } else {
1376 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1377 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
Ryan Hamilton0d65a8c2019-06-07 00:46:021378 !kFin, DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
1379 {kUploadData}));
Ryan Hamilton7505eb92019-06-08 00:22:171380 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, kUploadData));
Renjief49758b2019-01-11 23:32:411381 }
1382
Renjie90e808e2019-01-24 07:24:041383 AddWrite(ConstructClientAckPacket(4, 3, 1, 2));
[email protected]c9e49a02013-02-26 05:56:471384 Initialize();
1385
Jeremy Roman0579ed62017-08-29 15:56:191386 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121387 auto* chunked_upload_stream =
1388 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1389 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:471390
1391 request_.method = "POST";
rchcd379012017-04-12 21:53:321392 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121393 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071394 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201395 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]c9e49a02013-02-26 05:56:471396
xunjieli5fafe142016-03-23 23:32:541397 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271398 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541399 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021400 ASSERT_EQ(ERR_IO_PENDING,
1401 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:471402
rch97827ee2017-05-24 23:49:121403 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
robpercival214763f2016-07-01 23:27:011404 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]c9e49a02013-02-26 05:56:471405
1406 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041407 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]c9e49a02013-02-26 05:56:471408
1409 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071410 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451411 size_t spdy_response_headers_frame_length;
1412 ProcessPacket(ConstructResponseHeadersPacket(
1413 2, !kFin, &spdy_response_headers_frame_length));
[email protected]c9e49a02013-02-26 05:56:471414
rchfb47f712017-05-21 03:24:001415 // The headers have already arrived.
1416 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361417 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:471418 EXPECT_EQ(200, response_.headers->response_code());
1419 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1420
1421 // Send the response body.
1422 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431423 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171424 ProcessPacket(
1425 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
[email protected]c9e49a02013-02-26 05:56:471426
1427 // Since the body has already arrived, this should return immediately.
1428 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1429 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1430 callback_.callback()));
1431
1432 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1433 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101434
1435 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451436 // headers and payload.
1437 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411438 strlen(kUploadData) * 2 + header.length() * 2),
sclittle1edeeb22015-09-02 20:46:101439 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451440 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411441 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101442 stream_->GetTotalReceivedBytes());
[email protected]c9e49a02013-02-26 05:56:471443}
1444
[email protected]16ba7742014-08-22 00:57:251445TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
1446 SetRequest("POST", "/", DEFAULT_PRIORITY);
1447 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451448 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:021449 AddWrite(ConstructInitialSettingsPacket());
Victor Vasiliev076657c2019-03-12 02:46:431450 std::string header = ConstructDataHeader(chunk_size);
Renjief49758b2019-01-11 23:32:411451
Nick Harper23290b82019-05-02 00:02:561452 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411453 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1454 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
Ryan Hamilton0d65a8c2019-06-07 00:46:021455 !kFin, DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
1456 {kUploadData}));
Renjief49758b2019-01-11 23:32:411457 } else {
1458 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1459 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
Ryan Hamilton0d65a8c2019-06-07 00:46:021460 !kFin, DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
1461 {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411462 }
Ryan Hamilton7505eb92019-06-08 00:22:171463 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, ""));
Renjie90e808e2019-01-24 07:24:041464 AddWrite(ConstructClientAckPacket(4, 3, 1, 2));
[email protected]16ba7742014-08-22 00:57:251465 Initialize();
1466
Jeremy Roman0579ed62017-08-29 15:56:191467 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121468 auto* chunked_upload_stream =
1469 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1470 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:251471
1472 request_.method = "POST";
rchcd379012017-04-12 21:53:321473 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121474 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071475 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201476 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251477
xunjieli5fafe142016-03-23 23:32:541478 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271479 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541480 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021481 ASSERT_EQ(ERR_IO_PENDING,
1482 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251483
rch97827ee2017-05-24 23:49:121484 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011485 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251486
Renjie90e808e2019-01-24 07:24:041487 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]16ba7742014-08-22 00:57:251488
1489 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071490 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451491 size_t spdy_response_headers_frame_length;
1492 ProcessPacket(ConstructResponseHeadersPacket(
1493 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251494
rchfb47f712017-05-21 03:24:001495 // The headers have already arrived.
1496 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251497 ASSERT_TRUE(response_.headers.get());
1498 EXPECT_EQ(200, response_.headers->response_code());
1499 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1500
1501 // Send the response body.
1502 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431503 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171504 ProcessPacket(
1505 ConstructServerDataPacket(3, false, kFin, header2 + kResponseBody));
[email protected]16ba7742014-08-22 00:57:251506
rchb27683c2015-07-29 23:53:501507 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251508 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1509 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1510 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251511 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1512 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101513
1514 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451515 // headers and payload.
1516 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411517 strlen(kUploadData) + header.length()),
sclittle1edeeb22015-09-02 20:46:101518 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451519 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411520 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101521 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251522}
1523
1524TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
1525 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451526 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:021527 AddWrite(ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:371528 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331529 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, !kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:021530 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
Ryan Hamilton7505eb92019-06-08 00:22:171531 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, ""));
Renjie90e808e2019-01-24 07:24:041532 AddWrite(ConstructClientAckPacket(4, 3, 1, 2));
[email protected]16ba7742014-08-22 00:57:251533 Initialize();
1534
Jeremy Roman0579ed62017-08-29 15:56:191535 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121536 auto* chunked_upload_stream =
1537 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
[email protected]16ba7742014-08-22 00:57:251538
1539 request_.method = "POST";
rchcd379012017-04-12 21:53:321540 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121541 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071542 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201543 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251544
xunjieli5fafe142016-03-23 23:32:541545 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271546 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541547 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021548 ASSERT_EQ(ERR_IO_PENDING,
1549 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251550
rch97827ee2017-05-24 23:49:121551 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011552 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251553
Renjie90e808e2019-01-24 07:24:041554 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]16ba7742014-08-22 00:57:251555
1556 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071557 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451558 size_t spdy_response_headers_frame_length;
1559 ProcessPacket(ConstructResponseHeadersPacket(
1560 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251561
rchfb47f712017-05-21 03:24:001562 // The headers have already arrived.
1563 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251564 ASSERT_TRUE(response_.headers.get());
1565 EXPECT_EQ(200, response_.headers->response_code());
1566 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1567
1568 // Send the response body.
1569 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431570 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171571 ProcessPacket(
1572 ConstructServerDataPacket(3, false, kFin, header + kResponseBody));
[email protected]16ba7742014-08-22 00:57:251573
rchb27683c2015-07-29 23:53:501574 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251575 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1576 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1577 callback_.callback()));
1578
1579 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1580 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101581
1582 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451583 // headers and payload.
1584 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1585 stream_->GetTotalSentBytes());
1586 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411587 strlen(kResponseBody) + header.length()),
sclittle1edeeb22015-09-02 20:46:101588 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251589}
1590
[email protected]1e960032013-12-20 19:00:201591TEST_P(QuicHttpStreamTest, DestroyedEarly) {
1592 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451593 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:021594 AddWrite(ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:371595 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331596 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:021597 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
fayang3bcb8b502016-12-07 21:44:371598 AddWrite(ConstructAckAndRstStreamPacket(3));
[email protected]63534512012-12-23 18:49:001599 Initialize();
1600
1601 request_.method = "GET";
rchcd379012017-04-12 21:53:321602 request_.url = GURL("https://www.example.org/");
[email protected]63534512012-12-23 18:49:001603
xunjieli5fafe142016-03-23 23:32:541604 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271605 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541606 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021607 EXPECT_EQ(OK,
1608 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]63534512012-12-23 18:49:001609
1610 // Ack the request.
Renjie90e808e2019-01-24 07:24:041611 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
rchfb47f712017-05-21 03:24:001612 EXPECT_THAT(stream_->ReadResponseHeaders(
1613 base::Bind(&QuicHttpStreamTest::CloseStream,
1614 base::Unretained(this), stream_.get())),
robpercival214763f2016-07-01 23:27:011615 IsError(ERR_IO_PENDING));
[email protected]63534512012-12-23 18:49:001616
1617 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201618 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:001619 // In the course of processing this packet, the QuicHttpStream close itself.
rchfb47f712017-05-21 03:24:001620 size_t response_size = 0;
rch1bcfddf22017-06-03 00:26:291621 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin, &response_size));
[email protected]63534512012-12-23 18:49:001622
fdoray92e35a72016-06-10 15:54:551623 base::RunLoop().RunUntilIdle();
rchb27683c2015-07-29 23:53:501624
[email protected]63534512012-12-23 18:49:001625 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101626
1627 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451628 // headers and payload.
1629 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1630 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001631 // The stream was closed after receiving the headers.
1632 EXPECT_EQ(static_cast<int64_t>(response_size),
1633 stream_->GetTotalReceivedBytes());
[email protected]63534512012-12-23 18:49:001634}
1635
[email protected]1e960032013-12-20 19:00:201636TEST_P(QuicHttpStreamTest, Priority) {
1637 SetRequest("GET", "/", MEDIUM);
sclittlec4dc1a32015-09-24 00:15:451638 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:021639 AddWrite(ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:371640 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331641 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:021642 MEDIUM, &spdy_request_headers_frame_length));
[email protected]24e5bc52013-09-18 15:36:581643 Initialize();
1644
1645 request_.method = "GET";
rchcd379012017-04-12 21:53:321646 request_.url = GURL("https://www.example.org/");
[email protected]24e5bc52013-09-18 15:36:581647
Steven Valdezb4ff0412018-01-18 22:39:271648 EXPECT_EQ(OK,
1649 stream_->InitializeStream(&request_, true, MEDIUM, net_log_.bound(),
1650 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581651
rjshaded5ced072015-12-18 19:26:021652 EXPECT_EQ(OK,
1653 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581654
[email protected]24e5bc52013-09-18 15:36:581655 // Ack the request.
Renjie90e808e2019-01-24 07:24:041656 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011657 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1658 IsError(ERR_IO_PENDING));
[email protected]24e5bc52013-09-18 15:36:581659
1660 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201661 SetResponse("404 OK", "hello world!");
rchfb47f712017-05-21 03:24:001662 size_t response_size = 0;
1663 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, &response_size));
[email protected]24e5bc52013-09-18 15:36:581664
rchfb47f712017-05-21 03:24:001665 EXPECT_EQ(OK, callback_.WaitForResult());
rchb27683c2015-07-29 23:53:501666
[email protected]24e5bc52013-09-18 15:36:581667 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101668
1669 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451670 // headers and payload.
1671 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1672 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001673 EXPECT_EQ(static_cast<int64_t>(response_size),
1674 stream_->GetTotalReceivedBytes());
[email protected]24e5bc52013-09-18 15:36:581675}
1676
xunjieli8dff50b2016-07-22 14:19:061677TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
1678 SetRequest("POST", "/", DEFAULT_PRIORITY);
1679 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:021680 AddWrite(ConstructInitialSettingsPacket());
Victor Vasiliev076657c2019-03-12 02:46:431681 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harper23290b82019-05-02 00:02:561682 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411683 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1684 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
Ryan Hamilton0d65a8c2019-06-07 00:46:021685 !kFin, DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
1686 {kUploadData}));
Renjief49758b2019-01-11 23:32:411687 } else {
1688 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1689 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
Ryan Hamilton0d65a8c2019-06-07 00:46:021690 !kFin, DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
1691 {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411692 }
1693
xunjieli8dff50b2016-07-22 14:19:061694 // Second data write will result in a synchronous failure which will close
1695 // the session.
1696 AddWrite(SYNCHRONOUS, ERR_FAILED);
1697 Initialize();
1698
Jeremy Roman0579ed62017-08-29 15:56:191699 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121700 auto* chunked_upload_stream =
1701 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
xunjieli8dff50b2016-07-22 14:19:061702
1703 request_.method = "POST";
rchcd379012017-04-12 21:53:321704 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121705 request_.upload_data_stream = upload_data_stream_.get();
xunjieli8dff50b2016-07-22 14:19:061706 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201707 TestCompletionCallback().callback(), NetLogWithSource()));
xunjieli8dff50b2016-07-22 14:19:061708
1709 size_t chunk_size = strlen(kUploadData);
rch97827ee2017-05-24 23:49:121710 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
xunjieli8dff50b2016-07-22 14:19:061711 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271712 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli8dff50b2016-07-22 14:19:061713 net_log_.bound(), callback_.callback()));
1714 QuicHttpStream* stream = stream_.get();
1715 DeleteStreamCallback delete_stream_callback(std::move(stream_));
1716 // SendRequest() completes asynchronously after the final chunk is added.
Yixin Wange7ecc472018-03-06 19:00:251717 // Error does not surface yet since packet write is triggered by a packet
1718 // flusher that tries to bundle request body writes.
xunjieli8dff50b2016-07-22 14:19:061719 ASSERT_EQ(ERR_IO_PENDING,
1720 stream->SendRequest(headers_, &response_, callback_.callback()));
rch97827ee2017-05-24 23:49:121721 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
xunjieli8dff50b2016-07-22 14:19:061722 int rv = callback_.WaitForResult();
Yixin Wange7ecc472018-03-06 19:00:251723 EXPECT_EQ(OK, rv);
1724 // Error will be surfaced once an attempt to read the response occurs.
1725 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1726 stream->ReadResponseHeaders(callback_.callback()));
xunjieli8dff50b2016-07-22 14:19:061727}
1728
rtenneti15656ae2016-01-23 03:05:031729TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
1730 SetRequest("POST", "/", DEFAULT_PRIORITY);
Ryan Hamilton0d65a8c2019-06-07 00:46:021731 AddWrite(ConstructInitialSettingsPacket());
rtenneti15656ae2016-01-23 03:05:031732 AddWrite(SYNCHRONOUS, ERR_FAILED);
1733 Initialize();
1734
Jeremy Roman0579ed62017-08-29 15:56:191735 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
Yixin Wange7ecc472018-03-06 19:00:251736 auto* chunked_upload_stream =
1737 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031738
1739 request_.method = "POST";
rchcd379012017-04-12 21:53:321740 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121741 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031742 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201743 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031744
xunjieli5fafe142016-03-23 23:32:541745 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271746 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541747 net_log_.bound(), callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251748 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:031749 stream_->SendRequest(headers_, &response_, callback_.callback()));
mmenkeffff3642017-06-15 17:37:241750
Yixin Wange7ecc472018-03-06 19:00:251751 // Error will be surfaced once |upload_data_stream| triggers the next write.
1752 size_t chunk_size = strlen(kUploadData);
1753 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1754 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
1755
1756 EXPECT_LE(0, stream_->GetTotalSentBytes());
1757 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1758}
1759
1760TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersCompleteReadResponse) {
1761 SetRequest("POST", "/", DEFAULT_PRIORITY);
Ryan Hamilton0d65a8c2019-06-07 00:46:021762 AddWrite(ConstructInitialSettingsPacket());
Yixin Wange7ecc472018-03-06 19:00:251763 AddWrite(SYNCHRONOUS, ERR_FAILED);
1764 Initialize();
1765
1766 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1767 auto* chunked_upload_stream =
1768 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1769
1770 request_.method = "POST";
1771 request_.url = GURL("https://www.example.org/");
1772 request_.upload_data_stream = upload_data_stream_.get();
1773
1774 size_t chunk_size = strlen(kUploadData);
1775 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1776
1777 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1778 TestCompletionCallback().callback(), NetLogWithSource()));
1779
1780 ASSERT_EQ(OK,
1781 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
1782 net_log_.bound(), callback_.callback()));
1783 ASSERT_EQ(OK,
1784 stream_->SendRequest(headers_, &response_, callback_.callback()));
1785
1786 // Error will be surfaced once an attempt to read the response occurs.
1787 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1788 stream_->ReadResponseHeaders(callback_.callback()));
1789
mmenkeffff3642017-06-15 17:37:241790 EXPECT_LE(0, stream_->GetTotalSentBytes());
1791 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031792}
1793
1794TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
1795 SetRequest("POST", "/", DEFAULT_PRIORITY);
1796 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:021797 AddWrite(ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:371798 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331799 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, !kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:021800 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
rtenneti15656ae2016-01-23 03:05:031801 AddWrite(SYNCHRONOUS, ERR_FAILED);
1802 Initialize();
1803
Jeremy Roman0579ed62017-08-29 15:56:191804 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121805 auto* chunked_upload_stream =
1806 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031807
1808 request_.method = "POST";
rchcd379012017-04-12 21:53:321809 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121810 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031811 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201812 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031813
xunjieli5fafe142016-03-23 23:32:541814 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271815 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541816 net_log_.bound(), callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251817 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:031818 stream_->SendRequest(headers_, &response_, callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251819
1820 size_t chunk_size = strlen(kUploadData);
1821 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1822 // Error does not surface yet since packet write is triggered by a packet
1823 // flusher that tries to bundle request body writes.
1824 ASSERT_EQ(OK, callback_.WaitForResult());
1825 // Error will be surfaced once an attempt to read the response occurs.
1826 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1827 stream_->ReadResponseHeaders(callback_.callback()));
1828
1829 EXPECT_LE(0, stream_->GetTotalSentBytes());
1830 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1831}
1832
1833TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBundledBodyComplete) {
1834 SetRequest("POST", "/", DEFAULT_PRIORITY);
1835 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:021836 AddWrite(ConstructInitialSettingsPacket());
Victor Vasiliev076657c2019-03-12 02:46:431837 std::string header = ConstructDataHeader(strlen(kUploadData));
Nick Harper23290b82019-05-02 00:02:561838 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:411839 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1840 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
Ryan Hamilton0d65a8c2019-06-07 00:46:021841 !kFin, DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
1842 {kUploadData}));
Renjief49758b2019-01-11 23:32:411843 } else {
1844 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1845 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
Ryan Hamilton0d65a8c2019-06-07 00:46:021846 !kFin, DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
1847 {header, kUploadData}));
Renjief49758b2019-01-11 23:32:411848 }
1849
Yixin Wange7ecc472018-03-06 19:00:251850 AddWrite(SYNCHRONOUS, ERR_FAILED);
1851 Initialize();
1852
1853 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1854 auto* chunked_upload_stream =
1855 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1856
1857 request_.method = "POST";
1858 request_.url = GURL("https://www.example.org/");
1859 request_.upload_data_stream = upload_data_stream_.get();
1860
1861 size_t chunk_size = strlen(kUploadData);
1862 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
1863
1864 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1865 TestCompletionCallback().callback(), NetLogWithSource()));
1866
1867 ASSERT_EQ(OK,
1868 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
1869 net_log_.bound(), callback_.callback()));
1870 ASSERT_EQ(ERR_IO_PENDING,
1871 stream_->SendRequest(headers_, &response_, callback_.callback()));
1872
1873 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1874
1875 // Error does not surface yet since packet write is triggered by a packet
1876 // flusher that tries to bundle request body writes.
1877 ASSERT_EQ(OK, callback_.WaitForResult());
1878 // Error will be surfaced once an attempt to read the response occurs.
1879 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1880 stream_->ReadResponseHeaders(callback_.callback()));
1881
1882 EXPECT_LE(0, stream_->GetTotalSentBytes());
1883 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031884}
1885
ckrasic3865ee0f2016-02-29 22:04:561886TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
1887 SetRequest("GET", "/", DEFAULT_PRIORITY);
1888 Initialize();
1889
1890 // Initialize the first stream, for receiving the promise on.
1891 request_.method = "GET";
rchcd379012017-04-12 21:53:321892 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561893
xunjieli5fafe142016-03-23 23:32:541894 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271895 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541896 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561897
1898 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1899 // packet, but does it matter?
1900 ReceivePromise(promise_id_);
1901 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1902
1903 request_.url = GURL(promise_url_);
1904
1905 // Make the second stream that will exercise the first step of the
1906 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271907 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1908 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1909 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561910
1911 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251912 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561913 size_t spdy_response_headers_frame_length;
1914 ProcessPacket(InnerConstructResponseHeadersPacket(
1915 1, promise_id_, false, &spdy_response_headers_frame_length));
1916
1917 // Receive the promised response body.
1918 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431919 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171920 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
1921 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:561922
1923 // Now sending a matching request will have successful rendezvous
1924 // with the promised stream.
1925 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
1926 callback_.callback()));
1927
1928 EXPECT_EQ(
1929 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1930 ->id(),
1931 promise_id_);
1932
1933 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:011934 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1935 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561936
1937 // As will be the body.
1938 EXPECT_EQ(
1939 static_cast<int>(strlen(kResponseBody)),
1940 promised_stream_->ReadResponseBody(
1941 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1942 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1943 EXPECT_TRUE(AtEof());
1944
1945 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1946 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1947 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1948 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411949 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:561950 promised_stream_->GetTotalReceivedBytes());
1951}
1952
1953TEST_P(QuicHttpStreamTest, ServerPushGetRequestSlowResponse) {
1954 SetRequest("GET", "/", DEFAULT_PRIORITY);
1955 Initialize();
1956
1957 // Initialize the first stream, for receiving the promise on.
1958 request_.method = "GET";
rchcd379012017-04-12 21:53:321959 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561960
xunjieli5fafe142016-03-23 23:32:541961 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271962 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541963 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561964
1965 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1966 // packet, but does it matter?
1967 ReceivePromise(promise_id_);
1968 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1969
1970 request_.url = GURL(promise_url_);
1971
1972 // Make the second stream that will exercise the first step of the
1973 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271974 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1975 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1976 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561977
1978 // Now sending a matching request will rendezvous with the promised
1979 // stream, but pending secondary validation.
1980 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
1981 headers_, &response_, callback_.callback()));
1982
1983 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251984 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561985 size_t spdy_response_headers_frame_length;
1986 ProcessPacket(InnerConstructResponseHeadersPacket(
1987 1, promise_id_, false, &spdy_response_headers_frame_length));
1988
1989 // Receive the promised response body.
1990 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431991 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:171992 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
1993 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:561994
fdoray92e35a72016-06-10 15:54:551995 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:561996
1997 // Rendezvous should have succeeded now, so the promised stream
1998 // should point at our push stream, and we should be able read
1999 // headers and data from it.
robpercival214763f2016-07-01 23:27:012000 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562001
2002 EXPECT_EQ(
2003 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2004 ->id(),
2005 promise_id_);
2006
robpercival214763f2016-07-01 23:27:012007 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2008 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562009
2010 EXPECT_EQ(
2011 static_cast<int>(strlen(kResponseBody)),
2012 promised_stream_->ReadResponseBody(
2013 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2014
2015 // Callback should return
2016 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2017 EXPECT_TRUE(AtEof());
2018
2019 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2020 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2021 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2022 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412023 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562024 promised_stream_->GetTotalReceivedBytes());
2025}
2026
ckrasic2c63f9b2016-08-16 23:54:072027// Verify fix for crbug.com/637349
2028TEST_P(QuicHttpStreamTest, ServerPushCancelHttpStreamBeforeResponse) {
2029 SetRequest("GET", "/", DEFAULT_PRIORITY);
2030 Initialize();
2031
2032 // Initialize the first stream, for receiving the promise on.
2033 request_.method = "GET";
rchcd379012017-04-12 21:53:322034 request_.url = GURL("https://www.example.org/");
ckrasic2c63f9b2016-08-16 23:54:072035
2036 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272037 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
ckrasic2c63f9b2016-08-16 23:54:072038 net_log_.bound(), callback_.callback()));
2039
2040 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2041 // packet, but does it matter?
2042 ReceivePromise(promise_id_);
2043 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2044
2045 request_.url = GURL(promise_url_);
2046
2047 // Make the second stream that will exercise the first step of the
2048 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272049 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2050 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2051 callback_.callback()));
ckrasic2c63f9b2016-08-16 23:54:072052
2053 // Now sending a matching request will rendezvous with the promised
2054 // stream, but pending secondary validation.
2055 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2056 headers_, &response_, callback_.callback()));
2057
2058 base::RunLoop().RunUntilIdle();
2059
2060 // Cause of FinalValidation() crash as per bug.
2061 promised_stream_.reset();
2062
2063 // Receive the promised response headers.
2064 response_headers_ = promised_response_.Clone();
2065 size_t spdy_response_headers_frame_length;
2066 ProcessPacket(InnerConstructResponseHeadersPacket(
2067 1, promise_id_, false, &spdy_response_headers_frame_length));
2068}
2069
ckrasic3865ee0f2016-02-29 22:04:562070TEST_P(QuicHttpStreamTest, ServerPushCrossOriginOK) {
2071 SetRequest("GET", "/", DEFAULT_PRIORITY);
2072 Initialize();
2073
2074 // Initialize the first stream, for receiving the promise on.
2075 request_.method = "GET";
rchcd379012017-04-12 21:53:322076 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562077
xunjieli5fafe142016-03-23 23:32:542078 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272079 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542080 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562081
2082 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2083 // packet, but does it matter?
2084
2085 push_promise_[":authority"] = "mail.example.org";
Ryan Hamilton8d9ee76e2018-05-29 23:52:522086 promise_url_ = quic::SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562087
2088 ReceivePromise(promise_id_);
2089 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2090
2091 request_.url = GURL(promise_url_);
2092
2093 // Make the second stream that will exercise the first step of the
2094 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272095 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2096 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2097 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562098
2099 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252100 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562101 size_t spdy_response_headers_frame_length;
2102 ProcessPacket(InnerConstructResponseHeadersPacket(
2103 1, promise_id_, false, &spdy_response_headers_frame_length));
2104
2105 // Receive the promised response body.
2106 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432107 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172108 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2109 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562110
2111 // Now sending a matching request will have successful rendezvous
2112 // with the promised stream.
2113 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
2114 callback_.callback()));
2115
2116 EXPECT_EQ(
2117 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2118 ->id(),
2119 promise_id_);
2120
2121 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:012122 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2123 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562124
2125 // As will be the body.
2126 EXPECT_EQ(
2127 static_cast<int>(strlen(kResponseBody)),
2128 promised_stream_->ReadResponseBody(
2129 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2130 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2131 EXPECT_TRUE(AtEof());
2132
2133 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2134 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2135 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2136 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412137 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562138 promised_stream_->GetTotalReceivedBytes());
2139}
2140
2141TEST_P(QuicHttpStreamTest, ServerPushCrossOriginFail) {
2142 SetRequest("GET", "/", DEFAULT_PRIORITY);
2143 Initialize();
2144
2145 // Initialize the first stream, for receiving the promise on.
2146 request_.method = "GET";
rchcd379012017-04-12 21:53:322147 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562148
xunjieli5fafe142016-03-23 23:32:542149 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272150 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542151 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562152
2153 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2154 // packet, but does it matter?
2155 push_promise_[":authority"] = "www.notexample.org";
Ryan Hamilton8d9ee76e2018-05-29 23:52:522156 promise_url_ = quic::SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562157
2158 ReceivePromise(promise_id_);
2159 // The promise will have been rejected because the cert doesn't
2160 // match.
2161 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2162}
2163
2164TEST_P(QuicHttpStreamTest, ServerPushVaryCheckOK) {
2165 SetRequest("GET", "/", DEFAULT_PRIORITY);
2166 Initialize();
2167
2168 // Initialize the first stream, for receiving the promise on.
2169 request_.method = "GET";
rchcd379012017-04-12 21:53:322170 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562171
xunjieli5fafe142016-03-23 23:32:542172 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272173 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542174 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562175
2176 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562177
2178 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2179 // packet, but does it matter?
2180 ReceivePromise(promise_id_);
2181 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2182
2183 request_.url = GURL(promise_url_);
2184
2185 // Make the second stream that will exercise the first step of the
2186 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272187 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2188 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2189 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562190
2191 headers_.SetHeader("accept-encoding", "gzip");
2192
2193 // Now sending a matching request will rendezvous with the promised
2194 // stream, but pending secondary validation.
2195 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2196 headers_, &response_, callback_.callback()));
2197
2198 // Receive the promised response headers.
2199 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252200 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562201 size_t spdy_response_headers_frame_length;
2202 ProcessPacket(InnerConstructResponseHeadersPacket(
2203 1, promise_id_, false, &spdy_response_headers_frame_length));
2204
2205 // Receive the promised response body.
2206 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432207 std::string header = ConstructDataHeader(strlen(kResponseBody));
Ryan Hamilton7505eb92019-06-08 00:22:172208 ProcessPacket(server_maker_.MakeDataPacket(2, promise_id_, false, kFin,
2209 header + kResponseBody));
ckrasic3865ee0f2016-02-29 22:04:562210
fdoray92e35a72016-06-10 15:54:552211 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562212
2213 // Rendezvous should have succeeded now, so the promised stream
2214 // should point at our push stream, and we should be able read
2215 // headers and data from it.
robpercival214763f2016-07-01 23:27:012216 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562217
2218 EXPECT_EQ(
2219 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2220 ->id(),
2221 promise_id_);
2222
robpercival214763f2016-07-01 23:27:012223 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2224 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562225
2226 EXPECT_EQ(
2227 static_cast<int>(strlen(kResponseBody)),
2228 promised_stream_->ReadResponseBody(
2229 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2230
2231 // Callback should return
2232 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2233 EXPECT_TRUE(AtEof());
2234
2235 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2236 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2237 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2238 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412239 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562240 promised_stream_->GetTotalReceivedBytes());
2241}
2242
2243TEST_P(QuicHttpStreamTest, ServerPushVaryCheckFail) {
2244 SetRequest("GET", "/", DEFAULT_PRIORITY);
2245 request_headers_[":scheme"] = "https";
2246 request_headers_[":path"] = "/bar";
2247 request_headers_["accept-encoding"] = "sdch";
2248
2249 size_t spdy_request_header_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:022250 AddWrite(ConstructInitialSettingsPacket());
Yixin Wangb470bc882018-02-15 18:43:572251
Fan Yangac867502019-01-28 21:10:232252 uint64_t client_packet_number = 2;
Yixin Wangb470bc882018-02-15 18:43:572253 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:562254 version_.transport_version >= quic::QUIC_VERSION_43) {
Ryan Hamilton0d65a8c2019-06-07 00:46:022255 AddWrite(ConstructClientPriorityPacket(client_packet_number++,
2256 kIncludeVersion, promise_id_, 0,
2257 DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:572258 }
Michael Warresabba8b7d2018-07-20 22:50:272259 AddWrite(ConstructClientRstStreamVaryMismatchAndRequestHeadersPacket(
Victor Vasiliev4a6798e2019-03-06 02:26:092260 client_packet_number++,
Nick Harper23290b82019-05-02 00:02:562261 stream_id_ + quic::QuicUtils::StreamIdDelta(version_.transport_version),
2262 !kIncludeVersion, kFin, DEFAULT_PRIORITY, promise_id_,
Ryan Hamilton0d65a8c2019-06-07 00:46:022263 &spdy_request_header_frame_length));
Renjie90e808e2019-01-24 07:24:042264 AddWrite(ConstructClientAckPacket(client_packet_number++, 3, 1, 2));
Yixin Wangb470bc882018-02-15 18:43:572265 AddWrite(ConstructClientRstStreamCancelledPacket(client_packet_number++));
2266
ckrasic3865ee0f2016-02-29 22:04:562267 Initialize();
2268
2269 // Initialize the first stream, for receiving the promise on.
2270 request_.method = "GET";
rchcd379012017-04-12 21:53:322271 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562272
xunjieli5fafe142016-03-23 23:32:542273 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272274 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542275 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562276
2277 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562278
2279 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2280 // packet, but does it matter?
2281 ReceivePromise(promise_id_);
2282 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2283
2284 request_.url = GURL(promise_url_);
2285
2286 // Make the second stream that will exercise the first step of the
2287 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272288 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2289 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2290 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562291
2292 headers_.SetHeader("accept-encoding", "sdch");
2293
2294 // Now sending a matching request will rendezvous with the promised
2295 // stream, but pending secondary validation.
2296 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2297 headers_, &response_, callback_.callback()));
2298
2299 // Receive the promised response headers.
2300 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252301 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562302 size_t spdy_response_headers_frame_length;
2303 ProcessPacket(InnerConstructResponseHeadersPacket(
2304 1, promise_id_, false, &spdy_response_headers_frame_length));
2305
fdoray92e35a72016-06-10 15:54:552306 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562307
2308 // Rendezvous should have failed due to vary mismatch, so the
2309 // promised stream should have been aborted, and instead we have a
2310 // new, regular client initiated stream.
robpercival214763f2016-07-01 23:27:012311 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562312
2313 // Not a server-initiated stream.
2314 EXPECT_NE(
2315 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2316 ->id(),
2317 promise_id_);
2318
2319 // Instead, a new client-initiated stream.
2320 EXPECT_EQ(
2321 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2322 ->id(),
Nick Harper23290b82019-05-02 00:02:562323 stream_id_ + quic::QuicUtils::StreamIdDelta(version_.transport_version));
ckrasic3865ee0f2016-02-29 22:04:562324
2325 // After rendezvous failure, the push stream has been cancelled.
2326 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2327
2328 // The rest of the test verifies that the retried as
2329 // client-initiated version of |promised_stream_| works as intended.
2330
2331 // Ack the request.
Renjie90e808e2019-01-24 07:24:042332 ProcessPacket(ConstructServerAckPacket(2, 1, 1, 1));
ckrasic3865ee0f2016-02-29 22:04:562333
bnc614a92d32016-04-04 13:56:072334 SetResponse("404 Not Found", string());
ckrasic3865ee0f2016-02-29 22:04:562335 size_t spdy_response_header_frame_length;
2336 ProcessPacket(InnerConstructResponseHeadersPacket(
Nick Harper23290b82019-05-02 00:02:562337 3,
2338 stream_id_ + quic::QuicUtils::StreamIdDelta(version_.transport_version),
2339 kFin, &spdy_response_header_frame_length));
ckrasic3865ee0f2016-02-29 22:04:562340
fdoray92e35a72016-06-10 15:54:552341 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562342
robpercival214763f2016-07-01 23:27:012343 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2344 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562345 ASSERT_TRUE(response_.headers.get());
2346 EXPECT_EQ(404, response_.headers->response_code());
2347 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
2348 EXPECT_FALSE(response_.response_time.is_null());
2349 EXPECT_FALSE(response_.request_time.is_null());
2350
2351 // There is no body, so this should return immediately.
2352 EXPECT_EQ(
2353 0, promised_stream_->ReadResponseBody(
2354 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2355 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2356
2357 stream_->Close(true);
2358
2359 EXPECT_TRUE(AtEof());
2360
2361 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
2362 // headers and payload.
2363 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
2364 promised_stream_->GetTotalSentBytes());
2365 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
2366 promised_stream_->GetTotalReceivedBytes());
2367}
2368
maksim.sisov84e20c92016-06-23 08:49:342369TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
2370 SetRequest("POST", "/", DEFAULT_PRIORITY);
2371 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:022372 AddWrite(ConstructInitialSettingsPacket());
Yixin Wange7ecc472018-03-06 19:00:252373 AddWrite(ConstructRequestAndRstPacket(
Fan Yang32c5a112018-12-10 20:06:332374 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, !kFin,
Yixin Wange7ecc472018-03-06 19:00:252375 DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
Ryan Hamilton0d65a8c2019-06-07 00:46:022376 quic::QUIC_ERROR_PROCESSING_STREAM, 0));
maksim.sisov84e20c92016-06-23 08:49:342377
2378 Initialize();
2379
Jeremy Roman0579ed62017-08-29 15:56:192380 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342381 ReadErrorUploadDataStream::FailureMode::SYNC);
2382 request_.method = "POST";
rchcd379012017-04-12 21:53:322383 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122384 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342385 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202386 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342387
2388 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272389 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342390 net_log_.bound(), callback_.callback()));
2391
2392 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
robpercival214763f2016-07-01 23:27:012393 EXPECT_THAT(result, IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342394
2395 EXPECT_TRUE(AtEof());
2396
2397 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2398 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2399 stream_->GetTotalSentBytes());
2400 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2401}
2402
2403TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
2404 SetRequest("POST", "/", DEFAULT_PRIORITY);
2405 size_t spdy_request_headers_frame_length;
Ryan Hamilton0d65a8c2019-06-07 00:46:022406 AddWrite(ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:372407 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332408 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, !kFin,
Ryan Hamilton0d65a8c2019-06-07 00:46:022409 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
fayang3bcb8b502016-12-07 21:44:372410 AddWrite(ConstructClientRstStreamErrorPacket(3, !kIncludeVersion));
maksim.sisov84e20c92016-06-23 08:49:342411
2412 Initialize();
2413
Jeremy Roman0579ed62017-08-29 15:56:192414 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342415 ReadErrorUploadDataStream::FailureMode::ASYNC);
2416 request_.method = "POST";
rchcd379012017-04-12 21:53:322417 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122418 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342419 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202420 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342421
2422 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272423 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342424 net_log_.bound(), callback_.callback()));
2425
2426 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2427
Renjie90e808e2019-01-24 07:24:042428 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
maksim.sisov84e20c92016-06-23 08:49:342429 SetResponse("200 OK", string());
2430
robpercival214763f2016-07-01 23:27:012431 EXPECT_THAT(result, IsError(ERR_IO_PENDING));
2432 EXPECT_THAT(callback_.GetResult(result), IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342433
2434 EXPECT_TRUE(AtEof());
2435
2436 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2437 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2438 stream_->GetTotalSentBytes());
2439 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2440}
2441
[email protected]f702d572012-12-04 15:56:202442} // namespace test
[email protected]f702d572012-12-04 15:56:202443} // namespace net