blob: fae58c6e0ea6a7a2a8c370b69f9a4c0a36388a64 [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"
xunjieli188bd402016-03-12 00:17:2514#include "base/strings/string_number_conversions.h"
gabf767595f2016-05-11 18:50:3515#include "base/threading/thread_task_runner_handle.h"
xunjieli84adaab2016-09-20 01:12:2816#include "base/time/time.h"
mmenkecbc2b712014-10-09 20:29:0717#include "net/base/chunked_upload_data_stream.h"
18#include "net/base/elements_upload_data_stream.h"
xunjieli84adaab2016-09-20 01:12:2819#include "net/base/load_timing_info.h"
20#include "net/base/load_timing_info_test_util.h"
[email protected]f702d572012-12-04 15:56:2021#include "net/base/net_errors.h"
22#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0623#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2024#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1525#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0026#include "net/log/net_log_event_type.h"
xunjieli5fafe142016-03-23 23:32:5427#include "net/log/test_net_log.h"
28#include "net/log/test_net_log_util.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0829#include "net/quic/crypto/proof_verifier_chromium.h"
30#include "net/quic/mock_crypto_client_stream_factory.h"
31#include "net/quic/quic_chromium_alarm_factory.h"
32#include "net/quic/quic_chromium_connection_helper.h"
33#include "net/quic/quic_chromium_packet_reader.h"
34#include "net/quic/quic_chromium_packet_writer.h"
35#include "net/quic/quic_http_utils.h"
36#include "net/quic/quic_server_info.h"
37#include "net/quic/quic_stream_factory.h"
38#include "net/quic/quic_test_packet_maker.h"
39#include "net/quic/test_task_runner.h"
tbansalca83c002016-04-28 20:56:2840#include "net/socket/socket_performance_watcher.h"
[email protected]f702d572012-12-04 15:56:2041#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5842#include "net/spdy/spdy_http_utils.h"
rch03b7a202016-02-05 00:54:2043#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0144#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4345#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0146#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1647#include "net/third_party/quic/core/congestion_control/send_algorithm_interface.h"
48#include "net/third_party/quic/core/crypto/crypto_protocol.h"
49#include "net/third_party/quic/core/crypto/quic_decrypter.h"
50#include "net/third_party/quic/core/crypto/quic_encrypter.h"
Victor Vasilievc5b409c22018-07-24 12:23:4651#include "net/third_party/quic/core/http/spdy_utils.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1652#include "net/third_party/quic/core/quic_connection.h"
53#include "net/third_party/quic/core/quic_write_blocked_list.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1654#include "net/third_party/quic/core/tls_client_handshaker.h"
55#include "net/third_party/quic/platform/api/quic_string_piece.h"
56#include "net/third_party/quic/test_tools/crypto_test_utils.h"
57#include "net/third_party/quic/test_tools/mock_clock.h"
58#include "net/third_party/quic/test_tools/mock_random.h"
59#include "net/third_party/quic/test_tools/quic_connection_peer.h"
60#include "net/third_party/quic/test_tools/quic_spdy_session_peer.h"
61#include "net/third_party/quic/test_tools/quic_test_utils.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2962#include "net/third_party/spdy/core/spdy_frame_builder.h"
63#include "net/third_party/spdy/core/spdy_framer.h"
64#include "net/third_party/spdy/core/spdy_protocol.h"
Ramin Halavati683bcaa92018-02-14 08:42:3965#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]f702d572012-12-04 15:56:2066#include "testing/gmock/include/gmock/gmock.h"
67#include "testing/gtest/include/gtest/gtest.h"
68
bnc614a92d32016-04-04 13:56:0769using std::string;
[email protected]f702d572012-12-04 15:56:2070using testing::_;
[email protected]06ff5152013-08-29 01:03:0571using testing::AnyNumber;
72using testing::Return;
[email protected]f702d572012-12-04 15:56:2073
74namespace net {
[email protected]f702d572012-12-04 15:56:2075namespace test {
[email protected]f702d572012-12-04 15:56:2076namespace {
77
[email protected]16ba7742014-08-22 00:57:2578const char kUploadData[] = "Really nifty data!";
rch9ae5b3b2016-02-11 00:36:2979const char kDefaultServerHostName[] = "www.example.org";
rchcd379012017-04-12 21:53:3280const uint16_t kDefaultServerPort = 443;
[email protected]f702d572012-12-04 15:56:2081
Ryan Hamilton8d9ee76e2018-05-29 23:52:5282class TestQuicConnection : public quic::QuicConnection {
[email protected]f702d572012-12-04 15:56:2083 public:
Ryan Hamilton8d9ee76e2018-05-29 23:52:5284 TestQuicConnection(const quic::ParsedQuicVersionVector& versions,
85 quic::QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2086 IPEndPoint address,
rch12fef552016-01-15 16:26:3187 QuicChromiumConnectionHelper* helper,
rch16c74d1d2016-04-22 06:14:0788 QuicChromiumAlarmFactory* alarm_factory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5289 quic::QuicPacketWriter* writer)
90 : quic::QuicConnection(
91 connection_id,
92 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(address)),
93 helper,
94 alarm_factory,
95 writer,
96 true /* owns_writer */,
97 quic::Perspective::IS_CLIENT,
98 versions) {}
[email protected]f702d572012-12-04 15:56:2099
Ryan Hamilton8d9ee76e2018-05-29 23:52:52100 void SetSendAlgorithm(quic::SendAlgorithmInterface* send_algorithm) {
101 quic::test::QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:20102 }
103};
104
maksim.sisov84e20c92016-06-23 08:49:34105// UploadDataStream that always returns errors on data read.
106class ReadErrorUploadDataStream : public UploadDataStream {
107 public:
108 enum class FailureMode { SYNC, ASYNC };
109
110 explicit ReadErrorUploadDataStream(FailureMode mode)
111 : UploadDataStream(true, 0), async_(mode), weak_factory_(this) {}
112 ~ReadErrorUploadDataStream() override {}
113
114 private:
115 void CompleteRead() { UploadDataStream::OnReadCompleted(ERR_FAILED); }
116
117 // UploadDataStream implementation:
tfarina42834112016-09-22 13:38:20118 int InitInternal(const NetLogWithSource& net_log) override { return OK; }
maksim.sisov84e20c92016-06-23 08:49:34119
120 int ReadInternal(IOBuffer* buf, int buf_len) override {
121 if (async_ == FailureMode::ASYNC) {
122 base::ThreadTaskRunnerHandle::Get()->PostTask(
123 FROM_HERE, base::Bind(&ReadErrorUploadDataStream::CompleteRead,
124 weak_factory_.GetWeakPtr()));
125 return ERR_IO_PENDING;
126 }
127 return ERR_FAILED;
128 }
129
130 void ResetInternal() override {}
131
132 const FailureMode async_;
133
134 base::WeakPtrFactory<ReadErrorUploadDataStream> weak_factory_;
135
136 DISALLOW_COPY_AND_ASSIGN(ReadErrorUploadDataStream);
137};
138
Bence Béky8ddc2492018-06-13 01:02:04139// A helper class that will delete |stream| when the callback is invoked.
xunjieli8dff50b2016-07-22 14:19:06140class DeleteStreamCallback : public TestCompletionCallbackBase {
141 public:
Bence Béky8ddc2492018-06-13 01:02:04142 explicit DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)
143 : stream_(std::move(stream)) {}
xunjieli8dff50b2016-07-22 14:19:06144
Bence Béky8ddc2492018-06-13 01:02:04145 CompletionOnceCallback callback() {
146 return base::BindOnce(&DeleteStreamCallback::DeleteStream,
147 base::Unretained(this));
148 }
xunjieli8dff50b2016-07-22 14:19:06149
150 private:
151 void DeleteStream(int result) {
152 stream_.reset();
153 SetResult(result);
154 }
155
156 std::unique_ptr<QuicHttpStream> stream_;
xunjieli8dff50b2016-07-22 14:19:06157};
158
[email protected]f702d572012-12-04 15:56:20159} // namespace
160
[email protected]24e5bc52013-09-18 15:36:58161class QuicHttpStreamPeer {
162 public:
rch08e198572017-05-09 16:56:55163 static QuicChromiumClientStream::Handle* GetQuicChromiumClientStream(
[email protected]24e5bc52013-09-18 15:36:58164 QuicHttpStream* stream) {
rch08e198572017-05-09 16:56:55165 return stream->stream_.get();
[email protected]24e5bc52013-09-18 15:36:58166 }
167};
168
Ryan Hamilton8d9ee76e2018-05-29 23:52:52169class QuicHttpStreamTest : public ::testing::TestWithParam<
170 std::tuple<quic::QuicTransportVersion, bool>>,
171 public WithScopedTaskEnvironment {
rchfb47f712017-05-21 03:24:00172 public:
173 void CloseStream(QuicHttpStream* stream, int /*rv*/) { stream->Close(false); }
174
[email protected]f702d572012-12-04 15:56:20175 protected:
[email protected]1e960032013-12-20 19:00:20176 static const bool kFin = true;
177 static const bool kIncludeVersion = true;
178 static const bool kIncludeCongestionFeedback = true;
179
[email protected]f702d572012-12-04 15:56:20180 // Holds a packet to be written to the wire, and the IO mode that should
181 // be used by the mock socket when performing the write.
182 struct PacketToWrite {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52183 PacketToWrite(IoMode mode, quic::QuicReceivedPacket* packet)
rjshaded5ced072015-12-18 19:26:02184 : mode(mode), packet(packet) {}
rtenneti15656ae2016-01-23 03:05:03185 PacketToWrite(IoMode mode, int rv) : mode(mode), packet(nullptr), rv(rv) {}
[email protected]f702d572012-12-04 15:56:20186 IoMode mode;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52187 quic::QuicReceivedPacket* packet;
rtenneti15656ae2016-01-23 03:05:03188 int rv;
[email protected]f702d572012-12-04 15:56:20189 };
190
191 QuicHttpStreamTest()
Yixin Wang079ad542018-01-11 04:06:05192 : version_(std::get<0>(GetParam())),
193 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52194 crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting(),
195 quic::TlsClientHandshaker::CreateSslCtx()),
[email protected]f702d572012-12-04 15:56:20196 read_buffer_(new IOBufferWithSize(4096)),
ckrasicbf2f59c2017-05-04 23:54:36197 promise_id_(GetNthServerInitiatedStreamId(0)),
198 stream_id_(GetNthClientInitiatedStreamId(0)),
ckrasic3865ee0f2016-02-29 22:04:56199 connection_id_(2),
Yixin Wang079ad542018-01-11 04:06:05200 client_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58201 connection_id_,
202 &clock_,
203 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52204 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05205 client_headers_include_h2_stream_dependency_),
206 server_maker_(version_,
zhongyi5dbfdd42017-06-20 05:22:15207 connection_id_,
alyssar2adf3ac2016-05-03 17:12:58208 &clock_,
209 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52210 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05211 false),
ckrasic3865ee0f2016-02-29 22:04:56212 random_generator_(0),
213 response_offset_(0) {
martijn21968ea2016-02-24 18:46:20214 IPAddress ip(192, 0, 2, 33);
[email protected]f702d572012-12-04 15:56:20215 peer_addr_ = IPEndPoint(ip, 443);
216 self_addr_ = IPEndPoint(ip, 8435);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52217 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
Ramin Halavati683bcaa92018-02-14 08:42:39218 request_.traffic_annotation =
219 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f702d572012-12-04 15:56:20220 }
221
222 ~QuicHttpStreamTest() {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52223 session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR);
[email protected]f702d572012-12-04 15:56:20224 for (size_t i = 0; i < writes_.size(); i++) {
225 delete writes_[i].packet;
226 }
227 }
228
229 // Adds a packet to the list of expected writes.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52230 void AddWrite(std::unique_ptr<quic::QuicReceivedPacket> packet) {
[email protected]1e960032013-12-20 19:00:20231 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20232 }
233
rtenneti15656ae2016-01-23 03:05:03234 void AddWrite(IoMode mode, int rv) {
235 writes_.push_back(PacketToWrite(mode, rv));
236 }
237
[email protected]f702d572012-12-04 15:56:20238 // Returns the packet to be written at position |pos|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52239 quic::QuicReceivedPacket* GetWrite(size_t pos) { return writes_[pos].packet; }
[email protected]f702d572012-12-04 15:56:20240
241 bool AtEof() {
rch37de576c2015-05-17 20:28:17242 return socket_data_->AllReadDataConsumed() &&
243 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20244 }
245
Ryan Hamilton8d9ee76e2018-05-29 23:52:52246 void ProcessPacket(std::unique_ptr<quic::QuicReceivedPacket> packet) {
fayang91ca2012016-11-22 07:42:46247 connection_->ProcessUdpPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52248 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(self_addr_)),
249 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(peer_addr_)),
250 *packet);
[email protected]f702d572012-12-04 15:56:20251 }
252
253 // Configures the test fixture to use the list of expected writes.
254 void Initialize() {
255 mock_writes_.reset(new MockWrite[writes_.size()]);
256 for (size_t i = 0; i < writes_.size(); i++) {
rtenneti15656ae2016-01-23 03:05:03257 if (writes_[i].packet == nullptr) {
258 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
259 } else {
260 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
261 writes_[i].packet->length());
262 }
bnc614a92d32016-04-04 13:56:07263 }
[email protected]f702d572012-12-04 15:56:20264
rtennetibe635732014-10-02 22:51:42265 socket_data_.reset(new StaticSocketDataProvider(
Ryan Sleevib8d7ea02018-05-07 20:01:01266 base::span<MockRead>(),
267 base::make_span(mock_writes_.get(), writes_.size())));
[email protected]f702d572012-12-04 15:56:20268
danakjad1777e2016-04-16 00:56:42269 std::unique_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
xunjielib53b38c2016-03-24 15:54:36270 socket_data_.get(), net_log_.bound().net_log()));
[email protected]e13201d82012-12-12 05:00:32271 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20272 runner_ = new TestTaskRunner(&clock_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52273 send_algorithm_ = new quic::test::MockSendAlgorithm();
rch7dd15702015-07-01 18:57:57274 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
275 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
rjshaded5ced072015-12-18 19:26:02276 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
Dan Zhangf11470172017-09-18 22:02:09277 .Times(testing::AtLeast(1));
rtenneti44f4a2e2015-08-07 14:00:07278 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52279 .WillRepeatedly(Return(quic::kMaxPacketSize));
jokulik0e0a00c32016-06-13 21:51:58280 EXPECT_CALL(*send_algorithm_, PacingRate(_))
Ryan Hamilton8d9ee76e2018-05-29 23:52:52281 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Michael Warres74ee3ce2017-10-09 15:26:37282 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
rtenneti44f4a2e2015-08-07 14:00:07283 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52284 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40285 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
rch08cae032017-03-29 00:59:15286 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
rch0d5bcf62017-05-24 22:48:45287 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
288 .Times(AnyNumber());
rch16c74d1d2016-04-22 06:14:07289 helper_.reset(
290 new QuicChromiumConnectionHelper(&clock_, &random_generator_));
291 alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
292
Michael Warres74ee3ce2017-10-09 15:26:37293 connection_ = new TestQuicConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52294 quic::test::SupportedVersions(
295 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version_)),
Dan Zhangfefaf5b2017-12-11 17:06:24296 connection_id_, peer_addr_, helper_.get(), alarm_factory_.get(),
Ryan Hamilton9edcf1a2017-11-22 05:55:17297 new QuicChromiumPacketWriter(
298 socket.get(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]f702d572012-12-04 15:56:20299 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41300 connection_->SetSendAlgorithm(send_algorithm_);
rch03b7a202016-02-05 00:54:20301
302 // Load a certificate that is valid for *.example.org
303 scoped_refptr<X509Certificate> test_cert(
304 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
305 EXPECT_TRUE(test_cert.get());
306
307 verify_details_.cert_verify_result.verified_cert = test_cert;
308 verify_details_.cert_verify_result.is_issued_by_known_root = true;
309 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
310
xunjieli84adaab2016-09-20 01:12:28311 base::TimeTicks dns_end = base::TimeTicks::Now();
312 base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);
ckrasic4f9d88d2015-07-22 22:23:16313 session_.reset(new QuicChromiumClientSession(
xunjielib53b38c2016-03-24 15:54:36314 connection_, std::move(socket),
rtenneti1cd3b162015-09-29 02:58:28315 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57316 &transport_security_state_, /*ssl_config_service=*/nullptr,
danakjad1777e2016-04-16 00:56:42317 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
Paul Jensen8e3c5d32018-02-19 17:06:33318 QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
319 PRIVACY_MODE_DISABLED, SocketTag()),
Zhongyi Shi757fcce2018-06-27 05:41:27320 /*require_confirmation=*/false, /*migrate_session_early_v2=*/false,
321 /*migrate_session_on_network_change_v2=*/false,
322 /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shi73f23ca872017-12-13 18:37:13323 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shiee760762018-08-01 00:54:29324 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30325 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17326 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52327 quic::QuicTime::Delta::FromMilliseconds(
328 kQuicYieldAfterDurationMilliseconds),
Yixin Wang079ad542018-01-11 04:06:05329 client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52330 quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
331 dns_start, dns_end, &push_promise_index_, nullptr,
xunjieli84adaab2016-09-20 01:12:28332 base::ThreadTaskRunnerHandle::Get().get(),
xunjieli5fafe142016-03-23 23:32:54333 /*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));
rtennetid39bd762015-06-12 01:05:52334 session_->Initialize();
xunjieli100937eb52016-09-15 20:09:37335 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57336
rch433bf5f2017-02-14 04:10:47337 session_->CryptoConnect(callback.callback());
Ryan Hamilton6c2a2a82017-12-15 02:06:28338 stream_ = std::make_unique<QuicHttpStream>(
339 session_->CreateHandle(HostPortPair("www.example.org", 443)));
340 promised_stream_ = std::make_unique<QuicHttpStream>(
341 session_->CreateHandle(HostPortPair("www.example.org", 443)));
ckrasic3865ee0f2016-02-29 22:04:56342 push_promise_[":path"] = "/bar";
343 push_promise_[":authority"] = "www.example.org";
344 push_promise_[":version"] = "HTTP/1.1";
345 push_promise_[":method"] = "GET";
346 push_promise_[":scheme"] = "https";
347
348 promised_response_[":status"] = "200 OK";
349 promised_response_[":version"] = "HTTP/1.1";
350 promised_response_["content-type"] = "text/plain";
351
Ryan Hamilton8d9ee76e2018-05-29 23:52:52352 promise_url_ = quic::SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
[email protected]6cca996b2013-01-25 07:43:36353 }
354
bnc614a92d32016-04-04 13:56:07355 void SetRequest(const string& method,
356 const string& path,
[email protected]1e960032013-12-20 19:00:20357 RequestPriority priority) {
rchcd379012017-04-12 21:53:32358 request_headers_ = client_maker_.GetRequestHeaders(method, "https", path);
[email protected]6cca996b2013-01-25 07:43:36359 }
360
bnc614a92d32016-04-04 13:56:07361 void SetResponse(const string& status, const string& body) {
alyssar2adf3ac2016-05-03 17:12:58362 response_headers_ = server_maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03363 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36364 }
[email protected]f702d572012-12-04 15:56:20365
Ryan Hamilton8d9ee76e2018-05-29 23:52:52366 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructDataPacket(
367 quic::QuicPacketNumber packet_number,
368 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56369 bool should_include_version,
370 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52371 quic::QuicStreamOffset offset,
372 quic::QuicStringPiece data,
alyssar2adf3ac2016-05-03 17:12:58373 QuicTestPacketMaker* maker) {
374 return maker->MakeDataPacket(packet_number, stream_id,
ckrasic3865ee0f2016-02-29 22:04:56375 should_include_version, fin, offset, data);
376 }
377
Ryan Hamilton8d9ee76e2018-05-29 23:52:52378 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientDataPacket(
379 quic::QuicPacketNumber packet_number,
[email protected]e8ff26842013-03-22 21:02:05380 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20381 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52382 quic::QuicStreamOffset offset,
383 quic::QuicStringPiece data) {
ckrasic3865ee0f2016-02-29 22:04:56384 return InnerConstructDataPacket(packet_number, stream_id_,
alyssar2adf3ac2016-05-03 17:12:58385 should_include_version, fin, offset, data,
386 &client_maker_);
387 }
388
Ryan Hamilton8d9ee76e2018-05-29 23:52:52389 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
390 quic::QuicPacketNumber packet_number,
alyssar2adf3ac2016-05-03 17:12:58391 bool should_include_version,
392 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52393 quic::QuicStreamOffset offset,
394 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58395 return InnerConstructDataPacket(packet_number, stream_id_,
396 should_include_version, fin, offset, data,
397 &server_maker_);
ckrasic3865ee0f2016-02-29 22:04:56398 }
399
Ryan Hamilton8d9ee76e2018-05-29 23:52:52400 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
401 quic::QuicPacketNumber packet_number,
402 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56403 bool should_include_version,
404 bool fin,
405 RequestPriority request_priority,
xunjieli100937eb52016-09-15 20:09:37406 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52407 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48408 return InnerConstructRequestHeadersPacket(
409 packet_number, stream_id, should_include_version, fin, request_priority,
410 0, spdy_headers_frame_length, offset);
411 }
412
Ryan Hamilton8d9ee76e2018-05-29 23:52:52413 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
414 quic::QuicPacketNumber packet_number,
415 quic::QuicStreamId stream_id,
Yixin Wang7a3f1b8d2018-01-17 21:40:48416 bool should_include_version,
417 bool fin,
418 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52419 quic::QuicStreamId parent_stream_id,
Yixin Wang7a3f1b8d2018-01-17 21:40:48420 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52421 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13422 spdy::SpdyPriority priority =
ckrasic3865ee0f2016-02-29 22:04:56423 ConvertRequestPriorityToQuicPriority(request_priority);
alyssar2adf3ac2016-05-03 17:12:58424 return client_maker_.MakeRequestHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56425 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48426 std::move(request_headers_), parent_stream_id,
427 spdy_headers_frame_length, offset);
[email protected]f702d572012-12-04 15:56:20428 }
429
Ryan Hamilton8d9ee76e2018-05-29 23:52:52430 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25431 ConstructRequestHeadersAndDataFramesPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52432 quic::QuicPacketNumber packet_number,
433 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25434 bool should_include_version,
435 bool fin,
436 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52437 quic::QuicStreamId parent_stream_id,
438 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25439 size_t* spdy_headers_frame_length,
440 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13441 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25442 ConvertRequestPriorityToQuicPriority(request_priority);
443 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
444 packet_number, stream_id, should_include_version, fin, priority,
445 std::move(request_headers_), parent_stream_id, offset,
446 spdy_headers_frame_length, data_writes);
447 }
448
Ryan Hamilton8d9ee76e2018-05-29 23:52:52449 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestAndRstPacket(
450 quic::QuicPacketNumber packet_number,
451 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25452 bool should_include_version,
453 bool fin,
454 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52455 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25456 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52457 quic::QuicStreamOffset* header_stream_offset,
458 quic::QuicRstStreamErrorCode error_code,
Yixin Wange7ecc472018-03-06 19:00:25459 size_t bytes_written) {
Ryan Hamilton0239aac2018-05-19 00:03:13460 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25461 ConvertRequestPriorityToQuicPriority(request_priority);
462 return client_maker_.MakeRequestHeadersAndRstPacket(
463 packet_number, stream_id, should_include_version, fin, priority,
464 std::move(request_headers_), parent_stream_id,
465 spdy_headers_frame_length, header_stream_offset, error_code,
466 bytes_written);
467 }
468
Ryan Hamilton8d9ee76e2018-05-29 23:52:52469 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestHeadersPacket(
470 quic::QuicPacketNumber packet_number,
rtennetif4bdb542015-01-21 14:33:05471 bool fin,
sclittlec4dc1a32015-09-24 00:15:45472 RequestPriority request_priority,
473 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56474 return InnerConstructRequestHeadersPacket(
475 packet_number, stream_id_, kIncludeVersion, fin, request_priority,
xunjieli100937eb52016-09-15 20:09:37476 spdy_headers_frame_length, nullptr);
ckrasic3865ee0f2016-02-29 22:04:56477 }
478
Ryan Hamilton8d9ee76e2018-05-29 23:52:52479 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructResponseHeadersPacket(
480 quic::QuicPacketNumber packet_number,
481 quic::QuicStreamId stream_id,
ckrasic3865ee0f2016-02-29 22:04:56482 bool fin,
483 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58484 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26485 packet_number, stream_id, !kIncludeVersion, fin,
486 std::move(response_headers_), spdy_headers_frame_length,
487 &response_offset_);
[email protected]1e960032013-12-20 19:00:20488 }
489
Ryan Hamilton8d9ee76e2018-05-29 23:52:52490 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseHeadersPacket(
491 quic::QuicPacketNumber packet_number,
sclittlec4dc1a32015-09-24 00:15:45492 bool fin,
493 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56494 return InnerConstructResponseHeadersPacket(packet_number, stream_id_, fin,
495 spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20496 }
497
Ryan Hamilton8d9ee76e2018-05-29 23:52:52498 std::unique_ptr<quic::QuicReceivedPacket>
499 ConstructResponseHeadersPacketWithOffset(quic::QuicPacketNumber packet_number,
500 bool fin,
501 size_t* spdy_headers_frame_length,
502 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58503 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26504 packet_number, stream_id_, !kIncludeVersion, fin,
505 std::move(response_headers_), spdy_headers_frame_length, offset);
xunjieli34291fe12016-03-02 13:58:38506 }
507
Ryan Hamilton8d9ee76e2018-05-29 23:52:52508 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseTrailersPacket(
509 quic::QuicPacketNumber packet_number,
xunjieli34291fe12016-03-02 13:58:38510 bool fin,
Ryan Hamilton0239aac2018-05-19 00:03:13511 spdy::SpdyHeaderBlock trailers,
xunjieli34291fe12016-03-02 13:58:38512 size_t* spdy_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52513 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58514 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26515 packet_number, stream_id_, !kIncludeVersion, fin, std::move(trailers),
alyssar2adf3ac2016-05-03 17:12:58516 spdy_headers_frame_length, offset);
xunjieli34291fe12016-03-02 13:58:38517 }
518
Ryan Hamilton8d9ee76e2018-05-29 23:52:52519 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamPacket(
520 quic::QuicPacketNumber packet_number) {
alyssara72f5352016-10-20 12:45:16521 return client_maker_.MakeRstPacket(packet_number, true, stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52522 quic::QUIC_RST_ACKNOWLEDGEMENT);
[email protected]06ff5152013-08-29 01:03:05523 }
524
Ryan Hamilton8d9ee76e2018-05-29 23:52:52525 std::unique_ptr<quic::QuicReceivedPacket>
526 ConstructClientRstStreamCancelledPacket(
527 quic::QuicPacketNumber packet_number) {
alyssar2adf3ac2016-05-03 17:12:58528 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52529 stream_id_, quic::QUIC_STREAM_CANCELLED);
rtenneti6bd660b2015-07-18 00:19:53530 }
531
Ryan Hamilton8d9ee76e2018-05-29 23:52:52532 std::unique_ptr<quic::QuicReceivedPacket>
533 ConstructClientRstStreamVaryMismatchPacket(
534 quic::QuicPacketNumber packet_number) {
alyssar2adf3ac2016-05-03 17:12:58535 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52536 promise_id_,
537 quic::QUIC_PROMISE_VARY_MISMATCH);
ckrasic3865ee0f2016-02-29 22:04:56538 }
539
Fan Yang550c6282018-06-22 18:53:25540 std::unique_ptr<quic::QuicReceivedPacket>
541 ConstructClientRstStreamVaryMismatchAndRequestHeadersPacket(
542 quic::QuicPacketNumber packet_number,
543 quic::QuicStreamId stream_id,
544 bool should_include_version,
545 bool fin,
546 RequestPriority request_priority,
547 quic::QuicStreamId parent_stream_id,
548 size_t* spdy_headers_frame_length,
549 quic::QuicStreamOffset* offset) {
550 spdy::SpdyPriority priority =
551 ConvertRequestPriorityToQuicPriority(request_priority);
552 return client_maker_.MakeRstAndRequestHeadersPacket(
553 packet_number, should_include_version, promise_id_,
554 quic::QUIC_PROMISE_VARY_MISMATCH, stream_id, fin, priority,
555 std::move(request_headers_), parent_stream_id,
556 spdy_headers_frame_length, offset);
557 }
558
Ryan Hamilton8d9ee76e2018-05-29 23:52:52559 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
560 quic::QuicPacketNumber packet_number,
561 quic::QuicPacketNumber largest_received,
562 quic::QuicPacketNumber smallest_received,
563 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58564 return client_maker_.MakeAckAndRstPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52565 packet_number, !kIncludeVersion, stream_id_,
566 quic::QUIC_STREAM_CANCELLED, largest_received, smallest_received,
567 least_unacked, !kIncludeCongestionFeedback);
xunjieli34291fe12016-03-02 13:58:38568 }
569
Ryan Hamilton8d9ee76e2018-05-29 23:52:52570 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamErrorPacket(
571 quic::QuicPacketNumber packet_number,
maksim.sisov84e20c92016-06-23 08:49:34572 bool include_version) {
573 return client_maker_.MakeRstPacket(packet_number, include_version,
574 stream_id_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52575 quic::QUIC_ERROR_PROCESSING_STREAM);
maksim.sisov84e20c92016-06-23 08:49:34576 }
577
Ryan Hamilton8d9ee76e2018-05-29 23:52:52578 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
579 quic::QuicPacketNumber packet_number) {
xunjieli34291fe12016-03-02 13:58:38580 return ConstructAckAndRstStreamPacket(packet_number, 2, 1, 1);
[email protected]c5e1aca2014-01-30 04:03:04581 }
582
Ryan Hamilton8d9ee76e2018-05-29 23:52:52583 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckPacket(
584 quic::QuicPacketNumber packet_number,
585 quic::QuicPacketNumber largest_received,
586 quic::QuicPacketNumber smallest_received,
587 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58588 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49589 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58590 !kIncludeCongestionFeedback);
591 }
592
Ryan Hamilton8d9ee76e2018-05-29 23:52:52593 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
594 quic::QuicPacketNumber packet_number,
595 quic::QuicPacketNumber largest_received,
596 quic::QuicPacketNumber smallest_received,
597 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58598 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49599 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58600 !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00601 }
602
Ryan Hamilton8d9ee76e2018-05-29 23:52:52603 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
604 quic::QuicPacketNumber packet_number,
Yixin Wangb470bc882018-02-15 18:43:57605 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52606 quic::QuicStreamId id,
607 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57608 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52609 quic::QuicStreamOffset* header_stream_offset) {
Yixin Wangb470bc882018-02-15 18:43:57610 return client_maker_.MakePriorityPacket(
611 packet_number, should_include_version, id, parent_stream_id,
612 ConvertRequestPriorityToQuicPriority(request_priority),
613 header_stream_offset);
614 }
615
Ryan Hamilton8d9ee76e2018-05-29 23:52:52616 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
617 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36618 return client_maker_.MakeInitialSettingsPacket(1, offset);
fayang3bcb8b502016-12-07 21:44:37619 }
620
Ryan Hamilton8d9ee76e2018-05-29 23:52:52621 void ReceivePromise(quic::QuicStreamId id) {
622 auto headers = quic::test::AsHeaderList(push_promise_);
rch08e198572017-05-09 16:56:55623 QuicChromiumClientStream::Handle* stream =
ckrasic3865ee0f2016-02-29 22:04:56624 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
ckrasic32b17dcd2016-10-31 06:15:35625 stream->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
626 headers);
ckrasic3865ee0f2016-02-29 22:04:56627 }
628
xunjieli84adaab2016-09-20 01:12:28629 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info,
xunjieli100937eb52016-09-15 20:09:37630 bool session_reused) {
631 EXPECT_EQ(session_reused, load_timing_info.socket_reused);
xunjieli84adaab2016-09-20 01:12:28632 if (session_reused) {
633 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
634 } else {
635 ExpectConnectTimingHasTimes(
636 load_timing_info.connect_timing,
637 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
638 }
639 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
xunjieli100937eb52016-09-15 20:09:37640 }
641
Ryan Hamilton8d9ee76e2018-05-29 23:52:52642 quic::QuicStreamId GetNthClientInitiatedStreamId(int n) {
643 return quic::test::GetNthClientInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36644 }
645
Ryan Hamilton8d9ee76e2018-05-29 23:52:52646 quic::QuicStreamId GetNthServerInitiatedStreamId(int n) {
647 return quic::test::GetNthServerInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36648 }
649
Ryan Hamilton8d9ee76e2018-05-29 23:52:52650 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05651 const bool client_headers_include_h2_stream_dependency_;
652
xunjieli5fafe142016-03-23 23:32:54653 BoundTestNetLog net_log_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52654 quic::test::MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20655 scoped_refptr<TestTaskRunner> runner_;
danakjad1777e2016-04-16 00:56:42656 std::unique_ptr<MockWrite[]> mock_writes_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52657 quic::MockClock clock_;
[email protected]f702d572012-12-04 15:56:20658 TestQuicConnection* connection_;
danakjad1777e2016-04-16 00:56:42659 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
rch16c74d1d2016-04-22 06:14:07660 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52661 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
rch97827ee2017-05-24 23:49:12662 std::unique_ptr<UploadDataStream> upload_data_stream_;
danakjad1777e2016-04-16 00:56:42663 std::unique_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15664 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42665 std::unique_ptr<QuicChromiumClientSession> session_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52666 quic::QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20667 TestCompletionCallback callback_;
668 HttpRequestInfo request_;
669 HttpRequestHeaders headers_;
670 HttpResponseInfo response_;
671 scoped_refptr<IOBufferWithSize> read_buffer_;
Ryan Hamilton0239aac2018-05-19 00:03:13672 spdy::SpdyHeaderBlock request_headers_;
673 spdy::SpdyHeaderBlock response_headers_;
bnc614a92d32016-04-04 13:56:07674 string request_data_;
675 string response_data_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52676 quic::QuicClientPushPromiseIndex push_promise_index_;
[email protected]f702d572012-12-04 15:56:20677
ckrasic3865ee0f2016-02-29 22:04:56678 // For server push testing
danakjad1777e2016-04-16 00:56:42679 std::unique_ptr<QuicHttpStream> promised_stream_;
Ryan Hamilton0239aac2018-05-19 00:03:13680 spdy::SpdyHeaderBlock push_promise_;
681 spdy::SpdyHeaderBlock promised_response_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52682 const quic::QuicStreamId promise_id_;
ckrasic3865ee0f2016-02-29 22:04:56683 string promise_url_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52684 const quic::QuicStreamId stream_id_;
ckrasic3865ee0f2016-02-29 22:04:56685
Ryan Hamilton8d9ee76e2018-05-29 23:52:52686 const quic::QuicConnectionId connection_id_;
alyssar2adf3ac2016-05-03 17:12:58687 QuicTestPacketMaker client_maker_;
688 QuicTestPacketMaker server_maker_;
[email protected]f702d572012-12-04 15:56:20689 IPEndPoint self_addr_;
690 IPEndPoint peer_addr_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52691 quic::test::MockRandom random_generator_;
rch03b7a202016-02-05 00:54:20692 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05693 MockCryptoClientStreamFactory crypto_client_stream_factory_;
danakjad1777e2016-04-16 00:56:42694 std::unique_ptr<StaticSocketDataProvider> socket_data_;
[email protected]f702d572012-12-04 15:56:20695 std::vector<PacketToWrite> writes_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52696 quic::QuicStreamOffset response_offset_;
[email protected]f702d572012-12-04 15:56:20697};
698
Yixin Wang079ad542018-01-11 04:06:05699INSTANTIATE_TEST_CASE_P(
Bence Békyce380cb2018-04-26 23:39:55700 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05701 QuicHttpStreamTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52702 ::testing::Combine(
703 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
704 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20705
706TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44707 Initialize();
rtennetibe635732014-10-02 22:51:42708 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20709}
710
mmenkebd84c392015-09-02 14:12:34711TEST_P(QuicHttpStreamTest, CanReuseConnection) {
[email protected]ed3fc15d2013-03-08 18:37:44712 Initialize();
mmenkebd84c392015-09-02 14:12:34713 EXPECT_FALSE(stream_->CanReuseConnection());
[email protected]f702d572012-12-04 15:56:20714}
715
jri231c2972016-03-08 19:50:11716TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
Zhongyi Shibb28b1f2018-07-18 02:41:26717 request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri231c2972016-03-08 19:50:11718 Initialize();
xunjieli5fafe142016-03-23 23:32:54719 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27720 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54721 net_log_.bound(), callback_.callback()));
rch08e198572017-05-09 16:56:55722 QuicChromiumClientStream::Handle* client_stream =
jri231c2972016-03-08 19:50:11723 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
Zhongyi Shibb28b1f2018-07-18 02:41:26724 EXPECT_FALSE(client_stream->can_migrate_to_cellular_network());
jri231c2972016-03-08 19:50:11725}
726
[email protected]1e960032013-12-20 19:00:20727TEST_P(QuicHttpStreamTest, GetRequest) {
728 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45729 size_t spdy_request_header_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52730 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36731 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37732 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36733 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
734 DEFAULT_PRIORITY, &spdy_request_header_frame_length,
735 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37736
[email protected]f702d572012-12-04 15:56:20737 Initialize();
738
739 request_.method = "GET";
rchcd379012017-04-12 21:53:32740 request_.url = GURL("https://www.example.org/");
[email protected]f702d572012-12-04 15:56:20741
xunjieli100937eb52016-09-15 20:09:37742 // Make sure getting load timing from the stream early does not crash.
743 LoadTimingInfo load_timing_info;
744 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
745
xunjieli5fafe142016-03-23 23:32:54746 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27747 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54748 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02749 EXPECT_EQ(OK,
750 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20751
752 // Ack the request.
wangyix6444ffe2017-04-25 17:49:49753 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]f702d572012-12-04 15:56:20754
robpercival214763f2016-07-01 23:27:01755 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
756 IsError(ERR_IO_PENDING));
[email protected]f702d572012-12-04 15:56:20757
bnc614a92d32016-04-04 13:56:07758 SetResponse("404 Not Found", string());
sclittlec4dc1a32015-09-24 00:15:45759 size_t spdy_response_header_frame_length;
760 ProcessPacket(ConstructResponseHeadersPacket(
761 2, kFin, &spdy_response_header_frame_length));
[email protected]f702d572012-12-04 15:56:20762
763 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01764 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]cadac622013-06-11 16:46:36765 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20766 EXPECT_EQ(404, response_.headers->response_code());
767 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53768 EXPECT_FALSE(response_.response_time.is_null());
769 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20770
771 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02772 EXPECT_EQ(0,
773 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
774 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20775 EXPECT_TRUE(stream_->IsResponseBodyComplete());
776 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10777
xunjieli100937eb52016-09-15 20:09:37778 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28779 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37780
sclittle1edeeb22015-09-02 20:46:10781 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45782 // headers and payload.
783 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
784 stream_->GetTotalSentBytes());
785 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
786 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20787}
788
xunjieli100937eb52016-09-15 20:09:37789TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
790 SetRequest("GET", "/", DEFAULT_PRIORITY);
791 size_t spdy_request_header_frame_length;
792
Ryan Hamilton8d9ee76e2018-05-29 23:52:52793 quic::QuicStreamOffset offset = 0;
rch5cb522462017-04-25 20:18:36794 AddWrite(ConstructInitialSettingsPacket(&offset));
xunjieli100937eb52016-09-15 20:09:37795 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36796 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
797 DEFAULT_PRIORITY, &spdy_request_header_frame_length, &offset));
xunjieli100937eb52016-09-15 20:09:37798
799 // SetRequest() again for second request as |request_headers_| was moved.
800 SetRequest("GET", "/", DEFAULT_PRIORITY);
801 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36802 3, GetNthClientInitiatedStreamId(1), kIncludeVersion, kFin,
Yixin Wang7a3f1b8d2018-01-17 21:40:48803 DEFAULT_PRIORITY, GetNthClientInitiatedStreamId(0),
804 &spdy_request_header_frame_length, &offset));
wangyix6444ffe2017-04-25 17:49:49805 AddWrite(ConstructClientAckPacket(4, 3, 1, 1)); // Ack the responses.
xunjieli100937eb52016-09-15 20:09:37806
807 Initialize();
808
809 request_.method = "GET";
rchcd379012017-04-12 21:53:32810 request_.url = GURL("https://www.example.org/");
xunjieli100937eb52016-09-15 20:09:37811 // Start first request.
812 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27813 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37814 net_log_.bound(), callback_.callback()));
815 EXPECT_EQ(OK,
816 stream_->SendRequest(headers_, &response_, callback_.callback()));
817
818 // Start a second request.
Ryan Hamilton6c2a2a82017-12-15 02:06:28819 QuicHttpStream stream2(
820 session_->CreateHandle(HostPortPair("www.example.org", 443)));
xunjieli100937eb52016-09-15 20:09:37821 TestCompletionCallback callback2;
822 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27823 stream2.InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37824 net_log_.bound(), callback2.callback()));
825 EXPECT_EQ(OK,
826 stream2.SendRequest(headers_, &response_, callback2.callback()));
827
828 // Ack both requests.
wangyix6444ffe2017-04-25 17:49:49829 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
xunjieli100937eb52016-09-15 20:09:37830
831 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
832 IsError(ERR_IO_PENDING));
833 size_t spdy_response_header_frame_length;
834 SetResponse("200 OK", string());
835 ProcessPacket(InnerConstructResponseHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36836 2, GetNthClientInitiatedStreamId(0), kFin,
837 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37838
839 // Now that the headers have been processed, the callback will return.
840 EXPECT_THAT(callback_.WaitForResult(), IsOk());
841 EXPECT_EQ(200, response_.headers->response_code());
842
843 // There is no body, so this should return immediately.
844 EXPECT_EQ(0,
845 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
846 callback_.callback()));
847 EXPECT_TRUE(stream_->IsResponseBodyComplete());
848
849 LoadTimingInfo load_timing_info;
850 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28851 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37852
853 // SetResponse() again for second request as |response_headers_| was moved.
854 SetResponse("200 OK", string());
855 EXPECT_THAT(stream2.ReadResponseHeaders(callback2.callback()),
856 IsError(ERR_IO_PENDING));
857
858 ProcessPacket(InnerConstructResponseHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36859 3, GetNthClientInitiatedStreamId(1), kFin,
860 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37861
862 EXPECT_THAT(callback2.WaitForResult(), IsOk());
863
864 // There is no body, so this should return immediately.
865 EXPECT_EQ(0,
866 stream2.ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
867 callback2.callback()));
868 EXPECT_TRUE(stream2.IsResponseBodyComplete());
869
870 LoadTimingInfo load_timing_info2;
871 EXPECT_TRUE(stream2.GetLoadTimingInfo(&load_timing_info2));
xunjieli84adaab2016-09-20 01:12:28872 ExpectLoadTimingValid(load_timing_info2, /*session_reused=*/true);
xunjieli100937eb52016-09-15 20:09:37873}
874
xunjieli34291fe12016-03-02 13:58:38875// QuicHttpStream does not currently support trailers. It should ignore
876// trailers upon receiving them.
877TEST_P(QuicHttpStreamTest, GetRequestWithTrailers) {
878 SetRequest("GET", "/", DEFAULT_PRIORITY);
879 size_t spdy_request_header_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52880 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36881 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37882 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36883 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
884 DEFAULT_PRIORITY, &spdy_request_header_frame_length,
885 &header_stream_offset));
wangyix6444ffe2017-04-25 17:49:49886 AddWrite(ConstructClientAckPacket(3, 3, 1, 1)); // Ack the data packet.
xunjieli34291fe12016-03-02 13:58:38887
888 Initialize();
889
890 request_.method = "GET";
rchcd379012017-04-12 21:53:32891 request_.url = GURL("https://www.example.org/");
xunjieli34291fe12016-03-02 13:58:38892
xunjieli5fafe142016-03-23 23:32:54893 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27894 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54895 net_log_.bound(), callback_.callback()));
896
xunjieli34291fe12016-03-02 13:58:38897 EXPECT_EQ(OK,
898 stream_->SendRequest(headers_, &response_, callback_.callback()));
xunjieli34291fe12016-03-02 13:58:38899 // Ack the request.
wangyix6444ffe2017-04-25 17:49:49900 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
xunjieli34291fe12016-03-02 13:58:38901
robpercival214763f2016-07-01 23:27:01902 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
903 IsError(ERR_IO_PENDING));
xunjieli34291fe12016-03-02 13:58:38904
bnc614a92d32016-04-04 13:56:07905 SetResponse("200 OK", string());
xunjieli34291fe12016-03-02 13:58:38906
907 // Send the response headers.
908 size_t spdy_response_header_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52909 quic::QuicStreamOffset offset = 0;
xunjieli34291fe12016-03-02 13:58:38910 ProcessPacket(ConstructResponseHeadersPacketWithOffset(
911 2, !kFin, &spdy_response_header_frame_length, &offset));
912 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01913 EXPECT_THAT(callback_.WaitForResult(), IsOk());
xunjieli34291fe12016-03-02 13:58:38914 ASSERT_TRUE(response_.headers.get());
915 EXPECT_EQ(200, response_.headers->response_code());
916 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
917 EXPECT_FALSE(response_.response_time.is_null());
918 EXPECT_FALSE(response_.request_time.is_null());
919
920 // Send the response body.
921 const char kResponseBody[] = "Hello world!";
922 ProcessPacket(
alyssar2adf3ac2016-05-03 17:12:58923 ConstructServerDataPacket(3, false, !kFin, /*offset=*/0, kResponseBody));
Ryan Hamilton0239aac2018-05-19 00:03:13924 spdy::SpdyHeaderBlock trailers;
xunjieli34291fe12016-03-02 13:58:38925 size_t spdy_trailers_frame_length;
926 trailers["foo"] = "bar";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52927 trailers[quic::kFinalOffsetHeaderKey] =
928 base::IntToString(strlen(kResponseBody));
xunjieli34291fe12016-03-02 13:58:38929 ProcessPacket(ConstructResponseTrailersPacket(
bnc086b39e12016-06-24 13:05:26930 4, kFin, std::move(trailers), &spdy_trailers_frame_length, &offset));
xunjieli34291fe12016-03-02 13:58:38931
932 // Make sure trailers are processed.
fdoray92e35a72016-06-10 15:54:55933 base::RunLoop().RunUntilIdle();
xunjieli34291fe12016-03-02 13:58:38934
935 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
936 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
937 callback_.callback()));
938 EXPECT_TRUE(stream_->IsResponseBodyComplete());
939
940 EXPECT_EQ(OK,
941 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
942 callback_.callback()));
943
944 EXPECT_TRUE(stream_->IsResponseBodyComplete());
945 EXPECT_TRUE(AtEof());
946
947 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
948 // headers and payload.
949 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
950 stream_->GetTotalSentBytes());
951 EXPECT_EQ(
952 static_cast<int64_t>(spdy_response_header_frame_length +
953 strlen(kResponseBody) + +spdy_trailers_frame_length),
954 stream_->GetTotalReceivedBytes());
xunjieli5fafe142016-03-23 23:32:54955 // Check that NetLog was filled as expected.
956 TestNetLogEntry::List entries;
957 net_log_.GetEntries(&entries);
958 size_t pos = ExpectLogContainsSomewhere(
959 entries, /*min_offset=*/0,
mikecirone8b85c432016-09-08 19:11:00960 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
961 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54962 pos = ExpectLogContainsSomewhere(
963 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00964 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
965 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54966 ExpectLogContainsSomewhere(
967 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00968 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
969 NetLogEventPhase::NONE);
xunjieli34291fe12016-03-02 13:58:38970}
971
[email protected]3e7dca62013-09-10 16:14:23972// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20973TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
974 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45975 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52976 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36977 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37978 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36979 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
980 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
981 &header_stream_offset));
[email protected]3e7dca62013-09-10 16:14:23982 Initialize();
983
984 request_.method = "GET";
rchcd379012017-04-12 21:53:32985 request_.url = GURL("https://www.example.org/");
[email protected]3e7dca62013-09-10 16:14:23986
xunjieli5fafe142016-03-23 23:32:54987 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27988 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54989 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02990 EXPECT_EQ(OK,
991 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23992
993 // Ack the request.
wangyix6444ffe2017-04-25 17:49:49994 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]3e7dca62013-09-10 16:14:23995
robpercival214763f2016-07-01 23:27:01996 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
997 IsError(ERR_IO_PENDING));
[email protected]3e7dca62013-09-10 16:14:23998
bnc086b39e12016-06-24 13:05:26999 response_headers_[":status"] = "200 OK";
1000 response_headers_[":version"] = "HTTP/1.1";
1001 response_headers_["content-type"] = "text/plain";
1002 response_headers_["big6"] = string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:231003
sclittlec4dc1a32015-09-24 00:15:451004 size_t spdy_response_headers_frame_length;
1005 ProcessPacket(ConstructResponseHeadersPacket(
1006 2, kFin, &spdy_response_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:231007
1008 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:011009 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]3e7dca62013-09-10 16:14:231010 ASSERT_TRUE(response_.headers.get());
1011 EXPECT_EQ(200, response_.headers->response_code());
1012 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1013
1014 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:021015 EXPECT_EQ(0,
1016 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1017 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:231018 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1019 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101020
1021 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451022 // headers and payload.
1023 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1024 stream_->GetTotalSentBytes());
1025 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
1026 stream_->GetTotalReceivedBytes());
[email protected]3e7dca62013-09-10 16:14:231027}
1028
rchf9f103cbc2014-08-30 05:28:041029// Regression test for http://crbug.com/409101
1030TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
1031 SetRequest("GET", "/", DEFAULT_PRIORITY);
1032 Initialize();
1033
1034 request_.method = "GET";
rchcd379012017-04-12 21:53:321035 request_.url = GURL("https://www.example.org/");
rchf9f103cbc2014-08-30 05:28:041036
xunjieli5fafe142016-03-23 23:32:541037 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271038 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541039 net_log_.bound(), callback_.callback()));
rchf9f103cbc2014-08-30 05:28:041040
jri78ec06a2016-03-31 18:19:401041 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521042 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchf9f103cbc2014-08-30 05:28:041043
1044 EXPECT_EQ(ERR_CONNECTION_CLOSED,
rjshaded5ced072015-12-18 19:26:021045 stream_->SendRequest(headers_, &response_, callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101046
1047 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1048 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rchf9f103cbc2014-08-30 05:28:041049}
1050
rch03b7a202016-02-05 00:54:201051// Regression test for http://crbug.com/584441
1052TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
1053 SetRequest("GET", "/", DEFAULT_PRIORITY);
1054 Initialize();
1055
1056 request_.method = "GET";
rchcd379012017-04-12 21:53:321057 request_.url = GURL("https://www.example.org/");
rch03b7a202016-02-05 00:54:201058
xunjieli5fafe142016-03-23 23:32:541059 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271060 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541061 net_log_.bound(), callback_.callback()));
rch03b7a202016-02-05 00:54:201062
1063 SSLInfo ssl_info;
rch11565e02016-02-09 20:13:471064 EXPECT_FALSE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201065 stream_->GetSSLInfo(&ssl_info);
rch11565e02016-02-09 20:13:471066 EXPECT_TRUE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:201067
jri78ec06a2016-03-31 18:19:401068 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521069 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch03b7a202016-02-05 00:54:201070
rch11565e02016-02-09 20:13:471071 SSLInfo ssl_info2;
1072 stream_->GetSSLInfo(&ssl_info2);
1073 EXPECT_TRUE(ssl_info2.is_valid());
rch03b7a202016-02-05 00:54:201074}
1075
rchcd379012017-04-12 21:53:321076TEST_P(QuicHttpStreamTest, GetAlternativeService) {
1077 SetRequest("GET", "/", DEFAULT_PRIORITY);
1078 Initialize();
1079
1080 request_.method = "GET";
1081 request_.url = GURL("https://www.example.org/");
1082
1083 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271084 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
rchcd379012017-04-12 21:53:321085 net_log_.bound(), callback_.callback()));
1086
1087 AlternativeService alternative_service;
1088 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service));
1089 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1090 alternative_service);
1091
1092 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521093 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rchcd379012017-04-12 21:53:321094
1095 AlternativeService alternative_service2;
1096 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service2));
1097 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1098 alternative_service2);
1099}
1100
zhongyica364fbb2015-12-12 03:39:121101TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
1102 SetRequest("GET", "/", DEFAULT_PRIORITY);
1103 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521104 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361105 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371106 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361107 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1108 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1109 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371110 AddWrite(ConstructAckAndRstStreamPacket(3));
zhongyica364fbb2015-12-12 03:39:121111 Initialize();
1112
1113 request_.method = "GET";
rchcd379012017-04-12 21:53:321114 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121115
xunjieli5fafe142016-03-23 23:32:541116 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271117 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541118 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121119 EXPECT_EQ(OK,
1120 stream_->SendRequest(headers_, &response_, callback_.callback()));
1121
1122 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491123 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
robpercival214763f2016-07-01 23:27:011124 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1125 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121126
Ryan Hamilton8d9ee76e2018-05-29 23:52:521127 quic::QuicConnectionCloseFrame frame;
1128 frame.error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551129 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121130
1131 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521132 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121133 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521134 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121135}
1136
Ryan Hamiltone316e482017-08-17 02:48:531137TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
rch617e0652017-04-26 17:57:511138 // By default the test setup defaults handshake to be confirmed. Manually set
1139 // it to be not confirmed.
rch617e0652017-04-26 17:57:511140 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271141 MockCryptoClientStream::ZERO_RTT);
rch617e0652017-04-26 17:57:511142
zhongyica364fbb2015-12-12 03:39:121143 SetRequest("GET", "/", DEFAULT_PRIORITY);
1144 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521145 quic::QuicStreamOffset header_stream_offset = 0;
1146 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
1147 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
fayang3bcb8b502016-12-07 21:44:371148 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361149 1, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1150 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1151 &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:121152 Initialize();
1153
1154 request_.method = "GET";
rchcd379012017-04-12 21:53:321155 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121156
xunjieli5fafe142016-03-23 23:32:541157 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271158 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541159 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121160 EXPECT_EQ(OK,
1161 stream_->SendRequest(headers_, &response_, callback_.callback()));
1162
1163 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491164 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
robpercival214763f2016-07-01 23:27:011165 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1166 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121167
Ryan Hamilton8d9ee76e2018-05-29 23:52:521168 quic::QuicConnectionCloseFrame frame;
1169 frame.error_code = quic::QUIC_PEER_GOING_AWAY;
rch1c5b74a2016-06-23 22:10:551170 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121171
1172 NetErrorDetails details;
zhongyica364fbb2015-12-12 03:39:121173 stream_->PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521174 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121175}
1176
rch11a114a2014-09-04 23:41:591177// Regression test for http://crbug.com/409871
1178TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
1179 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451180 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521181 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361182 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371183 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361184 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1185 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1186 &header_stream_offset));
rch11a114a2014-09-04 23:41:591187 Initialize();
1188
1189 request_.method = "GET";
rchcd379012017-04-12 21:53:321190 request_.url = GURL("https://www.example.org/");
rch11a114a2014-09-04 23:41:591191
xunjieli5fafe142016-03-23 23:32:541192 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271193 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541194 net_log_.bound(), callback_.callback()));
rch11a114a2014-09-04 23:41:591195
rjshaded5ced072015-12-18 19:26:021196 EXPECT_EQ(OK,
1197 stream_->SendRequest(headers_, &response_, callback_.callback()));
rch11a114a2014-09-04 23:41:591198
jri78ec06a2016-03-31 18:19:401199 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521200 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
rch11a114a2014-09-04 23:41:591201
1202 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101203
1204 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451205 // headers and payload.
1206 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1207 stream_->GetTotalSentBytes());
sclittle1edeeb22015-09-02 20:46:101208 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rch11a114a2014-09-04 23:41:591209}
1210
[email protected]1e960032013-12-20 19:00:201211TEST_P(QuicHttpStreamTest, SendPostRequest) {
1212 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451213 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521214 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361215 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wange7ecc472018-03-06 19:00:251216
1217 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1218 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1219 DEFAULT_PRIORITY, 0, &header_stream_offset,
1220 &spdy_request_headers_frame_length, {kUploadData}));
1221
1222 AddWrite(ConstructClientAckPacket(3, 3, 1, 1));
[email protected]f702d572012-12-04 15:56:201223
1224 Initialize();
1225
danakjad1777e2016-04-16 00:56:421226 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191227 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
ricea2deef682016-09-09 08:04:071228 kUploadData, strlen(kUploadData)));
rch97827ee2017-05-24 23:49:121229 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191230 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
[email protected]f702d572012-12-04 15:56:201231 request_.method = "POST";
rchcd379012017-04-12 21:53:321232 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121233 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581234 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
tfarina42834112016-09-22 13:38:201235 NetLogWithSource()),
1236 IsOk());
[email protected]f702d572012-12-04 15:56:201237
xunjieli5fafe142016-03-23 23:32:541238 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271239 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541240 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021241 EXPECT_EQ(OK,
1242 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:201243
1244 // Ack both packets in the request.
wangyix6444ffe2017-04-25 17:49:491245 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]f702d572012-12-04 15:56:201246
1247 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071248 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451249 size_t spdy_response_headers_frame_length;
1250 ProcessPacket(ConstructResponseHeadersPacket(
1251 2, !kFin, &spdy_response_headers_frame_length));
[email protected]f702d572012-12-04 15:56:201252
rchfb47f712017-05-21 03:24:001253 // The headers have already arrived.
1254 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361255 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:201256 EXPECT_EQ(200, response_.headers->response_code());
1257 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1258
1259 // Send the response body.
1260 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581261 ProcessPacket(ConstructServerDataPacket(3, false, kFin, 0, kResponseBody));
[email protected]f702d572012-12-04 15:56:201262 // Since the body has already arrived, this should return immediately.
1263 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1264 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1265 callback_.callback()));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291266 EXPECT_EQ(0,
1267 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1268 callback_.callback()));
1269
1270 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1271 EXPECT_TRUE(AtEof());
1272
1273 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1274 // headers and payload.
1275 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1276 strlen(kUploadData)),
1277 stream_->GetTotalSentBytes());
1278 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1279 strlen(kResponseBody)),
1280 stream_->GetTotalReceivedBytes());
1281}
1282
1283TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
1284 SetRequest("POST", "/", DEFAULT_PRIORITY);
1285 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521286 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton2ef0a9c2017-07-25 03:18:291287 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wange7ecc472018-03-06 19:00:251288 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1289 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1290 DEFAULT_PRIORITY, 0, &header_stream_offset,
1291 &spdy_request_headers_frame_length, {kUploadData}));
1292 AddWrite(ConstructClientAckPacket(3, 3, 1, 1));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291293
1294 Initialize();
1295
1296 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191297 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
Ryan Hamilton2ef0a9c2017-07-25 03:18:291298 kUploadData, strlen(kUploadData)));
1299 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191300 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
Ryan Hamilton2ef0a9c2017-07-25 03:18:291301 request_.method = "POST";
1302 request_.url = GURL("https://www.example.org/");
1303 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:581304 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
Ryan Hamilton2ef0a9c2017-07-25 03:18:291305 NetLogWithSource()),
1306 IsOk());
1307
1308 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271309 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
Ryan Hamilton2ef0a9c2017-07-25 03:18:291310 net_log_.bound(), callback_.callback()));
1311 EXPECT_EQ(OK,
1312 stream_->SendRequest(headers_, &response_, callback_.callback()));
1313
1314 // Ack both packets in the request.
1315 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
1316
1317 // Send the response headers (but not the body).
1318 SetResponse("200 OK", string());
1319 size_t spdy_response_headers_frame_length;
1320 ProcessPacket(ConstructResponseHeadersPacket(
1321 2, !kFin, &spdy_response_headers_frame_length));
1322
1323 // The headers have already arrived.
1324 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1325 ASSERT_TRUE(response_.headers.get());
1326 EXPECT_EQ(200, response_.headers->response_code());
1327 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1328
1329 // Send the response body.
1330 const char kResponseBody[] = "Hello world!";
1331 ProcessPacket(ConstructServerDataPacket(3, false, !kFin, 0, kResponseBody));
1332 // Since the body has already arrived, this should return immediately.
1333 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1334 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1335 callback_.callback()));
1336 ProcessPacket(ConstructServerDataPacket(4, false, kFin,
1337 arraysize(kResponseBody) - 1, ""));
1338 EXPECT_EQ(0,
1339 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1340 callback_.callback()));
[email protected]f702d572012-12-04 15:56:201341
1342 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1343 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101344
1345 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451346 // headers and payload.
1347 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1348 strlen(kUploadData)),
sclittle1edeeb22015-09-02 20:46:101349 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451350 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1351 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101352 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:201353}
1354
[email protected]1e960032013-12-20 19:00:201355TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
1356 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:471357 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451358 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521359 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361360 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wange7ecc472018-03-06 19:00:251361 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
ckrasicbf2f59c2017-05-04 23:54:361362 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
Yixin Wange7ecc472018-03-06 19:00:251363 DEFAULT_PRIORITY, 0, &header_stream_offset,
1364 &spdy_request_headers_frame_length, {kUploadData}));
1365 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, chunk_size,
alyssar2adf3ac2016-05-03 17:12:581366 kUploadData));
Yixin Wange7ecc472018-03-06 19:00:251367 AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
[email protected]c9e49a02013-02-26 05:56:471368 Initialize();
1369
Jeremy Roman0579ed62017-08-29 15:56:191370 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121371 auto* chunked_upload_stream =
1372 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1373 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:471374
1375 request_.method = "POST";
rchcd379012017-04-12 21:53:321376 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121377 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071378 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201379 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]c9e49a02013-02-26 05:56:471380
xunjieli5fafe142016-03-23 23:32:541381 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271382 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541383 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021384 ASSERT_EQ(ERR_IO_PENDING,
1385 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:471386
rch97827ee2017-05-24 23:49:121387 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
robpercival214763f2016-07-01 23:27:011388 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]c9e49a02013-02-26 05:56:471389
1390 // Ack both packets in the request.
wangyix6444ffe2017-04-25 17:49:491391 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]c9e49a02013-02-26 05:56:471392
1393 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071394 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451395 size_t spdy_response_headers_frame_length;
1396 ProcessPacket(ConstructResponseHeadersPacket(
1397 2, !kFin, &spdy_response_headers_frame_length));
[email protected]c9e49a02013-02-26 05:56:471398
rchfb47f712017-05-21 03:24:001399 // The headers have already arrived.
1400 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361401 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:471402 EXPECT_EQ(200, response_.headers->response_code());
1403 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1404
1405 // Send the response body.
1406 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581407 ProcessPacket(ConstructServerDataPacket(
1408 3, false, kFin, response_data_.length(), kResponseBody));
[email protected]c9e49a02013-02-26 05:56:471409
1410 // Since the body has already arrived, this should return immediately.
1411 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1412 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1413 callback_.callback()));
1414
1415 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1416 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101417
1418 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451419 // headers and payload.
1420 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1421 strlen(kUploadData) * 2),
sclittle1edeeb22015-09-02 20:46:101422 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451423 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1424 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101425 stream_->GetTotalReceivedBytes());
[email protected]c9e49a02013-02-26 05:56:471426}
1427
[email protected]16ba7742014-08-22 00:57:251428TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
1429 SetRequest("POST", "/", DEFAULT_PRIORITY);
1430 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451431 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521432 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361433 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wange7ecc472018-03-06 19:00:251434 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
ckrasicbf2f59c2017-05-04 23:54:361435 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
Yixin Wange7ecc472018-03-06 19:00:251436 DEFAULT_PRIORITY, 0, &header_stream_offset,
1437 &spdy_request_headers_frame_length, {kUploadData}));
1438 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
1439 AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
[email protected]16ba7742014-08-22 00:57:251440 Initialize();
1441
Jeremy Roman0579ed62017-08-29 15:56:191442 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121443 auto* chunked_upload_stream =
1444 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1445 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:251446
1447 request_.method = "POST";
rchcd379012017-04-12 21:53:321448 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121449 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071450 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201451 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251452
xunjieli5fafe142016-03-23 23:32:541453 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271454 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541455 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021456 ASSERT_EQ(ERR_IO_PENDING,
1457 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251458
rch97827ee2017-05-24 23:49:121459 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011460 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251461
wangyix6444ffe2017-04-25 17:49:491462 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]16ba7742014-08-22 00:57:251463
1464 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071465 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451466 size_t spdy_response_headers_frame_length;
1467 ProcessPacket(ConstructResponseHeadersPacket(
1468 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251469
rchfb47f712017-05-21 03:24:001470 // The headers have already arrived.
1471 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251472 ASSERT_TRUE(response_.headers.get());
1473 EXPECT_EQ(200, response_.headers->response_code());
1474 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1475
1476 // Send the response body.
1477 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581478 ProcessPacket(ConstructServerDataPacket(
1479 3, false, kFin, response_data_.length(), kResponseBody));
[email protected]16ba7742014-08-22 00:57:251480
rchb27683c2015-07-29 23:53:501481 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251482 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1483 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1484 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251485 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1486 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101487
1488 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451489 // headers and payload.
1490 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1491 strlen(kUploadData)),
sclittle1edeeb22015-09-02 20:46:101492 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451493 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1494 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101495 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251496}
1497
1498TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
1499 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451500 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521501 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361502 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371503 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361504 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1505 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1506 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371507 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, 0, ""));
wangyix6444ffe2017-04-25 17:49:491508 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());
[email protected]16ba7742014-08-22 00:57:251514
1515 request_.method = "POST";
rchcd379012017-04-12 21:53:321516 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121517 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071518 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201519 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251520
xunjieli5fafe142016-03-23 23:32:541521 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271522 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541523 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021524 ASSERT_EQ(ERR_IO_PENDING,
1525 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251526
rch97827ee2017-05-24 23:49:121527 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011528 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251529
wangyix6444ffe2017-04-25 17:49:491530 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]16ba7742014-08-22 00:57:251531
1532 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071533 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451534 size_t spdy_response_headers_frame_length;
1535 ProcessPacket(ConstructResponseHeadersPacket(
1536 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251537
rchfb47f712017-05-21 03:24:001538 // The headers have already arrived.
1539 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251540 ASSERT_TRUE(response_.headers.get());
1541 EXPECT_EQ(200, response_.headers->response_code());
1542 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1543
1544 // Send the response body.
1545 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581546 ProcessPacket(ConstructServerDataPacket(
1547 3, false, kFin, response_data_.length(), kResponseBody));
[email protected]16ba7742014-08-22 00:57:251548
rchb27683c2015-07-29 23:53:501549 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251550 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1551 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1552 callback_.callback()));
1553
1554 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1555 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101556
1557 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451558 // headers and payload.
1559 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1560 stream_->GetTotalSentBytes());
1561 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1562 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101563 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251564}
1565
[email protected]1e960032013-12-20 19:00:201566TEST_P(QuicHttpStreamTest, DestroyedEarly) {
1567 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451568 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521569 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361570 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371571 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361572 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1573 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1574 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371575 AddWrite(ConstructAckAndRstStreamPacket(3));
[email protected]63534512012-12-23 18:49:001576 Initialize();
1577
1578 request_.method = "GET";
rchcd379012017-04-12 21:53:321579 request_.url = GURL("https://www.example.org/");
[email protected]63534512012-12-23 18:49:001580
xunjieli5fafe142016-03-23 23:32:541581 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271582 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541583 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021584 EXPECT_EQ(OK,
1585 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]63534512012-12-23 18:49:001586
1587 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491588 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
rchfb47f712017-05-21 03:24:001589 EXPECT_THAT(stream_->ReadResponseHeaders(
1590 base::Bind(&QuicHttpStreamTest::CloseStream,
1591 base::Unretained(this), stream_.get())),
robpercival214763f2016-07-01 23:27:011592 IsError(ERR_IO_PENDING));
[email protected]63534512012-12-23 18:49:001593
1594 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201595 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:001596 // In the course of processing this packet, the QuicHttpStream close itself.
rchfb47f712017-05-21 03:24:001597 size_t response_size = 0;
rch1bcfddf22017-06-03 00:26:291598 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin, &response_size));
[email protected]63534512012-12-23 18:49:001599
fdoray92e35a72016-06-10 15:54:551600 base::RunLoop().RunUntilIdle();
rchb27683c2015-07-29 23:53:501601
[email protected]63534512012-12-23 18:49:001602 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101603
1604 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451605 // headers and payload.
1606 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1607 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001608 // The stream was closed after receiving the headers.
1609 EXPECT_EQ(static_cast<int64_t>(response_size),
1610 stream_->GetTotalReceivedBytes());
[email protected]63534512012-12-23 18:49:001611}
1612
[email protected]1e960032013-12-20 19:00:201613TEST_P(QuicHttpStreamTest, Priority) {
1614 SetRequest("GET", "/", MEDIUM);
sclittlec4dc1a32015-09-24 00:15:451615 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521616 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361617 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371618 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361619 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin, MEDIUM,
fayang3bcb8b502016-12-07 21:44:371620 &spdy_request_headers_frame_length, &header_stream_offset));
[email protected]24e5bc52013-09-18 15:36:581621 Initialize();
1622
1623 request_.method = "GET";
rchcd379012017-04-12 21:53:321624 request_.url = GURL("https://www.example.org/");
[email protected]24e5bc52013-09-18 15:36:581625
Steven Valdezb4ff0412018-01-18 22:39:271626 EXPECT_EQ(OK,
1627 stream_->InitializeStream(&request_, true, MEDIUM, net_log_.bound(),
1628 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581629
rjshaded5ced072015-12-18 19:26:021630 EXPECT_EQ(OK,
1631 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581632
[email protected]24e5bc52013-09-18 15:36:581633 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491634 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
robpercival214763f2016-07-01 23:27:011635 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1636 IsError(ERR_IO_PENDING));
[email protected]24e5bc52013-09-18 15:36:581637
1638 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201639 SetResponse("404 OK", "hello world!");
rchfb47f712017-05-21 03:24:001640 size_t response_size = 0;
1641 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, &response_size));
[email protected]24e5bc52013-09-18 15:36:581642
rchfb47f712017-05-21 03:24:001643 EXPECT_EQ(OK, callback_.WaitForResult());
rchb27683c2015-07-29 23:53:501644
[email protected]24e5bc52013-09-18 15:36:581645 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101646
1647 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451648 // headers and payload.
1649 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1650 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001651 EXPECT_EQ(static_cast<int64_t>(response_size),
1652 stream_->GetTotalReceivedBytes());
[email protected]24e5bc52013-09-18 15:36:581653}
1654
xunjieli8dff50b2016-07-22 14:19:061655TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
1656 SetRequest("POST", "/", DEFAULT_PRIORITY);
1657 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521658 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361659 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wange7ecc472018-03-06 19:00:251660 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
ckrasicbf2f59c2017-05-04 23:54:361661 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
Yixin Wange7ecc472018-03-06 19:00:251662 DEFAULT_PRIORITY, 0, &header_stream_offset,
1663 &spdy_request_headers_frame_length, {kUploadData}));
xunjieli8dff50b2016-07-22 14:19:061664 // Second data write will result in a synchronous failure which will close
1665 // the session.
1666 AddWrite(SYNCHRONOUS, ERR_FAILED);
1667 Initialize();
1668
Jeremy Roman0579ed62017-08-29 15:56:191669 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121670 auto* chunked_upload_stream =
1671 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
xunjieli8dff50b2016-07-22 14:19:061672
1673 request_.method = "POST";
rchcd379012017-04-12 21:53:321674 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121675 request_.upload_data_stream = upload_data_stream_.get();
xunjieli8dff50b2016-07-22 14:19:061676 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201677 TestCompletionCallback().callback(), NetLogWithSource()));
xunjieli8dff50b2016-07-22 14:19:061678
1679 size_t chunk_size = strlen(kUploadData);
rch97827ee2017-05-24 23:49:121680 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
xunjieli8dff50b2016-07-22 14:19:061681 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271682 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli8dff50b2016-07-22 14:19:061683 net_log_.bound(), callback_.callback()));
1684 QuicHttpStream* stream = stream_.get();
1685 DeleteStreamCallback delete_stream_callback(std::move(stream_));
1686 // SendRequest() completes asynchronously after the final chunk is added.
Yixin Wange7ecc472018-03-06 19:00:251687 // Error does not surface yet since packet write is triggered by a packet
1688 // flusher that tries to bundle request body writes.
xunjieli8dff50b2016-07-22 14:19:061689 ASSERT_EQ(ERR_IO_PENDING,
1690 stream->SendRequest(headers_, &response_, callback_.callback()));
rch97827ee2017-05-24 23:49:121691 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
xunjieli8dff50b2016-07-22 14:19:061692 int rv = callback_.WaitForResult();
Yixin Wange7ecc472018-03-06 19:00:251693 EXPECT_EQ(OK, rv);
1694 // Error will be surfaced once an attempt to read the response occurs.
1695 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1696 stream->ReadResponseHeaders(callback_.callback()));
xunjieli8dff50b2016-07-22 14:19:061697}
1698
rtenneti15656ae2016-01-23 03:05:031699TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
1700 SetRequest("POST", "/", DEFAULT_PRIORITY);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521701 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361702 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
rtenneti15656ae2016-01-23 03:05:031703 AddWrite(SYNCHRONOUS, ERR_FAILED);
1704 Initialize();
1705
Jeremy Roman0579ed62017-08-29 15:56:191706 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
Yixin Wange7ecc472018-03-06 19:00:251707 auto* chunked_upload_stream =
1708 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031709
1710 request_.method = "POST";
rchcd379012017-04-12 21:53:321711 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121712 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031713 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201714 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031715
xunjieli5fafe142016-03-23 23:32:541716 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271717 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541718 net_log_.bound(), callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251719 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:031720 stream_->SendRequest(headers_, &response_, callback_.callback()));
mmenkeffff3642017-06-15 17:37:241721
Yixin Wange7ecc472018-03-06 19:00:251722 // Error will be surfaced once |upload_data_stream| triggers the next write.
1723 size_t chunk_size = strlen(kUploadData);
1724 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1725 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
1726
1727 EXPECT_LE(0, stream_->GetTotalSentBytes());
1728 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1729}
1730
1731TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersCompleteReadResponse) {
1732 SetRequest("POST", "/", DEFAULT_PRIORITY);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521733 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wange7ecc472018-03-06 19:00:251734 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
1735 AddWrite(SYNCHRONOUS, ERR_FAILED);
1736 Initialize();
1737
1738 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1739 auto* chunked_upload_stream =
1740 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1741
1742 request_.method = "POST";
1743 request_.url = GURL("https://www.example.org/");
1744 request_.upload_data_stream = upload_data_stream_.get();
1745
1746 size_t chunk_size = strlen(kUploadData);
1747 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1748
1749 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1750 TestCompletionCallback().callback(), NetLogWithSource()));
1751
1752 ASSERT_EQ(OK,
1753 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
1754 net_log_.bound(), callback_.callback()));
1755 ASSERT_EQ(OK,
1756 stream_->SendRequest(headers_, &response_, callback_.callback()));
1757
1758 // Error will be surfaced once an attempt to read the response occurs.
1759 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1760 stream_->ReadResponseHeaders(callback_.callback()));
1761
mmenkeffff3642017-06-15 17:37:241762 EXPECT_LE(0, stream_->GetTotalSentBytes());
1763 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031764}
1765
1766TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
1767 SetRequest("POST", "/", DEFAULT_PRIORITY);
1768 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521769 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361770 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371771 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361772 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1773 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1774 &header_stream_offset));
rtenneti15656ae2016-01-23 03:05:031775 AddWrite(SYNCHRONOUS, ERR_FAILED);
1776 Initialize();
1777
Jeremy Roman0579ed62017-08-29 15:56:191778 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121779 auto* chunked_upload_stream =
1780 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031781
1782 request_.method = "POST";
rchcd379012017-04-12 21:53:321783 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121784 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031785 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201786 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031787
xunjieli5fafe142016-03-23 23:32:541788 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271789 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541790 net_log_.bound(), callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251791 ASSERT_EQ(ERR_IO_PENDING,
rtenneti15656ae2016-01-23 03:05:031792 stream_->SendRequest(headers_, &response_, callback_.callback()));
Yixin Wange7ecc472018-03-06 19:00:251793
1794 size_t chunk_size = strlen(kUploadData);
1795 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1796 // Error does not surface yet since packet write is triggered by a packet
1797 // flusher that tries to bundle request body writes.
1798 ASSERT_EQ(OK, callback_.WaitForResult());
1799 // Error will be surfaced once an attempt to read the response occurs.
1800 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1801 stream_->ReadResponseHeaders(callback_.callback()));
1802
1803 EXPECT_LE(0, stream_->GetTotalSentBytes());
1804 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1805}
1806
1807TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBundledBodyComplete) {
1808 SetRequest("POST", "/", DEFAULT_PRIORITY);
1809 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521810 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wange7ecc472018-03-06 19:00:251811 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
1812 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1813 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1814 DEFAULT_PRIORITY, 0, &header_stream_offset,
1815 &spdy_request_headers_frame_length, {kUploadData}));
1816 AddWrite(SYNCHRONOUS, ERR_FAILED);
1817 Initialize();
1818
1819 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1820 auto* chunked_upload_stream =
1821 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1822
1823 request_.method = "POST";
1824 request_.url = GURL("https://www.example.org/");
1825 request_.upload_data_stream = upload_data_stream_.get();
1826
1827 size_t chunk_size = strlen(kUploadData);
1828 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
1829
1830 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1831 TestCompletionCallback().callback(), NetLogWithSource()));
1832
1833 ASSERT_EQ(OK,
1834 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
1835 net_log_.bound(), callback_.callback()));
1836 ASSERT_EQ(ERR_IO_PENDING,
1837 stream_->SendRequest(headers_, &response_, callback_.callback()));
1838
1839 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1840
1841 // Error does not surface yet since packet write is triggered by a packet
1842 // flusher that tries to bundle request body writes.
1843 ASSERT_EQ(OK, callback_.WaitForResult());
1844 // Error will be surfaced once an attempt to read the response occurs.
1845 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1846 stream_->ReadResponseHeaders(callback_.callback()));
1847
1848 EXPECT_LE(0, stream_->GetTotalSentBytes());
1849 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031850}
1851
ckrasic3865ee0f2016-02-29 22:04:561852TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
1853 SetRequest("GET", "/", DEFAULT_PRIORITY);
1854 Initialize();
1855
1856 // Initialize the first stream, for receiving the promise on.
1857 request_.method = "GET";
rchcd379012017-04-12 21:53:321858 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561859
xunjieli5fafe142016-03-23 23:32:541860 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271861 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541862 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561863
1864 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1865 // packet, but does it matter?
1866 ReceivePromise(promise_id_);
1867 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1868
1869 request_.url = GURL(promise_url_);
1870
1871 // Make the second stream that will exercise the first step of the
1872 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271873 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1874 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1875 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561876
1877 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251878 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561879 size_t spdy_response_headers_frame_length;
1880 ProcessPacket(InnerConstructResponseHeadersPacket(
1881 1, promise_id_, false, &spdy_response_headers_frame_length));
1882
1883 // Receive the promised response body.
1884 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581885 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
1886 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561887
1888 // Now sending a matching request will have successful rendezvous
1889 // with the promised stream.
1890 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
1891 callback_.callback()));
1892
1893 EXPECT_EQ(
1894 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1895 ->id(),
1896 promise_id_);
1897
1898 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:011899 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1900 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561901
1902 // As will be the body.
1903 EXPECT_EQ(
1904 static_cast<int>(strlen(kResponseBody)),
1905 promised_stream_->ReadResponseBody(
1906 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1907 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1908 EXPECT_TRUE(AtEof());
1909
1910 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1911 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1912 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1913 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1914 strlen(kResponseBody)),
1915 promised_stream_->GetTotalReceivedBytes());
1916}
1917
1918TEST_P(QuicHttpStreamTest, ServerPushGetRequestSlowResponse) {
1919 SetRequest("GET", "/", DEFAULT_PRIORITY);
1920 Initialize();
1921
1922 // Initialize the first stream, for receiving the promise on.
1923 request_.method = "GET";
rchcd379012017-04-12 21:53:321924 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561925
xunjieli5fafe142016-03-23 23:32:541926 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271927 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541928 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561929
1930 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1931 // packet, but does it matter?
1932 ReceivePromise(promise_id_);
1933 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1934
1935 request_.url = GURL(promise_url_);
1936
1937 // Make the second stream that will exercise the first step of the
1938 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271939 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1940 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1941 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561942
1943 // Now sending a matching request will rendezvous with the promised
1944 // stream, but pending secondary validation.
1945 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
1946 headers_, &response_, callback_.callback()));
1947
1948 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251949 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561950 size_t spdy_response_headers_frame_length;
1951 ProcessPacket(InnerConstructResponseHeadersPacket(
1952 1, promise_id_, false, &spdy_response_headers_frame_length));
1953
1954 // Receive the promised response body.
1955 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581956 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
1957 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561958
fdoray92e35a72016-06-10 15:54:551959 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:561960
1961 // Rendezvous should have succeeded now, so the promised stream
1962 // should point at our push stream, and we should be able read
1963 // headers and data from it.
robpercival214763f2016-07-01 23:27:011964 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:561965
1966 EXPECT_EQ(
1967 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1968 ->id(),
1969 promise_id_);
1970
robpercival214763f2016-07-01 23:27:011971 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1972 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561973
1974 EXPECT_EQ(
1975 static_cast<int>(strlen(kResponseBody)),
1976 promised_stream_->ReadResponseBody(
1977 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1978
1979 // Callback should return
1980 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1981 EXPECT_TRUE(AtEof());
1982
1983 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1984 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1985 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1986 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1987 strlen(kResponseBody)),
1988 promised_stream_->GetTotalReceivedBytes());
1989}
1990
ckrasic2c63f9b2016-08-16 23:54:071991// Verify fix for crbug.com/637349
1992TEST_P(QuicHttpStreamTest, ServerPushCancelHttpStreamBeforeResponse) {
1993 SetRequest("GET", "/", DEFAULT_PRIORITY);
1994 Initialize();
1995
1996 // Initialize the first stream, for receiving the promise on.
1997 request_.method = "GET";
rchcd379012017-04-12 21:53:321998 request_.url = GURL("https://www.example.org/");
ckrasic2c63f9b2016-08-16 23:54:071999
2000 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272001 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
ckrasic2c63f9b2016-08-16 23:54:072002 net_log_.bound(), callback_.callback()));
2003
2004 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2005 // packet, but does it matter?
2006 ReceivePromise(promise_id_);
2007 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2008
2009 request_.url = GURL(promise_url_);
2010
2011 // Make the second stream that will exercise the first step of the
2012 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272013 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2014 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2015 callback_.callback()));
ckrasic2c63f9b2016-08-16 23:54:072016
2017 // Now sending a matching request will rendezvous with the promised
2018 // stream, but pending secondary validation.
2019 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2020 headers_, &response_, callback_.callback()));
2021
2022 base::RunLoop().RunUntilIdle();
2023
2024 // Cause of FinalValidation() crash as per bug.
2025 promised_stream_.reset();
2026
2027 // Receive the promised response headers.
2028 response_headers_ = promised_response_.Clone();
2029 size_t spdy_response_headers_frame_length;
2030 ProcessPacket(InnerConstructResponseHeadersPacket(
2031 1, promise_id_, false, &spdy_response_headers_frame_length));
2032}
2033
ckrasic3865ee0f2016-02-29 22:04:562034TEST_P(QuicHttpStreamTest, ServerPushCrossOriginOK) {
2035 SetRequest("GET", "/", DEFAULT_PRIORITY);
2036 Initialize();
2037
2038 // Initialize the first stream, for receiving the promise on.
2039 request_.method = "GET";
rchcd379012017-04-12 21:53:322040 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562041
xunjieli5fafe142016-03-23 23:32:542042 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272043 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542044 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562045
2046 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2047 // packet, but does it matter?
2048
2049 push_promise_[":authority"] = "mail.example.org";
Ryan Hamilton8d9ee76e2018-05-29 23:52:522050 promise_url_ = quic::SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562051
2052 ReceivePromise(promise_id_);
2053 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2054
2055 request_.url = GURL(promise_url_);
2056
2057 // Make the second stream that will exercise the first step of the
2058 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272059 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2060 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2061 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562062
2063 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:252064 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562065 size_t spdy_response_headers_frame_length;
2066 ProcessPacket(InnerConstructResponseHeadersPacket(
2067 1, promise_id_, false, &spdy_response_headers_frame_length));
2068
2069 // Receive the promised response body.
2070 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:582071 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
2072 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:562073
2074 // Now sending a matching request will have successful rendezvous
2075 // with the promised stream.
2076 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
2077 callback_.callback()));
2078
2079 EXPECT_EQ(
2080 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2081 ->id(),
2082 promise_id_);
2083
2084 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:012085 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2086 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562087
2088 // As will be the body.
2089 EXPECT_EQ(
2090 static_cast<int>(strlen(kResponseBody)),
2091 promised_stream_->ReadResponseBody(
2092 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2093 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2094 EXPECT_TRUE(AtEof());
2095
2096 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2097 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2098 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2099 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
2100 strlen(kResponseBody)),
2101 promised_stream_->GetTotalReceivedBytes());
2102}
2103
2104TEST_P(QuicHttpStreamTest, ServerPushCrossOriginFail) {
2105 SetRequest("GET", "/", DEFAULT_PRIORITY);
2106 Initialize();
2107
2108 // Initialize the first stream, for receiving the promise on.
2109 request_.method = "GET";
rchcd379012017-04-12 21:53:322110 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562111
xunjieli5fafe142016-03-23 23:32:542112 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272113 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542114 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562115
2116 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2117 // packet, but does it matter?
2118 push_promise_[":authority"] = "www.notexample.org";
Ryan Hamilton8d9ee76e2018-05-29 23:52:522119 promise_url_ = quic::SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:562120
2121 ReceivePromise(promise_id_);
2122 // The promise will have been rejected because the cert doesn't
2123 // match.
2124 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2125}
2126
2127TEST_P(QuicHttpStreamTest, ServerPushVaryCheckOK) {
2128 SetRequest("GET", "/", DEFAULT_PRIORITY);
2129 Initialize();
2130
2131 // Initialize the first stream, for receiving the promise on.
2132 request_.method = "GET";
rchcd379012017-04-12 21:53:322133 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562134
xunjieli5fafe142016-03-23 23:32:542135 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272136 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542137 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562138
2139 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562140
2141 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2142 // packet, but does it matter?
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 headers_.SetHeader("accept-encoding", "gzip");
2155
2156 // Now sending a matching request will rendezvous with the promised
2157 // stream, but pending secondary validation.
2158 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2159 headers_, &response_, callback_.callback()));
2160
2161 // Receive the promised response headers.
2162 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252163 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562164 size_t spdy_response_headers_frame_length;
2165 ProcessPacket(InnerConstructResponseHeadersPacket(
2166 1, promise_id_, false, &spdy_response_headers_frame_length));
2167
2168 // Receive the promised response body.
2169 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:582170 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
2171 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:562172
fdoray92e35a72016-06-10 15:54:552173 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562174
2175 // Rendezvous should have succeeded now, so the promised stream
2176 // should point at our push stream, and we should be able read
2177 // headers and data from it.
robpercival214763f2016-07-01 23:27:012178 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562179
2180 EXPECT_EQ(
2181 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2182 ->id(),
2183 promise_id_);
2184
robpercival214763f2016-07-01 23:27:012185 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2186 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562187
2188 EXPECT_EQ(
2189 static_cast<int>(strlen(kResponseBody)),
2190 promised_stream_->ReadResponseBody(
2191 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2192
2193 // Callback should return
2194 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2195 EXPECT_TRUE(AtEof());
2196
2197 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2198 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2199 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2200 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
2201 strlen(kResponseBody)),
2202 promised_stream_->GetTotalReceivedBytes());
2203}
2204
2205TEST_P(QuicHttpStreamTest, ServerPushVaryCheckFail) {
2206 SetRequest("GET", "/", DEFAULT_PRIORITY);
2207 request_headers_[":scheme"] = "https";
2208 request_headers_[":path"] = "/bar";
2209 request_headers_["accept-encoding"] = "sdch";
2210
2211 size_t spdy_request_header_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522212 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362213 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:572214
Ryan Hamilton8d9ee76e2018-05-29 23:52:522215 quic::QuicPacketNumber client_packet_number = 2;
Yixin Wangb470bc882018-02-15 18:43:572216 if (client_headers_include_h2_stream_dependency_ &&
Ryan Hamilton8d9ee76e2018-05-29 23:52:522217 version_ > quic::QUIC_VERSION_42) {
Yixin Wangb470bc882018-02-15 18:43:572218 AddWrite(ConstructClientPriorityPacket(
2219 client_packet_number++, kIncludeVersion, promise_id_, 0,
2220 DEFAULT_PRIORITY, &header_stream_offset));
2221 }
Michael Warresabba8b7d2018-07-20 22:50:272222 AddWrite(ConstructClientRstStreamVaryMismatchAndRequestHeadersPacket(
2223 client_packet_number++, stream_id_ + 2, !kIncludeVersion, kFin,
2224 DEFAULT_PRIORITY, promise_id_, &spdy_request_header_frame_length,
2225 &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:572226 AddWrite(ConstructClientAckPacket(client_packet_number++, 3, 1, 1));
2227 AddWrite(ConstructClientRstStreamCancelledPacket(client_packet_number++));
2228
ckrasic3865ee0f2016-02-29 22:04:562229 Initialize();
2230
2231 // Initialize the first stream, for receiving the promise on.
2232 request_.method = "GET";
rchcd379012017-04-12 21:53:322233 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562234
xunjieli5fafe142016-03-23 23:32:542235 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272236 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542237 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562238
2239 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562240
2241 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2242 // packet, but does it matter?
2243 ReceivePromise(promise_id_);
2244 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2245
2246 request_.url = GURL(promise_url_);
2247
2248 // Make the second stream that will exercise the first step of the
2249 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272250 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2251 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2252 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562253
2254 headers_.SetHeader("accept-encoding", "sdch");
2255
2256 // Now sending a matching request will rendezvous with the promised
2257 // stream, but pending secondary validation.
2258 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2259 headers_, &response_, callback_.callback()));
2260
2261 // Receive the promised response headers.
2262 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252263 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562264 size_t spdy_response_headers_frame_length;
2265 ProcessPacket(InnerConstructResponseHeadersPacket(
2266 1, promise_id_, false, &spdy_response_headers_frame_length));
2267
fdoray92e35a72016-06-10 15:54:552268 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562269
2270 // Rendezvous should have failed due to vary mismatch, so the
2271 // promised stream should have been aborted, and instead we have a
2272 // new, regular client initiated stream.
robpercival214763f2016-07-01 23:27:012273 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562274
2275 // Not a server-initiated stream.
2276 EXPECT_NE(
2277 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2278 ->id(),
2279 promise_id_);
2280
2281 // Instead, a new client-initiated stream.
2282 EXPECT_EQ(
2283 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2284 ->id(),
2285 stream_id_ + 2);
2286
2287 // After rendezvous failure, the push stream has been cancelled.
2288 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2289
2290 // The rest of the test verifies that the retried as
2291 // client-initiated version of |promised_stream_| works as intended.
2292
2293 // Ack the request.
wangyix6444ffe2017-04-25 17:49:492294 ProcessPacket(ConstructServerAckPacket(2, 0, 0, 0));
ckrasic3865ee0f2016-02-29 22:04:562295
bnc614a92d32016-04-04 13:56:072296 SetResponse("404 Not Found", string());
ckrasic3865ee0f2016-02-29 22:04:562297 size_t spdy_response_header_frame_length;
2298 ProcessPacket(InnerConstructResponseHeadersPacket(
2299 3, stream_id_ + 2, kFin, &spdy_response_header_frame_length));
2300
fdoray92e35a72016-06-10 15:54:552301 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562302
robpercival214763f2016-07-01 23:27:012303 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2304 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562305 ASSERT_TRUE(response_.headers.get());
2306 EXPECT_EQ(404, response_.headers->response_code());
2307 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
2308 EXPECT_FALSE(response_.response_time.is_null());
2309 EXPECT_FALSE(response_.request_time.is_null());
2310
2311 // There is no body, so this should return immediately.
2312 EXPECT_EQ(
2313 0, promised_stream_->ReadResponseBody(
2314 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2315 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2316
2317 stream_->Close(true);
2318
2319 EXPECT_TRUE(AtEof());
2320
2321 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
2322 // headers and payload.
2323 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
2324 promised_stream_->GetTotalSentBytes());
2325 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
2326 promised_stream_->GetTotalReceivedBytes());
2327}
2328
maksim.sisov84e20c92016-06-23 08:49:342329TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
2330 SetRequest("POST", "/", DEFAULT_PRIORITY);
2331 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522332 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362333 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wange7ecc472018-03-06 19:00:252334 AddWrite(ConstructRequestAndRstPacket(
ckrasicbf2f59c2017-05-04 23:54:362335 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
Yixin Wange7ecc472018-03-06 19:00:252336 DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
Ryan Hamilton8d9ee76e2018-05-29 23:52:522337 &header_stream_offset, quic::QUIC_ERROR_PROCESSING_STREAM, 0));
maksim.sisov84e20c92016-06-23 08:49:342338
2339 Initialize();
2340
Jeremy Roman0579ed62017-08-29 15:56:192341 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342342 ReadErrorUploadDataStream::FailureMode::SYNC);
2343 request_.method = "POST";
rchcd379012017-04-12 21:53:322344 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122345 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342346 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202347 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342348
2349 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272350 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342351 net_log_.bound(), callback_.callback()));
2352
2353 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
robpercival214763f2016-07-01 23:27:012354 EXPECT_THAT(result, IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342355
2356 EXPECT_TRUE(AtEof());
2357
2358 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2359 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2360 stream_->GetTotalSentBytes());
2361 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2362}
2363
2364TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
2365 SetRequest("POST", "/", DEFAULT_PRIORITY);
2366 size_t spdy_request_headers_frame_length;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522367 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362368 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372369 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:362370 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
2371 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
2372 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372373 AddWrite(ConstructClientRstStreamErrorPacket(3, !kIncludeVersion));
maksim.sisov84e20c92016-06-23 08:49:342374
2375 Initialize();
2376
Jeremy Roman0579ed62017-08-29 15:56:192377 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342378 ReadErrorUploadDataStream::FailureMode::ASYNC);
2379 request_.method = "POST";
rchcd379012017-04-12 21:53:322380 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122381 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342382 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202383 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342384
2385 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272386 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342387 net_log_.bound(), callback_.callback()));
2388
2389 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2390
wangyix6444ffe2017-04-25 17:49:492391 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
maksim.sisov84e20c92016-06-23 08:49:342392 SetResponse("200 OK", string());
2393
robpercival214763f2016-07-01 23:27:012394 EXPECT_THAT(result, IsError(ERR_IO_PENDING));
2395 EXPECT_THAT(callback_.GetResult(result), IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342396
2397 EXPECT_TRUE(AtEof());
2398
2399 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2400 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2401 stream_->GetTotalSentBytes());
2402 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2403}
2404
[email protected]f702d572012-12-04 15:56:202405} // namespace test
[email protected]f702d572012-12-04 15:56:202406} // namespace net