blob: da7c531b65467930ce3a1ec2315ce74142be236d [file] [log] [blame]
[email protected]dd3fd0e2012-11-04 05:14:401// 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_chromium_client_session.h"
[email protected]dd3fd0e2012-11-04 05:14:406
[email protected]5db452202014-08-19 05:22:157#include "base/base64.h"
[email protected]f21ec372014-07-02 07:15:128#include "base/files/file_path.h"
danakjad1777e2016-04-16 00:56:429#include "base/memory/ptr_util.h"
jri9f303712016-09-13 01:10:2210#include "base/run_loop.h"
Ryan Sleevib8d7ea02018-05-07 20:01:0111#include "base/stl_util.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4712#include "base/test/metrics/histogram_tester.h"
gabf767595f2016-05-11 18:50:3513#include "base/threading/thread_task_runner_handle.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0814#include "build/build_config.h"
[email protected]8ee611b2012-11-20 01:48:1215#include "net/base/test_completion_callback.h"
[email protected]f21ec372014-07-02 07:15:1216#include "net/cert/cert_verify_result.h"
[email protected]5db452202014-08-19 05:22:1517#include "net/http/transport_security_state.h"
mikecironef22f9812016-10-04 03:40:1918#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5119#include "net/log/test_net_log.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0820#include "net/quic/crypto/proof_verifier_chromium.h"
21#include "net/quic/mock_crypto_client_stream_factory.h"
22#include "net/quic/mock_quic_data.h"
23#include "net/quic/quic_chromium_alarm_factory.h"
24#include "net/quic/quic_chromium_client_session_peer.h"
25#include "net/quic/quic_chromium_connection_helper.h"
26#include "net/quic/quic_chromium_packet_reader.h"
27#include "net/quic/quic_chromium_packet_writer.h"
28#include "net/quic/quic_crypto_client_stream_factory.h"
29#include "net/quic/quic_http_utils.h"
30#include "net/quic/quic_server_info.h"
31#include "net/quic/quic_test_packet_maker.h"
tfarina5dd13c22016-11-16 12:08:2632#include "net/socket/datagram_client_socket.h"
[email protected]4d283b32013-10-17 12:57:2733#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5834#include "net/spdy/spdy_test_util_common.h"
[email protected]f21ec372014-07-02 07:15:1235#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0136#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4337#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0138#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1639#include "net/third_party/quic/core/crypto/aes_128_gcm_12_encrypter.h"
40#include "net/third_party/quic/core/crypto/crypto_protocol.h"
41#include "net/third_party/quic/core/crypto/quic_decrypter.h"
42#include "net/third_party/quic/core/crypto/quic_encrypter.h"
Victor Vasilievc5b409c22018-07-24 12:23:4643#include "net/third_party/quic/core/http/quic_client_promised_info.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1644#include "net/third_party/quic/core/quic_packet_writer.h"
45#include "net/third_party/quic/core/tls_client_handshaker.h"
46#include "net/third_party/quic/platform/api/quic_flags.h"
47#include "net/third_party/quic/platform/api/quic_test.h"
48#include "net/third_party/quic/test_tools/crypto_test_utils.h"
49#include "net/third_party/quic/test_tools/quic_client_promised_info_peer.h"
50#include "net/third_party/quic/test_tools/quic_connection_peer.h"
51#include "net/third_party/quic/test_tools/quic_stream_peer.h"
52#include "net/third_party/quic/test_tools/quic_test_utils.h"
53#include "net/third_party/quic/test_tools/simple_quic_framer.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2954#include "net/third_party/spdy/core/spdy_test_utils.h"
Ramin Halavati683bcaa92018-02-14 08:42:3955#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0156#include "testing/gmock/include/gmock/gmock.h"
[email protected]dd3fd0e2012-11-04 05:14:4057
58using testing::_;
59
60namespace net {
61namespace test {
62namespace {
63
eroman36d84e54432016-03-17 03:23:0264const IPEndPoint kIpEndPoint = IPEndPoint(IPAddress::IPv4AllZeros(), 0);
rch1fe2eeb2015-10-26 14:45:5765const char kServerHostname[] = "test.example.com";
Avi Drissman13fc8932015-12-20 04:40:4666const uint16_t kServerPort = 443;
jri7e636642016-01-14 06:57:0867const size_t kMaxReadersPerQuicSession = 5;
68
Nick Harpere45fe4fc2017-07-13 00:34:5869// A subclass of QuicChromiumClientSession with GetSSLInfo overriden to allow
70// forcing the value of SSLInfo::channel_id_sent to true.
71class TestingQuicChromiumClientSession : public QuicChromiumClientSession {
72 public:
73 using QuicChromiumClientSession::QuicChromiumClientSession;
74
75 bool GetSSLInfo(SSLInfo* ssl_info) const override {
76 bool ret = QuicChromiumClientSession::GetSSLInfo(ssl_info);
77 if (ret)
78 ssl_info->channel_id_sent =
79 ssl_info->channel_id_sent || force_channel_id_sent_;
80 return ret;
81 }
82
83 void OverrideChannelIDSent() { force_channel_id_sent_ = true; }
84
85 private:
86 bool force_channel_id_sent_ = false;
87};
88
ckrasic4f9d88d2015-07-22 22:23:1689class QuicChromiumClientSessionTest
Ryan Hamilton8d9ee76e2018-05-29 23:52:5290 : public ::testing::TestWithParam<
91 std::tuple<quic::QuicTransportVersion, bool>>,
Bence Béky98447b12018-05-08 03:14:0192 public WithScopedTaskEnvironment {
Ryan Hamilton9883ff62017-08-01 06:07:0593 public:
ckrasic4f9d88d2015-07-22 22:23:1694 QuicChromiumClientSessionTest()
Yixin Wang079ad542018-01-11 04:06:0595 : version_(std::get<0>(GetParam())),
96 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:5297 crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting(),
98 quic::TlsClientHandshaker::CreateSslCtx()),
jri7e636642016-01-14 06:57:0899 default_read_(new MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)),
100 socket_data_(
Ryan Sleevib8d7ea02018-05-07 20:01:01101 new SequencedSocketData(base::make_span(default_read_.get(), 1),
102 base::span<MockWrite>())),
jri7e636642016-01-14 06:57:08103 random_(0),
rch16c74d1d2016-04-22 06:14:07104 helper_(&clock_, &random_),
Paul Jensen8e3c5d32018-02-19 17:06:33105 session_key_(kServerHostname,
106 kServerPort,
107 PRIVACY_MODE_DISABLED,
108 SocketTag()),
Ryan Hamilton6c2a2a82017-12-15 02:06:28109 destination_(kServerHostname, kServerPort),
Yixin Wang079ad542018-01-11 04:06:05110 client_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58111 0,
112 &clock_,
113 kServerHostname,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52114 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05115 client_headers_include_h2_stream_dependency_),
116 server_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58117 0,
118 &clock_,
119 kServerHostname,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52120 quic::Perspective::IS_SERVER,
Yixin Wangf65c4b6d2018-03-08 22:37:40121 false),
122 migrate_session_early_v2_(false) {
xunjielic70cc862016-02-19 15:29:26123 // Advance the time, because timers do not like uninitialized times.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52124 clock_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
xunjielic70cc862016-02-19 15:29:26125 }
jri7e636642016-01-14 06:57:08126
Ryan Hamilton9883ff62017-08-01 06:07:05127 void ResetHandleOnError(
128 std::unique_ptr<QuicChromiumClientSession::Handle>* handle,
129 int net_error) {
130 EXPECT_NE(OK, net_error);
131 handle->reset();
132 }
133
134 protected:
jri7e636642016-01-14 06:57:08135 void Initialize() {
rch1baa7472017-04-26 05:43:58136 if (socket_data_)
137 socket_factory_.AddSocketDataProvider(socket_data_.get());
danakjad1777e2016-04-16 00:56:42138 std::unique_ptr<DatagramClientSocket> socket =
jri7e636642016-01-14 06:57:08139 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:19140 &net_log_, NetLogSource());
jri7e636642016-01-14 06:57:08141 socket->Connect(kIpEndPoint);
Ryan Hamilton9edcf1a2017-11-22 05:55:17142 QuicChromiumPacketWriter* writer = new net::QuicChromiumPacketWriter(
143 socket.get(), base::ThreadTaskRunnerHandle::Get().get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52144 quic::QuicConnection* connection = new quic::QuicConnection(
145 0, quic::QuicSocketAddress(quic::QuicSocketAddressImpl(kIpEndPoint)),
146 &helper_, &alarm_factory_, writer, true, quic::Perspective::IS_CLIENT,
147 quic::test::SupportedVersions(
148 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version_)));
Nick Harpere45fe4fc2017-07-13 00:34:58149 session_.reset(new TestingQuicChromiumClientSession(
jri7e636642016-01-14 06:57:08150 connection, std::move(socket),
151 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57152 &transport_security_state_, /*ssl_config_service=*/nullptr,
Paul Jensen8e3c5d32018-02-19 17:06:33153 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)), session_key_,
Zhongyi Shi757fcce2018-06-27 05:41:27154 /*require_confirmation=*/false, migrate_session_early_v2_,
Yixin Wangf65c4b6d2018-03-08 22:37:40155 /*migrate_session_on_network_change_v2=*/false,
Zhongyi Shid672f7542018-06-08 01:03:26156 /*defaulet_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shi73f23ca872017-12-13 18:37:13157 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shiee760762018-08-01 00:54:29158 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30159 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17160 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52161 quic::QuicTime::Delta::FromMilliseconds(
162 kQuicYieldAfterDurationMilliseconds),
Yixin Wang079ad542018-01-11 04:06:05163 /*cert_verify_flags=*/0, client_headers_include_h2_stream_dependency_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52164 quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
Yixin Wang079ad542018-01-11 04:06:05165 base::TimeTicks::Now(), base::TimeTicks::Now(), &push_promise_index_,
166 &test_push_delegate_, base::ThreadTaskRunnerHandle::Get().get(),
jri7e636642016-01-14 06:57:08167 /*socket_performance_watcher=*/nullptr, &net_log_));
168
169 scoped_refptr<X509Certificate> cert(
170 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
171 verify_details_.cert_verify_result.verified_cert = cert;
172 verify_details_.cert_verify_result.is_issued_by_known_root = true;
jri7e636642016-01-14 06:57:08173 session_->Initialize();
174 session_->StartReading();
jribce3eec2016-09-09 05:41:08175 writer->set_delegate(session_.get());
[email protected]dd3fd0e2012-11-04 05:14:40176 }
177
rtenneti85dcfac22015-03-27 20:22:19178 void TearDown() override {
rchf0b18c8a2017-05-05 19:31:57179 if (session_)
Ryan Hamilton8d9ee76e2018-05-29 23:52:52180 session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR);
[email protected]4d283b32013-10-17 12:57:27181 }
182
[email protected]ed3fc15d2013-03-08 18:37:44183 void CompleteCryptoHandshake() {
rch433bf5f2017-02-14 04:10:47184 ASSERT_THAT(session_->CryptoConnect(callback_.callback()), IsOk());
[email protected]ed3fc15d2013-03-08 18:37:44185 }
186
jried79618b2016-07-02 03:18:52187 QuicChromiumPacketWriter* CreateQuicChromiumPacketWriter(
188 DatagramClientSocket* socket,
189 QuicChromiumClientSession* session) const {
danakjad1777e2016-04-16 00:56:42190 std::unique_ptr<QuicChromiumPacketWriter> writer(
Ryan Hamilton9edcf1a2017-11-22 05:55:17191 new QuicChromiumPacketWriter(
192 socket, base::ThreadTaskRunnerHandle::Get().get()));
jribce3eec2016-09-09 05:41:08193 writer->set_delegate(session);
jri7e636642016-01-14 06:57:08194 return writer.release();
195 }
196
Ryan Hamilton8d9ee76e2018-05-29 23:52:52197 quic::QuicStreamId GetNthClientInitiatedStreamId(int n) {
198 return quic::test::GetNthClientInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36199 }
200
Ryan Hamilton8d9ee76e2018-05-29 23:52:52201 quic::QuicStreamId GetNthServerInitiatedStreamId(int n) {
202 return quic::test::GetNthServerInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36203 }
204
Ryan Hamilton8d9ee76e2018-05-29 23:52:52205 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05206 const bool client_headers_include_h2_stream_dependency_;
Jana Iyengarf6b13d82017-09-04 02:09:10207 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52208 quic::QuicCryptoClientConfig crypto_config_;
vishal.b62985ca92015-04-17 08:45:51209 TestNetLog net_log_;
tfarina42834112016-09-22 13:38:20210 BoundTestNetLog bound_test_net_log_;
[email protected]4d283b32013-10-17 12:57:27211 MockClientSocketFactory socket_factory_;
danakjad1777e2016-04-16 00:56:42212 std::unique_ptr<MockRead> default_read_;
213 std::unique_ptr<SequencedSocketData> socket_data_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52214 quic::MockClock clock_;
215 quic::test::MockRandom random_;
rch12fef552016-01-15 16:26:31216 QuicChromiumConnectionHelper helper_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52217 quic::test::MockAlarmFactory alarm_factory_;
jri7e636642016-01-14 06:57:08218 TransportSecurityState transport_security_state_;
219 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52220 quic::QuicClientPushPromiseIndex push_promise_index_;
Paul Jensen8e3c5d32018-02-19 17:06:33221 QuicSessionKey session_key_;
Ryan Hamilton6c2a2a82017-12-15 02:06:28222 HostPortPair destination_;
Nick Harpere45fe4fc2017-07-13 00:34:58223 std::unique_ptr<TestingQuicChromiumClientSession> session_;
zhongyi0009f3e2016-11-11 19:47:50224 TestServerPushDelegate test_push_delegate_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52225 quic::QuicConnectionVisitorInterface* visitor_;
[email protected]8ee611b2012-11-20 01:48:12226 TestCompletionCallback callback_;
alyssar2adf3ac2016-05-03 17:12:58227 QuicTestPacketMaker client_maker_;
228 QuicTestPacketMaker server_maker_;
jri7e636642016-01-14 06:57:08229 ProofVerifyDetailsChromium verify_details_;
Yixin Wangf65c4b6d2018-03-08 22:37:40230 bool migrate_session_early_v2_;
[email protected]dd3fd0e2012-11-04 05:14:40231};
232
Yixin Wang079ad542018-01-11 04:06:05233INSTANTIATE_TEST_CASE_P(
Bence Békyce380cb2018-04-26 23:39:55234 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05235 QuicChromiumClientSessionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52236 ::testing::Combine(
237 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
238 ::testing::Bool()));
[email protected]4d640792013-12-18 22:21:08239
Carlos IL81133382017-12-06 17:18:45240TEST_P(QuicChromiumClientSessionTest, IsFatalErrorNotSetForNonFatalError) {
241 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52242 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Carlos IL81133382017-12-06 17:18:45243 client_maker_.MakeInitialSettingsPacket(1, nullptr));
244 MockWrite writes[] = {
245 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01246 socket_data_.reset(new SequencedSocketData(reads, writes));
Carlos IL81133382017-12-06 17:18:45247 Initialize();
248
249 SSLInfo ssl_info;
250 ProofVerifyDetailsChromium details;
251 details.cert_verify_result.verified_cert =
252 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
253 details.cert_verify_result.cert_status =
254 MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
255 details.is_fatal_cert_error = false;
256 CompleteCryptoHandshake();
257 session_->OnProofVerifyDetailsAvailable(details);
258
259 ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
260 EXPECT_FALSE(ssl_info.is_fatal_cert_error);
261}
262
263TEST_P(QuicChromiumClientSessionTest, IsFatalErrorSetForFatalError) {
264 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52265 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Carlos IL81133382017-12-06 17:18:45266 client_maker_.MakeInitialSettingsPacket(1, nullptr));
267 MockWrite writes[] = {
268 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01269 socket_data_.reset(new SequencedSocketData(reads, writes));
Carlos IL81133382017-12-06 17:18:45270 Initialize();
271
272 SSLInfo ssl_info;
273 ProofVerifyDetailsChromium details;
274 details.cert_verify_result.verified_cert =
275 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
276 details.cert_verify_result.cert_status =
277 MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
278 details.is_fatal_cert_error = true;
279 CompleteCryptoHandshake();
280 session_->OnProofVerifyDetailsAvailable(details);
281 ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
282 EXPECT_TRUE(ssl_info.is_fatal_cert_error);
283}
284
ckrasic4f9d88d2015-07-22 22:23:16285TEST_P(QuicChromiumClientSessionTest, CryptoConnect) {
fayang3bcb8b502016-12-07 21:44:37286 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52287 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36288 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:37289 MockWrite writes[] = {
290 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01291 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:08292 Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44293 CompleteCryptoHandshake();
[email protected]8ee611b2012-11-20 01:48:12294}
295
rchf0b18c8a2017-05-05 19:31:57296TEST_P(QuicChromiumClientSessionTest, Handle) {
297 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43298 quic_data.AddWrite(SYNCHRONOUS,
299 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rchf0b18c8a2017-05-05 19:31:57300 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
301 quic_data.AddRead(ASYNC, OK); // EOF
302 quic_data.AddSocketDataToFactory(&socket_factory_);
303
304 Initialize();
305
306 NetLogWithSource session_net_log = session_->net_log();
307 EXPECT_EQ(NetLogSourceType::QUIC_SESSION, session_net_log.source().type);
308 EXPECT_EQ(&net_log_, session_net_log.net_log());
309
310 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28311 session_->CreateHandle(destination_);
rchf0b18c8a2017-05-05 19:31:57312 EXPECT_TRUE(handle->IsConnected());
313 EXPECT_FALSE(handle->IsCryptoHandshakeConfirmed());
Yixin Wang079ad542018-01-11 04:06:05314 EXPECT_EQ(version_, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33315 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57316 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
317 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
318 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
319 IPEndPoint address;
320 EXPECT_EQ(OK, handle->GetPeerAddress(&address));
321 EXPECT_EQ(kIpEndPoint, address);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52322 EXPECT_TRUE(handle->CreatePacketBundler(quic::QuicConnection::NO_ACK).get() !=
rchf0b18c8a2017-05-05 19:31:57323 nullptr);
324
325 CompleteCryptoHandshake();
326
327 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
328
329 // Request a stream and verify that a stream was created.
330 TestCompletionCallback callback;
331 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39332 callback.callback(),
333 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29334 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchf0b18c8a2017-05-05 19:31:57335
336 quic_data.Resume();
337 EXPECT_TRUE(quic_data.AllReadDataConsumed());
338 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
339
340 // Veirfy that the handle works correctly after the session is closed.
341 EXPECT_FALSE(handle->IsConnected());
342 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
Yixin Wang079ad542018-01-11 04:06:05343 EXPECT_EQ(version_, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33344 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57345 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
346 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
347 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
348 EXPECT_EQ(ERR_CONNECTION_CLOSED, handle->GetPeerAddress(&address));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52349 EXPECT_TRUE(handle->CreatePacketBundler(quic::QuicConnection::NO_ACK).get() ==
rchf0b18c8a2017-05-05 19:31:57350 nullptr);
351 {
352 // Verify that CreateHandle() works even after the session is closed.
353 std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
Ryan Hamilton6c2a2a82017-12-15 02:06:28354 session_->CreateHandle(destination_);
rchf0b18c8a2017-05-05 19:31:57355 EXPECT_FALSE(handle2->IsConnected());
356 EXPECT_TRUE(handle2->IsCryptoHandshakeConfirmed());
357 ASSERT_EQ(ERR_CONNECTION_CLOSED,
358 handle2->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39359 callback.callback(),
360 TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57361 }
362
363 session_.reset();
364
365 // Veirfy that the handle works correctly after the session is deleted.
366 EXPECT_FALSE(handle->IsConnected());
367 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
Yixin Wang079ad542018-01-11 04:06:05368 EXPECT_EQ(version_, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33369 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57370 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
371 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
372 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
373 EXPECT_EQ(ERR_CONNECTION_CLOSED, handle->GetPeerAddress(&address));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52374 EXPECT_TRUE(handle->CreatePacketBundler(quic::QuicConnection::NO_ACK).get() ==
rchf0b18c8a2017-05-05 19:31:57375 nullptr);
Ramin Halavati683bcaa92018-02-14 08:42:39376 ASSERT_EQ(
377 ERR_CONNECTION_CLOSED,
378 handle->RequestStream(/*requires_confirmation=*/false,
379 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57380}
381
rch1baa7472017-04-26 05:43:58382TEST_P(QuicChromiumClientSessionTest, StreamRequest) {
383 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43384 quic_data.AddWrite(SYNCHRONOUS,
385 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rch1baa7472017-04-26 05:43:58386 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
387 quic_data.AddRead(ASYNC, OK); // EOF
388 quic_data.AddSocketDataToFactory(&socket_factory_);
389
390 Initialize();
391 CompleteCryptoHandshake();
392
393 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57394 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28395 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58396 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57397 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39398 callback.callback(),
399 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29400 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rch1baa7472017-04-26 05:43:58401
402 quic_data.Resume();
403 EXPECT_TRUE(quic_data.AllReadDataConsumed());
404 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
405}
406
rchd606b6c32017-05-02 17:32:57407TEST_P(QuicChromiumClientSessionTest, ConfirmationRequiredStreamRequest) {
408 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43409 quic_data.AddWrite(SYNCHRONOUS,
410 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rchd606b6c32017-05-02 17:32:57411 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
412 quic_data.AddRead(ASYNC, OK); // EOF
413 quic_data.AddSocketDataToFactory(&socket_factory_);
414
415 Initialize();
416 CompleteCryptoHandshake();
417
418 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57419 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28420 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57421 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57422 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/true,
Ramin Halavati683bcaa92018-02-14 08:42:39423 callback.callback(),
424 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29425 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchd606b6c32017-05-02 17:32:57426
427 quic_data.Resume();
428 EXPECT_TRUE(quic_data.AllReadDataConsumed());
429 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
430}
431
432TEST_P(QuicChromiumClientSessionTest, StreamRequestBeforeConfirmation) {
433 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43434 quic_data.AddWrite(SYNCHRONOUS,
435 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rchd606b6c32017-05-02 17:32:57436 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
437 quic_data.AddRead(ASYNC, OK); // EOF
438 quic_data.AddSocketDataToFactory(&socket_factory_);
439
440 Initialize();
441
442 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57443 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28444 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57445 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39446 ASSERT_EQ(
447 ERR_IO_PENDING,
448 handle->RequestStream(/*requires_confirmation=*/true, callback.callback(),
449 TRAFFIC_ANNOTATION_FOR_TESTS));
rchd606b6c32017-05-02 17:32:57450
451 CompleteCryptoHandshake();
452
453 EXPECT_THAT(callback.WaitForResult(), IsOk());
454
rch1bcfddf22017-06-03 00:26:29455 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchd606b6c32017-05-02 17:32:57456
457 quic_data.Resume();
458 EXPECT_TRUE(quic_data.AllReadDataConsumed());
459 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
460}
461
rch1baa7472017-04-26 05:43:58462TEST_P(QuicChromiumClientSessionTest, CancelStreamRequestBeforeRelease) {
463 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43464 quic_data.AddWrite(SYNCHRONOUS,
465 client_maker_.MakeInitialSettingsPacket(1, nullptr));
466 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
467 2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52468 quic::QUIC_STREAM_CANCELLED));
rch1baa7472017-04-26 05:43:58469 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
470 quic_data.AddRead(ASYNC, OK); // EOF
471 quic_data.AddSocketDataToFactory(&socket_factory_);
472
473 Initialize();
474 CompleteCryptoHandshake();
475
476 // Request a stream and cancel it without releasing the stream.
rchf0b18c8a2017-05-05 19:31:57477 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28478 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58479 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57480 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39481 callback.callback(),
482 TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57483 handle.reset();
rch1baa7472017-04-26 05:43:58484
485 quic_data.Resume();
486 EXPECT_TRUE(quic_data.AllReadDataConsumed());
487 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
488}
489
490TEST_P(QuicChromiumClientSessionTest, AsyncStreamRequest) {
491 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43492 quic_data.AddWrite(SYNCHRONOUS,
493 client_maker_.MakeInitialSettingsPacket(1, nullptr));
494 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
495 2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52496 quic::QUIC_RST_ACKNOWLEDGEMENT));
rch1baa7472017-04-26 05:43:58497 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
498 quic_data.AddRead(ASYNC, OK); // EOF
499 quic_data.AddSocketDataToFactory(&socket_factory_);
500
501 Initialize();
502 CompleteCryptoHandshake();
503
504 // Open the maximum number of streams so that a subsequent request
505 // can not proceed immediately.
506 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
507 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:57508 QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(session_.get());
rch1baa7472017-04-26 05:43:58509 }
510 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
511
512 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57513 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28514 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58515 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39516 ASSERT_EQ(
517 ERR_IO_PENDING,
518 handle->RequestStream(/*requires_confirmation=*/false,
519 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch1baa7472017-04-26 05:43:58520
521 // Close a stream and ensure the stream request completes.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52522 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
523 GetNthClientInitiatedStreamId(0),
524 quic::QUIC_STREAM_CANCELLED, 0);
rch1baa7472017-04-26 05:43:58525 session_->OnRstStream(rst);
526 ASSERT_TRUE(callback.have_result());
527 EXPECT_THAT(callback.WaitForResult(), IsOk());
rch1bcfddf22017-06-03 00:26:29528 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rch1baa7472017-04-26 05:43:58529
530 quic_data.Resume();
531 EXPECT_TRUE(quic_data.AllReadDataConsumed());
532 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
533}
534
Ryan Hamilton9883ff62017-08-01 06:07:05535TEST_P(QuicChromiumClientSessionTest, ClosedWithAsyncStreamRequest) {
536 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43537 quic_data.AddWrite(SYNCHRONOUS,
538 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton9883ff62017-08-01 06:07:05539 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
540 quic_data.AddRead(ASYNC, OK); // EOF
541 quic_data.AddSocketDataToFactory(&socket_factory_);
542
543 Initialize();
544 CompleteCryptoHandshake();
545
546 // Open the maximum number of streams so that a subsequent request
547 // can not proceed immediately.
548 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
549 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:57550 QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(session_.get());
Ryan Hamilton9883ff62017-08-01 06:07:05551 }
552 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
553
554 // Request two streams which will both be pending.
555 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28556 session_->CreateHandle(destination_);
Ryan Hamilton9883ff62017-08-01 06:07:05557 std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
Ryan Hamilton6c2a2a82017-12-15 02:06:28558 session_->CreateHandle(destination_);
Ryan Hamilton9883ff62017-08-01 06:07:05559
560 ASSERT_EQ(ERR_IO_PENDING,
561 handle->RequestStream(
562 /*requires_confirmation=*/false,
563 base::Bind(&QuicChromiumClientSessionTest::ResetHandleOnError,
Ramin Halavati683bcaa92018-02-14 08:42:39564 base::Unretained(this), &handle2),
565 TRAFFIC_ANNOTATION_FOR_TESTS));
Ryan Hamilton9883ff62017-08-01 06:07:05566
567 TestCompletionCallback callback2;
568 ASSERT_EQ(ERR_IO_PENDING,
569 handle2->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39570 callback2.callback(),
571 TRAFFIC_ANNOTATION_FOR_TESTS));
Ryan Hamilton9883ff62017-08-01 06:07:05572
573 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52574 quic::QUIC_NETWORK_IDLE_TIMEOUT, "Timed out",
575 quic::ConnectionCloseBehavior::SILENT_CLOSE);
Ryan Hamilton9883ff62017-08-01 06:07:05576
577 // Pump the message loop to read the connection close packet.
578 base::RunLoop().RunUntilIdle();
579 EXPECT_FALSE(handle2.get());
580 quic_data.Resume();
581 EXPECT_TRUE(quic_data.AllReadDataConsumed());
582 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
583}
584
rch1baa7472017-04-26 05:43:58585TEST_P(QuicChromiumClientSessionTest, CancelPendingStreamRequest) {
586 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43587 quic_data.AddWrite(SYNCHRONOUS,
588 client_maker_.MakeInitialSettingsPacket(1, nullptr));
589 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
590 2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52591 quic::QUIC_RST_ACKNOWLEDGEMENT));
rch1baa7472017-04-26 05:43:58592 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
593 quic_data.AddRead(ASYNC, OK); // EOF
594 quic_data.AddSocketDataToFactory(&socket_factory_);
595
596 Initialize();
597 CompleteCryptoHandshake();
598
599 // Open the maximum number of streams so that a subsequent request
600 // can not proceed immediately.
601 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
602 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:57603 QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(session_.get());
rch1baa7472017-04-26 05:43:58604 }
605 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
606
607 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57608 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28609 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58610 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39611 ASSERT_EQ(
612 ERR_IO_PENDING,
613 handle->RequestStream(/*requires_confirmation=*/false,
614 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch1baa7472017-04-26 05:43:58615
616 // Cancel the pending stream request.
rchf0b18c8a2017-05-05 19:31:57617 handle.reset();
rch1baa7472017-04-26 05:43:58618
619 // Close a stream and ensure that no new stream is created.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52620 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
621 GetNthClientInitiatedStreamId(0),
622 quic::QUIC_STREAM_CANCELLED, 0);
rch1baa7472017-04-26 05:43:58623 session_->OnRstStream(rst);
624 EXPECT_EQ(kMaxOpenStreams - 1, session_->GetNumOpenOutgoingStreams());
625
626 quic_data.Resume();
627 EXPECT_TRUE(quic_data.AllReadDataConsumed());
628 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
629}
630
rch94c26d682017-04-29 02:49:27631TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeStreamRequest) {
632 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43633 quic_data.AddWrite(SYNCHRONOUS,
634 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52635 quic_data.AddRead(
636 ASYNC,
637 server_maker_.MakeConnectionClosePacket(
638 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rch94c26d682017-04-29 02:49:27639 quic_data.AddSocketDataToFactory(&socket_factory_);
640
641 Initialize();
642 CompleteCryptoHandshake();
643
644 // Pump the message loop to read the connection close packet.
645 base::RunLoop().RunUntilIdle();
646
647 // Request a stream and verify that it failed.
rchf0b18c8a2017-05-05 19:31:57648 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28649 session_->CreateHandle(destination_);
rch94c26d682017-04-29 02:49:27650 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39651 ASSERT_EQ(
652 ERR_CONNECTION_CLOSED,
653 handle->RequestStream(/*requires_confirmation=*/false,
654 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch94c26d682017-04-29 02:49:27655
656 EXPECT_TRUE(quic_data.AllReadDataConsumed());
657 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
658}
659
rchd606b6c32017-05-02 17:32:57660TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeHandshakeConfirmed) {
661 MockQuicData quic_data;
662 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52663 quic_data.AddRead(
664 ASYNC,
665 server_maker_.MakeConnectionClosePacket(
666 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rchd606b6c32017-05-02 17:32:57667 quic_data.AddSocketDataToFactory(&socket_factory_);
668
669 Initialize();
670
671 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57672 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28673 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57674 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39675 ASSERT_EQ(
676 ERR_IO_PENDING,
677 handle->RequestStream(/*requires_confirmation=*/true, callback.callback(),
678 TRAFFIC_ANNOTATION_FOR_TESTS));
rchd606b6c32017-05-02 17:32:57679
680 // Close the connection and verify that the StreamRequest completes with
681 // an error.
682 quic_data.Resume();
683 base::RunLoop().RunUntilIdle();
684
685 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
686
687 EXPECT_TRUE(quic_data.AllReadDataConsumed());
688 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
689}
690
rch94c26d682017-04-29 02:49:27691TEST_P(QuicChromiumClientSessionTest, ConnectionCloseWithPendingStreamRequest) {
692 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43693 quic_data.AddWrite(SYNCHRONOUS,
694 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rch94c26d682017-04-29 02:49:27695 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52696 quic_data.AddRead(
697 ASYNC,
698 server_maker_.MakeConnectionClosePacket(
699 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rch94c26d682017-04-29 02:49:27700 quic_data.AddSocketDataToFactory(&socket_factory_);
701
702 Initialize();
703 CompleteCryptoHandshake();
704
705 // Open the maximum number of streams so that a subsequent request
706 // can not proceed immediately.
707 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
708 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:57709 QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(session_.get());
rch94c26d682017-04-29 02:49:27710 }
711 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
712
713 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57714 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28715 session_->CreateHandle(destination_);
rch94c26d682017-04-29 02:49:27716 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39717 ASSERT_EQ(
718 ERR_IO_PENDING,
719 handle->RequestStream(/*requires_confirmation=*/false,
720 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch94c26d682017-04-29 02:49:27721
722 // Close the connection and verify that the StreamRequest completes with
723 // an error.
724 quic_data.Resume();
725 base::RunLoop().RunUntilIdle();
726
727 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
728
729 EXPECT_TRUE(quic_data.AllReadDataConsumed());
730 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
731}
732
ckrasic4f9d88d2015-07-22 22:23:16733TEST_P(QuicChromiumClientSessionTest, MaxNumStreams) {
jri7e636642016-01-14 06:57:08734 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52735 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36736 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52737 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
738 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
739 quic::QUIC_RST_ACKNOWLEDGEMENT));
jri7e636642016-01-14 06:57:08740 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37741 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
742 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01743 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:08744
745 Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44746 CompleteCryptoHandshake();
rtenneti9f41c0a2016-02-02 23:59:30747 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
[email protected]dd3fd0e2012-11-04 05:14:40748
rch12fef552016-01-15 16:26:31749 std::vector<QuicChromiumClientStream*> streams;
jri7e636642016-01-14 06:57:08750 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:57751 QuicChromiumClientStream* stream =
752 QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
753 session_.get());
[email protected]dd3fd0e2012-11-04 05:14:40754 EXPECT_TRUE(stream);
[email protected]f702d572012-12-04 15:56:20755 streams.push_back(stream);
[email protected]dd3fd0e2012-11-04 05:14:40756 }
Ramin Halavatif7788ea2018-02-26 07:02:57757 EXPECT_FALSE(QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
758 session_.get()));
[email protected]dd3fd0e2012-11-04 05:14:40759
jri7e636642016-01-14 06:57:08760 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
rtennetiac06c2f2015-11-05 18:12:35761
[email protected]dd3fd0e2012-11-04 05:14:40762 // Close a stream and ensure I can now open a new one.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52763 quic::QuicStreamId stream_id = streams[0]->id();
jri7e636642016-01-14 06:57:08764 session_->CloseStream(stream_id);
rtennetiac06c2f2015-11-05 18:12:35765
Ramin Halavatif7788ea2018-02-26 07:02:57766 EXPECT_FALSE(QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
767 session_.get()));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52768 quic::QuicRstStreamFrame rst1(quic::kInvalidControlFrameId, stream_id,
769 quic::QUIC_STREAM_NO_ERROR, 0);
jri7e636642016-01-14 06:57:08770 session_->OnRstStream(rst1);
771 EXPECT_EQ(kMaxOpenStreams - 1, session_->GetNumOpenOutgoingStreams());
Ramin Halavatif7788ea2018-02-26 07:02:57772 EXPECT_TRUE(QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
773 session_.get()));
[email protected]dd3fd0e2012-11-04 05:14:40774}
775
zhongyie34c035662016-10-19 22:26:02776TEST_P(QuicChromiumClientSessionTest, PushStreamTimedOutNoResponse) {
777 base::HistogramTester histogram_tester;
778 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52779 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36780 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52781 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
782 client_maker_.MakeRstPacket(2, true, GetNthServerInitiatedStreamId(0),
783 quic::QUIC_PUSH_STREAM_TIMED_OUT));
zhongyie34c035662016-10-19 22:26:02784 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37785 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
786 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01787 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyie34c035662016-10-19 22:26:02788 Initialize();
789
790 ProofVerifyDetailsChromium details;
791 details.cert_verify_result.verified_cert =
792 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
793 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
794
795 CompleteCryptoHandshake();
796 session_->OnProofVerifyDetailsAvailable(details);
797
Ramin Halavatif7788ea2018-02-26 07:02:57798 QuicChromiumClientStream* stream =
799 QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
800 session_.get());
zhongyie34c035662016-10-19 22:26:02801 EXPECT_TRUE(stream);
802
Ryan Hamilton0239aac2018-05-19 00:03:13803 spdy::SpdyHeaderBlock promise_headers;
zhongyie34c035662016-10-19 22:26:02804 promise_headers[":method"] = "GET";
805 promise_headers[":authority"] = "www.example.org";
806 promise_headers[":scheme"] = "https";
807 promise_headers[":path"] = "/pushed.jpg";
808
809 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:36810 EXPECT_TRUE(session_->HandlePromised(
811 stream->id(), GetNthServerInitiatedStreamId(0), promise_headers));
zhongyie34c035662016-10-19 22:26:02812
Ryan Hamilton8d9ee76e2018-05-29 23:52:52813 quic::QuicClientPromisedInfo* promised =
ckrasicbf2f59c2017-05-04 23:54:36814 session_->GetPromisedById(GetNthServerInitiatedStreamId(0));
zhongyie34c035662016-10-19 22:26:02815 EXPECT_TRUE(promised);
816 // Fire alarm to time out the push stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52817 alarm_factory_.FireAlarm(
818 quic::test::QuicClientPromisedInfoPeer::GetAlarm(promised));
zhongyie34c035662016-10-19 22:26:02819 EXPECT_FALSE(
820 session_->GetPromisedByUrl("https://www.example.org/pushed.jpg"));
821 EXPECT_EQ(0u,
822 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
823 EXPECT_EQ(0u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
824 session_.get()));
825}
826
827TEST_P(QuicChromiumClientSessionTest, PushStreamTimedOutWithResponse) {
828 base::HistogramTester histogram_tester;
829 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52830 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36831 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52832 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
833 client_maker_.MakeRstPacket(2, true, GetNthServerInitiatedStreamId(0),
834 quic::QUIC_PUSH_STREAM_TIMED_OUT));
zhongyie34c035662016-10-19 22:26:02835 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37836 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
837 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01838 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyie34c035662016-10-19 22:26:02839 Initialize();
840
841 ProofVerifyDetailsChromium details;
842 details.cert_verify_result.verified_cert =
843 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
844 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
845
846 CompleteCryptoHandshake();
847 session_->OnProofVerifyDetailsAvailable(details);
848
Ramin Halavatif7788ea2018-02-26 07:02:57849 QuicChromiumClientStream* stream =
850 QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
851 session_.get());
zhongyie34c035662016-10-19 22:26:02852 EXPECT_TRUE(stream);
853
Ryan Hamilton0239aac2018-05-19 00:03:13854 spdy::SpdyHeaderBlock promise_headers;
zhongyie34c035662016-10-19 22:26:02855 promise_headers[":method"] = "GET";
856 promise_headers[":authority"] = "www.example.org";
857 promise_headers[":scheme"] = "https";
858 promise_headers[":path"] = "/pushed.jpg";
859
ckrasicbf2f59c2017-05-04 23:54:36860 session_->GetOrCreateStream(GetNthServerInitiatedStreamId(0));
zhongyie34c035662016-10-19 22:26:02861 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:36862 EXPECT_TRUE(session_->HandlePromised(
863 stream->id(), GetNthServerInitiatedStreamId(0), promise_headers));
864 session_->OnInitialHeadersComplete(GetNthServerInitiatedStreamId(0),
Ryan Hamilton0239aac2018-05-19 00:03:13865 spdy::SpdyHeaderBlock());
zhongyie34c035662016-10-19 22:26:02866 // Read data on the pushed stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52867 quic::QuicStreamFrame data(GetNthServerInitiatedStreamId(0), false, 0,
868 quic::QuicStringPiece("SP"));
zhongyie34c035662016-10-19 22:26:02869 session_->OnStreamFrame(data);
870
Ryan Hamilton8d9ee76e2018-05-29 23:52:52871 quic::QuicClientPromisedInfo* promised =
ckrasicbf2f59c2017-05-04 23:54:36872 session_->GetPromisedById(GetNthServerInitiatedStreamId(0));
zhongyie34c035662016-10-19 22:26:02873 EXPECT_TRUE(promised);
874 // Fire alarm to time out the push stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52875 alarm_factory_.FireAlarm(
876 quic::test::QuicClientPromisedInfoPeer::GetAlarm(promised));
zhongyie34c035662016-10-19 22:26:02877 EXPECT_EQ(2u,
878 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
879 EXPECT_EQ(2u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
880 session_.get()));
881}
882
zhongyi7465c1b2016-11-11 01:38:05883TEST_P(QuicChromiumClientSessionTest, CancelPushWhenPendingValidation) {
884 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52885 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36886 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52887 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
888 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
889 quic::QUIC_RST_ACKNOWLEDGEMENT));
zhongyi7465c1b2016-11-11 01:38:05890
891 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37892 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
893 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01894 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyi7465c1b2016-11-11 01:38:05895 Initialize();
896
897 ProofVerifyDetailsChromium details;
898 details.cert_verify_result.verified_cert =
899 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
900 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
901
902 CompleteCryptoHandshake();
903 session_->OnProofVerifyDetailsAvailable(details);
904
Ramin Halavatif7788ea2018-02-26 07:02:57905 QuicChromiumClientStream* stream =
906 QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
907 session_.get());
zhongyi7465c1b2016-11-11 01:38:05908 EXPECT_TRUE(stream);
909
Ryan Hamilton0239aac2018-05-19 00:03:13910 spdy::SpdyHeaderBlock promise_headers;
zhongyi7465c1b2016-11-11 01:38:05911 promise_headers[":method"] = "GET";
912 promise_headers[":authority"] = "www.example.org";
913 promise_headers[":scheme"] = "https";
914 promise_headers[":path"] = "/pushed.jpg";
915
916 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:36917 EXPECT_TRUE(session_->HandlePromised(
918 stream->id(), GetNthServerInitiatedStreamId(0), promise_headers));
zhongyi7465c1b2016-11-11 01:38:05919
Ryan Hamilton8d9ee76e2018-05-29 23:52:52920 quic::QuicClientPromisedInfo* promised =
ckrasicbf2f59c2017-05-04 23:54:36921 session_->GetPromisedById(GetNthServerInitiatedStreamId(0));
zhongyi7465c1b2016-11-11 01:38:05922 EXPECT_TRUE(promised);
923
924 // Initiate rendezvous.
Ryan Hamilton0239aac2018-05-19 00:03:13925 spdy::SpdyHeaderBlock client_request = promise_headers.Clone();
Ryan Hamilton8d9ee76e2018-05-29 23:52:52926 quic::test::TestPushPromiseDelegate delegate(/*match=*/true);
zhongyi7465c1b2016-11-11 01:38:05927 promised->HandleClientRequest(client_request, &delegate);
928
929 // Cancel the push before receiving the response to the pushed request.
930 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:50931 test_push_delegate_.CancelPush(pushed_url);
zhongyi7465c1b2016-11-11 01:38:05932 EXPECT_TRUE(session_->GetPromisedByUrl(pushed_url.spec()));
933
934 // Reset the stream now before tear down.
ckrasicbf2f59c2017-05-04 23:54:36935 session_->CloseStream(GetNthClientInitiatedStreamId(0));
zhongyi7465c1b2016-11-11 01:38:05936}
937
zhongyi18bb2d92016-10-27 19:38:50938TEST_P(QuicChromiumClientSessionTest, CancelPushBeforeReceivingResponse) {
939 base::HistogramTester histogram_tester;
940 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52941 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36942 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52943 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
944 client_maker_.MakeRstPacket(2, true, GetNthServerInitiatedStreamId(0),
945 quic::QUIC_STREAM_CANCELLED));
zhongyi18bb2d92016-10-27 19:38:50946 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37947 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
948 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01949 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyi18bb2d92016-10-27 19:38:50950 Initialize();
951
952 ProofVerifyDetailsChromium details;
953 details.cert_verify_result.verified_cert =
954 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
955 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
956
957 CompleteCryptoHandshake();
958 session_->OnProofVerifyDetailsAvailable(details);
959
Ramin Halavatif7788ea2018-02-26 07:02:57960 QuicChromiumClientStream* stream =
961 QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
962 session_.get());
zhongyi18bb2d92016-10-27 19:38:50963 EXPECT_TRUE(stream);
964
Ryan Hamilton0239aac2018-05-19 00:03:13965 spdy::SpdyHeaderBlock promise_headers;
zhongyi18bb2d92016-10-27 19:38:50966 promise_headers[":method"] = "GET";
967 promise_headers[":authority"] = "www.example.org";
968 promise_headers[":scheme"] = "https";
969 promise_headers[":path"] = "/pushed.jpg";
970
971 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:36972 EXPECT_TRUE(session_->HandlePromised(
973 stream->id(), GetNthServerInitiatedStreamId(0), promise_headers));
zhongyi18bb2d92016-10-27 19:38:50974
Ryan Hamilton8d9ee76e2018-05-29 23:52:52975 quic::QuicClientPromisedInfo* promised =
ckrasicbf2f59c2017-05-04 23:54:36976 session_->GetPromisedById(GetNthServerInitiatedStreamId(0));
zhongyi18bb2d92016-10-27 19:38:50977 EXPECT_TRUE(promised);
978 // Cancel the push before receiving the response to the pushed request.
979 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:50980 test_push_delegate_.CancelPush(pushed_url);
zhongyi18bb2d92016-10-27 19:38:50981
982 EXPECT_FALSE(session_->GetPromisedByUrl(pushed_url.spec()));
983 EXPECT_EQ(0u,
984 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
985 EXPECT_EQ(0u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
986 session_.get()));
987}
988
989TEST_P(QuicChromiumClientSessionTest, CancelPushAfterReceivingResponse) {
990 base::HistogramTester histogram_tester;
991 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52992 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36993 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52994 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
995 client_maker_.MakeRstPacket(2, true, GetNthServerInitiatedStreamId(0),
996 quic::QUIC_STREAM_CANCELLED));
zhongyi18bb2d92016-10-27 19:38:50997 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37998 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
999 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011000 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyi18bb2d92016-10-27 19:38:501001 Initialize();
1002
1003 ProofVerifyDetailsChromium details;
1004 details.cert_verify_result.verified_cert =
1005 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1006 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1007
1008 CompleteCryptoHandshake();
1009 session_->OnProofVerifyDetailsAvailable(details);
1010
Ramin Halavatif7788ea2018-02-26 07:02:571011 QuicChromiumClientStream* stream =
1012 QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
1013 session_.get());
zhongyi18bb2d92016-10-27 19:38:501014 EXPECT_TRUE(stream);
1015
Ryan Hamilton0239aac2018-05-19 00:03:131016 spdy::SpdyHeaderBlock promise_headers;
zhongyi18bb2d92016-10-27 19:38:501017 promise_headers[":method"] = "GET";
1018 promise_headers[":authority"] = "www.example.org";
1019 promise_headers[":scheme"] = "https";
1020 promise_headers[":path"] = "/pushed.jpg";
1021
ckrasicbf2f59c2017-05-04 23:54:361022 session_->GetOrCreateStream(GetNthServerInitiatedStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501023 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:361024 EXPECT_TRUE(session_->HandlePromised(
1025 stream->id(), GetNthServerInitiatedStreamId(0), promise_headers));
1026 session_->OnInitialHeadersComplete(GetNthServerInitiatedStreamId(0),
Ryan Hamilton0239aac2018-05-19 00:03:131027 spdy::SpdyHeaderBlock());
zhongyi18bb2d92016-10-27 19:38:501028 // Read data on the pushed stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521029 quic::QuicStreamFrame data(GetNthServerInitiatedStreamId(0), false, 0,
1030 quic::QuicStringPiece("SP"));
zhongyi18bb2d92016-10-27 19:38:501031 session_->OnStreamFrame(data);
1032
Ryan Hamilton8d9ee76e2018-05-29 23:52:521033 quic::QuicClientPromisedInfo* promised =
ckrasicbf2f59c2017-05-04 23:54:361034 session_->GetPromisedById(GetNthServerInitiatedStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501035 EXPECT_TRUE(promised);
1036 // Cancel the push after receiving data on the push stream.
1037 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:501038 test_push_delegate_.CancelPush(pushed_url);
zhongyi18bb2d92016-10-27 19:38:501039
1040 EXPECT_FALSE(session_->GetPromisedByUrl(pushed_url.spec()));
1041 EXPECT_EQ(2u,
1042 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
1043 EXPECT_EQ(2u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
1044 session_.get()));
1045}
1046
ckrasic4f9d88d2015-07-22 22:23:161047TEST_P(QuicChromiumClientSessionTest, MaxNumStreamsViaRequest) {
jri7e636642016-01-14 06:57:081048 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521049 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361050 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521051 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
1052 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
1053 quic::QUIC_RST_ACKNOWLEDGEMENT));
jri7e636642016-01-14 06:57:081054 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:371055 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
1056 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011057 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081058
1059 Initialize();
[email protected]0b2294d32013-08-02 00:46:361060 CompleteCryptoHandshake();
rtenneti9f41c0a2016-02-02 23:59:301061 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
[email protected]0b2294d32013-08-02 00:46:361062
rch12fef552016-01-15 16:26:311063 std::vector<QuicChromiumClientStream*> streams;
jri7e636642016-01-14 06:57:081064 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:571065 QuicChromiumClientStream* stream =
1066 QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
1067 session_.get());
[email protected]0b2294d32013-08-02 00:46:361068 EXPECT_TRUE(stream);
1069 streams.push_back(stream);
1070 }
1071
rchf0b18c8a2017-05-05 19:31:571072 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:281073 session_->CreateHandle(destination_);
[email protected]0b2294d32013-08-02 00:46:361074 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:391075 ASSERT_EQ(
1076 ERR_IO_PENDING,
1077 handle->RequestStream(/*requires_confirmation=*/false,
1078 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]0b2294d32013-08-02 00:46:361079
1080 // Close a stream and ensure I can now open a new one.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521081 quic::QuicStreamId stream_id = streams[0]->id();
jri7e636642016-01-14 06:57:081082 session_->CloseStream(stream_id);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521083 quic::QuicRstStreamFrame rst1(quic::kInvalidControlFrameId, stream_id,
1084 quic::QUIC_STREAM_NO_ERROR, 0);
jri7e636642016-01-14 06:57:081085 session_->OnRstStream(rst1);
[email protected]0b2294d32013-08-02 00:46:361086 ASSERT_TRUE(callback.have_result());
robpercival214763f2016-07-01 23:27:011087 EXPECT_THAT(callback.WaitForResult(), IsOk());
rch1bcfddf22017-06-03 00:26:291088 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
[email protected]0b2294d32013-08-02 00:46:361089}
1090
ckrasic4f9d88d2015-07-22 22:23:161091TEST_P(QuicChromiumClientSessionTest, GoAwayReceived) {
fayang3bcb8b502016-12-07 21:44:371092 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521093 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361094 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371095 MockWrite writes[] = {
1096 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011097 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081098 Initialize();
[email protected]8ba81212013-05-03 13:11:481099 CompleteCryptoHandshake();
[email protected]9db443912013-02-25 05:27:031100
1101 // After receiving a GoAway, I should no longer be able to create outgoing
1102 // streams.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521103 session_->connection()->OnGoAwayFrame(
1104 quic::QuicGoAwayFrame(quic::kInvalidControlFrameId,
1105 quic::QUIC_PEER_GOING_AWAY, 1u, "Going away."));
Ramin Halavatif7788ea2018-02-26 07:02:571106 EXPECT_EQ(nullptr, QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
1107 session_.get()));
[email protected]9db443912013-02-25 05:27:031108}
1109
ckrasic4f9d88d2015-07-22 22:23:161110TEST_P(QuicChromiumClientSessionTest, CanPool) {
fayang3bcb8b502016-12-07 21:44:371111 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521112 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361113 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371114 MockWrite writes[] = {
1115 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011116 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081117 Initialize();
[email protected]f21ec372014-07-02 07:15:121118 // Load a cert that is valid for:
1119 // www.example.org
1120 // mail.example.org
1121 // www.example.com
[email protected]f21ec372014-07-02 07:15:121122
[email protected]f21ec372014-07-02 07:15:121123 ProofVerifyDetailsChromium details;
1124 details.cert_verify_result.verified_cert =
[email protected]5db452202014-08-19 05:22:151125 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
dcheng4227c6d2014-08-25 23:58:181126 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]f21ec372014-07-02 07:15:121127
[email protected]f21ec372014-07-02 07:15:121128 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081129 session_->OnProofVerifyDetailsAvailable(details);
[email protected]f21ec372014-07-02 07:15:121130
Paul Jensen8e3c5d32018-02-19 17:06:331131 EXPECT_TRUE(
1132 session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, SocketTag()));
1133 EXPECT_FALSE(
1134 session_->CanPool("www.example.org", PRIVACY_MODE_ENABLED, SocketTag()));
1135#if defined(OS_ANDROID)
1136 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
1137 SocketTag tag2(getuid(), 0x87654321);
1138 EXPECT_FALSE(
1139 session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag1));
1140 EXPECT_FALSE(
1141 session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag2));
1142#endif
1143 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
1144 SocketTag()));
1145 EXPECT_TRUE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
1146 SocketTag()));
1147 EXPECT_FALSE(
1148 session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED, SocketTag()));
[email protected]f21ec372014-07-02 07:15:121149}
1150
ckrasic4f9d88d2015-07-22 22:23:161151TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithTlsChannelId) {
fayang3bcb8b502016-12-07 21:44:371152 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521153 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361154 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371155 MockWrite writes[] = {
1156 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011157 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081158 Initialize();
[email protected]f21ec372014-07-02 07:15:121159 // Load a cert that is valid for:
1160 // www.example.org
1161 // mail.example.org
1162 // www.example.com
[email protected]f21ec372014-07-02 07:15:121163
[email protected]f21ec372014-07-02 07:15:121164 ProofVerifyDetailsChromium details;
1165 details.cert_verify_result.verified_cert =
[email protected]5db452202014-08-19 05:22:151166 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
dcheng4227c6d2014-08-25 23:58:181167 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]f21ec372014-07-02 07:15:121168
[email protected]f21ec372014-07-02 07:15:121169 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081170 session_->OnProofVerifyDetailsAvailable(details);
1171 QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
Nick Harpere45fe4fc2017-07-13 00:34:581172 session_->OverrideChannelIDSent();
[email protected]f21ec372014-07-02 07:15:121173
Paul Jensen8e3c5d32018-02-19 17:06:331174 EXPECT_TRUE(
1175 session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, SocketTag()));
1176 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
1177 SocketTag()));
1178 EXPECT_FALSE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
1179 SocketTag()));
1180 EXPECT_FALSE(
1181 session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED, SocketTag()));
[email protected]f21ec372014-07-02 07:15:121182}
1183
ckrasic4f9d88d2015-07-22 22:23:161184TEST_P(QuicChromiumClientSessionTest, ConnectionNotPooledWithDifferentPin) {
fayang3bcb8b502016-12-07 21:44:371185 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521186 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361187 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371188 MockWrite writes[] = {
1189 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011190 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081191 Initialize();
1192
Avi Drissman13fc8932015-12-20 04:40:461193 uint8_t primary_pin = 1;
1194 uint8_t backup_pin = 2;
1195 uint8_t bad_pin = 3;
[email protected]5db452202014-08-19 05:22:151196 AddPin(&transport_security_state_, "mail.example.org", primary_pin,
1197 backup_pin);
1198
1199 ProofVerifyDetailsChromium details;
1200 details.cert_verify_result.verified_cert =
1201 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1202 details.cert_verify_result.is_issued_by_known_root = true;
1203 details.cert_verify_result.public_key_hashes.push_back(
1204 GetTestHashValue(bad_pin));
1205
dcheng4227c6d2014-08-25 23:58:181206 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:151207
[email protected]5db452202014-08-19 05:22:151208 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081209 session_->OnProofVerifyDetailsAvailable(details);
1210 QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
Nick Harpere45fe4fc2017-07-13 00:34:581211 session_->OverrideChannelIDSent();
[email protected]5db452202014-08-19 05:22:151212
Paul Jensen8e3c5d32018-02-19 17:06:331213 EXPECT_FALSE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
1214 SocketTag()));
[email protected]5db452202014-08-19 05:22:151215}
1216
ckrasic4f9d88d2015-07-22 22:23:161217TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithMatchingPin) {
fayang3bcb8b502016-12-07 21:44:371218 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521219 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361220 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371221 MockWrite writes[] = {
1222 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011223 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081224 Initialize();
1225
Avi Drissman13fc8932015-12-20 04:40:461226 uint8_t primary_pin = 1;
1227 uint8_t backup_pin = 2;
[email protected]5db452202014-08-19 05:22:151228 AddPin(&transport_security_state_, "mail.example.org", primary_pin,
1229 backup_pin);
1230
1231 ProofVerifyDetailsChromium details;
1232 details.cert_verify_result.verified_cert =
1233 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1234 details.cert_verify_result.is_issued_by_known_root = true;
1235 details.cert_verify_result.public_key_hashes.push_back(
1236 GetTestHashValue(primary_pin));
1237
dcheng4227c6d2014-08-25 23:58:181238 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:151239
[email protected]5db452202014-08-19 05:22:151240 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081241 session_->OnProofVerifyDetailsAvailable(details);
1242 QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
Nick Harpere45fe4fc2017-07-13 00:34:581243 session_->OverrideChannelIDSent();
[email protected]5db452202014-08-19 05:22:151244
Paul Jensen8e3c5d32018-02-19 17:06:331245 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
1246 SocketTag()));
jri7e636642016-01-14 06:57:081247}
1248
1249TEST_P(QuicChromiumClientSessionTest, MigrateToSocket) {
fayang3bcb8b502016-12-07 21:44:371250 MockRead old_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521251 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361252 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371253 MockWrite old_writes[] = {
1254 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011255 socket_data_.reset(new SequencedSocketData(old_reads, old_writes));
jri7e636642016-01-14 06:57:081256 Initialize();
1257 CompleteCryptoHandshake();
1258
1259 char data[] = "ABCD";
Ryan Hamilton8d9ee76e2018-05-29 23:52:521260 std::unique_ptr<quic::QuicEncryptedPacket> client_ping;
1261 std::unique_ptr<quic::QuicEncryptedPacket> ack_and_data_out;
1262 client_ping = client_maker_.MakeAckAndPingPacket(2, false, 1, 1, 1);
1263 ack_and_data_out = client_maker_.MakeDataPacket(3, 5, false, false, 0,
1264 quic::QuicStringPiece(data));
1265 std::unique_ptr<quic::QuicEncryptedPacket> server_ping(
alyssar2adf3ac2016-05-03 17:12:581266 server_maker_.MakePingPacket(1, /*include_version=*/false));
alyssar2adf3ac2016-05-03 17:12:581267 MockRead reads[] = {
1268 MockRead(SYNCHRONOUS, server_ping->data(), server_ping->length(), 0),
1269 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
1270 MockWrite writes[] = {
1271 MockWrite(SYNCHRONOUS, client_ping->data(), client_ping->length(), 2),
1272 MockWrite(SYNCHRONOUS, ack_and_data_out->data(),
1273 ack_and_data_out->length(), 3)};
Ryan Sleevib8d7ea02018-05-07 20:01:011274 StaticSocketDataProvider socket_data(reads, writes);
jri7e636642016-01-14 06:57:081275 socket_factory_.AddSocketDataProvider(&socket_data);
jri7e636642016-01-14 06:57:081276 // Create connected socket.
danakjad1777e2016-04-16 00:56:421277 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081278 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191279 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011280 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081281
1282 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421283 std::unique_ptr<QuicChromiumPacketReader> new_reader(
1284 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1285 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521286 quic::QuicTime::Delta::FromMilliseconds(
danakjad1777e2016-04-16 00:56:421287 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201288 bound_test_net_log_.bound()));
jried79618b2016-07-02 03:18:521289 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1290 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081291
1292 // Migrate session.
jri9f303712016-09-13 01:10:221293 EXPECT_TRUE(session_->MigrateToSocket(
1294 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1295 // Spin message loop to complete migration.
1296 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081297
1298 // Write data to session.
Ramin Halavatif7788ea2018-02-26 07:02:571299 QuicChromiumClientStream* stream =
1300 QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
1301 session_.get());
jri7e636642016-01-14 06:57:081302 struct iovec iov[1];
1303 iov[0].iov_base = data;
1304 iov[0].iov_len = 4;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521305 quic::test::QuicStreamPeer::SendBuffer(stream).SaveStreamData(iov, 1, 0, 4);
1306 quic::test::QuicStreamPeer::SetStreamBytesWritten(4, stream);
1307 session_->WritevData(stream, stream->id(), 4, 0, quic::NO_FIN);
jri7e636642016-01-14 06:57:081308
1309 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1310 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1311}
1312
1313TEST_P(QuicChromiumClientSessionTest, MigrateToSocketMaxReaders) {
fayang3bcb8b502016-12-07 21:44:371314 MockRead old_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521315 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361316 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371317 MockWrite old_writes[] = {
1318 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011319 socket_data_.reset(new SequencedSocketData(old_reads, old_writes));
jri7e636642016-01-14 06:57:081320 Initialize();
1321 CompleteCryptoHandshake();
1322
1323 for (size_t i = 0; i < kMaxReadersPerQuicSession; ++i) {
1324 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521325 std::unique_ptr<quic::QuicEncryptedPacket> ping_out(
fayang3bcb8b502016-12-07 21:44:371326 client_maker_.MakePingPacket(i + 2, /*include_version=*/true));
jri7e636642016-01-14 06:57:081327 MockWrite writes[] = {
1328 MockWrite(SYNCHRONOUS, ping_out->data(), ping_out->length(), i + 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011329 StaticSocketDataProvider socket_data(reads, writes);
jri7e636642016-01-14 06:57:081330 socket_factory_.AddSocketDataProvider(&socket_data);
1331
1332 // Create connected socket.
danakjad1777e2016-04-16 00:56:421333 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081334 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191335 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011336 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081337
1338 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421339 std::unique_ptr<QuicChromiumPacketReader> new_reader(
rcha02807b42016-01-29 21:56:151340 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1341 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521342 quic::QuicTime::Delta::FromMilliseconds(
rcha02807b42016-01-29 21:56:151343 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201344 bound_test_net_log_.bound()));
jried79618b2016-07-02 03:18:521345 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1346 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081347
1348 // Migrate session.
1349 if (i < kMaxReadersPerQuicSession - 1) {
jri9f303712016-09-13 01:10:221350 EXPECT_TRUE(session_->MigrateToSocket(
1351 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1352 // Spin message loop to complete migration.
1353 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081354 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1355 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1356 } else {
1357 // Max readers exceeded.
jri9f303712016-09-13 01:10:221358 EXPECT_FALSE(session_->MigrateToSocket(
1359 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
jri7e636642016-01-14 06:57:081360 EXPECT_FALSE(socket_data.AllReadDataConsumed());
1361 EXPECT_FALSE(socket_data.AllWriteDataConsumed());
1362 }
1363 }
1364}
1365
1366TEST_P(QuicChromiumClientSessionTest, MigrateToSocketReadError) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521367 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361368 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521369 std::unique_ptr<quic::QuicEncryptedPacket> client_ping;
1370 client_ping = client_maker_.MakeAckAndPingPacket(2, false, 1, 1, 1);
1371 std::unique_ptr<quic::QuicEncryptedPacket> server_ping(
alyssar2adf3ac2016-05-03 17:12:581372 server_maker_.MakePingPacket(1, /*include_version=*/false));
fayang3bcb8b502016-12-07 21:44:371373 MockWrite old_writes[] = {
1374 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 0)};
jri7e636642016-01-14 06:57:081375 MockRead old_reads[] = {
jri7e636642016-01-14 06:57:081376 MockRead(ASYNC, ERR_IO_PENDING, 1), // causes reading to pause.
1377 MockRead(ASYNC, ERR_NETWORK_CHANGED, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011378 socket_data_.reset(new SequencedSocketData(old_reads, old_writes));
jri7e636642016-01-14 06:57:081379 Initialize();
1380 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081381 MockWrite writes[] = {
alyssar2adf3ac2016-05-03 17:12:581382 MockWrite(SYNCHRONOUS, client_ping->data(), client_ping->length(), 1)};
jri7e636642016-01-14 06:57:081383 MockRead new_reads[] = {
alyssar2adf3ac2016-05-03 17:12:581384 MockRead(SYNCHRONOUS, server_ping->data(), server_ping->length(), 0),
jri7e636642016-01-14 06:57:081385 MockRead(ASYNC, ERR_IO_PENDING, 2), // pause reading.
alyssar2adf3ac2016-05-03 17:12:581386 MockRead(ASYNC, server_ping->data(), server_ping->length(), 3),
jri7e636642016-01-14 06:57:081387 MockRead(ASYNC, ERR_IO_PENDING, 4), // pause reading
1388 MockRead(ASYNC, ERR_NETWORK_CHANGED, 5)};
Ryan Sleevib8d7ea02018-05-07 20:01:011389 SequencedSocketData new_socket_data(new_reads, writes);
jri7e636642016-01-14 06:57:081390 socket_factory_.AddSocketDataProvider(&new_socket_data);
1391
1392 // Create connected socket.
danakjad1777e2016-04-16 00:56:421393 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081394 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191395 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011396 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081397
1398 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421399 std::unique_ptr<QuicChromiumPacketReader> new_reader(
1400 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1401 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521402 quic::QuicTime::Delta::FromMilliseconds(
danakjad1777e2016-04-16 00:56:421403 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201404 bound_test_net_log_.bound()));
jried79618b2016-07-02 03:18:521405 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1406 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081407
1408 // Store old socket and migrate session.
jri9f303712016-09-13 01:10:221409 EXPECT_TRUE(session_->MigrateToSocket(
1410 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1411 // Spin message loop to complete migration.
1412 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081413
1414 // Read error on old socket does not impact session.
1415 EXPECT_TRUE(socket_data_->IsPaused());
1416 socket_data_->Resume();
1417 EXPECT_TRUE(session_->connection()->connected());
1418 EXPECT_TRUE(new_socket_data.IsPaused());
1419 new_socket_data.Resume();
1420
1421 // Read error on new socket causes session close.
1422 EXPECT_TRUE(new_socket_data.IsPaused());
1423 EXPECT_TRUE(session_->connection()->connected());
1424 new_socket_data.Resume();
1425 EXPECT_FALSE(session_->connection()->connected());
1426
1427 EXPECT_TRUE(socket_data_->AllReadDataConsumed());
1428 EXPECT_TRUE(socket_data_->AllWriteDataConsumed());
1429 EXPECT_TRUE(new_socket_data.AllReadDataConsumed());
1430 EXPECT_TRUE(new_socket_data.AllWriteDataConsumed());
1431}
1432
Yixin Wangf65c4b6d2018-03-08 22:37:401433TEST_P(QuicChromiumClientSessionTest, RetransmittableOnWireTimeout) {
1434 migrate_session_early_v2_ = true;
1435
1436 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:431437 quic_data.AddWrite(SYNCHRONOUS,
1438 client_maker_.MakeInitialSettingsPacket(1, nullptr));
1439 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(2, true));
1440 quic_data.AddRead(ASYNC, server_maker_.MakeAckPacket(1, 2, 1, 1, false));
Yixin Wangf65c4b6d2018-03-08 22:37:401441
Zhongyi Shi32f2fd02018-04-16 18:23:431442 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(3, false));
Yixin Wangf65c4b6d2018-03-08 22:37:401443 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1444 quic_data.AddRead(ASYNC, OK); // EOF
1445 quic_data.AddSocketDataToFactory(&socket_factory_);
1446
1447 Initialize();
1448 CompleteCryptoHandshake();
1449
Ryan Hamilton8d9ee76e2018-05-29 23:52:521450 EXPECT_EQ(quic::QuicTime::Delta::FromMilliseconds(100),
Yixin Wangf65c4b6d2018-03-08 22:37:401451 session_->connection()->retransmittable_on_wire_timeout());
1452
1453 // Open a stream since the connection only sends PINGs to keep a
1454 // retransmittable packet on the wire if there's an open stream.
1455 EXPECT_TRUE(QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
1456 session_.get()));
1457
Ryan Hamilton8d9ee76e2018-05-29 23:52:521458 quic::QuicAlarm* alarm =
1459 quic::test::QuicConnectionPeer::GetRetransmittableOnWireAlarm(
1460 session_->connection());
Yixin Wangf65c4b6d2018-03-08 22:37:401461 EXPECT_FALSE(alarm->IsSet());
1462
1463 // Send PING, which will be ACKed by the server. After the ACK, there will be
1464 // no retransmittable packets on the wire, so the alarm should be set.
1465 session_->SendPing();
1466 base::RunLoop().RunUntilIdle();
1467 EXPECT_TRUE(alarm->IsSet());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521468 EXPECT_EQ(
1469 clock_.ApproximateNow() + quic::QuicTime::Delta::FromMilliseconds(100),
1470 alarm->deadline());
Yixin Wangf65c4b6d2018-03-08 22:37:401471
1472 // Advance clock and simulate the alarm firing. This should cause a PING to be
1473 // sent.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521474 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(100));
Yixin Wangf65c4b6d2018-03-08 22:37:401475 alarm_factory_.FireAlarm(alarm);
1476 base::RunLoop().RunUntilIdle();
1477
1478 quic_data.Resume();
1479 EXPECT_TRUE(quic_data.AllReadDataConsumed());
1480 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
1481}
1482
[email protected]dd3fd0e2012-11-04 05:14:401483} // namespace
1484} // namespace test
1485} // namespace net