blob: 030ab19ed22b0cd8feca60c344d82f6b8d5a5932 [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
Zhongyi Shi5068bb02018-08-03 02:44:0985 MOCK_METHOD0(OnPathDegrading, void());
86
Nick Harpere45fe4fc2017-07-13 00:34:5887 private:
88 bool force_channel_id_sent_ = false;
89};
90
ckrasic4f9d88d2015-07-22 22:23:1691class QuicChromiumClientSessionTest
Ryan Hamilton8d9ee76e2018-05-29 23:52:5292 : public ::testing::TestWithParam<
93 std::tuple<quic::QuicTransportVersion, bool>>,
Bence Béky98447b12018-05-08 03:14:0194 public WithScopedTaskEnvironment {
Ryan Hamilton9883ff62017-08-01 06:07:0595 public:
ckrasic4f9d88d2015-07-22 22:23:1696 QuicChromiumClientSessionTest()
Yixin Wang079ad542018-01-11 04:06:0597 : version_(std::get<0>(GetParam())),
98 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:5299 crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting(),
100 quic::TlsClientHandshaker::CreateSslCtx()),
jri7e636642016-01-14 06:57:08101 default_read_(new MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)),
102 socket_data_(
Ryan Sleevib8d7ea02018-05-07 20:01:01103 new SequencedSocketData(base::make_span(default_read_.get(), 1),
104 base::span<MockWrite>())),
jri7e636642016-01-14 06:57:08105 random_(0),
rch16c74d1d2016-04-22 06:14:07106 helper_(&clock_, &random_),
Paul Jensen8e3c5d32018-02-19 17:06:33107 session_key_(kServerHostname,
108 kServerPort,
109 PRIVACY_MODE_DISABLED,
110 SocketTag()),
Ryan Hamilton6c2a2a82017-12-15 02:06:28111 destination_(kServerHostname, kServerPort),
Yixin Wang079ad542018-01-11 04:06:05112 client_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58113 0,
114 &clock_,
115 kServerHostname,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52116 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05117 client_headers_include_h2_stream_dependency_),
118 server_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58119 0,
120 &clock_,
121 kServerHostname,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52122 quic::Perspective::IS_SERVER,
Yixin Wangf65c4b6d2018-03-08 22:37:40123 false),
124 migrate_session_early_v2_(false) {
xunjielic70cc862016-02-19 15:29:26125 // Advance the time, because timers do not like uninitialized times.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52126 clock_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
xunjielic70cc862016-02-19 15:29:26127 }
jri7e636642016-01-14 06:57:08128
Ryan Hamilton9883ff62017-08-01 06:07:05129 void ResetHandleOnError(
130 std::unique_ptr<QuicChromiumClientSession::Handle>* handle,
131 int net_error) {
132 EXPECT_NE(OK, net_error);
133 handle->reset();
134 }
135
136 protected:
jri7e636642016-01-14 06:57:08137 void Initialize() {
rch1baa7472017-04-26 05:43:58138 if (socket_data_)
139 socket_factory_.AddSocketDataProvider(socket_data_.get());
danakjad1777e2016-04-16 00:56:42140 std::unique_ptr<DatagramClientSocket> socket =
jri7e636642016-01-14 06:57:08141 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:19142 &net_log_, NetLogSource());
jri7e636642016-01-14 06:57:08143 socket->Connect(kIpEndPoint);
Ryan Hamilton9edcf1a2017-11-22 05:55:17144 QuicChromiumPacketWriter* writer = new net::QuicChromiumPacketWriter(
145 socket.get(), base::ThreadTaskRunnerHandle::Get().get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52146 quic::QuicConnection* connection = new quic::QuicConnection(
147 0, quic::QuicSocketAddress(quic::QuicSocketAddressImpl(kIpEndPoint)),
148 &helper_, &alarm_factory_, writer, true, quic::Perspective::IS_CLIENT,
149 quic::test::SupportedVersions(
150 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version_)));
Nick Harpere45fe4fc2017-07-13 00:34:58151 session_.reset(new TestingQuicChromiumClientSession(
jri7e636642016-01-14 06:57:08152 connection, std::move(socket),
153 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57154 &transport_security_state_, /*ssl_config_service=*/nullptr,
Paul Jensen8e3c5d32018-02-19 17:06:33155 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)), session_key_,
Zhongyi Shi757fcce2018-06-27 05:41:27156 /*require_confirmation=*/false, migrate_session_early_v2_,
Yixin Wangf65c4b6d2018-03-08 22:37:40157 /*migrate_session_on_network_change_v2=*/false,
Renjiea5722ccf2018-08-10 00:18:49158 /*go_away_on_path_degrading*/ false,
Zhongyi Shid672f7542018-06-08 01:03:26159 /*defaulet_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shi73f23ca872017-12-13 18:37:13160 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shiee760762018-08-01 00:54:29161 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30162 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17163 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52164 quic::QuicTime::Delta::FromMilliseconds(
165 kQuicYieldAfterDurationMilliseconds),
Yixin Wang079ad542018-01-11 04:06:05166 /*cert_verify_flags=*/0, client_headers_include_h2_stream_dependency_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52167 quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
Yixin Wang079ad542018-01-11 04:06:05168 base::TimeTicks::Now(), base::TimeTicks::Now(), &push_promise_index_,
169 &test_push_delegate_, base::ThreadTaskRunnerHandle::Get().get(),
jri7e636642016-01-14 06:57:08170 /*socket_performance_watcher=*/nullptr, &net_log_));
171
172 scoped_refptr<X509Certificate> cert(
173 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
174 verify_details_.cert_verify_result.verified_cert = cert;
175 verify_details_.cert_verify_result.is_issued_by_known_root = true;
jri7e636642016-01-14 06:57:08176 session_->Initialize();
177 session_->StartReading();
jribce3eec2016-09-09 05:41:08178 writer->set_delegate(session_.get());
[email protected]dd3fd0e2012-11-04 05:14:40179 }
180
rtenneti85dcfac22015-03-27 20:22:19181 void TearDown() override {
rchf0b18c8a2017-05-05 19:31:57182 if (session_)
Renjieba55fae2018-09-20 03:05:16183 session_->CloseSessionOnError(
184 ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
185 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]4d283b32013-10-17 12:57:27186 }
187
[email protected]ed3fc15d2013-03-08 18:37:44188 void CompleteCryptoHandshake() {
rch433bf5f2017-02-14 04:10:47189 ASSERT_THAT(session_->CryptoConnect(callback_.callback()), IsOk());
[email protected]ed3fc15d2013-03-08 18:37:44190 }
191
jried79618b2016-07-02 03:18:52192 QuicChromiumPacketWriter* CreateQuicChromiumPacketWriter(
193 DatagramClientSocket* socket,
194 QuicChromiumClientSession* session) const {
danakjad1777e2016-04-16 00:56:42195 std::unique_ptr<QuicChromiumPacketWriter> writer(
Ryan Hamilton9edcf1a2017-11-22 05:55:17196 new QuicChromiumPacketWriter(
197 socket, base::ThreadTaskRunnerHandle::Get().get()));
jribce3eec2016-09-09 05:41:08198 writer->set_delegate(session);
jri7e636642016-01-14 06:57:08199 return writer.release();
200 }
201
Ryan Hamilton8d9ee76e2018-05-29 23:52:52202 quic::QuicStreamId GetNthClientInitiatedStreamId(int n) {
203 return quic::test::GetNthClientInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36204 }
205
Ryan Hamilton8d9ee76e2018-05-29 23:52:52206 quic::QuicStreamId GetNthServerInitiatedStreamId(int n) {
207 return quic::test::GetNthServerInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36208 }
209
Ryan Hamilton8d9ee76e2018-05-29 23:52:52210 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05211 const bool client_headers_include_h2_stream_dependency_;
Jana Iyengarf6b13d82017-09-04 02:09:10212 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52213 quic::QuicCryptoClientConfig crypto_config_;
vishal.b62985ca92015-04-17 08:45:51214 TestNetLog net_log_;
tfarina42834112016-09-22 13:38:20215 BoundTestNetLog bound_test_net_log_;
[email protected]4d283b32013-10-17 12:57:27216 MockClientSocketFactory socket_factory_;
danakjad1777e2016-04-16 00:56:42217 std::unique_ptr<MockRead> default_read_;
218 std::unique_ptr<SequencedSocketData> socket_data_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52219 quic::MockClock clock_;
220 quic::test::MockRandom random_;
rch12fef552016-01-15 16:26:31221 QuicChromiumConnectionHelper helper_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52222 quic::test::MockAlarmFactory alarm_factory_;
jri7e636642016-01-14 06:57:08223 TransportSecurityState transport_security_state_;
224 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52225 quic::QuicClientPushPromiseIndex push_promise_index_;
Paul Jensen8e3c5d32018-02-19 17:06:33226 QuicSessionKey session_key_;
Ryan Hamilton6c2a2a82017-12-15 02:06:28227 HostPortPair destination_;
Nick Harpere45fe4fc2017-07-13 00:34:58228 std::unique_ptr<TestingQuicChromiumClientSession> session_;
zhongyi0009f3e2016-11-11 19:47:50229 TestServerPushDelegate test_push_delegate_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52230 quic::QuicConnectionVisitorInterface* visitor_;
[email protected]8ee611b2012-11-20 01:48:12231 TestCompletionCallback callback_;
alyssar2adf3ac2016-05-03 17:12:58232 QuicTestPacketMaker client_maker_;
233 QuicTestPacketMaker server_maker_;
jri7e636642016-01-14 06:57:08234 ProofVerifyDetailsChromium verify_details_;
Yixin Wangf65c4b6d2018-03-08 22:37:40235 bool migrate_session_early_v2_;
[email protected]dd3fd0e2012-11-04 05:14:40236};
237
Yixin Wang079ad542018-01-11 04:06:05238INSTANTIATE_TEST_CASE_P(
Bence Békyce380cb2018-04-26 23:39:55239 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05240 QuicChromiumClientSessionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52241 ::testing::Combine(
242 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
243 ::testing::Bool()));
[email protected]4d640792013-12-18 22:21:08244
Carlos IL81133382017-12-06 17:18:45245TEST_P(QuicChromiumClientSessionTest, IsFatalErrorNotSetForNonFatalError) {
246 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52247 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Carlos IL81133382017-12-06 17:18:45248 client_maker_.MakeInitialSettingsPacket(1, nullptr));
249 MockWrite writes[] = {
250 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01251 socket_data_.reset(new SequencedSocketData(reads, writes));
Carlos IL81133382017-12-06 17:18:45252 Initialize();
253
254 SSLInfo ssl_info;
255 ProofVerifyDetailsChromium details;
256 details.cert_verify_result.verified_cert =
257 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
258 details.cert_verify_result.cert_status =
259 MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
260 details.is_fatal_cert_error = false;
261 CompleteCryptoHandshake();
262 session_->OnProofVerifyDetailsAvailable(details);
263
264 ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
265 EXPECT_FALSE(ssl_info.is_fatal_cert_error);
266}
267
268TEST_P(QuicChromiumClientSessionTest, IsFatalErrorSetForFatalError) {
269 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52270 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Carlos IL81133382017-12-06 17:18:45271 client_maker_.MakeInitialSettingsPacket(1, nullptr));
272 MockWrite writes[] = {
273 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01274 socket_data_.reset(new SequencedSocketData(reads, writes));
Carlos IL81133382017-12-06 17:18:45275 Initialize();
276
277 SSLInfo ssl_info;
278 ProofVerifyDetailsChromium details;
279 details.cert_verify_result.verified_cert =
280 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
281 details.cert_verify_result.cert_status =
282 MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
283 details.is_fatal_cert_error = true;
284 CompleteCryptoHandshake();
285 session_->OnProofVerifyDetailsAvailable(details);
286 ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
287 EXPECT_TRUE(ssl_info.is_fatal_cert_error);
288}
289
ckrasic4f9d88d2015-07-22 22:23:16290TEST_P(QuicChromiumClientSessionTest, CryptoConnect) {
fayang3bcb8b502016-12-07 21:44:37291 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52292 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36293 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:37294 MockWrite writes[] = {
295 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01296 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:08297 Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44298 CompleteCryptoHandshake();
[email protected]8ee611b2012-11-20 01:48:12299}
300
rchf0b18c8a2017-05-05 19:31:57301TEST_P(QuicChromiumClientSessionTest, Handle) {
302 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43303 quic_data.AddWrite(SYNCHRONOUS,
304 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rchf0b18c8a2017-05-05 19:31:57305 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
306 quic_data.AddRead(ASYNC, OK); // EOF
307 quic_data.AddSocketDataToFactory(&socket_factory_);
308
309 Initialize();
310
311 NetLogWithSource session_net_log = session_->net_log();
312 EXPECT_EQ(NetLogSourceType::QUIC_SESSION, session_net_log.source().type);
313 EXPECT_EQ(&net_log_, session_net_log.net_log());
314
315 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28316 session_->CreateHandle(destination_);
rchf0b18c8a2017-05-05 19:31:57317 EXPECT_TRUE(handle->IsConnected());
318 EXPECT_FALSE(handle->IsCryptoHandshakeConfirmed());
Yixin Wang079ad542018-01-11 04:06:05319 EXPECT_EQ(version_, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33320 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57321 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
322 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
323 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
324 IPEndPoint address;
325 EXPECT_EQ(OK, handle->GetPeerAddress(&address));
326 EXPECT_EQ(kIpEndPoint, address);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52327 EXPECT_TRUE(handle->CreatePacketBundler(quic::QuicConnection::NO_ACK).get() !=
rchf0b18c8a2017-05-05 19:31:57328 nullptr);
329
330 CompleteCryptoHandshake();
331
332 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
333
334 // Request a stream and verify that a stream was created.
335 TestCompletionCallback callback;
336 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39337 callback.callback(),
338 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29339 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchf0b18c8a2017-05-05 19:31:57340
341 quic_data.Resume();
342 EXPECT_TRUE(quic_data.AllReadDataConsumed());
343 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
344
345 // Veirfy that the handle works correctly after the session is closed.
346 EXPECT_FALSE(handle->IsConnected());
347 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
Yixin Wang079ad542018-01-11 04:06:05348 EXPECT_EQ(version_, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33349 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57350 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
351 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
352 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
353 EXPECT_EQ(ERR_CONNECTION_CLOSED, handle->GetPeerAddress(&address));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52354 EXPECT_TRUE(handle->CreatePacketBundler(quic::QuicConnection::NO_ACK).get() ==
rchf0b18c8a2017-05-05 19:31:57355 nullptr);
356 {
357 // Verify that CreateHandle() works even after the session is closed.
358 std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
Ryan Hamilton6c2a2a82017-12-15 02:06:28359 session_->CreateHandle(destination_);
rchf0b18c8a2017-05-05 19:31:57360 EXPECT_FALSE(handle2->IsConnected());
361 EXPECT_TRUE(handle2->IsCryptoHandshakeConfirmed());
362 ASSERT_EQ(ERR_CONNECTION_CLOSED,
363 handle2->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39364 callback.callback(),
365 TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57366 }
367
368 session_.reset();
369
370 // Veirfy that the handle works correctly after the session is deleted.
371 EXPECT_FALSE(handle->IsConnected());
372 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
Yixin Wang079ad542018-01-11 04:06:05373 EXPECT_EQ(version_, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33374 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57375 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
376 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
377 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
378 EXPECT_EQ(ERR_CONNECTION_CLOSED, handle->GetPeerAddress(&address));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52379 EXPECT_TRUE(handle->CreatePacketBundler(quic::QuicConnection::NO_ACK).get() ==
rchf0b18c8a2017-05-05 19:31:57380 nullptr);
Ramin Halavati683bcaa92018-02-14 08:42:39381 ASSERT_EQ(
382 ERR_CONNECTION_CLOSED,
383 handle->RequestStream(/*requires_confirmation=*/false,
384 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57385}
386
rch1baa7472017-04-26 05:43:58387TEST_P(QuicChromiumClientSessionTest, StreamRequest) {
388 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43389 quic_data.AddWrite(SYNCHRONOUS,
390 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rch1baa7472017-04-26 05:43:58391 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
392 quic_data.AddRead(ASYNC, OK); // EOF
393 quic_data.AddSocketDataToFactory(&socket_factory_);
394
395 Initialize();
396 CompleteCryptoHandshake();
397
398 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57399 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28400 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58401 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57402 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39403 callback.callback(),
404 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29405 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rch1baa7472017-04-26 05:43:58406
407 quic_data.Resume();
408 EXPECT_TRUE(quic_data.AllReadDataConsumed());
409 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
410}
411
rchd606b6c32017-05-02 17:32:57412TEST_P(QuicChromiumClientSessionTest, ConfirmationRequiredStreamRequest) {
413 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43414 quic_data.AddWrite(SYNCHRONOUS,
415 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rchd606b6c32017-05-02 17:32:57416 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
417 quic_data.AddRead(ASYNC, OK); // EOF
418 quic_data.AddSocketDataToFactory(&socket_factory_);
419
420 Initialize();
421 CompleteCryptoHandshake();
422
423 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57424 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28425 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57426 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57427 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/true,
Ramin Halavati683bcaa92018-02-14 08:42:39428 callback.callback(),
429 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29430 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchd606b6c32017-05-02 17:32:57431
432 quic_data.Resume();
433 EXPECT_TRUE(quic_data.AllReadDataConsumed());
434 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
435}
436
437TEST_P(QuicChromiumClientSessionTest, StreamRequestBeforeConfirmation) {
438 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43439 quic_data.AddWrite(SYNCHRONOUS,
440 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rchd606b6c32017-05-02 17:32:57441 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
442 quic_data.AddRead(ASYNC, OK); // EOF
443 quic_data.AddSocketDataToFactory(&socket_factory_);
444
445 Initialize();
446
447 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57448 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28449 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57450 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39451 ASSERT_EQ(
452 ERR_IO_PENDING,
453 handle->RequestStream(/*requires_confirmation=*/true, callback.callback(),
454 TRAFFIC_ANNOTATION_FOR_TESTS));
rchd606b6c32017-05-02 17:32:57455
456 CompleteCryptoHandshake();
457
458 EXPECT_THAT(callback.WaitForResult(), IsOk());
459
rch1bcfddf22017-06-03 00:26:29460 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchd606b6c32017-05-02 17:32:57461
462 quic_data.Resume();
463 EXPECT_TRUE(quic_data.AllReadDataConsumed());
464 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
465}
466
rch1baa7472017-04-26 05:43:58467TEST_P(QuicChromiumClientSessionTest, CancelStreamRequestBeforeRelease) {
468 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43469 quic_data.AddWrite(SYNCHRONOUS,
470 client_maker_.MakeInitialSettingsPacket(1, nullptr));
471 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
472 2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52473 quic::QUIC_STREAM_CANCELLED));
rch1baa7472017-04-26 05:43:58474 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
475 quic_data.AddRead(ASYNC, OK); // EOF
476 quic_data.AddSocketDataToFactory(&socket_factory_);
477
478 Initialize();
479 CompleteCryptoHandshake();
480
481 // Request a stream and cancel it without releasing the stream.
rchf0b18c8a2017-05-05 19:31:57482 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28483 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58484 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57485 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39486 callback.callback(),
487 TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57488 handle.reset();
rch1baa7472017-04-26 05:43:58489
490 quic_data.Resume();
491 EXPECT_TRUE(quic_data.AllReadDataConsumed());
492 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
493}
494
495TEST_P(QuicChromiumClientSessionTest, AsyncStreamRequest) {
496 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43497 quic_data.AddWrite(SYNCHRONOUS,
498 client_maker_.MakeInitialSettingsPacket(1, nullptr));
499 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
500 2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52501 quic::QUIC_RST_ACKNOWLEDGEMENT));
rch1baa7472017-04-26 05:43:58502 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
503 quic_data.AddRead(ASYNC, OK); // EOF
504 quic_data.AddSocketDataToFactory(&socket_factory_);
505
506 Initialize();
507 CompleteCryptoHandshake();
508
509 // Open the maximum number of streams so that a subsequent request
510 // can not proceed immediately.
511 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
512 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50513 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
rch1baa7472017-04-26 05:43:58514 }
515 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
516
517 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57518 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28519 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58520 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39521 ASSERT_EQ(
522 ERR_IO_PENDING,
523 handle->RequestStream(/*requires_confirmation=*/false,
524 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch1baa7472017-04-26 05:43:58525
526 // Close a stream and ensure the stream request completes.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52527 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
528 GetNthClientInitiatedStreamId(0),
529 quic::QUIC_STREAM_CANCELLED, 0);
rch1baa7472017-04-26 05:43:58530 session_->OnRstStream(rst);
531 ASSERT_TRUE(callback.have_result());
532 EXPECT_THAT(callback.WaitForResult(), IsOk());
rch1bcfddf22017-06-03 00:26:29533 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rch1baa7472017-04-26 05:43:58534
535 quic_data.Resume();
536 EXPECT_TRUE(quic_data.AllReadDataConsumed());
537 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
538}
539
Ryan Hamilton9883ff62017-08-01 06:07:05540TEST_P(QuicChromiumClientSessionTest, ClosedWithAsyncStreamRequest) {
541 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43542 quic_data.AddWrite(SYNCHRONOUS,
543 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton9883ff62017-08-01 06:07:05544 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
545 quic_data.AddRead(ASYNC, OK); // EOF
546 quic_data.AddSocketDataToFactory(&socket_factory_);
547
548 Initialize();
549 CompleteCryptoHandshake();
550
551 // Open the maximum number of streams so that a subsequent request
552 // can not proceed immediately.
553 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
554 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50555 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
Ryan Hamilton9883ff62017-08-01 06:07:05556 }
557 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
558
559 // Request two streams which will both be pending.
560 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28561 session_->CreateHandle(destination_);
Ryan Hamilton9883ff62017-08-01 06:07:05562 std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
Ryan Hamilton6c2a2a82017-12-15 02:06:28563 session_->CreateHandle(destination_);
Ryan Hamilton9883ff62017-08-01 06:07:05564
565 ASSERT_EQ(ERR_IO_PENDING,
566 handle->RequestStream(
567 /*requires_confirmation=*/false,
568 base::Bind(&QuicChromiumClientSessionTest::ResetHandleOnError,
Ramin Halavati683bcaa92018-02-14 08:42:39569 base::Unretained(this), &handle2),
570 TRAFFIC_ANNOTATION_FOR_TESTS));
Ryan Hamilton9883ff62017-08-01 06:07:05571
572 TestCompletionCallback callback2;
573 ASSERT_EQ(ERR_IO_PENDING,
574 handle2->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39575 callback2.callback(),
576 TRAFFIC_ANNOTATION_FOR_TESTS));
Ryan Hamilton9883ff62017-08-01 06:07:05577
578 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52579 quic::QUIC_NETWORK_IDLE_TIMEOUT, "Timed out",
580 quic::ConnectionCloseBehavior::SILENT_CLOSE);
Ryan Hamilton9883ff62017-08-01 06:07:05581
582 // Pump the message loop to read the connection close packet.
583 base::RunLoop().RunUntilIdle();
584 EXPECT_FALSE(handle2.get());
585 quic_data.Resume();
586 EXPECT_TRUE(quic_data.AllReadDataConsumed());
587 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
588}
589
rch1baa7472017-04-26 05:43:58590TEST_P(QuicChromiumClientSessionTest, CancelPendingStreamRequest) {
591 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43592 quic_data.AddWrite(SYNCHRONOUS,
593 client_maker_.MakeInitialSettingsPacket(1, nullptr));
594 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
595 2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52596 quic::QUIC_RST_ACKNOWLEDGEMENT));
rch1baa7472017-04-26 05:43:58597 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
598 quic_data.AddRead(ASYNC, OK); // EOF
599 quic_data.AddSocketDataToFactory(&socket_factory_);
600
601 Initialize();
602 CompleteCryptoHandshake();
603
604 // Open the maximum number of streams so that a subsequent request
605 // can not proceed immediately.
606 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
607 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50608 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
rch1baa7472017-04-26 05:43:58609 }
610 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
611
612 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57613 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28614 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58615 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39616 ASSERT_EQ(
617 ERR_IO_PENDING,
618 handle->RequestStream(/*requires_confirmation=*/false,
619 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch1baa7472017-04-26 05:43:58620
621 // Cancel the pending stream request.
rchf0b18c8a2017-05-05 19:31:57622 handle.reset();
rch1baa7472017-04-26 05:43:58623
624 // Close a stream and ensure that no new stream is created.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52625 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
626 GetNthClientInitiatedStreamId(0),
627 quic::QUIC_STREAM_CANCELLED, 0);
rch1baa7472017-04-26 05:43:58628 session_->OnRstStream(rst);
629 EXPECT_EQ(kMaxOpenStreams - 1, session_->GetNumOpenOutgoingStreams());
630
631 quic_data.Resume();
632 EXPECT_TRUE(quic_data.AllReadDataConsumed());
633 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
634}
635
rch94c26d682017-04-29 02:49:27636TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeStreamRequest) {
637 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43638 quic_data.AddWrite(SYNCHRONOUS,
639 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52640 quic_data.AddRead(
641 ASYNC,
642 server_maker_.MakeConnectionClosePacket(
643 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rch94c26d682017-04-29 02:49:27644 quic_data.AddSocketDataToFactory(&socket_factory_);
645
646 Initialize();
647 CompleteCryptoHandshake();
648
649 // Pump the message loop to read the connection close packet.
650 base::RunLoop().RunUntilIdle();
651
652 // Request a stream and verify that it failed.
rchf0b18c8a2017-05-05 19:31:57653 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28654 session_->CreateHandle(destination_);
rch94c26d682017-04-29 02:49:27655 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39656 ASSERT_EQ(
657 ERR_CONNECTION_CLOSED,
658 handle->RequestStream(/*requires_confirmation=*/false,
659 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch94c26d682017-04-29 02:49:27660
661 EXPECT_TRUE(quic_data.AllReadDataConsumed());
662 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
663}
664
rchd606b6c32017-05-02 17:32:57665TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeHandshakeConfirmed) {
666 MockQuicData quic_data;
667 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52668 quic_data.AddRead(
669 ASYNC,
670 server_maker_.MakeConnectionClosePacket(
671 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rchd606b6c32017-05-02 17:32:57672 quic_data.AddSocketDataToFactory(&socket_factory_);
673
674 Initialize();
675
676 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57677 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28678 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57679 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39680 ASSERT_EQ(
681 ERR_IO_PENDING,
682 handle->RequestStream(/*requires_confirmation=*/true, callback.callback(),
683 TRAFFIC_ANNOTATION_FOR_TESTS));
rchd606b6c32017-05-02 17:32:57684
685 // Close the connection and verify that the StreamRequest completes with
686 // an error.
687 quic_data.Resume();
688 base::RunLoop().RunUntilIdle();
689
690 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
691
692 EXPECT_TRUE(quic_data.AllReadDataConsumed());
693 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
694}
695
rch94c26d682017-04-29 02:49:27696TEST_P(QuicChromiumClientSessionTest, ConnectionCloseWithPendingStreamRequest) {
697 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43698 quic_data.AddWrite(SYNCHRONOUS,
699 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rch94c26d682017-04-29 02:49:27700 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52701 quic_data.AddRead(
702 ASYNC,
703 server_maker_.MakeConnectionClosePacket(
704 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rch94c26d682017-04-29 02:49:27705 quic_data.AddSocketDataToFactory(&socket_factory_);
706
707 Initialize();
708 CompleteCryptoHandshake();
709
710 // Open the maximum number of streams so that a subsequent request
711 // can not proceed immediately.
712 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
713 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50714 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
rch94c26d682017-04-29 02:49:27715 }
716 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
717
718 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57719 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28720 session_->CreateHandle(destination_);
rch94c26d682017-04-29 02:49:27721 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39722 ASSERT_EQ(
723 ERR_IO_PENDING,
724 handle->RequestStream(/*requires_confirmation=*/false,
725 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch94c26d682017-04-29 02:49:27726
727 // Close the connection and verify that the StreamRequest completes with
728 // an error.
729 quic_data.Resume();
730 base::RunLoop().RunUntilIdle();
731
732 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
733
734 EXPECT_TRUE(quic_data.AllReadDataConsumed());
735 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
736}
737
ckrasic4f9d88d2015-07-22 22:23:16738TEST_P(QuicChromiumClientSessionTest, MaxNumStreams) {
jri7e636642016-01-14 06:57:08739 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52740 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36741 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52742 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
743 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
744 quic::QUIC_RST_ACKNOWLEDGEMENT));
jri7e636642016-01-14 06:57:08745 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37746 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
747 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01748 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:08749
750 Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44751 CompleteCryptoHandshake();
rtenneti9f41c0a2016-02-02 23:59:30752 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
[email protected]dd3fd0e2012-11-04 05:14:40753
rch12fef552016-01-15 16:26:31754 std::vector<QuicChromiumClientStream*> streams;
jri7e636642016-01-14 06:57:08755 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:57756 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50757 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
[email protected]dd3fd0e2012-11-04 05:14:40758 EXPECT_TRUE(stream);
[email protected]f702d572012-12-04 15:56:20759 streams.push_back(stream);
[email protected]dd3fd0e2012-11-04 05:14:40760 }
Fan Yang5a3bddf2018-10-12 10:05:50761 EXPECT_FALSE(
762 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
[email protected]dd3fd0e2012-11-04 05:14:40763
jri7e636642016-01-14 06:57:08764 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
rtennetiac06c2f2015-11-05 18:12:35765
[email protected]dd3fd0e2012-11-04 05:14:40766 // Close a stream and ensure I can now open a new one.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52767 quic::QuicStreamId stream_id = streams[0]->id();
jri7e636642016-01-14 06:57:08768 session_->CloseStream(stream_id);
rtennetiac06c2f2015-11-05 18:12:35769
Fan Yang5a3bddf2018-10-12 10:05:50770 EXPECT_FALSE(
771 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52772 quic::QuicRstStreamFrame rst1(quic::kInvalidControlFrameId, stream_id,
773 quic::QUIC_STREAM_NO_ERROR, 0);
jri7e636642016-01-14 06:57:08774 session_->OnRstStream(rst1);
775 EXPECT_EQ(kMaxOpenStreams - 1, session_->GetNumOpenOutgoingStreams());
Fan Yang5a3bddf2018-10-12 10:05:50776 EXPECT_TRUE(
777 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
[email protected]dd3fd0e2012-11-04 05:14:40778}
779
zhongyie34c035662016-10-19 22:26:02780TEST_P(QuicChromiumClientSessionTest, PushStreamTimedOutNoResponse) {
781 base::HistogramTester histogram_tester;
782 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52783 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36784 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52785 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
786 client_maker_.MakeRstPacket(2, true, GetNthServerInitiatedStreamId(0),
787 quic::QUIC_PUSH_STREAM_TIMED_OUT));
zhongyie34c035662016-10-19 22:26:02788 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37789 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
790 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01791 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyie34c035662016-10-19 22:26:02792 Initialize();
793
794 ProofVerifyDetailsChromium details;
795 details.cert_verify_result.verified_cert =
796 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
797 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
798
799 CompleteCryptoHandshake();
800 session_->OnProofVerifyDetailsAvailable(details);
801
Ramin Halavatif7788ea2018-02-26 07:02:57802 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50803 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyie34c035662016-10-19 22:26:02804 EXPECT_TRUE(stream);
805
Ryan Hamilton0239aac2018-05-19 00:03:13806 spdy::SpdyHeaderBlock promise_headers;
zhongyie34c035662016-10-19 22:26:02807 promise_headers[":method"] = "GET";
808 promise_headers[":authority"] = "www.example.org";
809 promise_headers[":scheme"] = "https";
810 promise_headers[":path"] = "/pushed.jpg";
811
812 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:36813 EXPECT_TRUE(session_->HandlePromised(
814 stream->id(), GetNthServerInitiatedStreamId(0), promise_headers));
zhongyie34c035662016-10-19 22:26:02815
Ryan Hamilton8d9ee76e2018-05-29 23:52:52816 quic::QuicClientPromisedInfo* promised =
ckrasicbf2f59c2017-05-04 23:54:36817 session_->GetPromisedById(GetNthServerInitiatedStreamId(0));
zhongyie34c035662016-10-19 22:26:02818 EXPECT_TRUE(promised);
819 // Fire alarm to time out the push stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52820 alarm_factory_.FireAlarm(
821 quic::test::QuicClientPromisedInfoPeer::GetAlarm(promised));
zhongyie34c035662016-10-19 22:26:02822 EXPECT_FALSE(
823 session_->GetPromisedByUrl("https://www.example.org/pushed.jpg"));
824 EXPECT_EQ(0u,
825 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
826 EXPECT_EQ(0u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
827 session_.get()));
828}
829
830TEST_P(QuicChromiumClientSessionTest, PushStreamTimedOutWithResponse) {
831 base::HistogramTester histogram_tester;
832 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52833 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36834 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52835 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
836 client_maker_.MakeRstPacket(2, true, GetNthServerInitiatedStreamId(0),
837 quic::QUIC_PUSH_STREAM_TIMED_OUT));
zhongyie34c035662016-10-19 22:26:02838 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37839 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
840 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01841 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyie34c035662016-10-19 22:26:02842 Initialize();
843
844 ProofVerifyDetailsChromium details;
845 details.cert_verify_result.verified_cert =
846 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
847 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
848
849 CompleteCryptoHandshake();
850 session_->OnProofVerifyDetailsAvailable(details);
851
Ramin Halavatif7788ea2018-02-26 07:02:57852 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50853 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyie34c035662016-10-19 22:26:02854 EXPECT_TRUE(stream);
855
Ryan Hamilton0239aac2018-05-19 00:03:13856 spdy::SpdyHeaderBlock promise_headers;
zhongyie34c035662016-10-19 22:26:02857 promise_headers[":method"] = "GET";
858 promise_headers[":authority"] = "www.example.org";
859 promise_headers[":scheme"] = "https";
860 promise_headers[":path"] = "/pushed.jpg";
861
ckrasicbf2f59c2017-05-04 23:54:36862 session_->GetOrCreateStream(GetNthServerInitiatedStreamId(0));
zhongyie34c035662016-10-19 22:26:02863 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:36864 EXPECT_TRUE(session_->HandlePromised(
865 stream->id(), GetNthServerInitiatedStreamId(0), promise_headers));
866 session_->OnInitialHeadersComplete(GetNthServerInitiatedStreamId(0),
Ryan Hamilton0239aac2018-05-19 00:03:13867 spdy::SpdyHeaderBlock());
zhongyie34c035662016-10-19 22:26:02868 // Read data on the pushed stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52869 quic::QuicStreamFrame data(GetNthServerInitiatedStreamId(0), false, 0,
870 quic::QuicStringPiece("SP"));
zhongyie34c035662016-10-19 22:26:02871 session_->OnStreamFrame(data);
872
Ryan Hamilton8d9ee76e2018-05-29 23:52:52873 quic::QuicClientPromisedInfo* promised =
ckrasicbf2f59c2017-05-04 23:54:36874 session_->GetPromisedById(GetNthServerInitiatedStreamId(0));
zhongyie34c035662016-10-19 22:26:02875 EXPECT_TRUE(promised);
876 // Fire alarm to time out the push stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52877 alarm_factory_.FireAlarm(
878 quic::test::QuicClientPromisedInfoPeer::GetAlarm(promised));
zhongyie34c035662016-10-19 22:26:02879 EXPECT_EQ(2u,
880 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
881 EXPECT_EQ(2u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
882 session_.get()));
883}
884
zhongyi7465c1b2016-11-11 01:38:05885TEST_P(QuicChromiumClientSessionTest, CancelPushWhenPendingValidation) {
886 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52887 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36888 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52889 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
890 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
891 quic::QUIC_RST_ACKNOWLEDGEMENT));
zhongyi7465c1b2016-11-11 01:38:05892
893 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37894 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
895 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01896 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyi7465c1b2016-11-11 01:38:05897 Initialize();
898
899 ProofVerifyDetailsChromium details;
900 details.cert_verify_result.verified_cert =
901 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
902 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
903
904 CompleteCryptoHandshake();
905 session_->OnProofVerifyDetailsAvailable(details);
906
Ramin Halavatif7788ea2018-02-26 07:02:57907 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50908 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyi7465c1b2016-11-11 01:38:05909 EXPECT_TRUE(stream);
910
Ryan Hamilton0239aac2018-05-19 00:03:13911 spdy::SpdyHeaderBlock promise_headers;
zhongyi7465c1b2016-11-11 01:38:05912 promise_headers[":method"] = "GET";
913 promise_headers[":authority"] = "www.example.org";
914 promise_headers[":scheme"] = "https";
915 promise_headers[":path"] = "/pushed.jpg";
916
917 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:36918 EXPECT_TRUE(session_->HandlePromised(
919 stream->id(), GetNthServerInitiatedStreamId(0), promise_headers));
zhongyi7465c1b2016-11-11 01:38:05920
Ryan Hamilton8d9ee76e2018-05-29 23:52:52921 quic::QuicClientPromisedInfo* promised =
ckrasicbf2f59c2017-05-04 23:54:36922 session_->GetPromisedById(GetNthServerInitiatedStreamId(0));
zhongyi7465c1b2016-11-11 01:38:05923 EXPECT_TRUE(promised);
924
925 // Initiate rendezvous.
Ryan Hamilton0239aac2018-05-19 00:03:13926 spdy::SpdyHeaderBlock client_request = promise_headers.Clone();
Ryan Hamilton8d9ee76e2018-05-29 23:52:52927 quic::test::TestPushPromiseDelegate delegate(/*match=*/true);
zhongyi7465c1b2016-11-11 01:38:05928 promised->HandleClientRequest(client_request, &delegate);
929
930 // Cancel the push before receiving the response to the pushed request.
931 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:50932 test_push_delegate_.CancelPush(pushed_url);
zhongyi7465c1b2016-11-11 01:38:05933 EXPECT_TRUE(session_->GetPromisedByUrl(pushed_url.spec()));
934
935 // Reset the stream now before tear down.
ckrasicbf2f59c2017-05-04 23:54:36936 session_->CloseStream(GetNthClientInitiatedStreamId(0));
zhongyi7465c1b2016-11-11 01:38:05937}
938
zhongyi18bb2d92016-10-27 19:38:50939TEST_P(QuicChromiumClientSessionTest, CancelPushBeforeReceivingResponse) {
940 base::HistogramTester histogram_tester;
941 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52942 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36943 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52944 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
945 client_maker_.MakeRstPacket(2, true, GetNthServerInitiatedStreamId(0),
946 quic::QUIC_STREAM_CANCELLED));
zhongyi18bb2d92016-10-27 19:38:50947 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37948 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
949 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01950 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyi18bb2d92016-10-27 19:38:50951 Initialize();
952
953 ProofVerifyDetailsChromium details;
954 details.cert_verify_result.verified_cert =
955 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
956 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
957
958 CompleteCryptoHandshake();
959 session_->OnProofVerifyDetailsAvailable(details);
960
Ramin Halavatif7788ea2018-02-26 07:02:57961 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50962 QuicChromiumClientSessionPeer::CreateOutgoingStream(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 =
Fan Yang5a3bddf2018-10-12 10:05:501012 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyi18bb2d92016-10-27 19:38:501013 EXPECT_TRUE(stream);
1014
Ryan Hamilton0239aac2018-05-19 00:03:131015 spdy::SpdyHeaderBlock promise_headers;
zhongyi18bb2d92016-10-27 19:38:501016 promise_headers[":method"] = "GET";
1017 promise_headers[":authority"] = "www.example.org";
1018 promise_headers[":scheme"] = "https";
1019 promise_headers[":path"] = "/pushed.jpg";
1020
ckrasicbf2f59c2017-05-04 23:54:361021 session_->GetOrCreateStream(GetNthServerInitiatedStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501022 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:361023 EXPECT_TRUE(session_->HandlePromised(
1024 stream->id(), GetNthServerInitiatedStreamId(0), promise_headers));
1025 session_->OnInitialHeadersComplete(GetNthServerInitiatedStreamId(0),
Ryan Hamilton0239aac2018-05-19 00:03:131026 spdy::SpdyHeaderBlock());
zhongyi18bb2d92016-10-27 19:38:501027 // Read data on the pushed stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521028 quic::QuicStreamFrame data(GetNthServerInitiatedStreamId(0), false, 0,
1029 quic::QuicStringPiece("SP"));
zhongyi18bb2d92016-10-27 19:38:501030 session_->OnStreamFrame(data);
1031
Ryan Hamilton8d9ee76e2018-05-29 23:52:521032 quic::QuicClientPromisedInfo* promised =
ckrasicbf2f59c2017-05-04 23:54:361033 session_->GetPromisedById(GetNthServerInitiatedStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501034 EXPECT_TRUE(promised);
1035 // Cancel the push after receiving data on the push stream.
1036 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:501037 test_push_delegate_.CancelPush(pushed_url);
zhongyi18bb2d92016-10-27 19:38:501038
1039 EXPECT_FALSE(session_->GetPromisedByUrl(pushed_url.spec()));
1040 EXPECT_EQ(2u,
1041 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
1042 EXPECT_EQ(2u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
1043 session_.get()));
1044}
1045
ckrasic4f9d88d2015-07-22 22:23:161046TEST_P(QuicChromiumClientSessionTest, MaxNumStreamsViaRequest) {
jri7e636642016-01-14 06:57:081047 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521048 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361049 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521050 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
1051 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
1052 quic::QUIC_RST_ACKNOWLEDGEMENT));
jri7e636642016-01-14 06:57:081053 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:371054 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
1055 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011056 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081057
1058 Initialize();
[email protected]0b2294d32013-08-02 00:46:361059 CompleteCryptoHandshake();
rtenneti9f41c0a2016-02-02 23:59:301060 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
[email protected]0b2294d32013-08-02 00:46:361061
rch12fef552016-01-15 16:26:311062 std::vector<QuicChromiumClientStream*> streams;
jri7e636642016-01-14 06:57:081063 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:571064 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501065 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
[email protected]0b2294d32013-08-02 00:46:361066 EXPECT_TRUE(stream);
1067 streams.push_back(stream);
1068 }
1069
rchf0b18c8a2017-05-05 19:31:571070 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:281071 session_->CreateHandle(destination_);
[email protected]0b2294d32013-08-02 00:46:361072 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:391073 ASSERT_EQ(
1074 ERR_IO_PENDING,
1075 handle->RequestStream(/*requires_confirmation=*/false,
1076 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]0b2294d32013-08-02 00:46:361077
1078 // Close a stream and ensure I can now open a new one.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521079 quic::QuicStreamId stream_id = streams[0]->id();
jri7e636642016-01-14 06:57:081080 session_->CloseStream(stream_id);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521081 quic::QuicRstStreamFrame rst1(quic::kInvalidControlFrameId, stream_id,
1082 quic::QUIC_STREAM_NO_ERROR, 0);
jri7e636642016-01-14 06:57:081083 session_->OnRstStream(rst1);
[email protected]0b2294d32013-08-02 00:46:361084 ASSERT_TRUE(callback.have_result());
robpercival214763f2016-07-01 23:27:011085 EXPECT_THAT(callback.WaitForResult(), IsOk());
rch1bcfddf22017-06-03 00:26:291086 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
[email protected]0b2294d32013-08-02 00:46:361087}
1088
ckrasic4f9d88d2015-07-22 22:23:161089TEST_P(QuicChromiumClientSessionTest, GoAwayReceived) {
fayang3bcb8b502016-12-07 21:44:371090 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521091 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361092 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371093 MockWrite writes[] = {
1094 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011095 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081096 Initialize();
[email protected]8ba81212013-05-03 13:11:481097 CompleteCryptoHandshake();
[email protected]9db443912013-02-25 05:27:031098
1099 // After receiving a GoAway, I should no longer be able to create outgoing
1100 // streams.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521101 session_->connection()->OnGoAwayFrame(
1102 quic::QuicGoAwayFrame(quic::kInvalidControlFrameId,
1103 quic::QUIC_PEER_GOING_AWAY, 1u, "Going away."));
Fan Yang5a3bddf2018-10-12 10:05:501104 EXPECT_EQ(nullptr, QuicChromiumClientSessionPeer::CreateOutgoingStream(
Ramin Halavatif7788ea2018-02-26 07:02:571105 session_.get()));
[email protected]9db443912013-02-25 05:27:031106}
1107
ckrasic4f9d88d2015-07-22 22:23:161108TEST_P(QuicChromiumClientSessionTest, CanPool) {
fayang3bcb8b502016-12-07 21:44:371109 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521110 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361111 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371112 MockWrite writes[] = {
1113 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011114 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081115 Initialize();
[email protected]f21ec372014-07-02 07:15:121116 // Load a cert that is valid for:
1117 // www.example.org
1118 // mail.example.org
1119 // www.example.com
[email protected]f21ec372014-07-02 07:15:121120
[email protected]f21ec372014-07-02 07:15:121121 ProofVerifyDetailsChromium details;
1122 details.cert_verify_result.verified_cert =
[email protected]5db452202014-08-19 05:22:151123 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
dcheng4227c6d2014-08-25 23:58:181124 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]f21ec372014-07-02 07:15:121125
[email protected]f21ec372014-07-02 07:15:121126 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081127 session_->OnProofVerifyDetailsAvailable(details);
[email protected]f21ec372014-07-02 07:15:121128
Paul Jensen8e3c5d32018-02-19 17:06:331129 EXPECT_TRUE(
1130 session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, SocketTag()));
1131 EXPECT_FALSE(
1132 session_->CanPool("www.example.org", PRIVACY_MODE_ENABLED, SocketTag()));
1133#if defined(OS_ANDROID)
1134 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
1135 SocketTag tag2(getuid(), 0x87654321);
1136 EXPECT_FALSE(
1137 session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag1));
1138 EXPECT_FALSE(
1139 session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag2));
1140#endif
1141 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
1142 SocketTag()));
1143 EXPECT_TRUE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
1144 SocketTag()));
1145 EXPECT_FALSE(
1146 session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED, SocketTag()));
[email protected]f21ec372014-07-02 07:15:121147}
1148
ckrasic4f9d88d2015-07-22 22:23:161149TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithTlsChannelId) {
fayang3bcb8b502016-12-07 21:44:371150 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521151 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361152 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371153 MockWrite writes[] = {
1154 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011155 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081156 Initialize();
[email protected]f21ec372014-07-02 07:15:121157 // Load a cert that is valid for:
1158 // www.example.org
1159 // mail.example.org
1160 // www.example.com
[email protected]f21ec372014-07-02 07:15:121161
[email protected]f21ec372014-07-02 07:15:121162 ProofVerifyDetailsChromium details;
1163 details.cert_verify_result.verified_cert =
[email protected]5db452202014-08-19 05:22:151164 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
dcheng4227c6d2014-08-25 23:58:181165 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]f21ec372014-07-02 07:15:121166
[email protected]f21ec372014-07-02 07:15:121167 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081168 session_->OnProofVerifyDetailsAvailable(details);
1169 QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
Nick Harpere45fe4fc2017-07-13 00:34:581170 session_->OverrideChannelIDSent();
[email protected]f21ec372014-07-02 07:15:121171
Paul Jensen8e3c5d32018-02-19 17:06:331172 EXPECT_TRUE(
1173 session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, SocketTag()));
1174 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
1175 SocketTag()));
1176 EXPECT_FALSE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
1177 SocketTag()));
1178 EXPECT_FALSE(
1179 session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED, SocketTag()));
[email protected]f21ec372014-07-02 07:15:121180}
1181
ckrasic4f9d88d2015-07-22 22:23:161182TEST_P(QuicChromiumClientSessionTest, ConnectionNotPooledWithDifferentPin) {
fayang3bcb8b502016-12-07 21:44:371183 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521184 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361185 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371186 MockWrite writes[] = {
1187 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011188 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081189 Initialize();
1190
Hiroki Nakagawa4e4967bcb2018-10-11 04:09:511191 uint8_t primary_pin = 1;
1192 uint8_t backup_pin = 2;
1193 uint8_t bad_pin = 3;
1194 AddPin(&transport_security_state_, "mail.example.org", primary_pin,
1195 backup_pin);
[email protected]5db452202014-08-19 05:22:151196
1197 ProofVerifyDetailsChromium details;
1198 details.cert_verify_result.verified_cert =
1199 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1200 details.cert_verify_result.is_issued_by_known_root = true;
1201 details.cert_verify_result.public_key_hashes.push_back(
1202 GetTestHashValue(bad_pin));
1203
dcheng4227c6d2014-08-25 23:58:181204 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:151205
[email protected]5db452202014-08-19 05:22:151206 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081207 session_->OnProofVerifyDetailsAvailable(details);
Hiroki Nakagawa4e4967bcb2018-10-11 04:09:511208 QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
Nick Harpere45fe4fc2017-07-13 00:34:581209 session_->OverrideChannelIDSent();
[email protected]5db452202014-08-19 05:22:151210
Hiroki Nakagawa4e4967bcb2018-10-11 04:09:511211 EXPECT_FALSE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
1212 SocketTag()));
[email protected]5db452202014-08-19 05:22:151213}
1214
ckrasic4f9d88d2015-07-22 22:23:161215TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithMatchingPin) {
fayang3bcb8b502016-12-07 21:44:371216 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521217 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361218 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371219 MockWrite writes[] = {
1220 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011221 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081222 Initialize();
1223
Hiroki Nakagawa4e4967bcb2018-10-11 04:09:511224 uint8_t primary_pin = 1;
1225 uint8_t backup_pin = 2;
1226 AddPin(&transport_security_state_, "mail.example.org", primary_pin,
1227 backup_pin);
[email protected]5db452202014-08-19 05:22:151228
1229 ProofVerifyDetailsChromium details;
1230 details.cert_verify_result.verified_cert =
1231 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1232 details.cert_verify_result.is_issued_by_known_root = true;
Hiroki Nakagawa4e4967bcb2018-10-11 04:09:511233 details.cert_verify_result.public_key_hashes.push_back(
1234 GetTestHashValue(primary_pin));
[email protected]5db452202014-08-19 05:22:151235
dcheng4227c6d2014-08-25 23:58:181236 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:151237
[email protected]5db452202014-08-19 05:22:151238 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081239 session_->OnProofVerifyDetailsAvailable(details);
1240 QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
Nick Harpere45fe4fc2017-07-13 00:34:581241 session_->OverrideChannelIDSent();
[email protected]5db452202014-08-19 05:22:151242
Paul Jensen8e3c5d32018-02-19 17:06:331243 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
1244 SocketTag()));
jri7e636642016-01-14 06:57:081245}
1246
1247TEST_P(QuicChromiumClientSessionTest, MigrateToSocket) {
fayang3bcb8b502016-12-07 21:44:371248 MockRead old_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521249 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361250 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371251 MockWrite old_writes[] = {
1252 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011253 socket_data_.reset(new SequencedSocketData(old_reads, old_writes));
jri7e636642016-01-14 06:57:081254 Initialize();
1255 CompleteCryptoHandshake();
1256
1257 char data[] = "ABCD";
Ryan Hamilton8d9ee76e2018-05-29 23:52:521258 std::unique_ptr<quic::QuicEncryptedPacket> client_ping;
1259 std::unique_ptr<quic::QuicEncryptedPacket> ack_and_data_out;
1260 client_ping = client_maker_.MakeAckAndPingPacket(2, false, 1, 1, 1);
1261 ack_and_data_out = client_maker_.MakeDataPacket(3, 5, false, false, 0,
1262 quic::QuicStringPiece(data));
1263 std::unique_ptr<quic::QuicEncryptedPacket> server_ping(
alyssar2adf3ac2016-05-03 17:12:581264 server_maker_.MakePingPacket(1, /*include_version=*/false));
alyssar2adf3ac2016-05-03 17:12:581265 MockRead reads[] = {
1266 MockRead(SYNCHRONOUS, server_ping->data(), server_ping->length(), 0),
1267 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
1268 MockWrite writes[] = {
1269 MockWrite(SYNCHRONOUS, client_ping->data(), client_ping->length(), 2),
1270 MockWrite(SYNCHRONOUS, ack_and_data_out->data(),
1271 ack_and_data_out->length(), 3)};
Ryan Sleevib8d7ea02018-05-07 20:01:011272 StaticSocketDataProvider socket_data(reads, writes);
jri7e636642016-01-14 06:57:081273 socket_factory_.AddSocketDataProvider(&socket_data);
jri7e636642016-01-14 06:57:081274 // Create connected socket.
danakjad1777e2016-04-16 00:56:421275 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081276 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191277 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011278 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081279
1280 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421281 std::unique_ptr<QuicChromiumPacketReader> new_reader(
1282 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1283 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521284 quic::QuicTime::Delta::FromMilliseconds(
danakjad1777e2016-04-16 00:56:421285 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201286 bound_test_net_log_.bound()));
Zhongyi Shid3d5f502018-08-10 00:22:221287 new_reader->StartReading();
jried79618b2016-07-02 03:18:521288 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1289 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081290
1291 // Migrate session.
jri9f303712016-09-13 01:10:221292 EXPECT_TRUE(session_->MigrateToSocket(
1293 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1294 // Spin message loop to complete migration.
1295 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081296
1297 // Write data to session.
Ramin Halavatif7788ea2018-02-26 07:02:571298 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501299 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
jri7e636642016-01-14 06:57:081300 struct iovec iov[1];
1301 iov[0].iov_base = data;
1302 iov[0].iov_len = 4;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521303 quic::test::QuicStreamPeer::SendBuffer(stream).SaveStreamData(iov, 1, 0, 4);
1304 quic::test::QuicStreamPeer::SetStreamBytesWritten(4, stream);
1305 session_->WritevData(stream, stream->id(), 4, 0, quic::NO_FIN);
jri7e636642016-01-14 06:57:081306
1307 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1308 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1309}
1310
1311TEST_P(QuicChromiumClientSessionTest, MigrateToSocketMaxReaders) {
fayang3bcb8b502016-12-07 21:44:371312 MockRead old_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521313 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361314 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371315 MockWrite old_writes[] = {
1316 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011317 socket_data_.reset(new SequencedSocketData(old_reads, old_writes));
jri7e636642016-01-14 06:57:081318 Initialize();
1319 CompleteCryptoHandshake();
1320
1321 for (size_t i = 0; i < kMaxReadersPerQuicSession; ++i) {
1322 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521323 std::unique_ptr<quic::QuicEncryptedPacket> ping_out(
fayang3bcb8b502016-12-07 21:44:371324 client_maker_.MakePingPacket(i + 2, /*include_version=*/true));
jri7e636642016-01-14 06:57:081325 MockWrite writes[] = {
1326 MockWrite(SYNCHRONOUS, ping_out->data(), ping_out->length(), i + 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011327 StaticSocketDataProvider socket_data(reads, writes);
jri7e636642016-01-14 06:57:081328 socket_factory_.AddSocketDataProvider(&socket_data);
1329
1330 // Create connected socket.
danakjad1777e2016-04-16 00:56:421331 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081332 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191333 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011334 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081335
1336 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421337 std::unique_ptr<QuicChromiumPacketReader> new_reader(
rcha02807b42016-01-29 21:56:151338 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1339 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521340 quic::QuicTime::Delta::FromMilliseconds(
rcha02807b42016-01-29 21:56:151341 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201342 bound_test_net_log_.bound()));
Zhongyi Shid3d5f502018-08-10 00:22:221343 new_reader->StartReading();
jried79618b2016-07-02 03:18:521344 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1345 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081346
1347 // Migrate session.
1348 if (i < kMaxReadersPerQuicSession - 1) {
jri9f303712016-09-13 01:10:221349 EXPECT_TRUE(session_->MigrateToSocket(
1350 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1351 // Spin message loop to complete migration.
1352 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081353 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1354 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1355 } else {
1356 // Max readers exceeded.
jri9f303712016-09-13 01:10:221357 EXPECT_FALSE(session_->MigrateToSocket(
1358 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
Zhongyi Shid3d5f502018-08-10 00:22:221359 EXPECT_TRUE(socket_data.AllReadDataConsumed());
jri7e636642016-01-14 06:57:081360 EXPECT_FALSE(socket_data.AllWriteDataConsumed());
1361 }
1362 }
1363}
1364
1365TEST_P(QuicChromiumClientSessionTest, MigrateToSocketReadError) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521366 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361367 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521368 std::unique_ptr<quic::QuicEncryptedPacket> client_ping;
1369 client_ping = client_maker_.MakeAckAndPingPacket(2, false, 1, 1, 1);
1370 std::unique_ptr<quic::QuicEncryptedPacket> server_ping(
alyssar2adf3ac2016-05-03 17:12:581371 server_maker_.MakePingPacket(1, /*include_version=*/false));
fayang3bcb8b502016-12-07 21:44:371372 MockWrite old_writes[] = {
1373 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 0)};
jri7e636642016-01-14 06:57:081374 MockRead old_reads[] = {
jri7e636642016-01-14 06:57:081375 MockRead(ASYNC, ERR_IO_PENDING, 1), // causes reading to pause.
1376 MockRead(ASYNC, ERR_NETWORK_CHANGED, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011377 socket_data_.reset(new SequencedSocketData(old_reads, old_writes));
jri7e636642016-01-14 06:57:081378 Initialize();
1379 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081380 MockWrite writes[] = {
alyssar2adf3ac2016-05-03 17:12:581381 MockWrite(SYNCHRONOUS, client_ping->data(), client_ping->length(), 1)};
jri7e636642016-01-14 06:57:081382 MockRead new_reads[] = {
alyssar2adf3ac2016-05-03 17:12:581383 MockRead(SYNCHRONOUS, server_ping->data(), server_ping->length(), 0),
jri7e636642016-01-14 06:57:081384 MockRead(ASYNC, ERR_IO_PENDING, 2), // pause reading.
alyssar2adf3ac2016-05-03 17:12:581385 MockRead(ASYNC, server_ping->data(), server_ping->length(), 3),
jri7e636642016-01-14 06:57:081386 MockRead(ASYNC, ERR_IO_PENDING, 4), // pause reading
1387 MockRead(ASYNC, ERR_NETWORK_CHANGED, 5)};
Ryan Sleevib8d7ea02018-05-07 20:01:011388 SequencedSocketData new_socket_data(new_reads, writes);
jri7e636642016-01-14 06:57:081389 socket_factory_.AddSocketDataProvider(&new_socket_data);
1390
1391 // Create connected socket.
danakjad1777e2016-04-16 00:56:421392 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081393 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191394 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011395 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081396
1397 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421398 std::unique_ptr<QuicChromiumPacketReader> new_reader(
1399 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1400 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521401 quic::QuicTime::Delta::FromMilliseconds(
danakjad1777e2016-04-16 00:56:421402 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201403 bound_test_net_log_.bound()));
Zhongyi Shid3d5f502018-08-10 00:22:221404 new_reader->StartReading();
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
Zhongyi Shi5068bb02018-08-03 02:44:091433TEST_P(QuicChromiumClientSessionTest, DetectPathDegradingDuringHandshake) {
1434 migrate_session_early_v2_ = true;
1435
1436 MockQuicData quic_data;
1437 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
1438 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
1439 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(2));
1440 quic_data.AddSocketDataToFactory(&socket_factory_);
1441
1442 // Set the crypto handshake mode to cold start and send CHLO packets.
1443 crypto_client_stream_factory_.set_handshake_mode(
1444 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
1445 Initialize();
1446
1447 session_->CryptoConnect(callback_.callback());
1448
1449 // Check retransmission alarm is set after sending the initial CHLO packet.
1450 quic::QuicAlarm* retransmission_alarm =
1451 quic::test::QuicConnectionPeer::GetRetransmissionAlarm(
1452 session_->connection());
1453 EXPECT_TRUE(retransmission_alarm->IsSet());
1454 quic::QuicTime retransmission_time = retransmission_alarm->deadline();
1455
1456 // Check path degrading alarm is set after sending the initial CHLO packet.
1457 quic::QuicAlarm* path_degrading_alarm =
1458 quic::test::QuicConnectionPeer::GetPathDegradingAlarm(
1459 session_->connection());
1460 EXPECT_TRUE(path_degrading_alarm->IsSet());
1461 quic::QuicTime path_degrading_time = path_degrading_alarm->deadline();
1462 EXPECT_LE(retransmission_time, path_degrading_time);
1463
1464 // Do not create outgoing stream since encryption is not established.
1465 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
1466 session_->CreateHandle(destination_);
1467 TestCompletionCallback callback;
1468 EXPECT_TRUE(handle->IsConnected());
1469 EXPECT_FALSE(handle->IsCryptoHandshakeConfirmed());
1470 EXPECT_EQ(
1471 ERR_IO_PENDING,
1472 handle->RequestStream(/*require_handshake_confirmation=*/true,
1473 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
1474
1475 // Fire the retransmission alarm to retransmit the crypto packet.
1476 quic::QuicTime::Delta delay = retransmission_time - clock_.ApproximateNow();
1477 clock_.AdvanceTime(delay);
1478 alarm_factory_.FireAlarm(retransmission_alarm);
1479
1480 // Fire the path degrading alarm to notify session that path is degrading
1481 // during crypto handshake.
1482 delay = path_degrading_time - clock_.ApproximateNow();
1483 clock_.AdvanceTime(delay);
1484 EXPECT_CALL(*session_.get(), OnPathDegrading());
1485 alarm_factory_.FireAlarm(path_degrading_alarm);
1486
1487 EXPECT_TRUE(session_->connection()->IsPathDegrading());
1488 EXPECT_TRUE(quic_data.AllReadDataConsumed());
1489 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
1490}
1491
Yixin Wangf65c4b6d2018-03-08 22:37:401492TEST_P(QuicChromiumClientSessionTest, RetransmittableOnWireTimeout) {
1493 migrate_session_early_v2_ = true;
1494
1495 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:431496 quic_data.AddWrite(SYNCHRONOUS,
1497 client_maker_.MakeInitialSettingsPacket(1, nullptr));
1498 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(2, true));
1499 quic_data.AddRead(ASYNC, server_maker_.MakeAckPacket(1, 2, 1, 1, false));
Yixin Wangf65c4b6d2018-03-08 22:37:401500
Zhongyi Shi32f2fd02018-04-16 18:23:431501 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(3, false));
Yixin Wangf65c4b6d2018-03-08 22:37:401502 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1503 quic_data.AddRead(ASYNC, OK); // EOF
1504 quic_data.AddSocketDataToFactory(&socket_factory_);
1505
1506 Initialize();
1507 CompleteCryptoHandshake();
1508
Ryan Hamilton8d9ee76e2018-05-29 23:52:521509 EXPECT_EQ(quic::QuicTime::Delta::FromMilliseconds(100),
Yixin Wangf65c4b6d2018-03-08 22:37:401510 session_->connection()->retransmittable_on_wire_timeout());
1511
1512 // Open a stream since the connection only sends PINGs to keep a
1513 // retransmittable packet on the wire if there's an open stream.
Fan Yang5a3bddf2018-10-12 10:05:501514 EXPECT_TRUE(
1515 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
Yixin Wangf65c4b6d2018-03-08 22:37:401516
Ryan Hamilton8d9ee76e2018-05-29 23:52:521517 quic::QuicAlarm* alarm =
1518 quic::test::QuicConnectionPeer::GetRetransmittableOnWireAlarm(
1519 session_->connection());
Yixin Wangf65c4b6d2018-03-08 22:37:401520 EXPECT_FALSE(alarm->IsSet());
1521
1522 // Send PING, which will be ACKed by the server. After the ACK, there will be
1523 // no retransmittable packets on the wire, so the alarm should be set.
1524 session_->SendPing();
1525 base::RunLoop().RunUntilIdle();
1526 EXPECT_TRUE(alarm->IsSet());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521527 EXPECT_EQ(
1528 clock_.ApproximateNow() + quic::QuicTime::Delta::FromMilliseconds(100),
1529 alarm->deadline());
Yixin Wangf65c4b6d2018-03-08 22:37:401530
1531 // Advance clock and simulate the alarm firing. This should cause a PING to be
1532 // sent.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521533 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(100));
Yixin Wangf65c4b6d2018-03-08 22:37:401534 alarm_factory_.FireAlarm(alarm);
1535 base::RunLoop().RunUntilIdle();
1536
1537 quic_data.Resume();
1538 EXPECT_TRUE(quic_data.AllReadDataConsumed());
1539 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
1540}
1541
[email protected]dd3fd0e2012-11-04 05:14:401542} // namespace
1543} // namespace test
1544} // namespace net