blob: b2e826e51acab055e9c0e5bba9bb38be463c5b78 [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"
Ryan Hamiltona3ee93a72018-08-01 22:03:0832#include "net/quic/crypto/proof_verifier_chromium.h"
33#include "net/quic/mock_crypto_client_stream_factory.h"
34#include "net/quic/quic_chromium_alarm_factory.h"
35#include "net/quic/quic_chromium_connection_helper.h"
36#include "net/quic/quic_chromium_packet_reader.h"
37#include "net/quic/quic_chromium_packet_writer.h"
38#include "net/quic/quic_http_utils.h"
39#include "net/quic/quic_server_info.h"
40#include "net/quic/quic_stream_factory.h"
41#include "net/quic/quic_test_packet_maker.h"
42#include "net/quic/test_task_runner.h"
tbansalca83c002016-04-28 20:56:2843#include "net/socket/socket_performance_watcher.h"
[email protected]f702d572012-12-04 15:56:2044#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5845#include "net/spdy/spdy_http_utils.h"
rch03b7a202016-02-05 00:54:2046#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0147#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4348#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0149#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5150#include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h"
51#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
52#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
53#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
54#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
55#include "net/third_party/quiche/src/quic/core/quic_connection.h"
56#include "net/third_party/quiche/src/quic/core/quic_utils.h"
57#include "net/third_party/quiche/src/quic/core/quic_write_blocked_list.h"
58#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
59#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
60#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
61#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
62#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
63#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
64#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
65#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1466#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
67#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
68#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
Ramin Halavati683bcaa92018-02-14 08:42:3969#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]f702d572012-12-04 15:56:2070#include "testing/gmock/include/gmock/gmock.h"
71#include "testing/gtest/include/gtest/gtest.h"
72
bnc614a92d32016-04-04 13:56:0773using std::string;
[email protected]f702d572012-12-04 15:56:2074using testing::_;
[email protected]06ff5152013-08-29 01:03:0575using testing::AnyNumber;
76using testing::Return;
[email protected]f702d572012-12-04 15:56:2077
78namespace net {
[email protected]f702d572012-12-04 15:56:2079namespace test {
[email protected]f702d572012-12-04 15:56:2080namespace {
81
[email protected]16ba7742014-08-22 00:57:2582const char kUploadData[] = "Really nifty data!";
rch9ae5b3b2016-02-11 00:36:2983const char kDefaultServerHostName[] = "www.example.org";
rchcd379012017-04-12 21:53:3284const uint16_t kDefaultServerPort = 443;
[email protected]f702d572012-12-04 15:56:2085
Ryan Hamilton8d9ee76e2018-05-29 23:52:5286class TestQuicConnection : public quic::QuicConnection {
[email protected]f702d572012-12-04 15:56:2087 public:
Ryan Hamilton8d9ee76e2018-05-29 23:52:5288 TestQuicConnection(const quic::ParsedQuicVersionVector& versions,
89 quic::QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2090 IPEndPoint address,
rch12fef552016-01-15 16:26:3191 QuicChromiumConnectionHelper* helper,
rch16c74d1d2016-04-22 06:14:0792 QuicChromiumAlarmFactory* alarm_factory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5293 quic::QuicPacketWriter* writer)
94 : quic::QuicConnection(
95 connection_id,
96 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(address)),
97 helper,
98 alarm_factory,
99 writer,
100 true /* owns_writer */,
101 quic::Perspective::IS_CLIENT,
102 versions) {}
[email protected]f702d572012-12-04 15:56:20103
Ryan Hamilton8d9ee76e2018-05-29 23:52:52104 void SetSendAlgorithm(quic::SendAlgorithmInterface* send_algorithm) {
105 quic::test::QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:20106 }
107};
108
maksim.sisov84e20c92016-06-23 08:49:34109// UploadDataStream that always returns errors on data read.
110class ReadErrorUploadDataStream : public UploadDataStream {
111 public:
112 enum class FailureMode { SYNC, ASYNC };
113
114 explicit ReadErrorUploadDataStream(FailureMode mode)
115 : UploadDataStream(true, 0), async_(mode), weak_factory_(this) {}
116 ~ReadErrorUploadDataStream() override {}
117
118 private:
119 void CompleteRead() { UploadDataStream::OnReadCompleted(ERR_FAILED); }
120
121 // UploadDataStream implementation:
tfarina42834112016-09-22 13:38:20122 int InitInternal(const NetLogWithSource& net_log) override { return OK; }
maksim.sisov84e20c92016-06-23 08:49:34123
124 int ReadInternal(IOBuffer* buf, int buf_len) override {
125 if (async_ == FailureMode::ASYNC) {
126 base::ThreadTaskRunnerHandle::Get()->PostTask(
kylecharf4fe5172019-02-15 18:53:49127 FROM_HERE, base::BindOnce(&ReadErrorUploadDataStream::CompleteRead,
128 weak_factory_.GetWeakPtr()));
maksim.sisov84e20c92016-06-23 08:49:34129 return ERR_IO_PENDING;
130 }
131 return ERR_FAILED;
132 }
133
134 void ResetInternal() override {}
135
136 const FailureMode async_;
137
138 base::WeakPtrFactory<ReadErrorUploadDataStream> weak_factory_;
139
140 DISALLOW_COPY_AND_ASSIGN(ReadErrorUploadDataStream);
141};
142
Bence Béky8ddc2492018-06-13 01:02:04143// A helper class that will delete |stream| when the callback is invoked.
xunjieli8dff50b2016-07-22 14:19:06144class DeleteStreamCallback : public TestCompletionCallbackBase {
145 public:
Bence Béky8ddc2492018-06-13 01:02:04146 explicit DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)
147 : stream_(std::move(stream)) {}
xunjieli8dff50b2016-07-22 14:19:06148
Bence Béky8ddc2492018-06-13 01:02:04149 CompletionOnceCallback callback() {
150 return base::BindOnce(&DeleteStreamCallback::DeleteStream,
151 base::Unretained(this));
152 }
xunjieli8dff50b2016-07-22 14:19:06153
154 private:
155 void DeleteStream(int result) {
156 stream_.reset();
157 SetResult(result);
158 }
159
160 std::unique_ptr<QuicHttpStream> stream_;
xunjieli8dff50b2016-07-22 14:19:06161};
162
[email protected]f702d572012-12-04 15:56:20163} // namespace
164
[email protected]24e5bc52013-09-18 15:36:58165class QuicHttpStreamPeer {
166 public:
rch08e198572017-05-09 16:56:55167 static QuicChromiumClientStream::Handle* GetQuicChromiumClientStream(
[email protected]24e5bc52013-09-18 15:36:58168 QuicHttpStream* stream) {
rch08e198572017-05-09 16:56:55169 return stream->stream_.get();
[email protected]24e5bc52013-09-18 15:36:58170 }
171};
172
Ryan Hamilton8d9ee76e2018-05-29 23:52:52173class QuicHttpStreamTest : public ::testing::TestWithParam<
174 std::tuple<quic::QuicTransportVersion, bool>>,
175 public WithScopedTaskEnvironment {
rchfb47f712017-05-21 03:24:00176 public:
177 void CloseStream(QuicHttpStream* stream, int /*rv*/) { stream->Close(false); }
178
[email protected]f702d572012-12-04 15:56:20179 protected:
[email protected]1e960032013-12-20 19:00:20180 static const bool kFin = true;
181 static const bool kIncludeVersion = true;
182 static const bool kIncludeCongestionFeedback = true;
183
[email protected]f702d572012-12-04 15:56:20184 // Holds a packet to be written to the wire, and the IO mode that should
185 // be used by the mock socket when performing the write.
186 struct PacketToWrite {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52187 PacketToWrite(IoMode mode, quic::QuicReceivedPacket* packet)
rjshaded5ced072015-12-18 19:26:02188 : mode(mode), packet(packet) {}
rtenneti15656ae2016-01-23 03:05:03189 PacketToWrite(IoMode mode, int rv) : mode(mode), packet(nullptr), rv(rv) {}
[email protected]f702d572012-12-04 15:56:20190 IoMode mode;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52191 quic::QuicReceivedPacket* packet;
rtenneti15656ae2016-01-23 03:05:03192 int rv;
[email protected]f702d572012-12-04 15:56:20193 };
194
195 QuicHttpStreamTest()
Yixin Wang079ad542018-01-11 04:06:05196 : version_(std::get<0>(GetParam())),
197 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52198 crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting(),
199 quic::TlsClientHandshaker::CreateSslCtx()),
Victor Costan9c7302b2018-08-27 16:39:44200 read_buffer_(base::MakeRefCounted<IOBufferWithSize>(4096)),
Fan Yang32c5a112018-12-10 20:06:33201 promise_id_(GetNthServerInitiatedUnidirectionalStreamId(0)),
202 stream_id_(GetNthClientInitiatedBidirectionalStreamId(0)),
David Schinazic8281052019-01-24 06:14:17203 connection_id_(quic::test::TestConnectionId(2)),
Yixin Wang079ad542018-01-11 04:06:05204 client_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58205 connection_id_,
206 &clock_,
207 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52208 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05209 client_headers_include_h2_stream_dependency_),
210 server_maker_(version_,
zhongyi5dbfdd42017-06-20 05:22:15211 connection_id_,
alyssar2adf3ac2016-05-03 17:12:58212 &clock_,
213 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52214 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05215 false),
ckrasic3865ee0f2016-02-29 22:04:56216 random_generator_(0),
217 response_offset_(0) {
martijn21968ea2016-02-24 18:46:20218 IPAddress ip(192, 0, 2, 33);
[email protected]f702d572012-12-04 15:56:20219 peer_addr_ = IPEndPoint(ip, 443);
220 self_addr_ = IPEndPoint(ip, 8435);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52221 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
Ramin Halavati683bcaa92018-02-14 08:42:39222 request_.traffic_annotation =
223 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f702d572012-12-04 15:56:20224 }
225
226 ~QuicHttpStreamTest() {
Renjieba55fae2018-09-20 03:05:16227 session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
228 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]f702d572012-12-04 15:56:20229 for (size_t i = 0; i < writes_.size(); i++) {
230 delete writes_[i].packet;
231 }
232 }
233
234 // Adds a packet to the list of expected writes.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52235 void AddWrite(std::unique_ptr<quic::QuicReceivedPacket> packet) {
[email protected]1e960032013-12-20 19:00:20236 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20237 }
238
rtenneti15656ae2016-01-23 03:05:03239 void AddWrite(IoMode mode, int rv) {
240 writes_.push_back(PacketToWrite(mode, rv));
241 }
242
[email protected]f702d572012-12-04 15:56:20243 // Returns the packet to be written at position |pos|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52244 quic::QuicReceivedPacket* GetWrite(size_t pos) { return writes_[pos].packet; }
[email protected]f702d572012-12-04 15:56:20245
246 bool AtEof() {
rch37de576c2015-05-17 20:28:17247 return socket_data_->AllReadDataConsumed() &&
248 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20249 }
250
Ryan Hamilton8d9ee76e2018-05-29 23:52:52251 void ProcessPacket(std::unique_ptr<quic::QuicReceivedPacket> packet) {
fayang91ca2012016-11-22 07:42:46252 connection_->ProcessUdpPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52253 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(self_addr_)),
254 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(peer_addr_)),
255 *packet);
[email protected]f702d572012-12-04 15:56:20256 }
257
258 // Configures the test fixture to use the list of expected writes.
259 void Initialize() {
260 mock_writes_.reset(new MockWrite[writes_.size()]);
261 for (size_t i = 0; i < writes_.size(); i++) {
rtenneti15656ae2016-01-23 03:05:03262 if (writes_[i].packet == nullptr) {
263 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
264 } else {
265 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
266 writes_[i].packet->length());
267 }
bnc614a92d32016-04-04 13:56:07268 }
[email protected]f702d572012-12-04 15:56:20269
rtennetibe635732014-10-02 22:51:42270 socket_data_.reset(new StaticSocketDataProvider(
Ryan Sleevib8d7ea02018-05-07 20:01:01271 base::span<MockRead>(),
272 base::make_span(mock_writes_.get(), writes_.size())));
[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(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52299 quic::test::SupportedVersions(
300 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version_)),
Dan Zhangfefaf5b2017-12-11 17:06:24301 connection_id_, peer_addr_, helper_.get(), alarm_factory_.get(),
Ryan Hamilton9edcf1a2017-11-22 05:55:17302 new QuicChromiumPacketWriter(
303 socket.get(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]f702d572012-12-04 15:56:20304 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41305 connection_->SetSendAlgorithm(send_algorithm_);
rch03b7a202016-02-05 00:54:20306
307 // Load a certificate that is valid for *.example.org
308 scoped_refptr<X509Certificate> test_cert(
309 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
310 EXPECT_TRUE(test_cert.get());
311
312 verify_details_.cert_verify_result.verified_cert = test_cert;
313 verify_details_.cert_verify_result.is_issued_by_known_root = true;
314 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
315
xunjieli84adaab2016-09-20 01:12:28316 base::TimeTicks dns_end = base::TimeTicks::Now();
317 base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);
ckrasic4f9d88d2015-07-22 22:23:16318 session_.reset(new QuicChromiumClientSession(
xunjielib53b38c2016-03-24 15:54:36319 connection_, std::move(socket),
rtenneti1cd3b162015-09-29 02:58:28320 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57321 &transport_security_state_, /*ssl_config_service=*/nullptr,
danakjad1777e2016-04-16 00:56:42322 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
Paul Jensen8e3c5d32018-02-19 17:06:33323 QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
324 PRIVACY_MODE_DISABLED, SocketTag()),
Zhongyi Shi757fcce2018-06-27 05:41:27325 /*require_confirmation=*/false, /*migrate_session_early_v2=*/false,
326 /*migrate_session_on_network_change_v2=*/false,
327 /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shie01f2db2019-02-22 19:53:23328 quic::QuicTime::Delta::FromMilliseconds(
329 kDefaultRetransmittableOnWireTimeoutMillisecs),
Zhongyi Shi32fe14d42019-02-28 00:25:36330 /*migrate_idle_session=*/false,
Zhongyi Shic16b4102019-02-12 00:37:40331 base::TimeDelta::FromSeconds(kDefaultIdleSessionMigrationPeriodSeconds),
Zhongyi Shi73f23ca872017-12-13 18:37:13332 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shiee760762018-08-01 00:54:29333 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30334 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17335 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52336 quic::QuicTime::Delta::FromMilliseconds(
337 kQuicYieldAfterDurationMilliseconds),
Zhongyi Shidbce7f412019-02-01 23:16:29338 /*go_away_on_path_degrading*/ false,
Yixin Wang079ad542018-01-11 04:06:05339 client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52340 quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
341 dns_start, dns_end, &push_promise_index_, nullptr,
Zhongyi Shic16b4102019-02-12 00:37:40342 base::DefaultTickClock::GetInstance(),
xunjieli84adaab2016-09-20 01:12:28343 base::ThreadTaskRunnerHandle::Get().get(),
xunjieli5fafe142016-03-23 23:32:54344 /*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));
rtennetid39bd762015-06-12 01:05:52345 session_->Initialize();
xunjieli100937eb52016-09-15 20:09:37346 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57347
rch433bf5f2017-02-14 04:10:47348 session_->CryptoConnect(callback.callback());
Ryan Hamilton6c2a2a82017-12-15 02:06:28349 stream_ = std::make_unique<QuicHttpStream>(
350 session_->CreateHandle(HostPortPair("www.example.org", 443)));
351 promised_stream_ = std::make_unique<QuicHttpStream>(
352 session_->CreateHandle(HostPortPair("www.example.org", 443)));
ckrasic3865ee0f2016-02-29 22:04:56353 push_promise_[":path"] = "/bar";
354 push_promise_[":authority"] = "www.example.org";
355 push_promise_[":version"] = "HTTP/1.1";
356 push_promise_[":method"] = "GET";
357 push_promise_[":scheme"] = "https";
358
359 promised_response_[":status"] = "200 OK";
360 promised_response_[":version"] = "HTTP/1.1";
361 promised_response_["content-type"] = "text/plain";
362
Ryan Hamilton8d9ee76e2018-05-29 23:52:52363 promise_url_ = quic::SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
[email protected]6cca996b2013-01-25 07:43:36364 }
365
bnc614a92d32016-04-04 13:56:07366 void SetRequest(const string& method,
367 const string& path,
[email protected]1e960032013-12-20 19:00:20368 RequestPriority priority) {
rchcd379012017-04-12 21:53:32369 request_headers_ = client_maker_.GetRequestHeaders(method, "https", path);
[email protected]6cca996b2013-01-25 07:43:36370 }
371
bnc614a92d32016-04-04 13:56:07372 void SetResponse(const string& status, const string& body) {
alyssar2adf3ac2016-05-03 17:12:58373 response_headers_ = server_maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03374 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36375 }
[email protected]f702d572012-12-04 15:56:20376
Ryan Hamilton8d9ee76e2018-05-29 23:52:52377 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructDataPacket(
Fan Yangac867502019-01-28 21:10:23378 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52379 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56380 bool should_include_version,
381 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52382 quic::QuicStreamOffset offset,
383 quic::QuicStringPiece data,
alyssar2adf3ac2016-05-03 17:12:58384 QuicTestPacketMaker* maker) {
385 return maker->MakeDataPacket(packet_number, stream_id,
ckrasic3865ee0f2016-02-29 22:04:56386 should_include_version, fin, offset, data);
387 }
388
Ryan Hamilton8d9ee76e2018-05-29 23:52:52389 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23390 uint64_t packet_number,
[email protected]e8ff26842013-03-22 21:02:05391 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20392 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52393 quic::QuicStreamOffset offset,
394 quic::QuicStringPiece data) {
ckrasic3865ee0f2016-02-29 22:04:56395 return InnerConstructDataPacket(packet_number, stream_id_,
alyssar2adf3ac2016-05-03 17:12:58396 should_include_version, fin, offset, data,
397 &client_maker_);
398 }
399
Renjief49758b2019-01-11 23:32:41400 std::unique_ptr<quic::QuicReceivedPacket>
401 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23402 uint64_t packet_number,
Renjief49758b2019-01-11 23:32:41403 bool should_include_version,
404 bool fin,
405 quic::QuicStreamOffset offset,
406 const std::vector<std::string>& data) {
407 return client_maker_.MakeMultipleDataFramesPacket(
408 packet_number, stream_id_, should_include_version, fin, offset, data);
409 }
410
Ryan Hamilton8d9ee76e2018-05-29 23:52:52411 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23412 uint64_t packet_number,
alyssar2adf3ac2016-05-03 17:12:58413 bool should_include_version,
414 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52415 quic::QuicStreamOffset offset,
416 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58417 return InnerConstructDataPacket(packet_number, stream_id_,
418 should_include_version, fin, offset, data,
419 &server_maker_);
ckrasic3865ee0f2016-02-29 22:04:56420 }
421
Ryan Hamilton8d9ee76e2018-05-29 23:52:52422 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23423 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52424 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56425 bool should_include_version,
426 bool fin,
427 RequestPriority request_priority,
xunjieli100937eb52016-09-15 20:09:37428 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52429 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48430 return InnerConstructRequestHeadersPacket(
431 packet_number, stream_id, should_include_version, fin, request_priority,
432 0, spdy_headers_frame_length, offset);
433 }
434
Ryan Hamilton8d9ee76e2018-05-29 23:52:52435 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23436 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52437 quic::QuicStreamId stream_id,
Yixin Wang7a3f1b8d2018-01-17 21:40:48438 bool should_include_version,
439 bool fin,
440 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52441 quic::QuicStreamId parent_stream_id,
Yixin Wang7a3f1b8d2018-01-17 21:40:48442 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52443 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13444 spdy::SpdyPriority priority =
ckrasic3865ee0f2016-02-29 22:04:56445 ConvertRequestPriorityToQuicPriority(request_priority);
alyssar2adf3ac2016-05-03 17:12:58446 return client_maker_.MakeRequestHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56447 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48448 std::move(request_headers_), parent_stream_id,
449 spdy_headers_frame_length, offset);
[email protected]f702d572012-12-04 15:56:20450 }
451
Ryan Hamilton8d9ee76e2018-05-29 23:52:52452 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25453 ConstructRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23454 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52455 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25456 bool should_include_version,
457 bool fin,
458 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52459 quic::QuicStreamId parent_stream_id,
460 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25461 size_t* spdy_headers_frame_length,
462 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13463 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25464 ConvertRequestPriorityToQuicPriority(request_priority);
465 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
466 packet_number, stream_id, should_include_version, fin, priority,
467 std::move(request_headers_), parent_stream_id, offset,
468 spdy_headers_frame_length, data_writes);
469 }
470
Ryan Hamilton8d9ee76e2018-05-29 23:52:52471 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestAndRstPacket(
Fan Yangac867502019-01-28 21:10:23472 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52473 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25474 bool should_include_version,
475 bool fin,
476 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52477 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25478 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52479 quic::QuicStreamOffset* header_stream_offset,
480 quic::QuicRstStreamErrorCode error_code,
Yixin Wange7ecc472018-03-06 19:00:25481 size_t bytes_written) {
Ryan Hamilton0239aac2018-05-19 00:03:13482 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25483 ConvertRequestPriorityToQuicPriority(request_priority);
484 return client_maker_.MakeRequestHeadersAndRstPacket(
485 packet_number, stream_id, should_include_version, fin, priority,
486 std::move(request_headers_), parent_stream_id,
487 spdy_headers_frame_length, header_stream_offset, error_code,
488 bytes_written);
489 }
490
Ryan Hamilton8d9ee76e2018-05-29 23:52:52491 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23492 uint64_t packet_number,
rtennetif4bdb542015-01-21 14:33:05493 bool fin,
sclittlec4dc1a32015-09-24 00:15:45494 RequestPriority request_priority,
495 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56496 return InnerConstructRequestHeadersPacket(
497 packet_number, stream_id_, kIncludeVersion, fin, request_priority,
xunjieli100937eb52016-09-15 20:09:37498 spdy_headers_frame_length, nullptr);
ckrasic3865ee0f2016-02-29 22:04:56499 }
500
Ryan Hamilton8d9ee76e2018-05-29 23:52:52501 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructResponseHeadersPacket(
Fan Yangac867502019-01-28 21:10:23502 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52503 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56504 bool fin,
505 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58506 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26507 packet_number, stream_id, !kIncludeVersion, fin,
508 std::move(response_headers_), spdy_headers_frame_length,
509 &response_offset_);
[email protected]1e960032013-12-20 19:00:20510 }
511
Ryan Hamilton8d9ee76e2018-05-29 23:52:52512 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseHeadersPacket(
Fan Yangac867502019-01-28 21:10:23513 uint64_t packet_number,
sclittlec4dc1a32015-09-24 00:15:45514 bool fin,
515 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56516 return InnerConstructResponseHeadersPacket(packet_number, stream_id_, fin,
517 spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20518 }
519
Ryan Hamilton8d9ee76e2018-05-29 23:52:52520 std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23521 ConstructResponseHeadersPacketWithOffset(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52522 bool fin,
523 size_t* spdy_headers_frame_length,
524 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58525 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26526 packet_number, stream_id_, !kIncludeVersion, fin,
527 std::move(response_headers_), spdy_headers_frame_length, offset);
xunjieli34291fe12016-03-02 13:58:38528 }
529
Ryan Hamilton8d9ee76e2018-05-29 23:52:52530 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseTrailersPacket(
Fan Yangac867502019-01-28 21:10:23531 uint64_t packet_number,
xunjieli34291fe12016-03-02 13:58:38532 bool fin,
Ryan Hamilton0239aac2018-05-19 00:03:13533 spdy::SpdyHeaderBlock trailers,
xunjieli34291fe12016-03-02 13:58:38534 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52535 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58536 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26537 packet_number, stream_id_, !kIncludeVersion, fin, std::move(trailers),
alyssar2adf3ac2016-05-03 17:12:58538 spdy_headers_frame_length, offset);
xunjieli34291fe12016-03-02 13:58:38539 }
540
Ryan Hamilton8d9ee76e2018-05-29 23:52:52541 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23542 uint64_t packet_number) {
alyssara72f5352016-10-20 12:45:16543 return client_maker_.MakeRstPacket(packet_number, true, stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52544 quic::QUIC_RST_ACKNOWLEDGEMENT);
[email protected]06ff5152013-08-29 01:03:05545 }
546
Ryan Hamilton8d9ee76e2018-05-29 23:52:52547 std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23548 ConstructClientRstStreamCancelledPacket(uint64_t packet_number) {
alyssar2adf3ac2016-05-03 17:12:58549 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52550 stream_id_, quic::QUIC_STREAM_CANCELLED);
rtenneti6bd660b2015-07-18 00:19:53551 }
552
Ryan Hamilton8d9ee76e2018-05-29 23:52:52553 std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23554 ConstructClientRstStreamVaryMismatchPacket(uint64_t packet_number) {
alyssar2adf3ac2016-05-03 17:12:58555 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52556 promise_id_,
557 quic::QUIC_PROMISE_VARY_MISMATCH);
ckrasic3865ee0f2016-02-29 22:04:56558 }
559
Fan Yang550c6282018-06-22 18:53:25560 std::unique_ptr<quic::QuicReceivedPacket>
561 ConstructClientRstStreamVaryMismatchAndRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23562 uint64_t packet_number,
Fan Yang550c6282018-06-22 18:53:25563 quic::QuicStreamId stream_id,
564 bool should_include_version,
565 bool fin,
566 RequestPriority request_priority,
567 quic::QuicStreamId parent_stream_id,
568 size_t* spdy_headers_frame_length,
569 quic::QuicStreamOffset* offset) {
570 spdy::SpdyPriority priority =
571 ConvertRequestPriorityToQuicPriority(request_priority);
572 return client_maker_.MakeRstAndRequestHeadersPacket(
573 packet_number, should_include_version, promise_id_,
574 quic::QUIC_PROMISE_VARY_MISMATCH, stream_id, fin, priority,
575 std::move(request_headers_), parent_stream_id,
576 spdy_headers_frame_length, offset);
577 }
578
Ryan Hamilton8d9ee76e2018-05-29 23:52:52579 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23580 uint64_t packet_number,
581 uint64_t largest_received,
582 uint64_t smallest_received,
583 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58584 return client_maker_.MakeAckAndRstPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52585 packet_number, !kIncludeVersion, stream_id_,
586 quic::QUIC_STREAM_CANCELLED, largest_received, smallest_received,
587 least_unacked, !kIncludeCongestionFeedback);
xunjieli34291fe12016-03-02 13:58:38588 }
589
Ryan Hamilton8d9ee76e2018-05-29 23:52:52590 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamErrorPacket(
Fan Yangac867502019-01-28 21:10:23591 uint64_t packet_number,
maksim.sisov84e20c92016-06-23 08:49:34592 bool include_version) {
593 return client_maker_.MakeRstPacket(packet_number, include_version,
594 stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52595 quic::QUIC_ERROR_PROCESSING_STREAM);
maksim.sisov84e20c92016-06-23 08:49:34596 }
597
Ryan Hamilton8d9ee76e2018-05-29 23:52:52598 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
Fan Yangac867502019-01-28 21:10:23599 uint64_t packet_number) {
Renjie90e808e2019-01-24 07:24:04600 return ConstructAckAndRstStreamPacket(packet_number, 2, 1, 2);
[email protected]c5e1aca2014-01-30 04:03:04601 }
602
Ryan Hamilton8d9ee76e2018-05-29 23:52:52603 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23604 uint64_t packet_number,
605 uint64_t largest_received,
606 uint64_t smallest_received,
607 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58608 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49609 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58610 !kIncludeCongestionFeedback);
611 }
612
Ryan Hamilton8d9ee76e2018-05-29 23:52:52613 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23614 uint64_t packet_number,
615 uint64_t largest_received,
616 uint64_t smallest_received,
617 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58618 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49619 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58620 !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00621 }
622
Ryan Hamilton8d9ee76e2018-05-29 23:52:52623 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23624 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57625 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52626 quic::QuicStreamId id,
627 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57628 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52629 quic::QuicStreamOffset* header_stream_offset) {
Yixin Wangb470bc882018-02-15 18:43:57630 return client_maker_.MakePriorityPacket(
631 packet_number, should_include_version, id, parent_stream_id,
632 ConvertRequestPriorityToQuicPriority(request_priority),
633 header_stream_offset);
634 }
635
Ryan Hamilton8d9ee76e2018-05-29 23:52:52636 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
637 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36638 return client_maker_.MakeInitialSettingsPacket(1, offset);
fayang3bcb8b502016-12-07 21:44:37639 }
640
Victor Vasiliev076657c2019-03-12 02:46:43641 std::string ConstructDataHeader(size_t body_len) {
Renjief49758b2019-01-11 23:32:41642 if (version_ != quic::QUIC_VERSION_99) {
643 return "";
644 }
645 quic::HttpEncoder encoder;
646 std::unique_ptr<char[]> buffer;
647 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43648 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41649 }
650
Ryan Hamilton8d9ee76e2018-05-29 23:52:52651 void ReceivePromise(quic::QuicStreamId id) {
652 auto headers = quic::test::AsHeaderList(push_promise_);
rch08e198572017-05-09 16:56:55653 QuicChromiumClientStream::Handle* stream =
ckrasic3865ee0f2016-02-29 22:04:56654 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
ckrasic32b17dcd2016-10-31 06:15:35655 stream->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
656 headers);
ckrasic3865ee0f2016-02-29 22:04:56657 }
658
xunjieli84adaab2016-09-20 01:12:28659 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info,
xunjieli100937eb52016-09-15 20:09:37660 bool session_reused) {
661 EXPECT_EQ(session_reused, load_timing_info.socket_reused);
xunjieli84adaab2016-09-20 01:12:28662 if (session_reused) {
663 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
664 } else {
665 ExpectConnectTimingHasTimes(
666 load_timing_info.connect_timing,
667 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
668 }
669 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
xunjieli100937eb52016-09-15 20:09:37670 }
671
Fan Yang32c5a112018-12-10 20:06:33672 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
673 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36674 }
675
Fan Yang32c5a112018-12-10 20:06:33676 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
677 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36678 }
679
Ryan Hamilton8d9ee76e2018-05-29 23:52:52680 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05681 const bool client_headers_include_h2_stream_dependency_;
682
xunjieli5fafe142016-03-23 23:32:54683 BoundTestNetLog net_log_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52684 quic::test::MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20685 scoped_refptr<TestTaskRunner> runner_;
danakjad1777e2016-04-16 00:56:42686 std::unique_ptr<MockWrite[]> mock_writes_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52687 quic::MockClock clock_;
[email protected]f702d572012-12-04 15:56:20688 TestQuicConnection* connection_;
danakjad1777e2016-04-16 00:56:42689 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
rch16c74d1d2016-04-22 06:14:07690 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52691 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
rch97827ee2017-05-24 23:49:12692 std::unique_ptr<UploadDataStream> upload_data_stream_;
danakjad1777e2016-04-16 00:56:42693 std::unique_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15694 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42695 std::unique_ptr<QuicChromiumClientSession> session_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52696 quic::QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20697 TestCompletionCallback callback_;
698 HttpRequestInfo request_;
699 HttpRequestHeaders headers_;
700 HttpResponseInfo response_;
701 scoped_refptr<IOBufferWithSize> read_buffer_;
Ryan Hamilton0239aac2018-05-19 00:03:13702 spdy::SpdyHeaderBlock request_headers_;
703 spdy::SpdyHeaderBlock response_headers_;
bnc614a92d32016-04-04 13:56:07704 string request_data_;
705 string response_data_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52706 quic::QuicClientPushPromiseIndex push_promise_index_;
[email protected]f702d572012-12-04 15:56:20707
ckrasic3865ee0f2016-02-29 22:04:56708 // For server push testing
danakjad1777e2016-04-16 00:56:42709 std::unique_ptr<QuicHttpStream> promised_stream_;
Ryan Hamilton0239aac2018-05-19 00:03:13710 spdy::SpdyHeaderBlock push_promise_;
711 spdy::SpdyHeaderBlock promised_response_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52712 const quic::QuicStreamId promise_id_;
ckrasic3865ee0f2016-02-29 22:04:56713 string promise_url_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52714 const quic::QuicStreamId stream_id_;
ckrasic3865ee0f2016-02-29 22:04:56715
Ryan Hamilton8d9ee76e2018-05-29 23:52:52716 const quic::QuicConnectionId connection_id_;
alyssar2adf3ac2016-05-03 17:12:58717 QuicTestPacketMaker client_maker_;
718 QuicTestPacketMaker server_maker_;
[email protected]f702d572012-12-04 15:56:20719 IPEndPoint self_addr_;
720 IPEndPoint peer_addr_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52721 quic::test::MockRandom random_generator_;
rch03b7a202016-02-05 00:54:20722 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05723 MockCryptoClientStreamFactory crypto_client_stream_factory_;
danakjad1777e2016-04-16 00:56:42724 std::unique_ptr<StaticSocketDataProvider> socket_data_;
[email protected]f702d572012-12-04 15:56:20725 std::vector<PacketToWrite> writes_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52726 quic::QuicStreamOffset response_offset_;
[email protected]f702d572012-12-04 15:56:20727};
728
Victor Costane635086f2019-01-27 05:20:30729INSTANTIATE_TEST_SUITE_P(
Bence Békyce380cb2018-04-26 23:39:55730 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05731 QuicHttpStreamTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52732 ::testing::Combine(
733 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
734 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20735
736TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44737 Initialize();
rtennetibe635732014-10-02 22:51:42738 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20739}
740
mmenkebd84c392015-09-02 14:12:34741TEST_P(QuicHttpStreamTest, CanReuseConnection) {
[email protected]ed3fc15d2013-03-08 18:37:44742 Initialize();
mmenkebd84c392015-09-02 14:12:34743 EXPECT_FALSE(stream_->CanReuseConnection());
[email protected]f702d572012-12-04 15:56:20744}
745
jri231c2972016-03-08 19:50:11746TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
Zhongyi Shibb28b1f2018-07-18 02:41:26747 request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri231c2972016-03-08 19:50:11748 Initialize();
xunjieli5fafe142016-03-23 23:32:54749 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27750 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54751 net_log_.bound(), callback_.callback()));
rch08e198572017-05-09 16:56:55752 QuicChromiumClientStream::Handle* client_stream =
jri231c2972016-03-08 19:50:11753 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
Zhongyi Shibb28b1f2018-07-18 02:41:26754 EXPECT_FALSE(client_stream->can_migrate_to_cellular_network());
jri231c2972016-03-08 19:50:11755}
756
[email protected]1e960032013-12-20 19:00:20757TEST_P(QuicHttpStreamTest, GetRequest) {
758 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45759 size_t spdy_request_header_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52760 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36761 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37762 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33763 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:36764 DEFAULT_PRIORITY, &spdy_request_header_frame_length,
765 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37766
[email protected]f702d572012-12-04 15:56:20767 Initialize();
768
769 request_.method = "GET";
rchcd379012017-04-12 21:53:32770 request_.url = GURL("https://www.example.org/");
[email protected]f702d572012-12-04 15:56:20771
xunjieli100937eb52016-09-15 20:09:37772 // Make sure getting load timing from the stream early does not crash.
773 LoadTimingInfo load_timing_info;
774 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
775
xunjieli5fafe142016-03-23 23:32:54776 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27777 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54778 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02779 EXPECT_EQ(OK,
780 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20781
782 // Ack the request.
Renjie90e808e2019-01-24 07:24:04783 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]f702d572012-12-04 15:56:20784
robpercival214763f2016-07-01 23:27:01785 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
786 IsError(ERR_IO_PENDING));
[email protected]f702d572012-12-04 15:56:20787
bnc614a92d32016-04-04 13:56:07788 SetResponse("404 Not Found", string());
sclittlec4dc1a32015-09-24 00:15:45789 size_t spdy_response_header_frame_length;
790 ProcessPacket(ConstructResponseHeadersPacket(
791 2, kFin, &spdy_response_header_frame_length));
[email protected]f702d572012-12-04 15:56:20792
793 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01794 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]cadac622013-06-11 16:46:36795 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20796 EXPECT_EQ(404, response_.headers->response_code());
797 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53798 EXPECT_FALSE(response_.response_time.is_null());
799 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20800
801 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02802 EXPECT_EQ(0,
803 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
804 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20805 EXPECT_TRUE(stream_->IsResponseBodyComplete());
806 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10807
xunjieli100937eb52016-09-15 20:09:37808 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28809 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37810
sclittle1edeeb22015-09-02 20:46:10811 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45812 // headers and payload.
813 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
814 stream_->GetTotalSentBytes());
815 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
816 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20817}
818
xunjieli100937eb52016-09-15 20:09:37819TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
820 SetRequest("GET", "/", DEFAULT_PRIORITY);
821 size_t spdy_request_header_frame_length;
822
Ryan Hamilton8d9ee76e2018-05-29 23:52:52823 quic::QuicStreamOffset offset = 0;
rch5cb522462017-04-25 20:18:36824 AddWrite(ConstructInitialSettingsPacket(&offset));
xunjieli100937eb52016-09-15 20:09:37825 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33826 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:36827 DEFAULT_PRIORITY, &spdy_request_header_frame_length, &offset));
xunjieli100937eb52016-09-15 20:09:37828
829 // SetRequest() again for second request as |request_headers_| was moved.
830 SetRequest("GET", "/", DEFAULT_PRIORITY);
831 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33832 3, GetNthClientInitiatedBidirectionalStreamId(1), kIncludeVersion, kFin,
833 DEFAULT_PRIORITY, GetNthClientInitiatedBidirectionalStreamId(0),
Yixin Wang7a3f1b8d2018-01-17 21:40:48834 &spdy_request_header_frame_length, &offset));
Renjie90e808e2019-01-24 07:24:04835 AddWrite(ConstructClientAckPacket(4, 3, 1, 2)); // Ack the responses.
xunjieli100937eb52016-09-15 20:09:37836
837 Initialize();
838
839 request_.method = "GET";
rchcd379012017-04-12 21:53:32840 request_.url = GURL("https://www.example.org/");
xunjieli100937eb52016-09-15 20:09:37841 // Start first request.
842 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27843 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37844 net_log_.bound(), callback_.callback()));
845 EXPECT_EQ(OK,
846 stream_->SendRequest(headers_, &response_, callback_.callback()));
847
848 // Start a second request.
Ryan Hamilton6c2a2a82017-12-15 02:06:28849 QuicHttpStream stream2(
850 session_->CreateHandle(HostPortPair("www.example.org", 443)));
xunjieli100937eb52016-09-15 20:09:37851 TestCompletionCallback callback2;
852 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27853 stream2.InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37854 net_log_.bound(), callback2.callback()));
855 EXPECT_EQ(OK,
856 stream2.SendRequest(headers_, &response_, callback2.callback()));
857
858 // Ack both requests.
Renjie90e808e2019-01-24 07:24:04859 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
xunjieli100937eb52016-09-15 20:09:37860
861 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
862 IsError(ERR_IO_PENDING));
863 size_t spdy_response_header_frame_length;
864 SetResponse("200 OK", string());
865 ProcessPacket(InnerConstructResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33866 2, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
ckrasicbf2f59c2017-05-04 23:54:36867 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37868
869 // Now that the headers have been processed, the callback will return.
870 EXPECT_THAT(callback_.WaitForResult(), IsOk());
871 EXPECT_EQ(200, response_.headers->response_code());
872
873 // There is no body, so this should return immediately.
874 EXPECT_EQ(0,
875 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
876 callback_.callback()));
877 EXPECT_TRUE(stream_->IsResponseBodyComplete());
878
879 LoadTimingInfo load_timing_info;
880 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28881 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37882
883 // SetResponse() again for second request as |response_headers_| was moved.
884 SetResponse("200 OK", string());
885 EXPECT_THAT(stream2.ReadResponseHeaders(callback2.callback()),
886 IsError(ERR_IO_PENDING));
887
888 ProcessPacket(InnerConstructResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33889 3, GetNthClientInitiatedBidirectionalStreamId(1), kFin,
ckrasicbf2f59c2017-05-04 23:54:36890 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37891
892 EXPECT_THAT(callback2.WaitForResult(), IsOk());
893
894 // There is no body, so this should return immediately.
895 EXPECT_EQ(0,
896 stream2.ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
897 callback2.callback()));
898 EXPECT_TRUE(stream2.IsResponseBodyComplete());
899
900 LoadTimingInfo load_timing_info2;
901 EXPECT_TRUE(stream2.GetLoadTimingInfo(&load_timing_info2));
xunjieli84adaab2016-09-20 01:12:28902 ExpectLoadTimingValid(load_timing_info2, /*session_reused=*/true);
xunjieli100937eb52016-09-15 20:09:37903}
904
xunjieli34291fe12016-03-02 13:58:38905// QuicHttpStream does not currently support trailers. It should ignore
906// trailers upon receiving them.
907TEST_P(QuicHttpStreamTest, GetRequestWithTrailers) {
908 SetRequest("GET", "/", DEFAULT_PRIORITY);
909 size_t spdy_request_header_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52910 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36911 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37912 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33913 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:36914 DEFAULT_PRIORITY, &spdy_request_header_frame_length,
915 &header_stream_offset));
Renjie90e808e2019-01-24 07:24:04916 AddWrite(ConstructClientAckPacket(3, 3, 1, 2)); // Ack the data packet.
xunjieli34291fe12016-03-02 13:58:38917
918 Initialize();
919
920 request_.method = "GET";
rchcd379012017-04-12 21:53:32921 request_.url = GURL("https://www.example.org/");
xunjieli34291fe12016-03-02 13:58:38922
xunjieli5fafe142016-03-23 23:32:54923 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27924 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54925 net_log_.bound(), callback_.callback()));
926
xunjieli34291fe12016-03-02 13:58:38927 EXPECT_EQ(OK,
928 stream_->SendRequest(headers_, &response_, callback_.callback()));
xunjieli34291fe12016-03-02 13:58:38929 // Ack the request.
Renjie90e808e2019-01-24 07:24:04930 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
xunjieli34291fe12016-03-02 13:58:38931
robpercival214763f2016-07-01 23:27:01932 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
933 IsError(ERR_IO_PENDING));
xunjieli34291fe12016-03-02 13:58:38934
bnc614a92d32016-04-04 13:56:07935 SetResponse("200 OK", string());
xunjieli34291fe12016-03-02 13:58:38936
937 // Send the response headers.
938 size_t spdy_response_header_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52939 quic::QuicStreamOffset offset = 0;
xunjieli34291fe12016-03-02 13:58:38940 ProcessPacket(ConstructResponseHeadersPacketWithOffset(
941 2, !kFin, &spdy_response_header_frame_length, &offset));
942 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01943 EXPECT_THAT(callback_.WaitForResult(), IsOk());
xunjieli34291fe12016-03-02 13:58:38944 ASSERT_TRUE(response_.headers.get());
945 EXPECT_EQ(200, response_.headers->response_code());
946 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
947 EXPECT_FALSE(response_.response_time.is_null());
948 EXPECT_FALSE(response_.request_time.is_null());
949
950 // Send the response body.
951 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:43952 std::string header = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:41953 ProcessPacket(ConstructServerDataPacket(3, false, !kFin, /*offset=*/0,
954 header + kResponseBody));
Ryan Hamilton0239aac2018-05-19 00:03:13955 spdy::SpdyHeaderBlock trailers;
xunjieli34291fe12016-03-02 13:58:38956 size_t spdy_trailers_frame_length;
957 trailers["foo"] = "bar";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52958 trailers[quic::kFinalOffsetHeaderKey] =
Raul Tambre8c1981d2019-02-08 02:22:26959 base::NumberToString(strlen(kResponseBody) + header.length());
xunjieli34291fe12016-03-02 13:58:38960 ProcessPacket(ConstructResponseTrailersPacket(
bnc086b39e12016-06-24 13:05:26961 4, kFin, std::move(trailers), &spdy_trailers_frame_length, &offset));
xunjieli34291fe12016-03-02 13:58:38962
963 // Make sure trailers are processed.
fdoray92e35a72016-06-10 15:54:55964 base::RunLoop().RunUntilIdle();
xunjieli34291fe12016-03-02 13:58:38965
966 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
967 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
968 callback_.callback()));
969 EXPECT_TRUE(stream_->IsResponseBodyComplete());
970
971 EXPECT_EQ(OK,
972 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
973 callback_.callback()));
974
975 EXPECT_TRUE(stream_->IsResponseBodyComplete());
976 EXPECT_TRUE(AtEof());
977
978 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
979 // headers and payload.
980 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
981 stream_->GetTotalSentBytes());
Renjief49758b2019-01-11 23:32:41982 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length +
983 strlen(kResponseBody) + header.length() +
984 +spdy_trailers_frame_length),
985 stream_->GetTotalReceivedBytes());
xunjieli5fafe142016-03-23 23:32:54986 // Check that NetLog was filled as expected.
987 TestNetLogEntry::List entries;
988 net_log_.GetEntries(&entries);
989 size_t pos = ExpectLogContainsSomewhere(
990 entries, /*min_offset=*/0,
mikecirone8b85c432016-09-08 19:11:00991 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
992 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54993 pos = ExpectLogContainsSomewhere(
994 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00995 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
996 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54997 ExpectLogContainsSomewhere(
998 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00999 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
1000 NetLogEventPhase::NONE);
xunjieli34291fe12016-03-02 13:58:381001}
1002
[email protected]3e7dca62013-09-10 16:14:231003// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:201004TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
1005 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451006 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521007 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361008 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371009 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331010 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:361011 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1012 &header_stream_offset));
[email protected]3e7dca62013-09-10 16:14:231013 Initialize();
1014
1015 request_.method = "GET";
rchcd379012017-04-12 21:53:321016 request_.url = GURL("https://www.example.org/");
[email protected]3e7dca62013-09-10 16:14:231017
xunjieli5fafe142016-03-23 23:32:541018 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271019 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541020 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021021 EXPECT_EQ(OK,
1022 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:231023
1024 // Ack the request.
Renjie90e808e2019-01-24 07:24:041025 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]3e7dca62013-09-10 16:14:231026
robpercival214763f2016-07-01 23:27:011027 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1028 IsError(ERR_IO_PENDING));
[email protected]3e7dca62013-09-10 16:14:231029
bnc086b39e12016-06-24 13:05:261030 response_headers_[":status"] = "200 OK";
1031 response_headers_[":version"] = "HTTP/1.1";
1032 response_headers_["content-type"] = "text/plain";
1033 response_headers_["big6"] = string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:231034
sclittlec4dc1a32015-09-24 00:15:451035 size_t spdy_response_headers_frame_length;
1036 ProcessPacket(ConstructResponseHeadersPacket(
1037 2, kFin, &spdy_response_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:231038
1039 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:011040 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]3e7dca62013-09-10 16:14:231041 ASSERT_TRUE(response_.headers.get());
1042 EXPECT_EQ(200, response_.headers->response_code());
1043 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1044
1045 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:021046 EXPECT_EQ(0,
1047 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1048 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:231049 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1050 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101051
1052 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451053 // headers and payload.
1054 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1055 stream_->GetTotalSentBytes());
1056 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
1057 stream_->GetTotalReceivedBytes());
[email protected]3e7dca62013-09-10 16:14:231058}
1059
rchf9f103cbc2014-08-30 05:28:041060// Regression test for http://crbug.com/409101
1061TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
1062 SetRequest("GET", "/", DEFAULT_PRIORITY);
1063 Initialize();
1064
1065 request_.method = "GET";
rchcd379012017-04-12 21:53:321066 request_.url = GURL("https://www.example.org/");
rchf9f103cbc2014-08-30 05:28:041067
xunjieli5fafe142016-03-23 23:32:541068 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271069 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541070 net_log_.bound(), callback_.callback()));
rchf9f103cbc2014-08-30 05:28:041071
jri78ec06a2016-03-31 18:19:401072 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521073 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchf9f103cbc2014-08-30 05:28:041074
1075 EXPECT_EQ(ERR_CONNECTION_CLOSED,
rjshaded5ced072015-12-18 19:26:021076 stream_->SendRequest(headers_, &response_, callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101077
1078 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1079 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rchf9f103cbc2014-08-30 05:28:041080}
1081
rch03b7a202016-02-05 00:54:201082// Regression test for http://crbug.com/584441
1083TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
1084 SetRequest("GET", "/", DEFAULT_PRIORITY);
1085 Initialize();
1086
1087 request_.method = "GET";
rchcd379012017-04-12 21:53:321088 request_.url = GURL("https://www.example.org/");
rch03b7a202016-02-05 00:54:201089
xunjieli5fafe142016-03-23 23:32:541090 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271091 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541092 net_log_.bound(), callback_.callback()));
rch03b7a202016-02-05 00:54:201093
1094 SSLInfo ssl_info;
rch11565e02016-02-09 20:13:471095 EXPECT_FALSE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201096 stream_->GetSSLInfo(&ssl_info);
rch11565e02016-02-09 20:13:471097 EXPECT_TRUE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201098
jri78ec06a2016-03-31 18:19:401099 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521100 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch03b7a202016-02-05 00:54:201101
rch11565e02016-02-09 20:13:471102 SSLInfo ssl_info2;
1103 stream_->GetSSLInfo(&ssl_info2);
1104 EXPECT_TRUE(ssl_info2.is_valid());
rch03b7a202016-02-05 00:54:201105}
1106
rchcd379012017-04-12 21:53:321107TEST_P(QuicHttpStreamTest, GetAlternativeService) {
1108 SetRequest("GET", "/", DEFAULT_PRIORITY);
1109 Initialize();
1110
1111 request_.method = "GET";
1112 request_.url = GURL("https://www.example.org/");
1113
1114 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271115 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
rchcd379012017-04-12 21:53:321116 net_log_.bound(), callback_.callback()));
1117
1118 AlternativeService alternative_service;
1119 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service));
1120 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1121 alternative_service);
1122
1123 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521124 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchcd379012017-04-12 21:53:321125
1126 AlternativeService alternative_service2;
1127 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service2));
1128 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1129 alternative_service2);
1130}
1131
zhongyica364fbb2015-12-12 03:39:121132TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
1133 SetRequest("GET", "/", DEFAULT_PRIORITY);
1134 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521135 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361136 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371137 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331138 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:361139 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1140 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371141 AddWrite(ConstructAckAndRstStreamPacket(3));
zhongyica364fbb2015-12-12 03:39:121142 Initialize();
1143
1144 request_.method = "GET";
rchcd379012017-04-12 21:53:321145 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121146
xunjieli5fafe142016-03-23 23:32:541147 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271148 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541149 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121150 EXPECT_EQ(OK,
1151 stream_->SendRequest(headers_, &response_, callback_.callback()));
1152
1153 // Ack the request.
Renjie90e808e2019-01-24 07:24:041154 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011155 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1156 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121157
Ryan Hamilton8d9ee76e2018-05-29 23:52:521158 quic::QuicConnectionCloseFrame frame;
Zhongyi Shica576df2019-04-12 17:43:401159 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551160 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121161
1162 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521163 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
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
Ryan Hamiltone316e482017-08-17 02:48:531168TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
rch617e0652017-04-26 17:57:511169 // By default the test setup defaults handshake to be confirmed. Manually set
1170 // it to be not confirmed.
rch617e0652017-04-26 17:57:511171 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271172 MockCryptoClientStream::ZERO_RTT);
rch617e0652017-04-26 17:57:511173
zhongyica364fbb2015-12-12 03:39:121174 SetRequest("GET", "/", DEFAULT_PRIORITY);
1175 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521176 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:031177 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
fayang3bcb8b502016-12-07 21:44:371178 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331179 1, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:361180 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1181 &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:121182 Initialize();
1183
1184 request_.method = "GET";
rchcd379012017-04-12 21:53:321185 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121186
xunjieli5fafe142016-03-23 23:32:541187 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271188 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541189 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121190 EXPECT_EQ(OK,
1191 stream_->SendRequest(headers_, &response_, callback_.callback()));
1192
1193 // Ack the request.
Renjie90e808e2019-01-24 07:24:041194 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011195 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1196 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121197
Ryan Hamilton8d9ee76e2018-05-29 23:52:521198 quic::QuicConnectionCloseFrame frame;
Zhongyi Shica576df2019-04-12 17:43:401199 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551200 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121201
1202 NetErrorDetails details;
zhongyica364fbb2015-12-12 03:39:121203 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521204 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121205}
1206
rch11a114a2014-09-04 23:41:591207// Regression test for http://crbug.com/409871
1208TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
1209 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451210 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521211 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361212 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371213 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331214 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:361215 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1216 &header_stream_offset));
rch11a114a2014-09-04 23:41:591217 Initialize();
1218
1219 request_.method = "GET";
rchcd379012017-04-12 21:53:321220 request_.url = GURL("https://www.example.org/");
rch11a114a2014-09-04 23:41:591221
xunjieli5fafe142016-03-23 23:32:541222 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271223 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541224 net_log_.bound(), callback_.callback()));
rch11a114a2014-09-04 23:41:591225
rjshaded5ced072015-12-18 19:26:021226 EXPECT_EQ(OK,
1227 stream_->SendRequest(headers_, &response_, callback_.callback()));
rch11a114a2014-09-04 23:41:591228
jri78ec06a2016-03-31 18:19:401229 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521230 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch11a114a2014-09-04 23:41:591231
1232 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101233
1234 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451235 // headers and payload.
1236 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1237 stream_->GetTotalSentBytes());
sclittle1edeeb22015-09-02 20:46:101238 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rch11a114a2014-09-04 23:41:591239}
1240
[email protected]1e960032013-12-20 19:00:201241TEST_P(QuicHttpStreamTest, SendPostRequest) {
1242 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451243 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521244 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361245 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wange7ecc472018-03-06 19:00:251246
Victor Vasiliev076657c2019-03-12 02:46:431247 std::string header = ConstructDataHeader(strlen(kUploadData));
Renjief49758b2019-01-11 23:32:411248 if (version_ != quic::QUIC_VERSION_99) {
1249 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1250 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
1251 DEFAULT_PRIORITY, 0, &header_stream_offset,
1252 &spdy_request_headers_frame_length, {kUploadData}));
1253 } else {
1254 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1255 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
1256 DEFAULT_PRIORITY, 0, &header_stream_offset,
1257 &spdy_request_headers_frame_length, {header, kUploadData}));
1258 }
Yixin Wange7ecc472018-03-06 19:00:251259
Renjie90e808e2019-01-24 07:24:041260 AddWrite(ConstructClientAckPacket(3, 3, 1, 2));
[email protected]f702d572012-12-04 15:56:201261
1262 Initialize();
1263
danakjad1777e2016-04-16 00:56:421264 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191265 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
ricea2deef682016-09-09 08:04:071266 kUploadData, strlen(kUploadData)));
rch97827ee2017-05-24 23:49:121267 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191268 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
[email protected]f702d572012-12-04 15:56:201269 request_.method = "POST";
rchcd379012017-04-12 21:53:321270 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121271 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581272 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
tfarina42834112016-09-22 13:38:201273 NetLogWithSource()),
1274 IsOk());
[email protected]f702d572012-12-04 15:56:201275
xunjieli5fafe142016-03-23 23:32:541276 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271277 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541278 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021279 EXPECT_EQ(OK,
1280 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:201281
1282 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041283 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]f702d572012-12-04 15:56:201284
1285 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071286 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451287 size_t spdy_response_headers_frame_length;
1288 ProcessPacket(ConstructResponseHeadersPacket(
1289 2, !kFin, &spdy_response_headers_frame_length));
[email protected]f702d572012-12-04 15:56:201290
rchfb47f712017-05-21 03:24:001291 // The headers have already arrived.
1292 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361293 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:201294 EXPECT_EQ(200, response_.headers->response_code());
1295 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1296
1297 // Send the response body.
1298 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431299 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:411300 ProcessPacket(
1301 ConstructServerDataPacket(3, false, kFin, 0, header2 + kResponseBody));
[email protected]f702d572012-12-04 15:56:201302 // Since the body has already arrived, this should return immediately.
1303 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1304 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1305 callback_.callback()));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291306 EXPECT_EQ(0,
1307 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1308 callback_.callback()));
1309
1310 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1311 EXPECT_TRUE(AtEof());
1312
1313 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1314 // headers and payload.
1315 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411316 strlen(kUploadData) + header.length()),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291317 stream_->GetTotalSentBytes());
1318 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411319 strlen(kResponseBody) + header2.length()),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291320 stream_->GetTotalReceivedBytes());
1321}
1322
1323TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
1324 SetRequest("POST", "/", DEFAULT_PRIORITY);
1325 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521326 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton2ef0a9c2017-07-25 03:18:291327 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Victor Vasiliev076657c2019-03-12 02:46:431328 std::string header = ConstructDataHeader(strlen(kUploadData));
Renjief49758b2019-01-11 23:32:411329 if (version_ != quic::QUIC_VERSION_99) {
1330 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1331 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
1332 DEFAULT_PRIORITY, 0, &header_stream_offset,
1333 &spdy_request_headers_frame_length, {kUploadData}));
1334 } else {
1335 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1336 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
1337 DEFAULT_PRIORITY, 0, &header_stream_offset,
1338 &spdy_request_headers_frame_length, {header, kUploadData}));
1339 }
1340
Renjie90e808e2019-01-24 07:24:041341 AddWrite(ConstructClientAckPacket(3, 3, 1, 2));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291342
1343 Initialize();
1344
1345 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191346 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
Ryan Hamilton2ef0a9c2017-07-25 03:18:291347 kUploadData, strlen(kUploadData)));
1348 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191349 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
Ryan Hamilton2ef0a9c2017-07-25 03:18:291350 request_.method = "POST";
1351 request_.url = GURL("https://www.example.org/");
1352 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581353 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291354 NetLogWithSource()),
1355 IsOk());
1356
1357 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271358 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
Ryan Hamilton2ef0a9c2017-07-25 03:18:291359 net_log_.bound(), callback_.callback()));
1360 EXPECT_EQ(OK,
1361 stream_->SendRequest(headers_, &response_, callback_.callback()));
1362
1363 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041364 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291365
1366 // Send the response headers (but not the body).
1367 SetResponse("200 OK", string());
1368 size_t spdy_response_headers_frame_length;
1369 ProcessPacket(ConstructResponseHeadersPacket(
1370 2, !kFin, &spdy_response_headers_frame_length));
1371
1372 // The headers have already arrived.
1373 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1374 ASSERT_TRUE(response_.headers.get());
1375 EXPECT_EQ(200, response_.headers->response_code());
1376 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1377
1378 // Send the response body.
1379 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431380 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:411381 ProcessPacket(
1382 ConstructServerDataPacket(3, false, !kFin, 0, header2 + kResponseBody));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291383 // Since the body has already arrived, this should return immediately.
1384 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1385 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1386 callback_.callback()));
Renjief49758b2019-01-11 23:32:411387 ProcessPacket(ConstructServerDataPacket(
1388 4, false, kFin, base::size(kResponseBody) - 1 + header2.length(), ""));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291389 EXPECT_EQ(0,
1390 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1391 callback_.callback()));
[email protected]f702d572012-12-04 15:56:201392
1393 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1394 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101395
1396 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451397 // headers and payload.
1398 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411399 strlen(kUploadData) + header.length()),
sclittle1edeeb22015-09-02 20:46:101400 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451401 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411402 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101403 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:201404}
1405
[email protected]1e960032013-12-20 19:00:201406TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
1407 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:471408 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451409 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521410 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361411 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Victor Vasiliev076657c2019-03-12 02:46:431412 std::string header = ConstructDataHeader(chunk_size);
Renjief49758b2019-01-11 23:32:411413 if (version_ == quic::QUIC_VERSION_99) {
1414 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1415 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1416 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1417 &spdy_request_headers_frame_length, {header, kUploadData}));
1418 AddWrite(ConstructClientMultipleDataFramesPacket(
1419 3, kIncludeVersion, kFin, header.length() + chunk_size,
1420 {header, kUploadData}));
1421 } else {
1422 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1423 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1424 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1425 &spdy_request_headers_frame_length, {kUploadData}));
1426 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, chunk_size,
1427 kUploadData));
1428 }
1429
Renjie90e808e2019-01-24 07:24:041430 AddWrite(ConstructClientAckPacket(4, 3, 1, 2));
[email protected]c9e49a02013-02-26 05:56:471431 Initialize();
1432
Jeremy Roman0579ed62017-08-29 15:56:191433 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121434 auto* chunked_upload_stream =
1435 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1436 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:471437
1438 request_.method = "POST";
rchcd379012017-04-12 21:53:321439 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121440 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071441 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201442 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]c9e49a02013-02-26 05:56:471443
xunjieli5fafe142016-03-23 23:32:541444 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271445 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541446 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021447 ASSERT_EQ(ERR_IO_PENDING,
1448 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:471449
rch97827ee2017-05-24 23:49:121450 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
robpercival214763f2016-07-01 23:27:011451 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]c9e49a02013-02-26 05:56:471452
1453 // Ack both packets in the request.
Renjie90e808e2019-01-24 07:24:041454 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]c9e49a02013-02-26 05:56:471455
1456 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071457 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451458 size_t spdy_response_headers_frame_length;
1459 ProcessPacket(ConstructResponseHeadersPacket(
1460 2, !kFin, &spdy_response_headers_frame_length));
[email protected]c9e49a02013-02-26 05:56:471461
rchfb47f712017-05-21 03:24:001462 // The headers have already arrived.
1463 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361464 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:471465 EXPECT_EQ(200, response_.headers->response_code());
1466 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1467
1468 // Send the response body.
1469 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431470 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
alyssar2adf3ac2016-05-03 17:12:581471 ProcessPacket(ConstructServerDataPacket(
Renjief49758b2019-01-11 23:32:411472 3, false, kFin, response_data_.length(), header2 + kResponseBody));
[email protected]c9e49a02013-02-26 05:56:471473
1474 // Since the body has already arrived, this should return immediately.
1475 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1476 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1477 callback_.callback()));
1478
1479 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1480 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101481
1482 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451483 // headers and payload.
1484 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411485 strlen(kUploadData) * 2 + header.length() * 2),
sclittle1edeeb22015-09-02 20:46:101486 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451487 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411488 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101489 stream_->GetTotalReceivedBytes());
[email protected]c9e49a02013-02-26 05:56:471490}
1491
[email protected]16ba7742014-08-22 00:57:251492TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
1493 SetRequest("POST", "/", DEFAULT_PRIORITY);
1494 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451495 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521496 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361497 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Victor Vasiliev076657c2019-03-12 02:46:431498 std::string header = ConstructDataHeader(chunk_size);
Renjief49758b2019-01-11 23:32:411499
1500 if (version_ != quic::QUIC_VERSION_99) {
1501 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1502 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1503 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1504 &spdy_request_headers_frame_length, {kUploadData}));
1505 } else {
1506 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1507 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1508 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1509 &spdy_request_headers_frame_length, {header, kUploadData}));
1510 }
1511 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin,
1512 chunk_size + header.length(), ""));
Renjie90e808e2019-01-24 07:24:041513 AddWrite(ConstructClientAckPacket(4, 3, 1, 2));
[email protected]16ba7742014-08-22 00:57:251514 Initialize();
1515
Jeremy Roman0579ed62017-08-29 15:56:191516 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121517 auto* chunked_upload_stream =
1518 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1519 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:251520
1521 request_.method = "POST";
rchcd379012017-04-12 21:53:321522 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121523 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071524 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201525 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251526
xunjieli5fafe142016-03-23 23:32:541527 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271528 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541529 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021530 ASSERT_EQ(ERR_IO_PENDING,
1531 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251532
rch97827ee2017-05-24 23:49:121533 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011534 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251535
Renjie90e808e2019-01-24 07:24:041536 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]16ba7742014-08-22 00:57:251537
1538 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071539 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451540 size_t spdy_response_headers_frame_length;
1541 ProcessPacket(ConstructResponseHeadersPacket(
1542 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251543
rchfb47f712017-05-21 03:24:001544 // The headers have already arrived.
1545 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251546 ASSERT_TRUE(response_.headers.get());
1547 EXPECT_EQ(200, response_.headers->response_code());
1548 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1549
1550 // Send the response body.
1551 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431552 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
alyssar2adf3ac2016-05-03 17:12:581553 ProcessPacket(ConstructServerDataPacket(
Renjief49758b2019-01-11 23:32:411554 3, false, kFin, response_data_.length(), header2 + kResponseBody));
[email protected]16ba7742014-08-22 00:57:251555
rchb27683c2015-07-29 23:53:501556 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251557 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1558 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1559 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251560 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1561 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101562
1563 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451564 // headers and payload.
1565 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411566 strlen(kUploadData) + header.length()),
sclittle1edeeb22015-09-02 20:46:101567 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451568 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411569 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101570 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251571}
1572
1573TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
1574 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451575 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521576 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361577 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371578 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331579 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, !kFin,
ckrasicbf2f59c2017-05-04 23:54:361580 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1581 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371582 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, 0, ""));
Renjie90e808e2019-01-24 07:24:041583 AddWrite(ConstructClientAckPacket(4, 3, 1, 2));
[email protected]16ba7742014-08-22 00:57:251584 Initialize();
1585
Jeremy Roman0579ed62017-08-29 15:56:191586 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121587 auto* chunked_upload_stream =
1588 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
[email protected]16ba7742014-08-22 00:57:251589
1590 request_.method = "POST";
rchcd379012017-04-12 21:53:321591 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121592 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071593 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201594 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251595
xunjieli5fafe142016-03-23 23:32:541596 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271597 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541598 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021599 ASSERT_EQ(ERR_IO_PENDING,
1600 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251601
rch97827ee2017-05-24 23:49:121602 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011603 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251604
Renjie90e808e2019-01-24 07:24:041605 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
[email protected]16ba7742014-08-22 00:57:251606
1607 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071608 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451609 size_t spdy_response_headers_frame_length;
1610 ProcessPacket(ConstructResponseHeadersPacket(
1611 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251612
rchfb47f712017-05-21 03:24:001613 // The headers have already arrived.
1614 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251615 ASSERT_TRUE(response_.headers.get());
1616 EXPECT_EQ(200, response_.headers->response_code());
1617 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1618
1619 // Send the response body.
1620 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431621 std::string header = ConstructDataHeader(strlen(kResponseBody));
alyssar2adf3ac2016-05-03 17:12:581622 ProcessPacket(ConstructServerDataPacket(
Renjief49758b2019-01-11 23:32:411623 3, false, kFin, response_data_.length(), header + kResponseBody));
[email protected]16ba7742014-08-22 00:57:251624
rchb27683c2015-07-29 23:53:501625 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251626 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1627 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1628 callback_.callback()));
1629
1630 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1631 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101632
1633 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451634 // headers and payload.
1635 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1636 stream_->GetTotalSentBytes());
1637 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411638 strlen(kResponseBody) + header.length()),
sclittle1edeeb22015-09-02 20:46:101639 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251640}
1641
[email protected]1e960032013-12-20 19:00:201642TEST_P(QuicHttpStreamTest, DestroyedEarly) {
1643 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451644 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521645 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361646 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371647 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331648 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:361649 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1650 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371651 AddWrite(ConstructAckAndRstStreamPacket(3));
[email protected]63534512012-12-23 18:49:001652 Initialize();
1653
1654 request_.method = "GET";
rchcd379012017-04-12 21:53:321655 request_.url = GURL("https://www.example.org/");
[email protected]63534512012-12-23 18:49:001656
xunjieli5fafe142016-03-23 23:32:541657 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271658 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541659 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021660 EXPECT_EQ(OK,
1661 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]63534512012-12-23 18:49:001662
1663 // Ack the request.
Renjie90e808e2019-01-24 07:24:041664 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
rchfb47f712017-05-21 03:24:001665 EXPECT_THAT(stream_->ReadResponseHeaders(
1666 base::Bind(&QuicHttpStreamTest::CloseStream,
1667 base::Unretained(this), stream_.get())),
robpercival214763f2016-07-01 23:27:011668 IsError(ERR_IO_PENDING));
[email protected]63534512012-12-23 18:49:001669
1670 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201671 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:001672 // In the course of processing this packet, the QuicHttpStream close itself.
rchfb47f712017-05-21 03:24:001673 size_t response_size = 0;
rch1bcfddf22017-06-03 00:26:291674 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin, &response_size));
[email protected]63534512012-12-23 18:49:001675
fdoray92e35a72016-06-10 15:54:551676 base::RunLoop().RunUntilIdle();
rchb27683c2015-07-29 23:53:501677
[email protected]63534512012-12-23 18:49:001678 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101679
1680 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451681 // headers and payload.
1682 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1683 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001684 // The stream was closed after receiving the headers.
1685 EXPECT_EQ(static_cast<int64_t>(response_size),
1686 stream_->GetTotalReceivedBytes());
[email protected]63534512012-12-23 18:49:001687}
1688
[email protected]1e960032013-12-20 19:00:201689TEST_P(QuicHttpStreamTest, Priority) {
1690 SetRequest("GET", "/", MEDIUM);
sclittlec4dc1a32015-09-24 00:15:451691 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521692 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361693 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371694 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331695 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
1696 MEDIUM, &spdy_request_headers_frame_length, &header_stream_offset));
[email protected]24e5bc52013-09-18 15:36:581697 Initialize();
1698
1699 request_.method = "GET";
rchcd379012017-04-12 21:53:321700 request_.url = GURL("https://www.example.org/");
[email protected]24e5bc52013-09-18 15:36:581701
Steven Valdezb4ff0412018-01-18 22:39:271702 EXPECT_EQ(OK,
1703 stream_->InitializeStream(&request_, true, MEDIUM, net_log_.bound(),
1704 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581705
rjshaded5ced072015-12-18 19:26:021706 EXPECT_EQ(OK,
1707 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581708
[email protected]24e5bc52013-09-18 15:36:581709 // Ack the request.
Renjie90e808e2019-01-24 07:24:041710 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
robpercival214763f2016-07-01 23:27:011711 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1712 IsError(ERR_IO_PENDING));
[email protected]24e5bc52013-09-18 15:36:581713
1714 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201715 SetResponse("404 OK", "hello world!");
rchfb47f712017-05-21 03:24:001716 size_t response_size = 0;
1717 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, &response_size));
[email protected]24e5bc52013-09-18 15:36:581718
rchfb47f712017-05-21 03:24:001719 EXPECT_EQ(OK, callback_.WaitForResult());
rchb27683c2015-07-29 23:53:501720
[email protected]24e5bc52013-09-18 15:36:581721 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101722
1723 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451724 // headers and payload.
1725 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1726 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001727 EXPECT_EQ(static_cast<int64_t>(response_size),
1728 stream_->GetTotalReceivedBytes());
[email protected]24e5bc52013-09-18 15:36:581729}
1730
xunjieli8dff50b2016-07-22 14:19:061731TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
1732 SetRequest("POST", "/", DEFAULT_PRIORITY);
1733 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521734 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361735 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Victor Vasiliev076657c2019-03-12 02:46:431736 std::string header = ConstructDataHeader(strlen(kUploadData));
Renjief49758b2019-01-11 23:32:411737 if (version_ != quic::QUIC_VERSION_99) {
1738 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1739 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1740 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1741 &spdy_request_headers_frame_length, {kUploadData}));
1742 } else {
1743 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1744 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1745 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1746 &spdy_request_headers_frame_length, {header, kUploadData}));
1747 }
1748
xunjieli8dff50b2016-07-22 14:19:061749 // Second data write will result in a synchronous failure which will close
1750 // the session.
1751 AddWrite(SYNCHRONOUS, ERR_FAILED);
1752 Initialize();
1753
Jeremy Roman0579ed62017-08-29 15:56:191754 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121755 auto* chunked_upload_stream =
1756 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
xunjieli8dff50b2016-07-22 14:19:061757
1758 request_.method = "POST";
rchcd379012017-04-12 21:53:321759 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121760 request_.upload_data_stream = upload_data_stream_.get();
xunjieli8dff50b2016-07-22 14:19:061761 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201762 TestCompletionCallback().callback(), NetLogWithSource()));
xunjieli8dff50b2016-07-22 14:19:061763
1764 size_t chunk_size = strlen(kUploadData);
rch97827ee2017-05-24 23:49:121765 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
xunjieli8dff50b2016-07-22 14:19:061766 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271767 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli8dff50b2016-07-22 14:19:061768 net_log_.bound(), callback_.callback()));
1769 QuicHttpStream* stream = stream_.get();
1770 DeleteStreamCallback delete_stream_callback(std::move(stream_));
1771 // SendRequest() completes asynchronously after the final chunk is added.
Yixin Wange7ecc472018-03-06 19:00:251772 // Error does not surface yet since packet write is triggered by a packet
1773 // flusher that tries to bundle request body writes.
xunjieli8dff50b2016-07-22 14:19:061774 ASSERT_EQ(ERR_IO_PENDING,
1775 stream->SendRequest(headers_, &response_, callback_.callback()));
rch97827ee2017-05-24 23:49:121776 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
xunjieli8dff50b2016-07-22 14:19:061777 int rv = callback_.WaitForResult();
Yixin Wange7ecc472018-03-06 19:00:251778 EXPECT_EQ(OK, rv);
1779 // Error will be surfaced once an attempt to read the response occurs.
1780 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1781 stream->ReadResponseHeaders(callback_.callback()));
xunjieli8dff50b2016-07-22 14:19:061782}
1783
rtenneti15656ae2016-01-23 03:05:031784TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
1785 SetRequest("POST", "/", DEFAULT_PRIORITY);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521786 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361787 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
rtenneti15656ae2016-01-23 03:05:031788 AddWrite(SYNCHRONOUS, ERR_FAILED);
1789 Initialize();
1790
Jeremy Roman0579ed62017-08-29 15:56:191791 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
Yixin Wange7ecc472018-03-06 19:00:251792 auto* chunked_upload_stream =
1793 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031794
1795 request_.method = "POST";
rchcd379012017-04-12 21:53:321796 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121797 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031798 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201799 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031800
xunjieli5fafe142016-03-23 23:32:541801 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271802 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541803 net_log_.bound(), callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251804 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:031805 stream_->SendRequest(headers_, &response_, callback_.callback()));
mmenkeffff3642017-06-15 17:37:241806
Yixin Wange7ecc472018-03-06 19:00:251807 // Error will be surfaced once |upload_data_stream| triggers the next write.
1808 size_t chunk_size = strlen(kUploadData);
1809 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1810 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
1811
1812 EXPECT_LE(0, stream_->GetTotalSentBytes());
1813 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1814}
1815
1816TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersCompleteReadResponse) {
1817 SetRequest("POST", "/", DEFAULT_PRIORITY);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521818 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wange7ecc472018-03-06 19:00:251819 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
1820 AddWrite(SYNCHRONOUS, ERR_FAILED);
1821 Initialize();
1822
1823 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1824 auto* chunked_upload_stream =
1825 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1826
1827 request_.method = "POST";
1828 request_.url = GURL("https://www.example.org/");
1829 request_.upload_data_stream = upload_data_stream_.get();
1830
1831 size_t chunk_size = strlen(kUploadData);
1832 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1833
1834 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1835 TestCompletionCallback().callback(), NetLogWithSource()));
1836
1837 ASSERT_EQ(OK,
1838 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
1839 net_log_.bound(), callback_.callback()));
1840 ASSERT_EQ(OK,
1841 stream_->SendRequest(headers_, &response_, callback_.callback()));
1842
1843 // Error will be surfaced once an attempt to read the response occurs.
1844 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1845 stream_->ReadResponseHeaders(callback_.callback()));
1846
mmenkeffff3642017-06-15 17:37:241847 EXPECT_LE(0, stream_->GetTotalSentBytes());
1848 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031849}
1850
1851TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
1852 SetRequest("POST", "/", DEFAULT_PRIORITY);
1853 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521854 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361855 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371856 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331857 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, !kFin,
ckrasicbf2f59c2017-05-04 23:54:361858 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1859 &header_stream_offset));
rtenneti15656ae2016-01-23 03:05:031860 AddWrite(SYNCHRONOUS, ERR_FAILED);
1861 Initialize();
1862
Jeremy Roman0579ed62017-08-29 15:56:191863 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121864 auto* chunked_upload_stream =
1865 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031866
1867 request_.method = "POST";
rchcd379012017-04-12 21:53:321868 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121869 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031870 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201871 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031872
xunjieli5fafe142016-03-23 23:32:541873 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271874 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541875 net_log_.bound(), callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251876 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:031877 stream_->SendRequest(headers_, &response_, callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251878
1879 size_t chunk_size = strlen(kUploadData);
1880 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1881 // Error does not surface yet since packet write is triggered by a packet
1882 // flusher that tries to bundle request body writes.
1883 ASSERT_EQ(OK, callback_.WaitForResult());
1884 // Error will be surfaced once an attempt to read the response occurs.
1885 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1886 stream_->ReadResponseHeaders(callback_.callback()));
1887
1888 EXPECT_LE(0, stream_->GetTotalSentBytes());
1889 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1890}
1891
1892TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBundledBodyComplete) {
1893 SetRequest("POST", "/", DEFAULT_PRIORITY);
1894 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521895 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wange7ecc472018-03-06 19:00:251896 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Victor Vasiliev076657c2019-03-12 02:46:431897 std::string header = ConstructDataHeader(strlen(kUploadData));
Renjief49758b2019-01-11 23:32:411898 if (version_ != quic::QUIC_VERSION_99) {
1899 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1900 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1901 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1902 &spdy_request_headers_frame_length, {kUploadData}));
1903 } else {
1904 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1905 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1906 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1907 &spdy_request_headers_frame_length, {header, kUploadData}));
1908 }
1909
Yixin Wange7ecc472018-03-06 19:00:251910 AddWrite(SYNCHRONOUS, ERR_FAILED);
1911 Initialize();
1912
1913 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1914 auto* chunked_upload_stream =
1915 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1916
1917 request_.method = "POST";
1918 request_.url = GURL("https://www.example.org/");
1919 request_.upload_data_stream = upload_data_stream_.get();
1920
1921 size_t chunk_size = strlen(kUploadData);
1922 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
1923
1924 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1925 TestCompletionCallback().callback(), NetLogWithSource()));
1926
1927 ASSERT_EQ(OK,
1928 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
1929 net_log_.bound(), callback_.callback()));
1930 ASSERT_EQ(ERR_IO_PENDING,
1931 stream_->SendRequest(headers_, &response_, callback_.callback()));
1932
1933 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1934
1935 // Error does not surface yet since packet write is triggered by a packet
1936 // flusher that tries to bundle request body writes.
1937 ASSERT_EQ(OK, callback_.WaitForResult());
1938 // Error will be surfaced once an attempt to read the response occurs.
1939 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1940 stream_->ReadResponseHeaders(callback_.callback()));
1941
1942 EXPECT_LE(0, stream_->GetTotalSentBytes());
1943 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031944}
1945
ckrasic3865ee0f2016-02-29 22:04:561946TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
1947 SetRequest("GET", "/", DEFAULT_PRIORITY);
1948 Initialize();
1949
1950 // Initialize the first stream, for receiving the promise on.
1951 request_.method = "GET";
rchcd379012017-04-12 21:53:321952 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561953
xunjieli5fafe142016-03-23 23:32:541954 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271955 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541956 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561957
1958 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1959 // packet, but does it matter?
1960 ReceivePromise(promise_id_);
1961 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1962
1963 request_.url = GURL(promise_url_);
1964
1965 // Make the second stream that will exercise the first step of the
1966 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271967 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1968 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1969 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561970
1971 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251972 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561973 size_t spdy_response_headers_frame_length;
1974 ProcessPacket(InnerConstructResponseHeadersPacket(
1975 1, promise_id_, false, &spdy_response_headers_frame_length));
1976
1977 // Receive the promised response body.
1978 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:431979 std::string header = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:411980 ProcessPacket(InnerConstructDataPacket(
1981 2, promise_id_, false, kFin, 0, header + kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561982
1983 // Now sending a matching request will have successful rendezvous
1984 // with the promised stream.
1985 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
1986 callback_.callback()));
1987
1988 EXPECT_EQ(
1989 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1990 ->id(),
1991 promise_id_);
1992
1993 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:011994 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1995 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561996
1997 // As will be the body.
1998 EXPECT_EQ(
1999 static_cast<int>(strlen(kResponseBody)),
2000 promised_stream_->ReadResponseBody(
2001 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2002 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2003 EXPECT_TRUE(AtEof());
2004
2005 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2006 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2007 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2008 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412009 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562010 promised_stream_->GetTotalReceivedBytes());
2011}
2012
2013TEST_P(QuicHttpStreamTest, ServerPushGetRequestSlowResponse) {
2014 SetRequest("GET", "/", DEFAULT_PRIORITY);
2015 Initialize();
2016
2017 // Initialize the first stream, for receiving the promise on.
2018 request_.method = "GET";
rchcd379012017-04-12 21:53:322019 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562020
xunjieli5fafe142016-03-23 23:32:542021 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272022 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542023 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562024
2025 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2026 // packet, but does it matter?
2027 ReceivePromise(promise_id_);
2028 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2029
2030 request_.url = GURL(promise_url_);
2031
2032 // Make the second stream that will exercise the first step of the
2033 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272034 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2035 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2036 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562037
2038 // Now sending a matching request will rendezvous with the promised
2039 // stream, but pending secondary validation.
2040 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2041 headers_, &response_, callback_.callback()));
2042
2043 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252044 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562045 size_t spdy_response_headers_frame_length;
2046 ProcessPacket(InnerConstructResponseHeadersPacket(
2047 1, promise_id_, false, &spdy_response_headers_frame_length));
2048
2049 // Receive the promised response body.
2050 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432051 std::string header = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:412052 ProcessPacket(InnerConstructDataPacket(
2053 2, promise_id_, false, kFin, 0, header + kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:562054
fdoray92e35a72016-06-10 15:54:552055 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562056
2057 // Rendezvous should have succeeded now, so the promised stream
2058 // should point at our push stream, and we should be able read
2059 // headers and data from it.
robpercival214763f2016-07-01 23:27:012060 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562061
2062 EXPECT_EQ(
2063 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2064 ->id(),
2065 promise_id_);
2066
robpercival214763f2016-07-01 23:27:012067 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2068 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562069
2070 EXPECT_EQ(
2071 static_cast<int>(strlen(kResponseBody)),
2072 promised_stream_->ReadResponseBody(
2073 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2074
2075 // Callback should return
2076 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2077 EXPECT_TRUE(AtEof());
2078
2079 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2080 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2081 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2082 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412083 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562084 promised_stream_->GetTotalReceivedBytes());
2085}
2086
ckrasic2c63f9b2016-08-16 23:54:072087// Verify fix for crbug.com/637349
2088TEST_P(QuicHttpStreamTest, ServerPushCancelHttpStreamBeforeResponse) {
2089 SetRequest("GET", "/", DEFAULT_PRIORITY);
2090 Initialize();
2091
2092 // Initialize the first stream, for receiving the promise on.
2093 request_.method = "GET";
rchcd379012017-04-12 21:53:322094 request_.url = GURL("https://www.example.org/");
ckrasic2c63f9b2016-08-16 23:54:072095
2096 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272097 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
ckrasic2c63f9b2016-08-16 23:54:072098 net_log_.bound(), callback_.callback()));
2099
2100 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2101 // packet, but does it matter?
2102 ReceivePromise(promise_id_);
2103 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2104
2105 request_.url = GURL(promise_url_);
2106
2107 // Make the second stream that will exercise the first step of the
2108 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272109 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2110 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2111 callback_.callback()));
ckrasic2c63f9b2016-08-16 23:54:072112
2113 // Now sending a matching request will rendezvous with the promised
2114 // stream, but pending secondary validation.
2115 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2116 headers_, &response_, callback_.callback()));
2117
2118 base::RunLoop().RunUntilIdle();
2119
2120 // Cause of FinalValidation() crash as per bug.
2121 promised_stream_.reset();
2122
2123 // Receive the promised response headers.
2124 response_headers_ = promised_response_.Clone();
2125 size_t spdy_response_headers_frame_length;
2126 ProcessPacket(InnerConstructResponseHeadersPacket(
2127 1, promise_id_, false, &spdy_response_headers_frame_length));
2128}
2129
ckrasic3865ee0f2016-02-29 22:04:562130TEST_P(QuicHttpStreamTest, ServerPushCrossOriginOK) {
2131 SetRequest("GET", "/", DEFAULT_PRIORITY);
2132 Initialize();
2133
2134 // Initialize the first stream, for receiving the promise on.
2135 request_.method = "GET";
rchcd379012017-04-12 21:53:322136 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562137
xunjieli5fafe142016-03-23 23:32:542138 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272139 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542140 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562141
2142 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2143 // packet, but does it matter?
2144
2145 push_promise_[":authority"] = "mail.example.org";
Ryan Hamilton8d9ee76e2018-05-29 23:52:522146 promise_url_ = quic::SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562147
2148 ReceivePromise(promise_id_);
2149 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2150
2151 request_.url = GURL(promise_url_);
2152
2153 // Make the second stream that will exercise the first step of the
2154 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272155 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2156 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2157 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562158
2159 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252160 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562161 size_t spdy_response_headers_frame_length;
2162 ProcessPacket(InnerConstructResponseHeadersPacket(
2163 1, promise_id_, false, &spdy_response_headers_frame_length));
2164
2165 // Receive the promised response body.
2166 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432167 std::string header = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:412168 ProcessPacket(InnerConstructDataPacket(
2169 2, promise_id_, false, kFin, 0, header + kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:562170
2171 // Now sending a matching request will have successful rendezvous
2172 // with the promised stream.
2173 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
2174 callback_.callback()));
2175
2176 EXPECT_EQ(
2177 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2178 ->id(),
2179 promise_id_);
2180
2181 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:012182 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2183 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562184
2185 // As will be the body.
2186 EXPECT_EQ(
2187 static_cast<int>(strlen(kResponseBody)),
2188 promised_stream_->ReadResponseBody(
2189 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2190 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2191 EXPECT_TRUE(AtEof());
2192
2193 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2194 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2195 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2196 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412197 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562198 promised_stream_->GetTotalReceivedBytes());
2199}
2200
2201TEST_P(QuicHttpStreamTest, ServerPushCrossOriginFail) {
2202 SetRequest("GET", "/", DEFAULT_PRIORITY);
2203 Initialize();
2204
2205 // Initialize the first stream, for receiving the promise on.
2206 request_.method = "GET";
rchcd379012017-04-12 21:53:322207 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562208
xunjieli5fafe142016-03-23 23:32:542209 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272210 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542211 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562212
2213 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2214 // packet, but does it matter?
2215 push_promise_[":authority"] = "www.notexample.org";
Ryan Hamilton8d9ee76e2018-05-29 23:52:522216 promise_url_ = quic::SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562217
2218 ReceivePromise(promise_id_);
2219 // The promise will have been rejected because the cert doesn't
2220 // match.
2221 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2222}
2223
2224TEST_P(QuicHttpStreamTest, ServerPushVaryCheckOK) {
2225 SetRequest("GET", "/", DEFAULT_PRIORITY);
2226 Initialize();
2227
2228 // Initialize the first stream, for receiving the promise on.
2229 request_.method = "GET";
rchcd379012017-04-12 21:53:322230 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562231
xunjieli5fafe142016-03-23 23:32:542232 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272233 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542234 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562235
2236 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562237
2238 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2239 // packet, but does it matter?
2240 ReceivePromise(promise_id_);
2241 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2242
2243 request_.url = GURL(promise_url_);
2244
2245 // Make the second stream that will exercise the first step of the
2246 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272247 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2248 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2249 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562250
2251 headers_.SetHeader("accept-encoding", "gzip");
2252
2253 // Now sending a matching request will rendezvous with the promised
2254 // stream, but pending secondary validation.
2255 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2256 headers_, &response_, callback_.callback()));
2257
2258 // Receive the promised response headers.
2259 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252260 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562261 size_t spdy_response_headers_frame_length;
2262 ProcessPacket(InnerConstructResponseHeadersPacket(
2263 1, promise_id_, false, &spdy_response_headers_frame_length));
2264
2265 // Receive the promised response body.
2266 const char kResponseBody[] = "Hello world!";
Victor Vasiliev076657c2019-03-12 02:46:432267 std::string header = ConstructDataHeader(strlen(kResponseBody));
Renjief49758b2019-01-11 23:32:412268 ProcessPacket(InnerConstructDataPacket(
2269 2, promise_id_, false, kFin, 0, header + kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:562270
fdoray92e35a72016-06-10 15:54:552271 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562272
2273 // Rendezvous should have succeeded now, so the promised stream
2274 // should point at our push stream, and we should be able read
2275 // headers and data from it.
robpercival214763f2016-07-01 23:27:012276 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562277
2278 EXPECT_EQ(
2279 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2280 ->id(),
2281 promise_id_);
2282
robpercival214763f2016-07-01 23:27:012283 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2284 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562285
2286 EXPECT_EQ(
2287 static_cast<int>(strlen(kResponseBody)),
2288 promised_stream_->ReadResponseBody(
2289 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2290
2291 // Callback should return
2292 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2293 EXPECT_TRUE(AtEof());
2294
2295 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2296 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2297 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2298 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412299 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562300 promised_stream_->GetTotalReceivedBytes());
2301}
2302
2303TEST_P(QuicHttpStreamTest, ServerPushVaryCheckFail) {
2304 SetRequest("GET", "/", DEFAULT_PRIORITY);
2305 request_headers_[":scheme"] = "https";
2306 request_headers_[":path"] = "/bar";
2307 request_headers_["accept-encoding"] = "sdch";
2308
2309 size_t spdy_request_header_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522310 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362311 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:572312
Fan Yangac867502019-01-28 21:10:232313 uint64_t client_packet_number = 2;
Yixin Wangb470bc882018-02-15 18:43:572314 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:262315 version_ >= quic::QUIC_VERSION_43) {
Yixin Wangb470bc882018-02-15 18:43:572316 AddWrite(ConstructClientPriorityPacket(
2317 client_packet_number++, kIncludeVersion, promise_id_, 0,
2318 DEFAULT_PRIORITY, &header_stream_offset));
2319 }
Michael Warresabba8b7d2018-07-20 22:50:272320 AddWrite(ConstructClientRstStreamVaryMismatchAndRequestHeadersPacket(
Victor Vasiliev4a6798e2019-03-06 02:26:092321 client_packet_number++,
2322 stream_id_ + quic::QuicUtils::StreamIdDelta(version_), !kIncludeVersion,
2323 kFin, DEFAULT_PRIORITY, promise_id_, &spdy_request_header_frame_length,
2324 &header_stream_offset));
Renjie90e808e2019-01-24 07:24:042325 AddWrite(ConstructClientAckPacket(client_packet_number++, 3, 1, 2));
Yixin Wangb470bc882018-02-15 18:43:572326 AddWrite(ConstructClientRstStreamCancelledPacket(client_packet_number++));
2327
ckrasic3865ee0f2016-02-29 22:04:562328 Initialize();
2329
2330 // Initialize the first stream, for receiving the promise on.
2331 request_.method = "GET";
rchcd379012017-04-12 21:53:322332 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562333
xunjieli5fafe142016-03-23 23:32:542334 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272335 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542336 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562337
2338 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562339
2340 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2341 // packet, but does it matter?
2342 ReceivePromise(promise_id_);
2343 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2344
2345 request_.url = GURL(promise_url_);
2346
2347 // Make the second stream that will exercise the first step of the
2348 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272349 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2350 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2351 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562352
2353 headers_.SetHeader("accept-encoding", "sdch");
2354
2355 // Now sending a matching request will rendezvous with the promised
2356 // stream, but pending secondary validation.
2357 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2358 headers_, &response_, callback_.callback()));
2359
2360 // Receive the promised response headers.
2361 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252362 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562363 size_t spdy_response_headers_frame_length;
2364 ProcessPacket(InnerConstructResponseHeadersPacket(
2365 1, promise_id_, false, &spdy_response_headers_frame_length));
2366
fdoray92e35a72016-06-10 15:54:552367 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562368
2369 // Rendezvous should have failed due to vary mismatch, so the
2370 // promised stream should have been aborted, and instead we have a
2371 // new, regular client initiated stream.
robpercival214763f2016-07-01 23:27:012372 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562373
2374 // Not a server-initiated stream.
2375 EXPECT_NE(
2376 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2377 ->id(),
2378 promise_id_);
2379
2380 // Instead, a new client-initiated stream.
2381 EXPECT_EQ(
2382 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2383 ->id(),
Victor Vasiliev4a6798e2019-03-06 02:26:092384 stream_id_ + quic::QuicUtils::StreamIdDelta(version_));
ckrasic3865ee0f2016-02-29 22:04:562385
2386 // After rendezvous failure, the push stream has been cancelled.
2387 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2388
2389 // The rest of the test verifies that the retried as
2390 // client-initiated version of |promised_stream_| works as intended.
2391
2392 // Ack the request.
Renjie90e808e2019-01-24 07:24:042393 ProcessPacket(ConstructServerAckPacket(2, 1, 1, 1));
ckrasic3865ee0f2016-02-29 22:04:562394
bnc614a92d32016-04-04 13:56:072395 SetResponse("404 Not Found", string());
ckrasic3865ee0f2016-02-29 22:04:562396 size_t spdy_response_header_frame_length;
2397 ProcessPacket(InnerConstructResponseHeadersPacket(
Victor Vasiliev4a6798e2019-03-06 02:26:092398 3, stream_id_ + quic::QuicUtils::StreamIdDelta(version_), kFin,
Fan Yang32c5a112018-12-10 20:06:332399 &spdy_response_header_frame_length));
ckrasic3865ee0f2016-02-29 22:04:562400
fdoray92e35a72016-06-10 15:54:552401 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562402
robpercival214763f2016-07-01 23:27:012403 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2404 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562405 ASSERT_TRUE(response_.headers.get());
2406 EXPECT_EQ(404, response_.headers->response_code());
2407 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
2408 EXPECT_FALSE(response_.response_time.is_null());
2409 EXPECT_FALSE(response_.request_time.is_null());
2410
2411 // There is no body, so this should return immediately.
2412 EXPECT_EQ(
2413 0, promised_stream_->ReadResponseBody(
2414 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2415 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2416
2417 stream_->Close(true);
2418
2419 EXPECT_TRUE(AtEof());
2420
2421 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
2422 // headers and payload.
2423 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
2424 promised_stream_->GetTotalSentBytes());
2425 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
2426 promised_stream_->GetTotalReceivedBytes());
2427}
2428
maksim.sisov84e20c92016-06-23 08:49:342429TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
2430 SetRequest("POST", "/", DEFAULT_PRIORITY);
2431 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522432 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362433 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wange7ecc472018-03-06 19:00:252434 AddWrite(ConstructRequestAndRstPacket(
Fan Yang32c5a112018-12-10 20:06:332435 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, !kFin,
Yixin Wange7ecc472018-03-06 19:00:252436 DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:522437 &header_stream_offset, quic::QUIC_ERROR_PROCESSING_STREAM, 0));
maksim.sisov84e20c92016-06-23 08:49:342438
2439 Initialize();
2440
Jeremy Roman0579ed62017-08-29 15:56:192441 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342442 ReadErrorUploadDataStream::FailureMode::SYNC);
2443 request_.method = "POST";
rchcd379012017-04-12 21:53:322444 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122445 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342446 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202447 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342448
2449 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272450 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342451 net_log_.bound(), callback_.callback()));
2452
2453 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
robpercival214763f2016-07-01 23:27:012454 EXPECT_THAT(result, IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342455
2456 EXPECT_TRUE(AtEof());
2457
2458 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2459 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2460 stream_->GetTotalSentBytes());
2461 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2462}
2463
2464TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
2465 SetRequest("POST", "/", DEFAULT_PRIORITY);
2466 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522467 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362468 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372469 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332470 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, !kFin,
ckrasicbf2f59c2017-05-04 23:54:362471 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
2472 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372473 AddWrite(ConstructClientRstStreamErrorPacket(3, !kIncludeVersion));
maksim.sisov84e20c92016-06-23 08:49:342474
2475 Initialize();
2476
Jeremy Roman0579ed62017-08-29 15:56:192477 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342478 ReadErrorUploadDataStream::FailureMode::ASYNC);
2479 request_.method = "POST";
rchcd379012017-04-12 21:53:322480 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122481 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342482 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202483 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342484
2485 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272486 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342487 net_log_.bound(), callback_.callback()));
2488
2489 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2490
Renjie90e808e2019-01-24 07:24:042491 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
maksim.sisov84e20c92016-06-23 08:49:342492 SetResponse("200 OK", string());
2493
robpercival214763f2016-07-01 23:27:012494 EXPECT_THAT(result, IsError(ERR_IO_PENDING));
2495 EXPECT_THAT(callback_.GetResult(result), IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342496
2497 EXPECT_TRUE(AtEof());
2498
2499 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2500 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2501 stream_->GetTotalSentBytes());
2502 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2503}
2504
[email protected]f702d572012-12-04 15:56:202505} // namespace test
[email protected]f702d572012-12-04 15:56:202506} // namespace net