blob: 076527ee8d99654fe66f0d29aa0eef62e82cf24e [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
danakjad1777e2016-04-16 00:56:4212#include "base/memory/ptr_util.h"
fdoray92e35a72016-06-10 15:54:5513#include "base/run_loop.h"
Avi Drissman4365a4782018-12-28 19:26:2414#include "base/stl_util.h"
xunjieli188bd402016-03-12 00:17:2515#include "base/strings/string_number_conversions.h"
gabf767595f2016-05-11 18:50:3516#include "base/threading/thread_task_runner_handle.h"
xunjieli84adaab2016-09-20 01:12:2817#include "base/time/time.h"
mmenkecbc2b712014-10-09 20:29:0718#include "net/base/chunked_upload_data_stream.h"
19#include "net/base/elements_upload_data_stream.h"
xunjieli84adaab2016-09-20 01:12:2820#include "net/base/load_timing_info.h"
21#include "net/base/load_timing_info_test_util.h"
[email protected]f702d572012-12-04 15:56:2022#include "net/base/net_errors.h"
23#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0624#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2025#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1526#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0027#include "net/log/net_log_event_type.h"
xunjieli5fafe142016-03-23 23:32:5428#include "net/log/test_net_log.h"
29#include "net/log/test_net_log_util.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0830#include "net/quic/crypto/proof_verifier_chromium.h"
31#include "net/quic/mock_crypto_client_stream_factory.h"
32#include "net/quic/quic_chromium_alarm_factory.h"
33#include "net/quic/quic_chromium_connection_helper.h"
34#include "net/quic/quic_chromium_packet_reader.h"
35#include "net/quic/quic_chromium_packet_writer.h"
36#include "net/quic/quic_http_utils.h"
37#include "net/quic/quic_server_info.h"
38#include "net/quic/quic_stream_factory.h"
39#include "net/quic/quic_test_packet_maker.h"
40#include "net/quic/test_task_runner.h"
tbansalca83c002016-04-28 20:56:2841#include "net/socket/socket_performance_watcher.h"
[email protected]f702d572012-12-04 15:56:2042#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5843#include "net/spdy/spdy_http_utils.h"
rch03b7a202016-02-05 00:54:2044#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0145#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4346#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0147#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1648#include "net/third_party/quic/core/congestion_control/send_algorithm_interface.h"
49#include "net/third_party/quic/core/crypto/crypto_protocol.h"
50#include "net/third_party/quic/core/crypto/quic_decrypter.h"
51#include "net/third_party/quic/core/crypto/quic_encrypter.h"
Victor Vasilievc5b409c22018-07-24 12:23:4652#include "net/third_party/quic/core/http/spdy_utils.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1653#include "net/third_party/quic/core/quic_connection.h"
54#include "net/third_party/quic/core/quic_write_blocked_list.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1655#include "net/third_party/quic/core/tls_client_handshaker.h"
56#include "net/third_party/quic/platform/api/quic_string_piece.h"
57#include "net/third_party/quic/test_tools/crypto_test_utils.h"
58#include "net/third_party/quic/test_tools/mock_clock.h"
59#include "net/third_party/quic/test_tools/mock_random.h"
60#include "net/third_party/quic/test_tools/quic_connection_peer.h"
61#include "net/third_party/quic/test_tools/quic_spdy_session_peer.h"
62#include "net/third_party/quic/test_tools/quic_test_utils.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2963#include "net/third_party/spdy/core/spdy_frame_builder.h"
64#include "net/third_party/spdy/core/spdy_framer.h"
65#include "net/third_party/spdy/core/spdy_protocol.h"
Ramin Halavati683bcaa92018-02-14 08:42:3966#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]f702d572012-12-04 15:56:2067#include "testing/gmock/include/gmock/gmock.h"
68#include "testing/gtest/include/gtest/gtest.h"
69
bnc614a92d32016-04-04 13:56:0770using std::string;
[email protected]f702d572012-12-04 15:56:2071using testing::_;
[email protected]06ff5152013-08-29 01:03:0572using testing::AnyNumber;
73using testing::Return;
[email protected]f702d572012-12-04 15:56:2074
75namespace net {
[email protected]f702d572012-12-04 15:56:2076namespace test {
[email protected]f702d572012-12-04 15:56:2077namespace {
78
[email protected]16ba7742014-08-22 00:57:2579const char kUploadData[] = "Really nifty data!";
rch9ae5b3b2016-02-11 00:36:2980const char kDefaultServerHostName[] = "www.example.org";
rchcd379012017-04-12 21:53:3281const uint16_t kDefaultServerPort = 443;
[email protected]f702d572012-12-04 15:56:2082
Ryan Hamilton8d9ee76e2018-05-29 23:52:5283class TestQuicConnection : public quic::QuicConnection {
[email protected]f702d572012-12-04 15:56:2084 public:
Ryan Hamilton8d9ee76e2018-05-29 23:52:5285 TestQuicConnection(const quic::ParsedQuicVersionVector& versions,
86 quic::QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2087 IPEndPoint address,
rch12fef552016-01-15 16:26:3188 QuicChromiumConnectionHelper* helper,
rch16c74d1d2016-04-22 06:14:0789 QuicChromiumAlarmFactory* alarm_factory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5290 quic::QuicPacketWriter* writer)
91 : quic::QuicConnection(
92 connection_id,
93 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(address)),
94 helper,
95 alarm_factory,
96 writer,
97 true /* owns_writer */,
98 quic::Perspective::IS_CLIENT,
99 versions) {}
[email protected]f702d572012-12-04 15:56:20100
Ryan Hamilton8d9ee76e2018-05-29 23:52:52101 void SetSendAlgorithm(quic::SendAlgorithmInterface* send_algorithm) {
102 quic::test::QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:20103 }
104};
105
maksim.sisov84e20c92016-06-23 08:49:34106// UploadDataStream that always returns errors on data read.
107class ReadErrorUploadDataStream : public UploadDataStream {
108 public:
109 enum class FailureMode { SYNC, ASYNC };
110
111 explicit ReadErrorUploadDataStream(FailureMode mode)
112 : UploadDataStream(true, 0), async_(mode), weak_factory_(this) {}
113 ~ReadErrorUploadDataStream() override {}
114
115 private:
116 void CompleteRead() { UploadDataStream::OnReadCompleted(ERR_FAILED); }
117
118 // UploadDataStream implementation:
tfarina42834112016-09-22 13:38:20119 int InitInternal(const NetLogWithSource& net_log) override { return OK; }
maksim.sisov84e20c92016-06-23 08:49:34120
121 int ReadInternal(IOBuffer* buf, int buf_len) override {
122 if (async_ == FailureMode::ASYNC) {
123 base::ThreadTaskRunnerHandle::Get()->PostTask(
124 FROM_HERE, base::Bind(&ReadErrorUploadDataStream::CompleteRead,
125 weak_factory_.GetWeakPtr()));
126 return ERR_IO_PENDING;
127 }
128 return ERR_FAILED;
129 }
130
131 void ResetInternal() override {}
132
133 const FailureMode async_;
134
135 base::WeakPtrFactory<ReadErrorUploadDataStream> weak_factory_;
136
137 DISALLOW_COPY_AND_ASSIGN(ReadErrorUploadDataStream);
138};
139
Bence Béky8ddc2492018-06-13 01:02:04140// A helper class that will delete |stream| when the callback is invoked.
xunjieli8dff50b2016-07-22 14:19:06141class DeleteStreamCallback : public TestCompletionCallbackBase {
142 public:
Bence Béky8ddc2492018-06-13 01:02:04143 explicit DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)
144 : stream_(std::move(stream)) {}
xunjieli8dff50b2016-07-22 14:19:06145
Bence Béky8ddc2492018-06-13 01:02:04146 CompletionOnceCallback callback() {
147 return base::BindOnce(&DeleteStreamCallback::DeleteStream,
148 base::Unretained(this));
149 }
xunjieli8dff50b2016-07-22 14:19:06150
151 private:
152 void DeleteStream(int result) {
153 stream_.reset();
154 SetResult(result);
155 }
156
157 std::unique_ptr<QuicHttpStream> stream_;
xunjieli8dff50b2016-07-22 14:19:06158};
159
[email protected]f702d572012-12-04 15:56:20160} // namespace
161
[email protected]24e5bc52013-09-18 15:36:58162class QuicHttpStreamPeer {
163 public:
rch08e198572017-05-09 16:56:55164 static QuicChromiumClientStream::Handle* GetQuicChromiumClientStream(
[email protected]24e5bc52013-09-18 15:36:58165 QuicHttpStream* stream) {
rch08e198572017-05-09 16:56:55166 return stream->stream_.get();
[email protected]24e5bc52013-09-18 15:36:58167 }
168};
169
Ryan Hamilton8d9ee76e2018-05-29 23:52:52170class QuicHttpStreamTest : public ::testing::TestWithParam<
171 std::tuple<quic::QuicTransportVersion, bool>>,
172 public WithScopedTaskEnvironment {
rchfb47f712017-05-21 03:24:00173 public:
174 void CloseStream(QuicHttpStream* stream, int /*rv*/) { stream->Close(false); }
175
[email protected]f702d572012-12-04 15:56:20176 protected:
[email protected]1e960032013-12-20 19:00:20177 static const bool kFin = true;
178 static const bool kIncludeVersion = true;
179 static const bool kIncludeCongestionFeedback = true;
180
[email protected]f702d572012-12-04 15:56:20181 // Holds a packet to be written to the wire, and the IO mode that should
182 // be used by the mock socket when performing the write.
183 struct PacketToWrite {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52184 PacketToWrite(IoMode mode, quic::QuicReceivedPacket* packet)
rjshaded5ced072015-12-18 19:26:02185 : mode(mode), packet(packet) {}
rtenneti15656ae2016-01-23 03:05:03186 PacketToWrite(IoMode mode, int rv) : mode(mode), packet(nullptr), rv(rv) {}
[email protected]f702d572012-12-04 15:56:20187 IoMode mode;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52188 quic::QuicReceivedPacket* packet;
rtenneti15656ae2016-01-23 03:05:03189 int rv;
[email protected]f702d572012-12-04 15:56:20190 };
191
192 QuicHttpStreamTest()
Yixin Wang079ad542018-01-11 04:06:05193 : version_(std::get<0>(GetParam())),
194 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52195 crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting(),
196 quic::TlsClientHandshaker::CreateSslCtx()),
Victor Costan9c7302b2018-08-27 16:39:44197 read_buffer_(base::MakeRefCounted<IOBufferWithSize>(4096)),
Fan Yang32c5a112018-12-10 20:06:33198 promise_id_(GetNthServerInitiatedUnidirectionalStreamId(0)),
199 stream_id_(GetNthClientInitiatedBidirectionalStreamId(0)),
David Schinazic8281052019-01-24 06:14:17200 connection_id_(quic::test::TestConnectionId(2)),
Yixin Wang079ad542018-01-11 04:06:05201 client_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58202 connection_id_,
203 &clock_,
204 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52205 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05206 client_headers_include_h2_stream_dependency_),
207 server_maker_(version_,
zhongyi5dbfdd42017-06-20 05:22:15208 connection_id_,
alyssar2adf3ac2016-05-03 17:12:58209 &clock_,
210 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52211 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05212 false),
ckrasic3865ee0f2016-02-29 22:04:56213 random_generator_(0),
214 response_offset_(0) {
martijn21968ea2016-02-24 18:46:20215 IPAddress ip(192, 0, 2, 33);
[email protected]f702d572012-12-04 15:56:20216 peer_addr_ = IPEndPoint(ip, 443);
217 self_addr_ = IPEndPoint(ip, 8435);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52218 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
Ramin Halavati683bcaa92018-02-14 08:42:39219 request_.traffic_annotation =
220 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f702d572012-12-04 15:56:20221 }
222
223 ~QuicHttpStreamTest() {
Renjieba55fae2018-09-20 03:05:16224 session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
225 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]f702d572012-12-04 15:56:20226 for (size_t i = 0; i < writes_.size(); i++) {
227 delete writes_[i].packet;
228 }
229 }
230
231 // Adds a packet to the list of expected writes.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52232 void AddWrite(std::unique_ptr<quic::QuicReceivedPacket> packet) {
[email protected]1e960032013-12-20 19:00:20233 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20234 }
235
rtenneti15656ae2016-01-23 03:05:03236 void AddWrite(IoMode mode, int rv) {
237 writes_.push_back(PacketToWrite(mode, rv));
238 }
239
[email protected]f702d572012-12-04 15:56:20240 // Returns the packet to be written at position |pos|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52241 quic::QuicReceivedPacket* GetWrite(size_t pos) { return writes_[pos].packet; }
[email protected]f702d572012-12-04 15:56:20242
243 bool AtEof() {
rch37de576c2015-05-17 20:28:17244 return socket_data_->AllReadDataConsumed() &&
245 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20246 }
247
Ryan Hamilton8d9ee76e2018-05-29 23:52:52248 void ProcessPacket(std::unique_ptr<quic::QuicReceivedPacket> packet) {
fayang91ca2012016-11-22 07:42:46249 connection_->ProcessUdpPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52250 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(self_addr_)),
251 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(peer_addr_)),
252 *packet);
[email protected]f702d572012-12-04 15:56:20253 }
254
255 // Configures the test fixture to use the list of expected writes.
256 void Initialize() {
257 mock_writes_.reset(new MockWrite[writes_.size()]);
258 for (size_t i = 0; i < writes_.size(); i++) {
rtenneti15656ae2016-01-23 03:05:03259 if (writes_[i].packet == nullptr) {
260 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
261 } else {
262 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
263 writes_[i].packet->length());
264 }
bnc614a92d32016-04-04 13:56:07265 }
[email protected]f702d572012-12-04 15:56:20266
rtennetibe635732014-10-02 22:51:42267 socket_data_.reset(new StaticSocketDataProvider(
Ryan Sleevib8d7ea02018-05-07 20:01:01268 base::span<MockRead>(),
269 base::make_span(mock_writes_.get(), writes_.size())));
[email protected]f702d572012-12-04 15:56:20270
danakjad1777e2016-04-16 00:56:42271 std::unique_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
xunjielib53b38c2016-03-24 15:54:36272 socket_data_.get(), net_log_.bound().net_log()));
[email protected]e13201d82012-12-12 05:00:32273 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20274 runner_ = new TestTaskRunner(&clock_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52275 send_algorithm_ = new quic::test::MockSendAlgorithm();
rch7dd15702015-07-01 18:57:57276 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
277 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
rjshaded5ced072015-12-18 19:26:02278 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
Dan Zhangf11470172017-09-18 22:02:09279 .Times(testing::AtLeast(1));
rtenneti44f4a2e2015-08-07 14:00:07280 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52281 .WillRepeatedly(Return(quic::kMaxPacketSize));
jokulik0e0a00c32016-06-13 21:51:58282 EXPECT_CALL(*send_algorithm_, PacingRate(_))
Ryan Hamilton8d9ee76e2018-05-29 23:52:52283 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Michael Warres74ee3ce2017-10-09 15:26:37284 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
rtenneti44f4a2e2015-08-07 14:00:07285 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52286 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40287 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
rch08cae032017-03-29 00:59:15288 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
rch0d5bcf62017-05-24 22:48:45289 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
290 .Times(AnyNumber());
rch16c74d1d2016-04-22 06:14:07291 helper_.reset(
292 new QuicChromiumConnectionHelper(&clock_, &random_generator_));
293 alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
294
Michael Warres74ee3ce2017-10-09 15:26:37295 connection_ = new TestQuicConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52296 quic::test::SupportedVersions(
297 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version_)),
Dan Zhangfefaf5b2017-12-11 17:06:24298 connection_id_, peer_addr_, helper_.get(), alarm_factory_.get(),
Ryan Hamilton9edcf1a2017-11-22 05:55:17299 new QuicChromiumPacketWriter(
300 socket.get(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]f702d572012-12-04 15:56:20301 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41302 connection_->SetSendAlgorithm(send_algorithm_);
rch03b7a202016-02-05 00:54:20303
304 // Load a certificate that is valid for *.example.org
305 scoped_refptr<X509Certificate> test_cert(
306 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
307 EXPECT_TRUE(test_cert.get());
308
309 verify_details_.cert_verify_result.verified_cert = test_cert;
310 verify_details_.cert_verify_result.is_issued_by_known_root = true;
311 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
312
xunjieli84adaab2016-09-20 01:12:28313 base::TimeTicks dns_end = base::TimeTicks::Now();
314 base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);
ckrasic4f9d88d2015-07-22 22:23:16315 session_.reset(new QuicChromiumClientSession(
xunjielib53b38c2016-03-24 15:54:36316 connection_, std::move(socket),
rtenneti1cd3b162015-09-29 02:58:28317 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57318 &transport_security_state_, /*ssl_config_service=*/nullptr,
danakjad1777e2016-04-16 00:56:42319 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
Paul Jensen8e3c5d32018-02-19 17:06:33320 QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
321 PRIVACY_MODE_DISABLED, SocketTag()),
Zhongyi Shi757fcce2018-06-27 05:41:27322 /*require_confirmation=*/false, /*migrate_session_early_v2=*/false,
323 /*migrate_session_on_network_change_v2=*/false,
Renjiea5722ccf2018-08-10 00:18:49324 /*go_away_on_path_degrading*/ false,
Zhongyi Shi757fcce2018-06-27 05:41:27325 /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shi73f23ca872017-12-13 18:37:13326 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shiee760762018-08-01 00:54:29327 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30328 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17329 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52330 quic::QuicTime::Delta::FromMilliseconds(
331 kQuicYieldAfterDurationMilliseconds),
Yixin Wang079ad542018-01-11 04:06:05332 client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52333 quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
334 dns_start, dns_end, &push_promise_index_, nullptr,
xunjieli84adaab2016-09-20 01:12:28335 base::ThreadTaskRunnerHandle::Get().get(),
xunjieli5fafe142016-03-23 23:32:54336 /*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));
rtennetid39bd762015-06-12 01:05:52337 session_->Initialize();
xunjieli100937eb52016-09-15 20:09:37338 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57339
rch433bf5f2017-02-14 04:10:47340 session_->CryptoConnect(callback.callback());
Ryan Hamilton6c2a2a82017-12-15 02:06:28341 stream_ = std::make_unique<QuicHttpStream>(
342 session_->CreateHandle(HostPortPair("www.example.org", 443)));
343 promised_stream_ = std::make_unique<QuicHttpStream>(
344 session_->CreateHandle(HostPortPair("www.example.org", 443)));
ckrasic3865ee0f2016-02-29 22:04:56345 push_promise_[":path"] = "/bar";
346 push_promise_[":authority"] = "www.example.org";
347 push_promise_[":version"] = "HTTP/1.1";
348 push_promise_[":method"] = "GET";
349 push_promise_[":scheme"] = "https";
350
351 promised_response_[":status"] = "200 OK";
352 promised_response_[":version"] = "HTTP/1.1";
353 promised_response_["content-type"] = "text/plain";
354
Ryan Hamilton8d9ee76e2018-05-29 23:52:52355 promise_url_ = quic::SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
[email protected]6cca996b2013-01-25 07:43:36356 }
357
bnc614a92d32016-04-04 13:56:07358 void SetRequest(const string& method,
359 const string& path,
[email protected]1e960032013-12-20 19:00:20360 RequestPriority priority) {
rchcd379012017-04-12 21:53:32361 request_headers_ = client_maker_.GetRequestHeaders(method, "https", path);
[email protected]6cca996b2013-01-25 07:43:36362 }
363
bnc614a92d32016-04-04 13:56:07364 void SetResponse(const string& status, const string& body) {
alyssar2adf3ac2016-05-03 17:12:58365 response_headers_ = server_maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03366 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36367 }
[email protected]f702d572012-12-04 15:56:20368
Ryan Hamilton8d9ee76e2018-05-29 23:52:52369 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructDataPacket(
370 quic::QuicPacketNumber packet_number,
371 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56372 bool should_include_version,
373 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52374 quic::QuicStreamOffset offset,
375 quic::QuicStringPiece data,
alyssar2adf3ac2016-05-03 17:12:58376 QuicTestPacketMaker* maker) {
377 return maker->MakeDataPacket(packet_number, stream_id,
ckrasic3865ee0f2016-02-29 22:04:56378 should_include_version, fin, offset, data);
379 }
380
Ryan Hamilton8d9ee76e2018-05-29 23:52:52381 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientDataPacket(
382 quic::QuicPacketNumber packet_number,
[email protected]e8ff26842013-03-22 21:02:05383 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20384 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52385 quic::QuicStreamOffset offset,
386 quic::QuicStringPiece data) {
ckrasic3865ee0f2016-02-29 22:04:56387 return InnerConstructDataPacket(packet_number, stream_id_,
alyssar2adf3ac2016-05-03 17:12:58388 should_include_version, fin, offset, data,
389 &client_maker_);
390 }
391
Renjief49758b2019-01-11 23:32:41392 std::unique_ptr<quic::QuicReceivedPacket>
393 ConstructClientMultipleDataFramesPacket(
394 quic::QuicPacketNumber packet_number,
395 bool should_include_version,
396 bool fin,
397 quic::QuicStreamOffset offset,
398 const std::vector<std::string>& data) {
399 return client_maker_.MakeMultipleDataFramesPacket(
400 packet_number, stream_id_, should_include_version, fin, offset, data);
401 }
402
Ryan Hamilton8d9ee76e2018-05-29 23:52:52403 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
404 quic::QuicPacketNumber packet_number,
alyssar2adf3ac2016-05-03 17:12:58405 bool should_include_version,
406 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52407 quic::QuicStreamOffset offset,
408 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58409 return InnerConstructDataPacket(packet_number, stream_id_,
410 should_include_version, fin, offset, data,
411 &server_maker_);
ckrasic3865ee0f2016-02-29 22:04:56412 }
413
Ryan Hamilton8d9ee76e2018-05-29 23:52:52414 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
415 quic::QuicPacketNumber packet_number,
416 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56417 bool should_include_version,
418 bool fin,
419 RequestPriority request_priority,
xunjieli100937eb52016-09-15 20:09:37420 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52421 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48422 return InnerConstructRequestHeadersPacket(
423 packet_number, stream_id, should_include_version, fin, request_priority,
424 0, spdy_headers_frame_length, offset);
425 }
426
Ryan Hamilton8d9ee76e2018-05-29 23:52:52427 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
428 quic::QuicPacketNumber packet_number,
429 quic::QuicStreamId stream_id,
Yixin Wang7a3f1b8d2018-01-17 21:40:48430 bool should_include_version,
431 bool fin,
432 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52433 quic::QuicStreamId parent_stream_id,
Yixin Wang7a3f1b8d2018-01-17 21:40:48434 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52435 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13436 spdy::SpdyPriority priority =
ckrasic3865ee0f2016-02-29 22:04:56437 ConvertRequestPriorityToQuicPriority(request_priority);
alyssar2adf3ac2016-05-03 17:12:58438 return client_maker_.MakeRequestHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56439 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48440 std::move(request_headers_), parent_stream_id,
441 spdy_headers_frame_length, offset);
[email protected]f702d572012-12-04 15:56:20442 }
443
Ryan Hamilton8d9ee76e2018-05-29 23:52:52444 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25445 ConstructRequestHeadersAndDataFramesPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52446 quic::QuicPacketNumber packet_number,
447 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25448 bool should_include_version,
449 bool fin,
450 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52451 quic::QuicStreamId parent_stream_id,
452 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25453 size_t* spdy_headers_frame_length,
454 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13455 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25456 ConvertRequestPriorityToQuicPriority(request_priority);
457 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
458 packet_number, stream_id, should_include_version, fin, priority,
459 std::move(request_headers_), parent_stream_id, offset,
460 spdy_headers_frame_length, data_writes);
461 }
462
Ryan Hamilton8d9ee76e2018-05-29 23:52:52463 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestAndRstPacket(
464 quic::QuicPacketNumber packet_number,
465 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25466 bool should_include_version,
467 bool fin,
468 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52469 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25470 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52471 quic::QuicStreamOffset* header_stream_offset,
472 quic::QuicRstStreamErrorCode error_code,
Yixin Wange7ecc472018-03-06 19:00:25473 size_t bytes_written) {
Ryan Hamilton0239aac2018-05-19 00:03:13474 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25475 ConvertRequestPriorityToQuicPriority(request_priority);
476 return client_maker_.MakeRequestHeadersAndRstPacket(
477 packet_number, stream_id, should_include_version, fin, priority,
478 std::move(request_headers_), parent_stream_id,
479 spdy_headers_frame_length, header_stream_offset, error_code,
480 bytes_written);
481 }
482
Ryan Hamilton8d9ee76e2018-05-29 23:52:52483 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestHeadersPacket(
484 quic::QuicPacketNumber packet_number,
rtennetif4bdb542015-01-21 14:33:05485 bool fin,
sclittlec4dc1a32015-09-24 00:15:45486 RequestPriority request_priority,
487 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56488 return InnerConstructRequestHeadersPacket(
489 packet_number, stream_id_, kIncludeVersion, fin, request_priority,
xunjieli100937eb52016-09-15 20:09:37490 spdy_headers_frame_length, nullptr);
ckrasic3865ee0f2016-02-29 22:04:56491 }
492
Ryan Hamilton8d9ee76e2018-05-29 23:52:52493 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructResponseHeadersPacket(
494 quic::QuicPacketNumber packet_number,
495 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56496 bool fin,
497 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58498 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26499 packet_number, stream_id, !kIncludeVersion, fin,
500 std::move(response_headers_), spdy_headers_frame_length,
501 &response_offset_);
[email protected]1e960032013-12-20 19:00:20502 }
503
Ryan Hamilton8d9ee76e2018-05-29 23:52:52504 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseHeadersPacket(
505 quic::QuicPacketNumber packet_number,
sclittlec4dc1a32015-09-24 00:15:45506 bool fin,
507 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56508 return InnerConstructResponseHeadersPacket(packet_number, stream_id_, fin,
509 spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20510 }
511
Ryan Hamilton8d9ee76e2018-05-29 23:52:52512 std::unique_ptr<quic::QuicReceivedPacket>
513 ConstructResponseHeadersPacketWithOffset(quic::QuicPacketNumber packet_number,
514 bool fin,
515 size_t* spdy_headers_frame_length,
516 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58517 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26518 packet_number, stream_id_, !kIncludeVersion, fin,
519 std::move(response_headers_), spdy_headers_frame_length, offset);
xunjieli34291fe12016-03-02 13:58:38520 }
521
Ryan Hamilton8d9ee76e2018-05-29 23:52:52522 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseTrailersPacket(
523 quic::QuicPacketNumber packet_number,
xunjieli34291fe12016-03-02 13:58:38524 bool fin,
Ryan Hamilton0239aac2018-05-19 00:03:13525 spdy::SpdyHeaderBlock trailers,
xunjieli34291fe12016-03-02 13:58:38526 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52527 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58528 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26529 packet_number, stream_id_, !kIncludeVersion, fin, std::move(trailers),
alyssar2adf3ac2016-05-03 17:12:58530 spdy_headers_frame_length, offset);
xunjieli34291fe12016-03-02 13:58:38531 }
532
Ryan Hamilton8d9ee76e2018-05-29 23:52:52533 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamPacket(
534 quic::QuicPacketNumber packet_number) {
alyssara72f5352016-10-20 12:45:16535 return client_maker_.MakeRstPacket(packet_number, true, stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52536 quic::QUIC_RST_ACKNOWLEDGEMENT);
[email protected]06ff5152013-08-29 01:03:05537 }
538
Ryan Hamilton8d9ee76e2018-05-29 23:52:52539 std::unique_ptr<quic::QuicReceivedPacket>
540 ConstructClientRstStreamCancelledPacket(
541 quic::QuicPacketNumber packet_number) {
alyssar2adf3ac2016-05-03 17:12:58542 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52543 stream_id_, quic::QUIC_STREAM_CANCELLED);
rtenneti6bd660b2015-07-18 00:19:53544 }
545
Ryan Hamilton8d9ee76e2018-05-29 23:52:52546 std::unique_ptr<quic::QuicReceivedPacket>
547 ConstructClientRstStreamVaryMismatchPacket(
548 quic::QuicPacketNumber packet_number) {
alyssar2adf3ac2016-05-03 17:12:58549 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52550 promise_id_,
551 quic::QUIC_PROMISE_VARY_MISMATCH);
ckrasic3865ee0f2016-02-29 22:04:56552 }
553
Fan Yang550c6282018-06-22 18:53:25554 std::unique_ptr<quic::QuicReceivedPacket>
555 ConstructClientRstStreamVaryMismatchAndRequestHeadersPacket(
556 quic::QuicPacketNumber packet_number,
557 quic::QuicStreamId stream_id,
558 bool should_include_version,
559 bool fin,
560 RequestPriority request_priority,
561 quic::QuicStreamId parent_stream_id,
562 size_t* spdy_headers_frame_length,
563 quic::QuicStreamOffset* offset) {
564 spdy::SpdyPriority priority =
565 ConvertRequestPriorityToQuicPriority(request_priority);
566 return client_maker_.MakeRstAndRequestHeadersPacket(
567 packet_number, should_include_version, promise_id_,
568 quic::QUIC_PROMISE_VARY_MISMATCH, stream_id, fin, priority,
569 std::move(request_headers_), parent_stream_id,
570 spdy_headers_frame_length, offset);
571 }
572
Ryan Hamilton8d9ee76e2018-05-29 23:52:52573 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
574 quic::QuicPacketNumber packet_number,
575 quic::QuicPacketNumber largest_received,
576 quic::QuicPacketNumber smallest_received,
577 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58578 return client_maker_.MakeAckAndRstPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52579 packet_number, !kIncludeVersion, stream_id_,
580 quic::QUIC_STREAM_CANCELLED, largest_received, smallest_received,
581 least_unacked, !kIncludeCongestionFeedback);
xunjieli34291fe12016-03-02 13:58:38582 }
583
Ryan Hamilton8d9ee76e2018-05-29 23:52:52584 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamErrorPacket(
585 quic::QuicPacketNumber packet_number,
maksim.sisov84e20c92016-06-23 08:49:34586 bool include_version) {
587 return client_maker_.MakeRstPacket(packet_number, include_version,
588 stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52589 quic::QUIC_ERROR_PROCESSING_STREAM);
maksim.sisov84e20c92016-06-23 08:49:34590 }
591
Ryan Hamilton8d9ee76e2018-05-29 23:52:52592 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
593 quic::QuicPacketNumber packet_number) {
xunjieli34291fe12016-03-02 13:58:38594 return ConstructAckAndRstStreamPacket(packet_number, 2, 1, 1);
[email protected]c5e1aca2014-01-30 04:03:04595 }
596
Ryan Hamilton8d9ee76e2018-05-29 23:52:52597 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckPacket(
598 quic::QuicPacketNumber packet_number,
599 quic::QuicPacketNumber largest_received,
600 quic::QuicPacketNumber smallest_received,
601 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58602 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49603 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58604 !kIncludeCongestionFeedback);
605 }
606
Ryan Hamilton8d9ee76e2018-05-29 23:52:52607 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
608 quic::QuicPacketNumber packet_number,
609 quic::QuicPacketNumber largest_received,
610 quic::QuicPacketNumber smallest_received,
611 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58612 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49613 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58614 !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00615 }
616
Ryan Hamilton8d9ee76e2018-05-29 23:52:52617 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
618 quic::QuicPacketNumber packet_number,
Yixin Wangb470bc882018-02-15 18:43:57619 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52620 quic::QuicStreamId id,
621 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57622 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52623 quic::QuicStreamOffset* header_stream_offset) {
Yixin Wangb470bc882018-02-15 18:43:57624 return client_maker_.MakePriorityPacket(
625 packet_number, should_include_version, id, parent_stream_id,
626 ConvertRequestPriorityToQuicPriority(request_priority),
627 header_stream_offset);
628 }
629
Ryan Hamilton8d9ee76e2018-05-29 23:52:52630 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
631 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36632 return client_maker_.MakeInitialSettingsPacket(1, offset);
fayang3bcb8b502016-12-07 21:44:37633 }
634
Renjief49758b2019-01-11 23:32:41635 quic::QuicString ConstructDataHeader(size_t body_len) {
636 if (version_ != quic::QUIC_VERSION_99) {
637 return "";
638 }
639 quic::HttpEncoder encoder;
640 std::unique_ptr<char[]> buffer;
641 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
642 return quic::QuicString(buffer.get(), header_length);
643 }
644
Ryan Hamilton8d9ee76e2018-05-29 23:52:52645 void ReceivePromise(quic::QuicStreamId id) {
646 auto headers = quic::test::AsHeaderList(push_promise_);
rch08e198572017-05-09 16:56:55647 QuicChromiumClientStream::Handle* stream =
ckrasic3865ee0f2016-02-29 22:04:56648 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
ckrasic32b17dcd2016-10-31 06:15:35649 stream->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
650 headers);
ckrasic3865ee0f2016-02-29 22:04:56651 }
652
xunjieli84adaab2016-09-20 01:12:28653 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info,
xunjieli100937eb52016-09-15 20:09:37654 bool session_reused) {
655 EXPECT_EQ(session_reused, load_timing_info.socket_reused);
xunjieli84adaab2016-09-20 01:12:28656 if (session_reused) {
657 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
658 } else {
659 ExpectConnectTimingHasTimes(
660 load_timing_info.connect_timing,
661 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
662 }
663 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
xunjieli100937eb52016-09-15 20:09:37664 }
665
Fan Yang32c5a112018-12-10 20:06:33666 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
667 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36668 }
669
Fan Yang32c5a112018-12-10 20:06:33670 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
671 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36672 }
673
Ryan Hamilton8d9ee76e2018-05-29 23:52:52674 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05675 const bool client_headers_include_h2_stream_dependency_;
676
xunjieli5fafe142016-03-23 23:32:54677 BoundTestNetLog net_log_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52678 quic::test::MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20679 scoped_refptr<TestTaskRunner> runner_;
danakjad1777e2016-04-16 00:56:42680 std::unique_ptr<MockWrite[]> mock_writes_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52681 quic::MockClock clock_;
[email protected]f702d572012-12-04 15:56:20682 TestQuicConnection* connection_;
danakjad1777e2016-04-16 00:56:42683 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
rch16c74d1d2016-04-22 06:14:07684 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52685 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
rch97827ee2017-05-24 23:49:12686 std::unique_ptr<UploadDataStream> upload_data_stream_;
danakjad1777e2016-04-16 00:56:42687 std::unique_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15688 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42689 std::unique_ptr<QuicChromiumClientSession> session_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52690 quic::QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20691 TestCompletionCallback callback_;
692 HttpRequestInfo request_;
693 HttpRequestHeaders headers_;
694 HttpResponseInfo response_;
695 scoped_refptr<IOBufferWithSize> read_buffer_;
Ryan Hamilton0239aac2018-05-19 00:03:13696 spdy::SpdyHeaderBlock request_headers_;
697 spdy::SpdyHeaderBlock response_headers_;
bnc614a92d32016-04-04 13:56:07698 string request_data_;
699 string response_data_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52700 quic::QuicClientPushPromiseIndex push_promise_index_;
[email protected]f702d572012-12-04 15:56:20701
ckrasic3865ee0f2016-02-29 22:04:56702 // For server push testing
danakjad1777e2016-04-16 00:56:42703 std::unique_ptr<QuicHttpStream> promised_stream_;
Ryan Hamilton0239aac2018-05-19 00:03:13704 spdy::SpdyHeaderBlock push_promise_;
705 spdy::SpdyHeaderBlock promised_response_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52706 const quic::QuicStreamId promise_id_;
ckrasic3865ee0f2016-02-29 22:04:56707 string promise_url_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52708 const quic::QuicStreamId stream_id_;
ckrasic3865ee0f2016-02-29 22:04:56709
Ryan Hamilton8d9ee76e2018-05-29 23:52:52710 const quic::QuicConnectionId connection_id_;
alyssar2adf3ac2016-05-03 17:12:58711 QuicTestPacketMaker client_maker_;
712 QuicTestPacketMaker server_maker_;
[email protected]f702d572012-12-04 15:56:20713 IPEndPoint self_addr_;
714 IPEndPoint peer_addr_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52715 quic::test::MockRandom random_generator_;
rch03b7a202016-02-05 00:54:20716 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05717 MockCryptoClientStreamFactory crypto_client_stream_factory_;
danakjad1777e2016-04-16 00:56:42718 std::unique_ptr<StaticSocketDataProvider> socket_data_;
[email protected]f702d572012-12-04 15:56:20719 std::vector<PacketToWrite> writes_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52720 quic::QuicStreamOffset response_offset_;
[email protected]f702d572012-12-04 15:56:20721};
722
Yixin Wang079ad542018-01-11 04:06:05723INSTANTIATE_TEST_CASE_P(
Bence Békyce380cb2018-04-26 23:39:55724 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05725 QuicHttpStreamTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52726 ::testing::Combine(
727 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
728 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20729
730TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44731 Initialize();
rtennetibe635732014-10-02 22:51:42732 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20733}
734
mmenkebd84c392015-09-02 14:12:34735TEST_P(QuicHttpStreamTest, CanReuseConnection) {
[email protected]ed3fc15d2013-03-08 18:37:44736 Initialize();
mmenkebd84c392015-09-02 14:12:34737 EXPECT_FALSE(stream_->CanReuseConnection());
[email protected]f702d572012-12-04 15:56:20738}
739
jri231c2972016-03-08 19:50:11740TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
Zhongyi Shibb28b1f2018-07-18 02:41:26741 request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri231c2972016-03-08 19:50:11742 Initialize();
xunjieli5fafe142016-03-23 23:32:54743 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27744 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54745 net_log_.bound(), callback_.callback()));
rch08e198572017-05-09 16:56:55746 QuicChromiumClientStream::Handle* client_stream =
jri231c2972016-03-08 19:50:11747 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
Zhongyi Shibb28b1f2018-07-18 02:41:26748 EXPECT_FALSE(client_stream->can_migrate_to_cellular_network());
jri231c2972016-03-08 19:50:11749}
750
[email protected]1e960032013-12-20 19:00:20751TEST_P(QuicHttpStreamTest, GetRequest) {
752 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45753 size_t spdy_request_header_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52754 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36755 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37756 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33757 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:36758 DEFAULT_PRIORITY, &spdy_request_header_frame_length,
759 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37760
[email protected]f702d572012-12-04 15:56:20761 Initialize();
762
763 request_.method = "GET";
rchcd379012017-04-12 21:53:32764 request_.url = GURL("https://www.example.org/");
[email protected]f702d572012-12-04 15:56:20765
xunjieli100937eb52016-09-15 20:09:37766 // Make sure getting load timing from the stream early does not crash.
767 LoadTimingInfo load_timing_info;
768 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
769
xunjieli5fafe142016-03-23 23:32:54770 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27771 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54772 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02773 EXPECT_EQ(OK,
774 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20775
776 // Ack the request.
wangyix6444ffe2017-04-25 17:49:49777 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]f702d572012-12-04 15:56:20778
robpercival214763f2016-07-01 23:27:01779 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
780 IsError(ERR_IO_PENDING));
[email protected]f702d572012-12-04 15:56:20781
bnc614a92d32016-04-04 13:56:07782 SetResponse("404 Not Found", string());
sclittlec4dc1a32015-09-24 00:15:45783 size_t spdy_response_header_frame_length;
784 ProcessPacket(ConstructResponseHeadersPacket(
785 2, kFin, &spdy_response_header_frame_length));
[email protected]f702d572012-12-04 15:56:20786
787 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01788 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]cadac622013-06-11 16:46:36789 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20790 EXPECT_EQ(404, response_.headers->response_code());
791 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53792 EXPECT_FALSE(response_.response_time.is_null());
793 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20794
795 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02796 EXPECT_EQ(0,
797 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
798 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20799 EXPECT_TRUE(stream_->IsResponseBodyComplete());
800 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10801
xunjieli100937eb52016-09-15 20:09:37802 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28803 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37804
sclittle1edeeb22015-09-02 20:46:10805 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45806 // headers and payload.
807 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
808 stream_->GetTotalSentBytes());
809 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
810 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20811}
812
xunjieli100937eb52016-09-15 20:09:37813TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
814 SetRequest("GET", "/", DEFAULT_PRIORITY);
815 size_t spdy_request_header_frame_length;
816
Ryan Hamilton8d9ee76e2018-05-29 23:52:52817 quic::QuicStreamOffset offset = 0;
rch5cb522462017-04-25 20:18:36818 AddWrite(ConstructInitialSettingsPacket(&offset));
xunjieli100937eb52016-09-15 20:09:37819 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33820 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:36821 DEFAULT_PRIORITY, &spdy_request_header_frame_length, &offset));
xunjieli100937eb52016-09-15 20:09:37822
823 // SetRequest() again for second request as |request_headers_| was moved.
824 SetRequest("GET", "/", DEFAULT_PRIORITY);
825 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33826 3, GetNthClientInitiatedBidirectionalStreamId(1), kIncludeVersion, kFin,
827 DEFAULT_PRIORITY, GetNthClientInitiatedBidirectionalStreamId(0),
Yixin Wang7a3f1b8d2018-01-17 21:40:48828 &spdy_request_header_frame_length, &offset));
wangyix6444ffe2017-04-25 17:49:49829 AddWrite(ConstructClientAckPacket(4, 3, 1, 1)); // Ack the responses.
xunjieli100937eb52016-09-15 20:09:37830
831 Initialize();
832
833 request_.method = "GET";
rchcd379012017-04-12 21:53:32834 request_.url = GURL("https://www.example.org/");
xunjieli100937eb52016-09-15 20:09:37835 // Start first request.
836 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27837 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37838 net_log_.bound(), callback_.callback()));
839 EXPECT_EQ(OK,
840 stream_->SendRequest(headers_, &response_, callback_.callback()));
841
842 // Start a second request.
Ryan Hamilton6c2a2a82017-12-15 02:06:28843 QuicHttpStream stream2(
844 session_->CreateHandle(HostPortPair("www.example.org", 443)));
xunjieli100937eb52016-09-15 20:09:37845 TestCompletionCallback callback2;
846 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27847 stream2.InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37848 net_log_.bound(), callback2.callback()));
849 EXPECT_EQ(OK,
850 stream2.SendRequest(headers_, &response_, callback2.callback()));
851
852 // Ack both requests.
wangyix6444ffe2017-04-25 17:49:49853 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
xunjieli100937eb52016-09-15 20:09:37854
855 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
856 IsError(ERR_IO_PENDING));
857 size_t spdy_response_header_frame_length;
858 SetResponse("200 OK", string());
859 ProcessPacket(InnerConstructResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33860 2, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
ckrasicbf2f59c2017-05-04 23:54:36861 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37862
863 // Now that the headers have been processed, the callback will return.
864 EXPECT_THAT(callback_.WaitForResult(), IsOk());
865 EXPECT_EQ(200, response_.headers->response_code());
866
867 // There is no body, so this should return immediately.
868 EXPECT_EQ(0,
869 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
870 callback_.callback()));
871 EXPECT_TRUE(stream_->IsResponseBodyComplete());
872
873 LoadTimingInfo load_timing_info;
874 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28875 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37876
877 // SetResponse() again for second request as |response_headers_| was moved.
878 SetResponse("200 OK", string());
879 EXPECT_THAT(stream2.ReadResponseHeaders(callback2.callback()),
880 IsError(ERR_IO_PENDING));
881
882 ProcessPacket(InnerConstructResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33883 3, GetNthClientInitiatedBidirectionalStreamId(1), kFin,
ckrasicbf2f59c2017-05-04 23:54:36884 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37885
886 EXPECT_THAT(callback2.WaitForResult(), IsOk());
887
888 // There is no body, so this should return immediately.
889 EXPECT_EQ(0,
890 stream2.ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
891 callback2.callback()));
892 EXPECT_TRUE(stream2.IsResponseBodyComplete());
893
894 LoadTimingInfo load_timing_info2;
895 EXPECT_TRUE(stream2.GetLoadTimingInfo(&load_timing_info2));
xunjieli84adaab2016-09-20 01:12:28896 ExpectLoadTimingValid(load_timing_info2, /*session_reused=*/true);
xunjieli100937eb52016-09-15 20:09:37897}
898
xunjieli34291fe12016-03-02 13:58:38899// QuicHttpStream does not currently support trailers. It should ignore
900// trailers upon receiving them.
901TEST_P(QuicHttpStreamTest, GetRequestWithTrailers) {
902 SetRequest("GET", "/", DEFAULT_PRIORITY);
903 size_t spdy_request_header_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52904 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36905 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37906 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:33907 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:36908 DEFAULT_PRIORITY, &spdy_request_header_frame_length,
909 &header_stream_offset));
wangyix6444ffe2017-04-25 17:49:49910 AddWrite(ConstructClientAckPacket(3, 3, 1, 1)); // Ack the data packet.
xunjieli34291fe12016-03-02 13:58:38911
912 Initialize();
913
914 request_.method = "GET";
rchcd379012017-04-12 21:53:32915 request_.url = GURL("https://www.example.org/");
xunjieli34291fe12016-03-02 13:58:38916
xunjieli5fafe142016-03-23 23:32:54917 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27918 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54919 net_log_.bound(), callback_.callback()));
920
xunjieli34291fe12016-03-02 13:58:38921 EXPECT_EQ(OK,
922 stream_->SendRequest(headers_, &response_, callback_.callback()));
xunjieli34291fe12016-03-02 13:58:38923 // Ack the request.
wangyix6444ffe2017-04-25 17:49:49924 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
xunjieli34291fe12016-03-02 13:58:38925
robpercival214763f2016-07-01 23:27:01926 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
927 IsError(ERR_IO_PENDING));
xunjieli34291fe12016-03-02 13:58:38928
bnc614a92d32016-04-04 13:56:07929 SetResponse("200 OK", string());
xunjieli34291fe12016-03-02 13:58:38930
931 // Send the response headers.
932 size_t spdy_response_header_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52933 quic::QuicStreamOffset offset = 0;
xunjieli34291fe12016-03-02 13:58:38934 ProcessPacket(ConstructResponseHeadersPacketWithOffset(
935 2, !kFin, &spdy_response_header_frame_length, &offset));
936 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01937 EXPECT_THAT(callback_.WaitForResult(), IsOk());
xunjieli34291fe12016-03-02 13:58:38938 ASSERT_TRUE(response_.headers.get());
939 EXPECT_EQ(200, response_.headers->response_code());
940 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
941 EXPECT_FALSE(response_.response_time.is_null());
942 EXPECT_FALSE(response_.request_time.is_null());
943
944 // Send the response body.
945 const char kResponseBody[] = "Hello world!";
Renjief49758b2019-01-11 23:32:41946 quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
947 ProcessPacket(ConstructServerDataPacket(3, false, !kFin, /*offset=*/0,
948 header + kResponseBody));
Ryan Hamilton0239aac2018-05-19 00:03:13949 spdy::SpdyHeaderBlock trailers;
xunjieli34291fe12016-03-02 13:58:38950 size_t spdy_trailers_frame_length;
951 trailers["foo"] = "bar";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52952 trailers[quic::kFinalOffsetHeaderKey] =
Renjief49758b2019-01-11 23:32:41953 base::IntToString(strlen(kResponseBody) + header.length());
xunjieli34291fe12016-03-02 13:58:38954 ProcessPacket(ConstructResponseTrailersPacket(
bnc086b39e12016-06-24 13:05:26955 4, kFin, std::move(trailers), &spdy_trailers_frame_length, &offset));
xunjieli34291fe12016-03-02 13:58:38956
957 // Make sure trailers are processed.
fdoray92e35a72016-06-10 15:54:55958 base::RunLoop().RunUntilIdle();
xunjieli34291fe12016-03-02 13:58:38959
960 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
961 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
962 callback_.callback()));
963 EXPECT_TRUE(stream_->IsResponseBodyComplete());
964
965 EXPECT_EQ(OK,
966 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
967 callback_.callback()));
968
969 EXPECT_TRUE(stream_->IsResponseBodyComplete());
970 EXPECT_TRUE(AtEof());
971
972 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
973 // headers and payload.
974 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
975 stream_->GetTotalSentBytes());
Renjief49758b2019-01-11 23:32:41976 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length +
977 strlen(kResponseBody) + header.length() +
978 +spdy_trailers_frame_length),
979 stream_->GetTotalReceivedBytes());
xunjieli5fafe142016-03-23 23:32:54980 // Check that NetLog was filled as expected.
981 TestNetLogEntry::List entries;
982 net_log_.GetEntries(&entries);
983 size_t pos = ExpectLogContainsSomewhere(
984 entries, /*min_offset=*/0,
mikecirone8b85c432016-09-08 19:11:00985 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
986 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54987 pos = ExpectLogContainsSomewhere(
988 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00989 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
990 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54991 ExpectLogContainsSomewhere(
992 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00993 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
994 NetLogEventPhase::NONE);
xunjieli34291fe12016-03-02 13:58:38995}
996
[email protected]3e7dca62013-09-10 16:14:23997// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20998TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
999 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451000 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521001 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361002 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371003 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331004 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:361005 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1006 &header_stream_offset));
[email protected]3e7dca62013-09-10 16:14:231007 Initialize();
1008
1009 request_.method = "GET";
rchcd379012017-04-12 21:53:321010 request_.url = GURL("https://www.example.org/");
[email protected]3e7dca62013-09-10 16:14:231011
xunjieli5fafe142016-03-23 23:32:541012 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271013 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541014 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021015 EXPECT_EQ(OK,
1016 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:231017
1018 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491019 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]3e7dca62013-09-10 16:14:231020
robpercival214763f2016-07-01 23:27:011021 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1022 IsError(ERR_IO_PENDING));
[email protected]3e7dca62013-09-10 16:14:231023
bnc086b39e12016-06-24 13:05:261024 response_headers_[":status"] = "200 OK";
1025 response_headers_[":version"] = "HTTP/1.1";
1026 response_headers_["content-type"] = "text/plain";
1027 response_headers_["big6"] = string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:231028
sclittlec4dc1a32015-09-24 00:15:451029 size_t spdy_response_headers_frame_length;
1030 ProcessPacket(ConstructResponseHeadersPacket(
1031 2, kFin, &spdy_response_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:231032
1033 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:011034 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]3e7dca62013-09-10 16:14:231035 ASSERT_TRUE(response_.headers.get());
1036 EXPECT_EQ(200, response_.headers->response_code());
1037 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1038
1039 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:021040 EXPECT_EQ(0,
1041 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1042 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:231043 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1044 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101045
1046 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451047 // headers and payload.
1048 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1049 stream_->GetTotalSentBytes());
1050 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
1051 stream_->GetTotalReceivedBytes());
[email protected]3e7dca62013-09-10 16:14:231052}
1053
rchf9f103cbc2014-08-30 05:28:041054// Regression test for http://crbug.com/409101
1055TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
1056 SetRequest("GET", "/", DEFAULT_PRIORITY);
1057 Initialize();
1058
1059 request_.method = "GET";
rchcd379012017-04-12 21:53:321060 request_.url = GURL("https://www.example.org/");
rchf9f103cbc2014-08-30 05:28:041061
xunjieli5fafe142016-03-23 23:32:541062 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271063 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541064 net_log_.bound(), callback_.callback()));
rchf9f103cbc2014-08-30 05:28:041065
jri78ec06a2016-03-31 18:19:401066 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521067 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchf9f103cbc2014-08-30 05:28:041068
1069 EXPECT_EQ(ERR_CONNECTION_CLOSED,
rjshaded5ced072015-12-18 19:26:021070 stream_->SendRequest(headers_, &response_, callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101071
1072 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1073 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rchf9f103cbc2014-08-30 05:28:041074}
1075
rch03b7a202016-02-05 00:54:201076// Regression test for http://crbug.com/584441
1077TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
1078 SetRequest("GET", "/", DEFAULT_PRIORITY);
1079 Initialize();
1080
1081 request_.method = "GET";
rchcd379012017-04-12 21:53:321082 request_.url = GURL("https://www.example.org/");
rch03b7a202016-02-05 00:54:201083
xunjieli5fafe142016-03-23 23:32:541084 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271085 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541086 net_log_.bound(), callback_.callback()));
rch03b7a202016-02-05 00:54:201087
1088 SSLInfo ssl_info;
rch11565e02016-02-09 20:13:471089 EXPECT_FALSE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201090 stream_->GetSSLInfo(&ssl_info);
rch11565e02016-02-09 20:13:471091 EXPECT_TRUE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201092
jri78ec06a2016-03-31 18:19:401093 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521094 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch03b7a202016-02-05 00:54:201095
rch11565e02016-02-09 20:13:471096 SSLInfo ssl_info2;
1097 stream_->GetSSLInfo(&ssl_info2);
1098 EXPECT_TRUE(ssl_info2.is_valid());
rch03b7a202016-02-05 00:54:201099}
1100
rchcd379012017-04-12 21:53:321101TEST_P(QuicHttpStreamTest, GetAlternativeService) {
1102 SetRequest("GET", "/", DEFAULT_PRIORITY);
1103 Initialize();
1104
1105 request_.method = "GET";
1106 request_.url = GURL("https://www.example.org/");
1107
1108 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271109 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
rchcd379012017-04-12 21:53:321110 net_log_.bound(), callback_.callback()));
1111
1112 AlternativeService alternative_service;
1113 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service));
1114 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1115 alternative_service);
1116
1117 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521118 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchcd379012017-04-12 21:53:321119
1120 AlternativeService alternative_service2;
1121 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service2));
1122 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1123 alternative_service2);
1124}
1125
zhongyica364fbb2015-12-12 03:39:121126TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
1127 SetRequest("GET", "/", DEFAULT_PRIORITY);
1128 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521129 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361130 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371131 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331132 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:361133 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1134 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371135 AddWrite(ConstructAckAndRstStreamPacket(3));
zhongyica364fbb2015-12-12 03:39:121136 Initialize();
1137
1138 request_.method = "GET";
rchcd379012017-04-12 21:53:321139 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121140
xunjieli5fafe142016-03-23 23:32:541141 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271142 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541143 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121144 EXPECT_EQ(OK,
1145 stream_->SendRequest(headers_, &response_, callback_.callback()));
1146
1147 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491148 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
robpercival214763f2016-07-01 23:27:011149 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1150 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121151
Ryan Hamilton8d9ee76e2018-05-29 23:52:521152 quic::QuicConnectionCloseFrame frame;
1153 frame.error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551154 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121155
1156 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521157 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121158 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521159 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121160}
1161
Ryan Hamiltone316e482017-08-17 02:48:531162TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
rch617e0652017-04-26 17:57:511163 // By default the test setup defaults handshake to be confirmed. Manually set
1164 // it to be not confirmed.
rch617e0652017-04-26 17:57:511165 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271166 MockCryptoClientStream::ZERO_RTT);
rch617e0652017-04-26 17:57:511167
zhongyica364fbb2015-12-12 03:39:121168 SetRequest("GET", "/", DEFAULT_PRIORITY);
1169 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521170 quic::QuicStreamOffset header_stream_offset = 0;
1171 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
1172 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
fayang3bcb8b502016-12-07 21:44:371173 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331174 1, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:361175 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1176 &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:121177 Initialize();
1178
1179 request_.method = "GET";
rchcd379012017-04-12 21:53:321180 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121181
xunjieli5fafe142016-03-23 23:32:541182 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271183 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541184 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121185 EXPECT_EQ(OK,
1186 stream_->SendRequest(headers_, &response_, callback_.callback()));
1187
1188 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491189 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
robpercival214763f2016-07-01 23:27:011190 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1191 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121192
Ryan Hamilton8d9ee76e2018-05-29 23:52:521193 quic::QuicConnectionCloseFrame frame;
1194 frame.error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551195 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121196
1197 NetErrorDetails details;
zhongyica364fbb2015-12-12 03:39:121198 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521199 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121200}
1201
rch11a114a2014-09-04 23:41:591202// Regression test for http://crbug.com/409871
1203TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
1204 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451205 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521206 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361207 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371208 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331209 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:361210 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1211 &header_stream_offset));
rch11a114a2014-09-04 23:41:591212 Initialize();
1213
1214 request_.method = "GET";
rchcd379012017-04-12 21:53:321215 request_.url = GURL("https://www.example.org/");
rch11a114a2014-09-04 23:41:591216
xunjieli5fafe142016-03-23 23:32:541217 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271218 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541219 net_log_.bound(), callback_.callback()));
rch11a114a2014-09-04 23:41:591220
rjshaded5ced072015-12-18 19:26:021221 EXPECT_EQ(OK,
1222 stream_->SendRequest(headers_, &response_, callback_.callback()));
rch11a114a2014-09-04 23:41:591223
jri78ec06a2016-03-31 18:19:401224 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521225 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch11a114a2014-09-04 23:41:591226
1227 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101228
1229 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451230 // headers and payload.
1231 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1232 stream_->GetTotalSentBytes());
sclittle1edeeb22015-09-02 20:46:101233 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rch11a114a2014-09-04 23:41:591234}
1235
[email protected]1e960032013-12-20 19:00:201236TEST_P(QuicHttpStreamTest, SendPostRequest) {
1237 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451238 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521239 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361240 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wange7ecc472018-03-06 19:00:251241
Renjief49758b2019-01-11 23:32:411242 quic::QuicString header = ConstructDataHeader(strlen(kUploadData));
1243 if (version_ != quic::QUIC_VERSION_99) {
1244 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1245 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
1246 DEFAULT_PRIORITY, 0, &header_stream_offset,
1247 &spdy_request_headers_frame_length, {kUploadData}));
1248 } else {
1249 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1250 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
1251 DEFAULT_PRIORITY, 0, &header_stream_offset,
1252 &spdy_request_headers_frame_length, {header, kUploadData}));
1253 }
Yixin Wange7ecc472018-03-06 19:00:251254
1255 AddWrite(ConstructClientAckPacket(3, 3, 1, 1));
[email protected]f702d572012-12-04 15:56:201256
1257 Initialize();
1258
danakjad1777e2016-04-16 00:56:421259 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191260 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
ricea2deef682016-09-09 08:04:071261 kUploadData, strlen(kUploadData)));
rch97827ee2017-05-24 23:49:121262 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191263 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
[email protected]f702d572012-12-04 15:56:201264 request_.method = "POST";
rchcd379012017-04-12 21:53:321265 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121266 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581267 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
tfarina42834112016-09-22 13:38:201268 NetLogWithSource()),
1269 IsOk());
[email protected]f702d572012-12-04 15:56:201270
xunjieli5fafe142016-03-23 23:32:541271 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271272 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541273 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021274 EXPECT_EQ(OK,
1275 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:201276
1277 // Ack both packets in the request.
wangyix6444ffe2017-04-25 17:49:491278 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]f702d572012-12-04 15:56:201279
1280 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071281 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451282 size_t spdy_response_headers_frame_length;
1283 ProcessPacket(ConstructResponseHeadersPacket(
1284 2, !kFin, &spdy_response_headers_frame_length));
[email protected]f702d572012-12-04 15:56:201285
rchfb47f712017-05-21 03:24:001286 // The headers have already arrived.
1287 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361288 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:201289 EXPECT_EQ(200, response_.headers->response_code());
1290 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1291
1292 // Send the response body.
1293 const char kResponseBody[] = "Hello world!";
Renjief49758b2019-01-11 23:32:411294 quic::QuicString header2 = ConstructDataHeader(strlen(kResponseBody));
1295 ProcessPacket(
1296 ConstructServerDataPacket(3, false, kFin, 0, header2 + kResponseBody));
[email protected]f702d572012-12-04 15:56:201297 // Since the body has already arrived, this should return immediately.
1298 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1299 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1300 callback_.callback()));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291301 EXPECT_EQ(0,
1302 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1303 callback_.callback()));
1304
1305 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1306 EXPECT_TRUE(AtEof());
1307
1308 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1309 // headers and payload.
1310 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411311 strlen(kUploadData) + header.length()),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291312 stream_->GetTotalSentBytes());
1313 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411314 strlen(kResponseBody) + header2.length()),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291315 stream_->GetTotalReceivedBytes());
1316}
1317
1318TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
1319 SetRequest("POST", "/", DEFAULT_PRIORITY);
1320 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521321 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton2ef0a9c2017-07-25 03:18:291322 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Renjief49758b2019-01-11 23:32:411323 quic::QuicString header = ConstructDataHeader(strlen(kUploadData));
1324 if (version_ != quic::QUIC_VERSION_99) {
1325 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1326 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
1327 DEFAULT_PRIORITY, 0, &header_stream_offset,
1328 &spdy_request_headers_frame_length, {kUploadData}));
1329 } else {
1330 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1331 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
1332 DEFAULT_PRIORITY, 0, &header_stream_offset,
1333 &spdy_request_headers_frame_length, {header, kUploadData}));
1334 }
1335
Yixin Wange7ecc472018-03-06 19:00:251336 AddWrite(ConstructClientAckPacket(3, 3, 1, 1));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291337
1338 Initialize();
1339
1340 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191341 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
Ryan Hamilton2ef0a9c2017-07-25 03:18:291342 kUploadData, strlen(kUploadData)));
1343 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191344 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
Ryan Hamilton2ef0a9c2017-07-25 03:18:291345 request_.method = "POST";
1346 request_.url = GURL("https://www.example.org/");
1347 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581348 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291349 NetLogWithSource()),
1350 IsOk());
1351
1352 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271353 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
Ryan Hamilton2ef0a9c2017-07-25 03:18:291354 net_log_.bound(), callback_.callback()));
1355 EXPECT_EQ(OK,
1356 stream_->SendRequest(headers_, &response_, callback_.callback()));
1357
1358 // Ack both packets in the request.
1359 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
1360
1361 // Send the response headers (but not the body).
1362 SetResponse("200 OK", string());
1363 size_t spdy_response_headers_frame_length;
1364 ProcessPacket(ConstructResponseHeadersPacket(
1365 2, !kFin, &spdy_response_headers_frame_length));
1366
1367 // The headers have already arrived.
1368 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1369 ASSERT_TRUE(response_.headers.get());
1370 EXPECT_EQ(200, response_.headers->response_code());
1371 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1372
1373 // Send the response body.
1374 const char kResponseBody[] = "Hello world!";
Renjief49758b2019-01-11 23:32:411375 quic::QuicString header2 = ConstructDataHeader(strlen(kResponseBody));
1376 ProcessPacket(
1377 ConstructServerDataPacket(3, false, !kFin, 0, header2 + kResponseBody));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291378 // Since the body has already arrived, this should return immediately.
1379 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1380 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1381 callback_.callback()));
Renjief49758b2019-01-11 23:32:411382 ProcessPacket(ConstructServerDataPacket(
1383 4, false, kFin, base::size(kResponseBody) - 1 + header2.length(), ""));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291384 EXPECT_EQ(0,
1385 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1386 callback_.callback()));
[email protected]f702d572012-12-04 15:56:201387
1388 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1389 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101390
1391 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451392 // headers and payload.
1393 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411394 strlen(kUploadData) + header.length()),
sclittle1edeeb22015-09-02 20:46:101395 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451396 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411397 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101398 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:201399}
1400
[email protected]1e960032013-12-20 19:00:201401TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
1402 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:471403 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451404 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521405 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361406 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Renjief49758b2019-01-11 23:32:411407 quic::QuicString header = ConstructDataHeader(chunk_size);
1408 if (version_ == quic::QUIC_VERSION_99) {
1409 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1410 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1411 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1412 &spdy_request_headers_frame_length, {header, kUploadData}));
1413 AddWrite(ConstructClientMultipleDataFramesPacket(
1414 3, kIncludeVersion, kFin, header.length() + chunk_size,
1415 {header, kUploadData}));
1416 } else {
1417 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1418 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1419 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1420 &spdy_request_headers_frame_length, {kUploadData}));
1421 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, chunk_size,
1422 kUploadData));
1423 }
1424
Yixin Wange7ecc472018-03-06 19:00:251425 AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
[email protected]c9e49a02013-02-26 05:56:471426 Initialize();
1427
Jeremy Roman0579ed62017-08-29 15:56:191428 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121429 auto* chunked_upload_stream =
1430 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1431 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:471432
1433 request_.method = "POST";
rchcd379012017-04-12 21:53:321434 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121435 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071436 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201437 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]c9e49a02013-02-26 05:56:471438
xunjieli5fafe142016-03-23 23:32:541439 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271440 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541441 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021442 ASSERT_EQ(ERR_IO_PENDING,
1443 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:471444
rch97827ee2017-05-24 23:49:121445 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
robpercival214763f2016-07-01 23:27:011446 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]c9e49a02013-02-26 05:56:471447
1448 // Ack both packets in the request.
wangyix6444ffe2017-04-25 17:49:491449 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]c9e49a02013-02-26 05:56:471450
1451 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071452 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451453 size_t spdy_response_headers_frame_length;
1454 ProcessPacket(ConstructResponseHeadersPacket(
1455 2, !kFin, &spdy_response_headers_frame_length));
[email protected]c9e49a02013-02-26 05:56:471456
rchfb47f712017-05-21 03:24:001457 // The headers have already arrived.
1458 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361459 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:471460 EXPECT_EQ(200, response_.headers->response_code());
1461 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1462
1463 // Send the response body.
1464 const char kResponseBody[] = "Hello world!";
Renjief49758b2019-01-11 23:32:411465 quic::QuicString header2 = ConstructDataHeader(strlen(kResponseBody));
alyssar2adf3ac2016-05-03 17:12:581466 ProcessPacket(ConstructServerDataPacket(
Renjief49758b2019-01-11 23:32:411467 3, false, kFin, response_data_.length(), header2 + kResponseBody));
[email protected]c9e49a02013-02-26 05:56:471468
1469 // Since the body has already arrived, this should return immediately.
1470 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1471 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1472 callback_.callback()));
1473
1474 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1475 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101476
1477 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451478 // headers and payload.
1479 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411480 strlen(kUploadData) * 2 + header.length() * 2),
sclittle1edeeb22015-09-02 20:46:101481 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451482 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411483 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101484 stream_->GetTotalReceivedBytes());
[email protected]c9e49a02013-02-26 05:56:471485}
1486
[email protected]16ba7742014-08-22 00:57:251487TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
1488 SetRequest("POST", "/", DEFAULT_PRIORITY);
1489 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451490 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521491 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361492 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Renjief49758b2019-01-11 23:32:411493 quic::QuicString header = ConstructDataHeader(chunk_size);
1494
1495 if (version_ != quic::QUIC_VERSION_99) {
1496 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1497 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1498 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1499 &spdy_request_headers_frame_length, {kUploadData}));
1500 } else {
1501 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1502 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1503 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1504 &spdy_request_headers_frame_length, {header, kUploadData}));
1505 }
1506 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin,
1507 chunk_size + header.length(), ""));
Yixin Wange7ecc472018-03-06 19:00:251508 AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
[email protected]16ba7742014-08-22 00:57:251509 Initialize();
1510
Jeremy Roman0579ed62017-08-29 15:56:191511 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121512 auto* chunked_upload_stream =
1513 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1514 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:251515
1516 request_.method = "POST";
rchcd379012017-04-12 21:53:321517 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121518 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071519 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201520 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251521
xunjieli5fafe142016-03-23 23:32:541522 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271523 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541524 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021525 ASSERT_EQ(ERR_IO_PENDING,
1526 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251527
rch97827ee2017-05-24 23:49:121528 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011529 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251530
wangyix6444ffe2017-04-25 17:49:491531 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]16ba7742014-08-22 00:57:251532
1533 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071534 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451535 size_t spdy_response_headers_frame_length;
1536 ProcessPacket(ConstructResponseHeadersPacket(
1537 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251538
rchfb47f712017-05-21 03:24:001539 // The headers have already arrived.
1540 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251541 ASSERT_TRUE(response_.headers.get());
1542 EXPECT_EQ(200, response_.headers->response_code());
1543 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1544
1545 // Send the response body.
1546 const char kResponseBody[] = "Hello world!";
Renjief49758b2019-01-11 23:32:411547 quic::QuicString header2 = ConstructDataHeader(strlen(kResponseBody));
alyssar2adf3ac2016-05-03 17:12:581548 ProcessPacket(ConstructServerDataPacket(
Renjief49758b2019-01-11 23:32:411549 3, false, kFin, response_data_.length(), header2 + kResponseBody));
[email protected]16ba7742014-08-22 00:57:251550
rchb27683c2015-07-29 23:53:501551 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251552 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1553 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1554 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251555 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1556 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101557
1558 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451559 // headers and payload.
1560 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
Renjief49758b2019-01-11 23:32:411561 strlen(kUploadData) + header.length()),
sclittle1edeeb22015-09-02 20:46:101562 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451563 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411564 strlen(kResponseBody) + header2.length()),
sclittle1edeeb22015-09-02 20:46:101565 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251566}
1567
1568TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
1569 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451570 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521571 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361572 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371573 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331574 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, !kFin,
ckrasicbf2f59c2017-05-04 23:54:361575 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1576 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371577 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, 0, ""));
wangyix6444ffe2017-04-25 17:49:491578 AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
[email protected]16ba7742014-08-22 00:57:251579 Initialize();
1580
Jeremy Roman0579ed62017-08-29 15:56:191581 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121582 auto* chunked_upload_stream =
1583 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
[email protected]16ba7742014-08-22 00:57:251584
1585 request_.method = "POST";
rchcd379012017-04-12 21:53:321586 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121587 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071588 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201589 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251590
xunjieli5fafe142016-03-23 23:32:541591 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271592 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541593 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021594 ASSERT_EQ(ERR_IO_PENDING,
1595 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251596
rch97827ee2017-05-24 23:49:121597 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011598 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251599
wangyix6444ffe2017-04-25 17:49:491600 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]16ba7742014-08-22 00:57:251601
1602 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071603 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451604 size_t spdy_response_headers_frame_length;
1605 ProcessPacket(ConstructResponseHeadersPacket(
1606 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251607
rchfb47f712017-05-21 03:24:001608 // The headers have already arrived.
1609 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251610 ASSERT_TRUE(response_.headers.get());
1611 EXPECT_EQ(200, response_.headers->response_code());
1612 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1613
1614 // Send the response body.
1615 const char kResponseBody[] = "Hello world!";
Renjief49758b2019-01-11 23:32:411616 quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
alyssar2adf3ac2016-05-03 17:12:581617 ProcessPacket(ConstructServerDataPacket(
Renjief49758b2019-01-11 23:32:411618 3, false, kFin, response_data_.length(), header + kResponseBody));
[email protected]16ba7742014-08-22 00:57:251619
rchb27683c2015-07-29 23:53:501620 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251621 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1622 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1623 callback_.callback()));
1624
1625 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1626 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101627
1628 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451629 // headers and payload.
1630 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1631 stream_->GetTotalSentBytes());
1632 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:411633 strlen(kResponseBody) + header.length()),
sclittle1edeeb22015-09-02 20:46:101634 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251635}
1636
[email protected]1e960032013-12-20 19:00:201637TEST_P(QuicHttpStreamTest, DestroyedEarly) {
1638 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451639 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521640 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361641 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371642 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331643 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
ckrasicbf2f59c2017-05-04 23:54:361644 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1645 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371646 AddWrite(ConstructAckAndRstStreamPacket(3));
[email protected]63534512012-12-23 18:49:001647 Initialize();
1648
1649 request_.method = "GET";
rchcd379012017-04-12 21:53:321650 request_.url = GURL("https://www.example.org/");
[email protected]63534512012-12-23 18:49:001651
xunjieli5fafe142016-03-23 23:32:541652 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271653 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541654 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021655 EXPECT_EQ(OK,
1656 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]63534512012-12-23 18:49:001657
1658 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491659 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
rchfb47f712017-05-21 03:24:001660 EXPECT_THAT(stream_->ReadResponseHeaders(
1661 base::Bind(&QuicHttpStreamTest::CloseStream,
1662 base::Unretained(this), stream_.get())),
robpercival214763f2016-07-01 23:27:011663 IsError(ERR_IO_PENDING));
[email protected]63534512012-12-23 18:49:001664
1665 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201666 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:001667 // In the course of processing this packet, the QuicHttpStream close itself.
rchfb47f712017-05-21 03:24:001668 size_t response_size = 0;
rch1bcfddf22017-06-03 00:26:291669 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin, &response_size));
[email protected]63534512012-12-23 18:49:001670
fdoray92e35a72016-06-10 15:54:551671 base::RunLoop().RunUntilIdle();
rchb27683c2015-07-29 23:53:501672
[email protected]63534512012-12-23 18:49:001673 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101674
1675 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451676 // headers and payload.
1677 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1678 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001679 // The stream was closed after receiving the headers.
1680 EXPECT_EQ(static_cast<int64_t>(response_size),
1681 stream_->GetTotalReceivedBytes());
[email protected]63534512012-12-23 18:49:001682}
1683
[email protected]1e960032013-12-20 19:00:201684TEST_P(QuicHttpStreamTest, Priority) {
1685 SetRequest("GET", "/", MEDIUM);
sclittlec4dc1a32015-09-24 00:15:451686 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521687 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361688 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371689 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331690 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
1691 MEDIUM, &spdy_request_headers_frame_length, &header_stream_offset));
[email protected]24e5bc52013-09-18 15:36:581692 Initialize();
1693
1694 request_.method = "GET";
rchcd379012017-04-12 21:53:321695 request_.url = GURL("https://www.example.org/");
[email protected]24e5bc52013-09-18 15:36:581696
Steven Valdezb4ff0412018-01-18 22:39:271697 EXPECT_EQ(OK,
1698 stream_->InitializeStream(&request_, true, MEDIUM, net_log_.bound(),
1699 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581700
rjshaded5ced072015-12-18 19:26:021701 EXPECT_EQ(OK,
1702 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581703
[email protected]24e5bc52013-09-18 15:36:581704 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491705 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
robpercival214763f2016-07-01 23:27:011706 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1707 IsError(ERR_IO_PENDING));
[email protected]24e5bc52013-09-18 15:36:581708
1709 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201710 SetResponse("404 OK", "hello world!");
rchfb47f712017-05-21 03:24:001711 size_t response_size = 0;
1712 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, &response_size));
[email protected]24e5bc52013-09-18 15:36:581713
rchfb47f712017-05-21 03:24:001714 EXPECT_EQ(OK, callback_.WaitForResult());
rchb27683c2015-07-29 23:53:501715
[email protected]24e5bc52013-09-18 15:36:581716 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101717
1718 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451719 // headers and payload.
1720 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1721 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001722 EXPECT_EQ(static_cast<int64_t>(response_size),
1723 stream_->GetTotalReceivedBytes());
[email protected]24e5bc52013-09-18 15:36:581724}
1725
xunjieli8dff50b2016-07-22 14:19:061726TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
1727 SetRequest("POST", "/", DEFAULT_PRIORITY);
1728 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521729 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361730 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Renjief49758b2019-01-11 23:32:411731 quic::QuicString header = ConstructDataHeader(strlen(kUploadData));
1732 if (version_ != quic::QUIC_VERSION_99) {
1733 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1734 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1735 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1736 &spdy_request_headers_frame_length, {kUploadData}));
1737 } else {
1738 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1739 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1740 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1741 &spdy_request_headers_frame_length, {header, kUploadData}));
1742 }
1743
xunjieli8dff50b2016-07-22 14:19:061744 // Second data write will result in a synchronous failure which will close
1745 // the session.
1746 AddWrite(SYNCHRONOUS, ERR_FAILED);
1747 Initialize();
1748
Jeremy Roman0579ed62017-08-29 15:56:191749 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121750 auto* chunked_upload_stream =
1751 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
xunjieli8dff50b2016-07-22 14:19:061752
1753 request_.method = "POST";
rchcd379012017-04-12 21:53:321754 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121755 request_.upload_data_stream = upload_data_stream_.get();
xunjieli8dff50b2016-07-22 14:19:061756 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201757 TestCompletionCallback().callback(), NetLogWithSource()));
xunjieli8dff50b2016-07-22 14:19:061758
1759 size_t chunk_size = strlen(kUploadData);
rch97827ee2017-05-24 23:49:121760 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
xunjieli8dff50b2016-07-22 14:19:061761 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271762 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli8dff50b2016-07-22 14:19:061763 net_log_.bound(), callback_.callback()));
1764 QuicHttpStream* stream = stream_.get();
1765 DeleteStreamCallback delete_stream_callback(std::move(stream_));
1766 // SendRequest() completes asynchronously after the final chunk is added.
Yixin Wange7ecc472018-03-06 19:00:251767 // Error does not surface yet since packet write is triggered by a packet
1768 // flusher that tries to bundle request body writes.
xunjieli8dff50b2016-07-22 14:19:061769 ASSERT_EQ(ERR_IO_PENDING,
1770 stream->SendRequest(headers_, &response_, callback_.callback()));
rch97827ee2017-05-24 23:49:121771 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
xunjieli8dff50b2016-07-22 14:19:061772 int rv = callback_.WaitForResult();
Yixin Wange7ecc472018-03-06 19:00:251773 EXPECT_EQ(OK, rv);
1774 // Error will be surfaced once an attempt to read the response occurs.
1775 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1776 stream->ReadResponseHeaders(callback_.callback()));
xunjieli8dff50b2016-07-22 14:19:061777}
1778
rtenneti15656ae2016-01-23 03:05:031779TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
1780 SetRequest("POST", "/", DEFAULT_PRIORITY);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521781 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361782 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
rtenneti15656ae2016-01-23 03:05:031783 AddWrite(SYNCHRONOUS, ERR_FAILED);
1784 Initialize();
1785
Jeremy Roman0579ed62017-08-29 15:56:191786 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
Yixin Wange7ecc472018-03-06 19:00:251787 auto* chunked_upload_stream =
1788 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031789
1790 request_.method = "POST";
rchcd379012017-04-12 21:53:321791 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121792 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031793 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201794 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031795
xunjieli5fafe142016-03-23 23:32:541796 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271797 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541798 net_log_.bound(), callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251799 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:031800 stream_->SendRequest(headers_, &response_, callback_.callback()));
mmenkeffff3642017-06-15 17:37:241801
Yixin Wange7ecc472018-03-06 19:00:251802 // Error will be surfaced once |upload_data_stream| triggers the next write.
1803 size_t chunk_size = strlen(kUploadData);
1804 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1805 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
1806
1807 EXPECT_LE(0, stream_->GetTotalSentBytes());
1808 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1809}
1810
1811TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersCompleteReadResponse) {
1812 SetRequest("POST", "/", DEFAULT_PRIORITY);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521813 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wange7ecc472018-03-06 19:00:251814 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
1815 AddWrite(SYNCHRONOUS, ERR_FAILED);
1816 Initialize();
1817
1818 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1819 auto* chunked_upload_stream =
1820 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1821
1822 request_.method = "POST";
1823 request_.url = GURL("https://www.example.org/");
1824 request_.upload_data_stream = upload_data_stream_.get();
1825
1826 size_t chunk_size = strlen(kUploadData);
1827 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1828
1829 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1830 TestCompletionCallback().callback(), NetLogWithSource()));
1831
1832 ASSERT_EQ(OK,
1833 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
1834 net_log_.bound(), callback_.callback()));
1835 ASSERT_EQ(OK,
1836 stream_->SendRequest(headers_, &response_, callback_.callback()));
1837
1838 // Error will be surfaced once an attempt to read the response occurs.
1839 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1840 stream_->ReadResponseHeaders(callback_.callback()));
1841
mmenkeffff3642017-06-15 17:37:241842 EXPECT_LE(0, stream_->GetTotalSentBytes());
1843 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031844}
1845
1846TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
1847 SetRequest("POST", "/", DEFAULT_PRIORITY);
1848 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521849 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361850 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371851 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331852 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, !kFin,
ckrasicbf2f59c2017-05-04 23:54:361853 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1854 &header_stream_offset));
rtenneti15656ae2016-01-23 03:05:031855 AddWrite(SYNCHRONOUS, ERR_FAILED);
1856 Initialize();
1857
Jeremy Roman0579ed62017-08-29 15:56:191858 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121859 auto* chunked_upload_stream =
1860 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031861
1862 request_.method = "POST";
rchcd379012017-04-12 21:53:321863 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121864 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031865 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201866 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031867
xunjieli5fafe142016-03-23 23:32:541868 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271869 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541870 net_log_.bound(), callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251871 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:031872 stream_->SendRequest(headers_, &response_, callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251873
1874 size_t chunk_size = strlen(kUploadData);
1875 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1876 // Error does not surface yet since packet write is triggered by a packet
1877 // flusher that tries to bundle request body writes.
1878 ASSERT_EQ(OK, callback_.WaitForResult());
1879 // Error will be surfaced once an attempt to read the response occurs.
1880 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1881 stream_->ReadResponseHeaders(callback_.callback()));
1882
1883 EXPECT_LE(0, stream_->GetTotalSentBytes());
1884 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1885}
1886
1887TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBundledBodyComplete) {
1888 SetRequest("POST", "/", DEFAULT_PRIORITY);
1889 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521890 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wange7ecc472018-03-06 19:00:251891 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Renjief49758b2019-01-11 23:32:411892 quic::QuicString header = ConstructDataHeader(strlen(kUploadData));
1893 if (version_ != quic::QUIC_VERSION_99) {
1894 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1895 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1896 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1897 &spdy_request_headers_frame_length, {kUploadData}));
1898 } else {
1899 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1900 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
1901 !kFin, DEFAULT_PRIORITY, 0, &header_stream_offset,
1902 &spdy_request_headers_frame_length, {header, kUploadData}));
1903 }
1904
Yixin Wange7ecc472018-03-06 19:00:251905 AddWrite(SYNCHRONOUS, ERR_FAILED);
1906 Initialize();
1907
1908 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1909 auto* chunked_upload_stream =
1910 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1911
1912 request_.method = "POST";
1913 request_.url = GURL("https://www.example.org/");
1914 request_.upload_data_stream = upload_data_stream_.get();
1915
1916 size_t chunk_size = strlen(kUploadData);
1917 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
1918
1919 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1920 TestCompletionCallback().callback(), NetLogWithSource()));
1921
1922 ASSERT_EQ(OK,
1923 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
1924 net_log_.bound(), callback_.callback()));
1925 ASSERT_EQ(ERR_IO_PENDING,
1926 stream_->SendRequest(headers_, &response_, callback_.callback()));
1927
1928 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1929
1930 // Error does not surface yet since packet write is triggered by a packet
1931 // flusher that tries to bundle request body writes.
1932 ASSERT_EQ(OK, callback_.WaitForResult());
1933 // Error will be surfaced once an attempt to read the response occurs.
1934 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1935 stream_->ReadResponseHeaders(callback_.callback()));
1936
1937 EXPECT_LE(0, stream_->GetTotalSentBytes());
1938 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031939}
1940
ckrasic3865ee0f2016-02-29 22:04:561941TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
1942 SetRequest("GET", "/", DEFAULT_PRIORITY);
1943 Initialize();
1944
1945 // Initialize the first stream, for receiving the promise on.
1946 request_.method = "GET";
rchcd379012017-04-12 21:53:321947 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561948
xunjieli5fafe142016-03-23 23:32:541949 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271950 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541951 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561952
1953 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1954 // packet, but does it matter?
1955 ReceivePromise(promise_id_);
1956 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1957
1958 request_.url = GURL(promise_url_);
1959
1960 // Make the second stream that will exercise the first step of the
1961 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271962 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1963 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1964 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561965
1966 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251967 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561968 size_t spdy_response_headers_frame_length;
1969 ProcessPacket(InnerConstructResponseHeadersPacket(
1970 1, promise_id_, false, &spdy_response_headers_frame_length));
1971
1972 // Receive the promised response body.
1973 const char kResponseBody[] = "Hello world!";
Renjief49758b2019-01-11 23:32:411974 quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
1975 ProcessPacket(InnerConstructDataPacket(
1976 2, promise_id_, false, kFin, 0, header + kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561977
1978 // Now sending a matching request will have successful rendezvous
1979 // with the promised stream.
1980 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
1981 callback_.callback()));
1982
1983 EXPECT_EQ(
1984 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1985 ->id(),
1986 promise_id_);
1987
1988 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:011989 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1990 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561991
1992 // As will be the body.
1993 EXPECT_EQ(
1994 static_cast<int>(strlen(kResponseBody)),
1995 promised_stream_->ReadResponseBody(
1996 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1997 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1998 EXPECT_TRUE(AtEof());
1999
2000 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2001 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2002 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2003 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412004 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562005 promised_stream_->GetTotalReceivedBytes());
2006}
2007
2008TEST_P(QuicHttpStreamTest, ServerPushGetRequestSlowResponse) {
2009 SetRequest("GET", "/", DEFAULT_PRIORITY);
2010 Initialize();
2011
2012 // Initialize the first stream, for receiving the promise on.
2013 request_.method = "GET";
rchcd379012017-04-12 21:53:322014 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562015
xunjieli5fafe142016-03-23 23:32:542016 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272017 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542018 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562019
2020 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2021 // packet, but does it matter?
2022 ReceivePromise(promise_id_);
2023 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2024
2025 request_.url = GURL(promise_url_);
2026
2027 // Make the second stream that will exercise the first step of the
2028 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272029 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2030 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2031 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562032
2033 // Now sending a matching request will rendezvous with the promised
2034 // stream, but pending secondary validation.
2035 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2036 headers_, &response_, callback_.callback()));
2037
2038 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252039 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562040 size_t spdy_response_headers_frame_length;
2041 ProcessPacket(InnerConstructResponseHeadersPacket(
2042 1, promise_id_, false, &spdy_response_headers_frame_length));
2043
2044 // Receive the promised response body.
2045 const char kResponseBody[] = "Hello world!";
Renjief49758b2019-01-11 23:32:412046 quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
2047 ProcessPacket(InnerConstructDataPacket(
2048 2, promise_id_, false, kFin, 0, header + kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:562049
fdoray92e35a72016-06-10 15:54:552050 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562051
2052 // Rendezvous should have succeeded now, so the promised stream
2053 // should point at our push stream, and we should be able read
2054 // headers and data from it.
robpercival214763f2016-07-01 23:27:012055 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562056
2057 EXPECT_EQ(
2058 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2059 ->id(),
2060 promise_id_);
2061
robpercival214763f2016-07-01 23:27:012062 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2063 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562064
2065 EXPECT_EQ(
2066 static_cast<int>(strlen(kResponseBody)),
2067 promised_stream_->ReadResponseBody(
2068 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2069
2070 // Callback should return
2071 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2072 EXPECT_TRUE(AtEof());
2073
2074 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2075 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2076 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2077 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412078 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562079 promised_stream_->GetTotalReceivedBytes());
2080}
2081
ckrasic2c63f9b2016-08-16 23:54:072082// Verify fix for crbug.com/637349
2083TEST_P(QuicHttpStreamTest, ServerPushCancelHttpStreamBeforeResponse) {
2084 SetRequest("GET", "/", DEFAULT_PRIORITY);
2085 Initialize();
2086
2087 // Initialize the first stream, for receiving the promise on.
2088 request_.method = "GET";
rchcd379012017-04-12 21:53:322089 request_.url = GURL("https://www.example.org/");
ckrasic2c63f9b2016-08-16 23:54:072090
2091 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272092 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
ckrasic2c63f9b2016-08-16 23:54:072093 net_log_.bound(), callback_.callback()));
2094
2095 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2096 // packet, but does it matter?
2097 ReceivePromise(promise_id_);
2098 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2099
2100 request_.url = GURL(promise_url_);
2101
2102 // Make the second stream that will exercise the first step of the
2103 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272104 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2105 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2106 callback_.callback()));
ckrasic2c63f9b2016-08-16 23:54:072107
2108 // Now sending a matching request will rendezvous with the promised
2109 // stream, but pending secondary validation.
2110 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2111 headers_, &response_, callback_.callback()));
2112
2113 base::RunLoop().RunUntilIdle();
2114
2115 // Cause of FinalValidation() crash as per bug.
2116 promised_stream_.reset();
2117
2118 // Receive the promised response headers.
2119 response_headers_ = promised_response_.Clone();
2120 size_t spdy_response_headers_frame_length;
2121 ProcessPacket(InnerConstructResponseHeadersPacket(
2122 1, promise_id_, false, &spdy_response_headers_frame_length));
2123}
2124
ckrasic3865ee0f2016-02-29 22:04:562125TEST_P(QuicHttpStreamTest, ServerPushCrossOriginOK) {
2126 SetRequest("GET", "/", DEFAULT_PRIORITY);
2127 Initialize();
2128
2129 // Initialize the first stream, for receiving the promise on.
2130 request_.method = "GET";
rchcd379012017-04-12 21:53:322131 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562132
xunjieli5fafe142016-03-23 23:32:542133 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272134 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542135 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562136
2137 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2138 // packet, but does it matter?
2139
2140 push_promise_[":authority"] = "mail.example.org";
Ryan Hamilton8d9ee76e2018-05-29 23:52:522141 promise_url_ = quic::SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562142
2143 ReceivePromise(promise_id_);
2144 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2145
2146 request_.url = GURL(promise_url_);
2147
2148 // Make the second stream that will exercise the first step of the
2149 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272150 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2151 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2152 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562153
2154 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252155 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562156 size_t spdy_response_headers_frame_length;
2157 ProcessPacket(InnerConstructResponseHeadersPacket(
2158 1, promise_id_, false, &spdy_response_headers_frame_length));
2159
2160 // Receive the promised response body.
2161 const char kResponseBody[] = "Hello world!";
Renjief49758b2019-01-11 23:32:412162 quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
2163 ProcessPacket(InnerConstructDataPacket(
2164 2, promise_id_, false, kFin, 0, header + kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:562165
2166 // Now sending a matching request will have successful rendezvous
2167 // with the promised stream.
2168 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
2169 callback_.callback()));
2170
2171 EXPECT_EQ(
2172 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2173 ->id(),
2174 promise_id_);
2175
2176 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:012177 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2178 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562179
2180 // As will be the body.
2181 EXPECT_EQ(
2182 static_cast<int>(strlen(kResponseBody)),
2183 promised_stream_->ReadResponseBody(
2184 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2185 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2186 EXPECT_TRUE(AtEof());
2187
2188 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2189 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2190 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2191 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412192 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562193 promised_stream_->GetTotalReceivedBytes());
2194}
2195
2196TEST_P(QuicHttpStreamTest, ServerPushCrossOriginFail) {
2197 SetRequest("GET", "/", DEFAULT_PRIORITY);
2198 Initialize();
2199
2200 // Initialize the first stream, for receiving the promise on.
2201 request_.method = "GET";
rchcd379012017-04-12 21:53:322202 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562203
xunjieli5fafe142016-03-23 23:32:542204 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272205 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542206 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562207
2208 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2209 // packet, but does it matter?
2210 push_promise_[":authority"] = "www.notexample.org";
Ryan Hamilton8d9ee76e2018-05-29 23:52:522211 promise_url_ = quic::SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562212
2213 ReceivePromise(promise_id_);
2214 // The promise will have been rejected because the cert doesn't
2215 // match.
2216 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2217}
2218
2219TEST_P(QuicHttpStreamTest, ServerPushVaryCheckOK) {
2220 SetRequest("GET", "/", DEFAULT_PRIORITY);
2221 Initialize();
2222
2223 // Initialize the first stream, for receiving the promise on.
2224 request_.method = "GET";
rchcd379012017-04-12 21:53:322225 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562226
xunjieli5fafe142016-03-23 23:32:542227 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272228 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542229 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562230
2231 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562232
2233 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2234 // packet, but does it matter?
2235 ReceivePromise(promise_id_);
2236 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2237
2238 request_.url = GURL(promise_url_);
2239
2240 // Make the second stream that will exercise the first step of the
2241 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272242 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2243 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2244 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562245
2246 headers_.SetHeader("accept-encoding", "gzip");
2247
2248 // Now sending a matching request will rendezvous with the promised
2249 // stream, but pending secondary validation.
2250 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2251 headers_, &response_, callback_.callback()));
2252
2253 // Receive the promised response headers.
2254 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252255 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562256 size_t spdy_response_headers_frame_length;
2257 ProcessPacket(InnerConstructResponseHeadersPacket(
2258 1, promise_id_, false, &spdy_response_headers_frame_length));
2259
2260 // Receive the promised response body.
2261 const char kResponseBody[] = "Hello world!";
Renjief49758b2019-01-11 23:32:412262 quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
2263 ProcessPacket(InnerConstructDataPacket(
2264 2, promise_id_, false, kFin, 0, header + kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:562265
fdoray92e35a72016-06-10 15:54:552266 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562267
2268 // Rendezvous should have succeeded now, so the promised stream
2269 // should point at our push stream, and we should be able read
2270 // headers and data from it.
robpercival214763f2016-07-01 23:27:012271 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562272
2273 EXPECT_EQ(
2274 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2275 ->id(),
2276 promise_id_);
2277
robpercival214763f2016-07-01 23:27:012278 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2279 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562280
2281 EXPECT_EQ(
2282 static_cast<int>(strlen(kResponseBody)),
2283 promised_stream_->ReadResponseBody(
2284 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2285
2286 // Callback should return
2287 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2288 EXPECT_TRUE(AtEof());
2289
2290 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2291 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2292 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2293 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
Renjief49758b2019-01-11 23:32:412294 strlen(kResponseBody) + header.length()),
ckrasic3865ee0f2016-02-29 22:04:562295 promised_stream_->GetTotalReceivedBytes());
2296}
2297
2298TEST_P(QuicHttpStreamTest, ServerPushVaryCheckFail) {
2299 SetRequest("GET", "/", DEFAULT_PRIORITY);
2300 request_headers_[":scheme"] = "https";
2301 request_headers_[":path"] = "/bar";
2302 request_headers_["accept-encoding"] = "sdch";
2303
2304 size_t spdy_request_header_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522305 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362306 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:572307
Ryan Hamilton8d9ee76e2018-05-29 23:52:522308 quic::QuicPacketNumber client_packet_number = 2;
Yixin Wangb470bc882018-02-15 18:43:572309 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:262310 version_ >= quic::QUIC_VERSION_43) {
Yixin Wangb470bc882018-02-15 18:43:572311 AddWrite(ConstructClientPriorityPacket(
2312 client_packet_number++, kIncludeVersion, promise_id_, 0,
2313 DEFAULT_PRIORITY, &header_stream_offset));
2314 }
Michael Warresabba8b7d2018-07-20 22:50:272315 AddWrite(ConstructClientRstStreamVaryMismatchAndRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332316 client_packet_number++, stream_id_ + quic::test::NextStreamId(version_),
2317 !kIncludeVersion, kFin, DEFAULT_PRIORITY, promise_id_,
2318 &spdy_request_header_frame_length, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:572319 AddWrite(ConstructClientAckPacket(client_packet_number++, 3, 1, 1));
2320 AddWrite(ConstructClientRstStreamCancelledPacket(client_packet_number++));
2321
ckrasic3865ee0f2016-02-29 22:04:562322 Initialize();
2323
2324 // Initialize the first stream, for receiving the promise on.
2325 request_.method = "GET";
rchcd379012017-04-12 21:53:322326 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562327
xunjieli5fafe142016-03-23 23:32:542328 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272329 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542330 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562331
2332 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562333
2334 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2335 // packet, but does it matter?
2336 ReceivePromise(promise_id_);
2337 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2338
2339 request_.url = GURL(promise_url_);
2340
2341 // Make the second stream that will exercise the first step of the
2342 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272343 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2344 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2345 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562346
2347 headers_.SetHeader("accept-encoding", "sdch");
2348
2349 // Now sending a matching request will rendezvous with the promised
2350 // stream, but pending secondary validation.
2351 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2352 headers_, &response_, callback_.callback()));
2353
2354 // Receive the promised response headers.
2355 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252356 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562357 size_t spdy_response_headers_frame_length;
2358 ProcessPacket(InnerConstructResponseHeadersPacket(
2359 1, promise_id_, false, &spdy_response_headers_frame_length));
2360
fdoray92e35a72016-06-10 15:54:552361 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562362
2363 // Rendezvous should have failed due to vary mismatch, so the
2364 // promised stream should have been aborted, and instead we have a
2365 // new, regular client initiated stream.
robpercival214763f2016-07-01 23:27:012366 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562367
2368 // Not a server-initiated stream.
2369 EXPECT_NE(
2370 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2371 ->id(),
2372 promise_id_);
2373
2374 // Instead, a new client-initiated stream.
2375 EXPECT_EQ(
2376 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2377 ->id(),
Fan Yang32c5a112018-12-10 20:06:332378 stream_id_ + quic::test::NextStreamId(version_));
ckrasic3865ee0f2016-02-29 22:04:562379
2380 // After rendezvous failure, the push stream has been cancelled.
2381 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2382
2383 // The rest of the test verifies that the retried as
2384 // client-initiated version of |promised_stream_| works as intended.
2385
2386 // Ack the request.
wangyix6444ffe2017-04-25 17:49:492387 ProcessPacket(ConstructServerAckPacket(2, 0, 0, 0));
ckrasic3865ee0f2016-02-29 22:04:562388
bnc614a92d32016-04-04 13:56:072389 SetResponse("404 Not Found", string());
ckrasic3865ee0f2016-02-29 22:04:562390 size_t spdy_response_header_frame_length;
2391 ProcessPacket(InnerConstructResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332392 3, stream_id_ + quic::test::NextStreamId(version_), kFin,
2393 &spdy_response_header_frame_length));
ckrasic3865ee0f2016-02-29 22:04:562394
fdoray92e35a72016-06-10 15:54:552395 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562396
robpercival214763f2016-07-01 23:27:012397 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2398 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562399 ASSERT_TRUE(response_.headers.get());
2400 EXPECT_EQ(404, response_.headers->response_code());
2401 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
2402 EXPECT_FALSE(response_.response_time.is_null());
2403 EXPECT_FALSE(response_.request_time.is_null());
2404
2405 // There is no body, so this should return immediately.
2406 EXPECT_EQ(
2407 0, promised_stream_->ReadResponseBody(
2408 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2409 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2410
2411 stream_->Close(true);
2412
2413 EXPECT_TRUE(AtEof());
2414
2415 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
2416 // headers and payload.
2417 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
2418 promised_stream_->GetTotalSentBytes());
2419 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
2420 promised_stream_->GetTotalReceivedBytes());
2421}
2422
maksim.sisov84e20c92016-06-23 08:49:342423TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
2424 SetRequest("POST", "/", DEFAULT_PRIORITY);
2425 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522426 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362427 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wange7ecc472018-03-06 19:00:252428 AddWrite(ConstructRequestAndRstPacket(
Fan Yang32c5a112018-12-10 20:06:332429 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, !kFin,
Yixin Wange7ecc472018-03-06 19:00:252430 DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:522431 &header_stream_offset, quic::QUIC_ERROR_PROCESSING_STREAM, 0));
maksim.sisov84e20c92016-06-23 08:49:342432
2433 Initialize();
2434
Jeremy Roman0579ed62017-08-29 15:56:192435 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342436 ReadErrorUploadDataStream::FailureMode::SYNC);
2437 request_.method = "POST";
rchcd379012017-04-12 21:53:322438 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122439 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342440 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202441 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342442
2443 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272444 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342445 net_log_.bound(), callback_.callback()));
2446
2447 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
robpercival214763f2016-07-01 23:27:012448 EXPECT_THAT(result, IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342449
2450 EXPECT_TRUE(AtEof());
2451
2452 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2453 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2454 stream_->GetTotalSentBytes());
2455 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2456}
2457
2458TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
2459 SetRequest("POST", "/", DEFAULT_PRIORITY);
2460 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522461 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362462 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372463 AddWrite(InnerConstructRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332464 2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, !kFin,
ckrasicbf2f59c2017-05-04 23:54:362465 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
2466 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372467 AddWrite(ConstructClientRstStreamErrorPacket(3, !kIncludeVersion));
maksim.sisov84e20c92016-06-23 08:49:342468
2469 Initialize();
2470
Jeremy Roman0579ed62017-08-29 15:56:192471 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342472 ReadErrorUploadDataStream::FailureMode::ASYNC);
2473 request_.method = "POST";
rchcd379012017-04-12 21:53:322474 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122475 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342476 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202477 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342478
2479 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272480 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342481 net_log_.bound(), callback_.callback()));
2482
2483 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2484
wangyix6444ffe2017-04-25 17:49:492485 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
maksim.sisov84e20c92016-06-23 08:49:342486 SetResponse("200 OK", string());
2487
robpercival214763f2016-07-01 23:27:012488 EXPECT_THAT(result, IsError(ERR_IO_PENDING));
2489 EXPECT_THAT(callback_.GetResult(result), IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342490
2491 EXPECT_TRUE(AtEof());
2492
2493 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2494 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2495 stream_->GetTotalSentBytes());
2496 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2497}
2498
[email protected]f702d572012-12-04 15:56:202499} // namespace test
[email protected]f702d572012-12-04 15:56:202500} // namespace net