1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/http/http_server_properties.h"
6
7 #include <memory>
8 #include <string>
9 #include <vector>
10
11 #include "base/check.h"
12 #include "base/feature_list.h"
13 #include "base/functional/bind.h"
14 #include "base/functional/callback.h"
15 #include "base/json/json_writer.h"
16 #include "base/memory/raw_ptr.h"
17 #include "base/run_loop.h"
18 #include "base/test/scoped_feature_list.h"
19 #include "base/test/simple_test_clock.h"
20 #include "base/test/task_environment.h"
21 #include "base/time/time.h"
22 #include "base/values.h"
23 #include "net/base/features.h"
24 #include "net/base/host_port_pair.h"
25 #include "net/base/ip_address.h"
26 #include "net/base/schemeful_site.h"
27 #include "net/http/http_network_session.h"
28 #include "net/test/test_with_task_environment.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "url/gurl.h"
31
32 namespace net {
33
34 const base::TimeDelta BROKEN_ALT_SVC_EXPIRE_DELAYS[10] = {
35 base::Seconds(300), base::Seconds(600), base::Seconds(1200),
36 base::Seconds(2400), base::Seconds(4800), base::Seconds(9600),
37 base::Seconds(19200), base::Seconds(38400), base::Seconds(76800),
38 base::Seconds(153600),
39 };
40
41 class HttpServerPropertiesPeer {
42 public:
AddBrokenAlternativeServiceWithExpirationTime(HttpServerProperties * impl,const AlternativeService & alternative_service,base::TimeTicks when,const NetworkAnonymizationKey network_anonymization_key=NetworkAnonymizationKey ())43 static void AddBrokenAlternativeServiceWithExpirationTime(
44 HttpServerProperties* impl,
45 const AlternativeService& alternative_service,
46 base::TimeTicks when,
47 const NetworkAnonymizationKey network_anonymization_key =
48 NetworkAnonymizationKey()) {
49 BrokenAlternativeService broken_alternative_service(
50 alternative_service, network_anonymization_key,
51 true /* use_network_anonymization_key */);
52 BrokenAlternativeServiceList::iterator unused_it;
53 impl->broken_alternative_services_.AddToBrokenListAndMap(
54 broken_alternative_service, when, &unused_it);
55 auto it =
56 impl->broken_alternative_services_.recently_broken_alternative_services_
57 .Get(broken_alternative_service);
58 if (it == impl->broken_alternative_services_
59 .recently_broken_alternative_services_.end()) {
60 impl->broken_alternative_services_.recently_broken_alternative_services_
61 .Put(broken_alternative_service, 1);
62 } else {
63 it->second++;
64 }
65 }
66
ExpireBrokenAlternateProtocolMappings(HttpServerProperties * impl)67 static void ExpireBrokenAlternateProtocolMappings(
68 HttpServerProperties* impl) {
69 impl->broken_alternative_services_.ExpireBrokenAlternateProtocolMappings();
70 }
71 };
72
73 namespace {
74
75 // Creates a ServerInfoMapKey without a NetworkAnonymizationKey.
CreateSimpleKey(const url::SchemeHostPort & server)76 HttpServerProperties::ServerInfoMapKey CreateSimpleKey(
77 const url::SchemeHostPort& server) {
78 return HttpServerProperties::ServerInfoMapKey(
79 server, net::NetworkAnonymizationKey(),
80 false /* use_network_anonymization_key */);
81 }
82
83 class HttpServerPropertiesTest : public TestWithTaskEnvironment {
84 protected:
HttpServerPropertiesTest()85 HttpServerPropertiesTest()
86 : TestWithTaskEnvironment(
87 base::test::TaskEnvironment::TimeSource::MOCK_TIME),
88 // Many tests assume partitioning is disabled by default.
89 feature_list_(CreateFeatureListWithPartitioningDisabled()),
90 test_tick_clock_(GetMockTickClock()),
91 impl_(nullptr /* pref_delegate */,
92 nullptr /* net_log */,
93 test_tick_clock_,
94 &test_clock_) {
95 // Set |test_clock_| to some random time.
96 test_clock_.Advance(base::Seconds(12345));
97
98 SchemefulSite site1(GURL("https://foo.test/"));
99 network_anonymization_key1_ =
100 NetworkAnonymizationKey::CreateSameSite(site1);
101 SchemefulSite site2(GURL("https://bar.test/"));
102 network_anonymization_key2_ =
103 NetworkAnonymizationKey::CreateSameSite(site2);
104 }
105
106 // This is a little awkward, but need to create and configure the
107 // ScopedFeatureList before creating the HttpServerProperties.
108 static std::unique_ptr<base::test::ScopedFeatureList>
CreateFeatureListWithPartitioningDisabled()109 CreateFeatureListWithPartitioningDisabled() {
110 std::unique_ptr<base::test::ScopedFeatureList> feature_list =
111 std::make_unique<base::test::ScopedFeatureList>();
112 feature_list->InitAndDisableFeature(
113 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
114 return feature_list;
115 }
116
HasAlternativeService(const url::SchemeHostPort & origin,const NetworkAnonymizationKey & network_anonymization_key)117 bool HasAlternativeService(
118 const url::SchemeHostPort& origin,
119 const NetworkAnonymizationKey& network_anonymization_key) {
120 const AlternativeServiceInfoVector alternative_service_info_vector =
121 impl_.GetAlternativeServiceInfos(origin, network_anonymization_key);
122 return !alternative_service_info_vector.empty();
123 }
124
SetAlternativeService(const url::SchemeHostPort & origin,const AlternativeService & alternative_service)125 void SetAlternativeService(const url::SchemeHostPort& origin,
126 const AlternativeService& alternative_service) {
127 const base::Time expiration = test_clock_.Now() + base::Days(1);
128 if (alternative_service.protocol == kProtoQUIC) {
129 impl_.SetQuicAlternativeService(origin, NetworkAnonymizationKey(),
130 alternative_service, expiration,
131 DefaultSupportedQuicVersions());
132 } else {
133 impl_.SetHttp2AlternativeService(origin, NetworkAnonymizationKey(),
134 alternative_service, expiration);
135 }
136 }
137
MarkBrokenAndLetExpireAlternativeServiceNTimes(const AlternativeService & alternative_service,int num_times)138 void MarkBrokenAndLetExpireAlternativeServiceNTimes(
139 const AlternativeService& alternative_service,
140 int num_times) {}
141
142 std::unique_ptr<base::test::ScopedFeatureList> feature_list_;
143
144 raw_ptr<const base::TickClock> test_tick_clock_;
145 base::SimpleTestClock test_clock_;
146
147 // Two different non-empty network isolation keys for use in tests that need
148 // them.
149 NetworkAnonymizationKey network_anonymization_key1_;
150 NetworkAnonymizationKey network_anonymization_key2_;
151
152 HttpServerProperties impl_;
153 };
154
TEST_F(HttpServerPropertiesTest,SetSupportsSpdy)155 TEST_F(HttpServerPropertiesTest, SetSupportsSpdy) {
156 // Check spdy servers are correctly set with SchemeHostPort key.
157 url::SchemeHostPort https_www_server("https", "www.google.com", 443);
158 url::SchemeHostPort http_photo_server("http", "photos.google.com", 80);
159 url::SchemeHostPort https_mail_server("https", "mail.google.com", 443);
160 // Servers with port equal to default port in scheme will drop port components
161 // when calling Serialize().
162
163 url::SchemeHostPort http_google_server("http", "www.google.com", 443);
164 url::SchemeHostPort https_photos_server("https", "photos.google.com", 443);
165 url::SchemeHostPort valid_google_server((GURL("https://www.google.com")));
166
167 impl_.SetSupportsSpdy(https_www_server, NetworkAnonymizationKey(), true);
168 impl_.SetSupportsSpdy(http_photo_server, NetworkAnonymizationKey(), true);
169 impl_.SetSupportsSpdy(https_mail_server, NetworkAnonymizationKey(), false);
170 EXPECT_TRUE(
171 impl_.GetSupportsSpdy(https_www_server, NetworkAnonymizationKey()));
172 EXPECT_TRUE(impl_.SupportsRequestPriority(https_www_server,
173 NetworkAnonymizationKey()));
174 EXPECT_TRUE(
175 impl_.GetSupportsSpdy(http_photo_server, NetworkAnonymizationKey()));
176 EXPECT_TRUE(impl_.SupportsRequestPriority(http_photo_server,
177 NetworkAnonymizationKey()));
178 EXPECT_FALSE(
179 impl_.GetSupportsSpdy(https_mail_server, NetworkAnonymizationKey()));
180 EXPECT_FALSE(impl_.SupportsRequestPriority(https_mail_server,
181 NetworkAnonymizationKey()));
182 EXPECT_FALSE(
183 impl_.GetSupportsSpdy(http_google_server, NetworkAnonymizationKey()));
184 EXPECT_FALSE(impl_.SupportsRequestPriority(http_google_server,
185 NetworkAnonymizationKey()));
186 EXPECT_FALSE(
187 impl_.GetSupportsSpdy(https_photos_server, NetworkAnonymizationKey()));
188 EXPECT_FALSE(impl_.SupportsRequestPriority(https_photos_server,
189 NetworkAnonymizationKey()));
190 EXPECT_TRUE(
191 impl_.GetSupportsSpdy(valid_google_server, NetworkAnonymizationKey()));
192 EXPECT_TRUE(impl_.SupportsRequestPriority(valid_google_server,
193 NetworkAnonymizationKey()));
194
195 // Flip values of two servers.
196 impl_.SetSupportsSpdy(https_www_server, NetworkAnonymizationKey(), false);
197 impl_.SetSupportsSpdy(https_mail_server, NetworkAnonymizationKey(), true);
198 EXPECT_FALSE(
199 impl_.GetSupportsSpdy(https_www_server, NetworkAnonymizationKey()));
200 EXPECT_FALSE(impl_.SupportsRequestPriority(https_www_server,
201 NetworkAnonymizationKey()));
202 EXPECT_TRUE(
203 impl_.GetSupportsSpdy(https_mail_server, NetworkAnonymizationKey()));
204 EXPECT_TRUE(impl_.SupportsRequestPriority(https_mail_server,
205 NetworkAnonymizationKey()));
206 }
207
TEST_F(HttpServerPropertiesTest,SetSupportsSpdyWebSockets)208 TEST_F(HttpServerPropertiesTest, SetSupportsSpdyWebSockets) {
209 // The https and wss servers should be treated as the same server, as should
210 // the http and ws servers.
211 url::SchemeHostPort https_server("https", "www.test.com", 443);
212 url::SchemeHostPort wss_server("wss", "www.test.com", 443);
213 url::SchemeHostPort http_server("http", "www.test.com", 443);
214 url::SchemeHostPort ws_server("ws", "www.test.com", 443);
215
216 EXPECT_FALSE(impl_.GetSupportsSpdy(https_server, NetworkAnonymizationKey()));
217 EXPECT_FALSE(impl_.GetSupportsSpdy(wss_server, NetworkAnonymizationKey()));
218 EXPECT_FALSE(impl_.GetSupportsSpdy(http_server, NetworkAnonymizationKey()));
219 EXPECT_FALSE(impl_.GetSupportsSpdy(ws_server, NetworkAnonymizationKey()));
220
221 impl_.SetSupportsSpdy(wss_server, NetworkAnonymizationKey(), true);
222 EXPECT_TRUE(impl_.GetSupportsSpdy(https_server, NetworkAnonymizationKey()));
223 EXPECT_TRUE(impl_.GetSupportsSpdy(wss_server, NetworkAnonymizationKey()));
224 EXPECT_FALSE(impl_.GetSupportsSpdy(http_server, NetworkAnonymizationKey()));
225 EXPECT_FALSE(impl_.GetSupportsSpdy(ws_server, NetworkAnonymizationKey()));
226
227 impl_.SetSupportsSpdy(http_server, NetworkAnonymizationKey(), true);
228 EXPECT_TRUE(impl_.GetSupportsSpdy(https_server, NetworkAnonymizationKey()));
229 EXPECT_TRUE(impl_.GetSupportsSpdy(wss_server, NetworkAnonymizationKey()));
230 EXPECT_TRUE(impl_.GetSupportsSpdy(http_server, NetworkAnonymizationKey()));
231 EXPECT_TRUE(impl_.GetSupportsSpdy(ws_server, NetworkAnonymizationKey()));
232
233 impl_.SetSupportsSpdy(https_server, NetworkAnonymizationKey(), false);
234 EXPECT_FALSE(impl_.GetSupportsSpdy(https_server, NetworkAnonymizationKey()));
235 EXPECT_FALSE(impl_.GetSupportsSpdy(wss_server, NetworkAnonymizationKey()));
236 EXPECT_TRUE(impl_.GetSupportsSpdy(http_server, NetworkAnonymizationKey()));
237 EXPECT_TRUE(impl_.GetSupportsSpdy(ws_server, NetworkAnonymizationKey()));
238
239 impl_.SetSupportsSpdy(ws_server, NetworkAnonymizationKey(), false);
240 EXPECT_FALSE(impl_.GetSupportsSpdy(https_server, NetworkAnonymizationKey()));
241 EXPECT_FALSE(impl_.GetSupportsSpdy(wss_server, NetworkAnonymizationKey()));
242 EXPECT_FALSE(impl_.GetSupportsSpdy(http_server, NetworkAnonymizationKey()));
243 EXPECT_FALSE(impl_.GetSupportsSpdy(ws_server, NetworkAnonymizationKey()));
244 }
245
TEST_F(HttpServerPropertiesTest,SetSupportsSpdyWithNetworkIsolationKey)246 TEST_F(HttpServerPropertiesTest, SetSupportsSpdyWithNetworkIsolationKey) {
247 const url::SchemeHostPort kServer("https", "foo.test", 443);
248
249 EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, network_anonymization_key1_));
250 EXPECT_FALSE(
251 impl_.SupportsRequestPriority(kServer, network_anonymization_key1_));
252 EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
253 EXPECT_FALSE(
254 impl_.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
255
256 // Without network isolation keys enabled for HttpServerProperties, passing in
257 // a NetworkAnonymizationKey should have no effect on behavior.
258 for (const auto& network_anonymization_key_to_set :
259 {NetworkAnonymizationKey(), network_anonymization_key1_}) {
260 impl_.SetSupportsSpdy(kServer, network_anonymization_key_to_set, true);
261 EXPECT_TRUE(impl_.GetSupportsSpdy(kServer, network_anonymization_key1_));
262 EXPECT_TRUE(
263 impl_.SupportsRequestPriority(kServer, network_anonymization_key1_));
264 EXPECT_TRUE(impl_.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
265 EXPECT_TRUE(
266 impl_.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
267
268 impl_.SetSupportsSpdy(kServer, network_anonymization_key_to_set, false);
269 EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, network_anonymization_key1_));
270 EXPECT_FALSE(
271 impl_.SupportsRequestPriority(kServer, network_anonymization_key1_));
272 EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
273 EXPECT_FALSE(
274 impl_.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
275 }
276
277 // With network isolation keys enabled for HttpServerProperties, the
278 // NetworkAnonymizationKey argument should be respected.
279
280 base::test::ScopedFeatureList feature_list;
281 feature_list.InitAndEnableFeature(
282 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
283 // Since HttpServerProperties caches the feature value, have to create a new
284 // one.
285 HttpServerProperties properties(nullptr /* pref_delegate */,
286 nullptr /* net_log */, test_tick_clock_,
287 &test_clock_);
288
289 EXPECT_FALSE(
290 properties.GetSupportsSpdy(kServer, network_anonymization_key1_));
291 EXPECT_FALSE(
292 properties.SupportsRequestPriority(kServer, network_anonymization_key1_));
293 EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
294 EXPECT_FALSE(
295 properties.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
296
297 properties.SetSupportsSpdy(kServer, network_anonymization_key1_, true);
298 EXPECT_TRUE(properties.GetSupportsSpdy(kServer, network_anonymization_key1_));
299 EXPECT_TRUE(
300 properties.SupportsRequestPriority(kServer, network_anonymization_key1_));
301 EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
302 EXPECT_FALSE(
303 properties.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
304
305 properties.SetSupportsSpdy(kServer, NetworkAnonymizationKey(), true);
306 EXPECT_TRUE(properties.GetSupportsSpdy(kServer, network_anonymization_key1_));
307 EXPECT_TRUE(
308 properties.SupportsRequestPriority(kServer, network_anonymization_key1_));
309 EXPECT_TRUE(properties.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
310 EXPECT_TRUE(
311 properties.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
312
313 properties.SetSupportsSpdy(kServer, network_anonymization_key1_, false);
314 EXPECT_FALSE(
315 properties.GetSupportsSpdy(kServer, network_anonymization_key1_));
316 EXPECT_FALSE(
317 properties.SupportsRequestPriority(kServer, network_anonymization_key1_));
318 EXPECT_TRUE(properties.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
319 EXPECT_TRUE(
320 properties.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
321
322 properties.SetSupportsSpdy(kServer, NetworkAnonymizationKey(), false);
323 EXPECT_FALSE(
324 properties.GetSupportsSpdy(kServer, network_anonymization_key1_));
325 EXPECT_FALSE(
326 properties.SupportsRequestPriority(kServer, network_anonymization_key1_));
327 EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
328 EXPECT_FALSE(
329 properties.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
330 }
331
TEST_F(HttpServerPropertiesTest,LoadSupportsSpdy)332 TEST_F(HttpServerPropertiesTest, LoadSupportsSpdy) {
333 HttpServerProperties::ServerInfo supports_spdy;
334 supports_spdy.supports_spdy = true;
335 HttpServerProperties::ServerInfo no_spdy;
336 no_spdy.supports_spdy = false;
337
338 url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
339 url::SchemeHostPort spdy_server_photos("https", "photos.google.com", 443);
340 url::SchemeHostPort spdy_server_docs("https", "docs.google.com", 443);
341 url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
342
343 // Check by initializing empty spdy servers.
344 std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers =
345 std::make_unique<HttpServerProperties::ServerInfoMap>();
346 impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers));
347 EXPECT_FALSE(
348 impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
349
350 // Check by initializing www.google.com:443 and photos.google.com:443 as spdy
351 // servers.
352 std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers1 =
353 std::make_unique<HttpServerProperties::ServerInfoMap>();
354 spdy_servers1->Put(CreateSimpleKey(spdy_server_google), supports_spdy);
355 spdy_servers1->Put(CreateSimpleKey(spdy_server_photos), no_spdy);
356 impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers1));
357 // Note: these calls affect MRU order.
358 EXPECT_TRUE(
359 impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
360 EXPECT_FALSE(
361 impl_.GetSupportsSpdy(spdy_server_photos, NetworkAnonymizationKey()));
362
363 // Verify google and photos are in the list in MRU order.
364 ASSERT_EQ(2U, impl_.server_info_map_for_testing().size());
365 auto it = impl_.server_info_map_for_testing().begin();
366 EXPECT_EQ(spdy_server_photos, it->first.server);
367 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
368 ASSERT_TRUE(it->second.supports_spdy.has_value());
369 EXPECT_FALSE(*it->second.supports_spdy);
370 ++it;
371 EXPECT_EQ(spdy_server_google, it->first.server);
372 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
373 ASSERT_TRUE(it->second.supports_spdy.has_value());
374 EXPECT_TRUE(*it->second.supports_spdy);
375
376 // Check by initializing mail.google.com:443 and docs.google.com:443.
377 std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers2 =
378 std::make_unique<HttpServerProperties::ServerInfoMap>();
379 spdy_servers2->Put(CreateSimpleKey(spdy_server_mail), supports_spdy);
380 spdy_servers2->Put(CreateSimpleKey(spdy_server_docs), supports_spdy);
381 impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers2));
382
383 // Verify all the servers are in the list in MRU order. Note that
384 // OnServerInfoLoadedForTesting will put existing spdy server entries in
385 // front of newly added entries.
386 ASSERT_EQ(4U, impl_.server_info_map_for_testing().size());
387 it = impl_.server_info_map_for_testing().begin();
388 EXPECT_EQ(spdy_server_photos, it->first.server);
389 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
390 ASSERT_TRUE(it->second.supports_spdy.has_value());
391 EXPECT_FALSE(*it->second.supports_spdy);
392 ++it;
393 EXPECT_EQ(spdy_server_google, it->first.server);
394 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
395 ASSERT_TRUE(it->second.supports_spdy.has_value());
396 EXPECT_TRUE(*it->second.supports_spdy);
397 ++it;
398 EXPECT_EQ(spdy_server_docs, it->first.server);
399 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
400 ASSERT_TRUE(it->second.supports_spdy.has_value());
401 EXPECT_TRUE(*it->second.supports_spdy);
402 ++it;
403 EXPECT_EQ(spdy_server_mail, it->first.server);
404 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
405 ASSERT_TRUE(it->second.supports_spdy.has_value());
406 EXPECT_TRUE(*it->second.supports_spdy);
407
408 // Check these in reverse MRU order so that MRU order stays the same.
409 EXPECT_TRUE(
410 impl_.GetSupportsSpdy(spdy_server_mail, NetworkAnonymizationKey()));
411 EXPECT_TRUE(
412 impl_.GetSupportsSpdy(spdy_server_docs, NetworkAnonymizationKey()));
413 EXPECT_TRUE(
414 impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
415 EXPECT_FALSE(
416 impl_.GetSupportsSpdy(spdy_server_photos, NetworkAnonymizationKey()));
417
418 // Verify that old values loaded from disk take precedence over newer learned
419 // values and also verify the recency list order is unchanged.
420 std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers3 =
421 std::make_unique<HttpServerProperties::ServerInfoMap>();
422 spdy_servers3->Put(CreateSimpleKey(spdy_server_mail), no_spdy);
423 spdy_servers3->Put(CreateSimpleKey(spdy_server_photos), supports_spdy);
424 impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers3));
425
426 // Verify the entries are in the same order.
427 ASSERT_EQ(4U, impl_.server_info_map_for_testing().size());
428 it = impl_.server_info_map_for_testing().begin();
429 EXPECT_EQ(spdy_server_photos, it->first.server);
430 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
431 ASSERT_TRUE(it->second.supports_spdy.has_value());
432 EXPECT_TRUE(*it->second.supports_spdy);
433 ++it;
434 EXPECT_EQ(spdy_server_google, it->first.server);
435 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
436 ASSERT_TRUE(it->second.supports_spdy.has_value());
437 EXPECT_TRUE(*it->second.supports_spdy);
438 ++it;
439 EXPECT_EQ(spdy_server_docs, it->first.server);
440 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
441 ASSERT_TRUE(it->second.supports_spdy.has_value());
442 EXPECT_TRUE(*it->second.supports_spdy);
443 ++it;
444 EXPECT_EQ(spdy_server_mail, it->first.server);
445 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
446 ASSERT_TRUE(it->second.supports_spdy.has_value());
447 EXPECT_FALSE(*it->second.supports_spdy);
448
449 // Verify photos server doesn't support SPDY and other servers support SPDY.
450 EXPECT_FALSE(
451 impl_.GetSupportsSpdy(spdy_server_mail, NetworkAnonymizationKey()));
452 EXPECT_TRUE(
453 impl_.GetSupportsSpdy(spdy_server_docs, NetworkAnonymizationKey()));
454 EXPECT_TRUE(
455 impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
456 EXPECT_TRUE(
457 impl_.GetSupportsSpdy(spdy_server_photos, NetworkAnonymizationKey()));
458 }
459
TEST_F(HttpServerPropertiesTest,SupportsRequestPriority)460 TEST_F(HttpServerPropertiesTest, SupportsRequestPriority) {
461 url::SchemeHostPort spdy_server_empty("https", std::string(), 443);
462 EXPECT_FALSE(impl_.SupportsRequestPriority(spdy_server_empty,
463 NetworkAnonymizationKey()));
464
465 // Add www.google.com:443 as supporting SPDY.
466 url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
467 impl_.SetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey(), true);
468 EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_google,
469 NetworkAnonymizationKey()));
470
471 // Add mail.google.com:443 as not supporting SPDY.
472 url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
473 EXPECT_FALSE(impl_.SupportsRequestPriority(spdy_server_mail,
474 NetworkAnonymizationKey()));
475
476 // Add docs.google.com:443 as supporting SPDY.
477 url::SchemeHostPort spdy_server_docs("https", "docs.google.com", 443);
478 impl_.SetSupportsSpdy(spdy_server_docs, NetworkAnonymizationKey(), true);
479 EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_docs,
480 NetworkAnonymizationKey()));
481
482 // Add www.youtube.com:443 as supporting QUIC.
483 url::SchemeHostPort youtube_server("https", "www.youtube.com", 443);
484 const AlternativeService alternative_service1(kProtoQUIC, "www.youtube.com",
485 443);
486 SetAlternativeService(youtube_server, alternative_service1);
487 EXPECT_TRUE(
488 impl_.SupportsRequestPriority(youtube_server, NetworkAnonymizationKey()));
489
490 // Add www.example.com:443 with two alternative services, one supporting QUIC.
491 url::SchemeHostPort example_server("https", "www.example.com", 443);
492 const AlternativeService alternative_service2(kProtoHTTP2, "", 443);
493 SetAlternativeService(example_server, alternative_service2);
494 SetAlternativeService(example_server, alternative_service1);
495 EXPECT_TRUE(
496 impl_.SupportsRequestPriority(example_server, NetworkAnonymizationKey()));
497
498 // Verify all the entries are the same after additions.
499 EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_google,
500 NetworkAnonymizationKey()));
501 EXPECT_FALSE(impl_.SupportsRequestPriority(spdy_server_mail,
502 NetworkAnonymizationKey()));
503 EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_docs,
504 NetworkAnonymizationKey()));
505 EXPECT_TRUE(
506 impl_.SupportsRequestPriority(youtube_server, NetworkAnonymizationKey()));
507 EXPECT_TRUE(
508 impl_.SupportsRequestPriority(example_server, NetworkAnonymizationKey()));
509 }
510
TEST_F(HttpServerPropertiesTest,ClearSupportsSpdy)511 TEST_F(HttpServerPropertiesTest, ClearSupportsSpdy) {
512 // Add www.google.com:443 and mail.google.com:443 as supporting SPDY.
513 url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
514 impl_.SetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey(), true);
515 url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
516 impl_.SetSupportsSpdy(spdy_server_mail, NetworkAnonymizationKey(), true);
517
518 EXPECT_TRUE(
519 impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
520 EXPECT_TRUE(
521 impl_.GetSupportsSpdy(spdy_server_mail, NetworkAnonymizationKey()));
522
523 base::RunLoop run_loop;
524 bool callback_invoked_ = false;
525 impl_.Clear(base::BindOnce(
526 [](bool* callback_invoked, base::OnceClosure quit_closure) {
527 *callback_invoked = true;
528 std::move(quit_closure).Run();
529 },
530 &callback_invoked_, run_loop.QuitClosure()));
531 EXPECT_FALSE(
532 impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
533 EXPECT_FALSE(
534 impl_.GetSupportsSpdy(spdy_server_mail, NetworkAnonymizationKey()));
535
536 // Callback should be run asynchronously.
537 EXPECT_FALSE(callback_invoked_);
538 run_loop.Run();
539 EXPECT_TRUE(callback_invoked_);
540 }
541
TEST_F(HttpServerPropertiesTest,MRUOfServerInfoMap)542 TEST_F(HttpServerPropertiesTest, MRUOfServerInfoMap) {
543 url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
544 url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
545
546 // Add www.google.com:443 as supporting SPDY.
547 impl_.SetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey(), true);
548 ASSERT_EQ(1u, impl_.server_info_map_for_testing().size());
549 auto it = impl_.server_info_map_for_testing().begin();
550 ASSERT_EQ(spdy_server_google, it->first.server);
551 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
552
553 // Add mail.google.com:443 as supporting SPDY. Verify mail.google.com:443 and
554 // www.google.com:443 are in the list.
555 impl_.SetSupportsSpdy(spdy_server_mail, NetworkAnonymizationKey(), true);
556 ASSERT_EQ(2u, impl_.server_info_map_for_testing().size());
557 it = impl_.server_info_map_for_testing().begin();
558 ASSERT_EQ(spdy_server_mail, it->first.server);
559 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
560 ++it;
561 ASSERT_EQ(spdy_server_google, it->first.server);
562 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
563
564 // Get www.google.com:443. It should become the most-recently-used server.
565 EXPECT_TRUE(
566 impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
567 ASSERT_EQ(2u, impl_.server_info_map_for_testing().size());
568 it = impl_.server_info_map_for_testing().begin();
569 ASSERT_EQ(spdy_server_google, it->first.server);
570 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
571 ++it;
572 ASSERT_EQ(spdy_server_mail, it->first.server);
573 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
574 }
575
576 typedef HttpServerPropertiesTest AlternateProtocolServerPropertiesTest;
577
TEST_F(AlternateProtocolServerPropertiesTest,Basic)578 TEST_F(AlternateProtocolServerPropertiesTest, Basic) {
579 url::SchemeHostPort test_server("http", "foo", 80);
580 EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
581
582 AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
583 SetAlternativeService(test_server, alternative_service);
584 const AlternativeServiceInfoVector alternative_service_info_vector =
585 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
586 ASSERT_EQ(1u, alternative_service_info_vector.size());
587 EXPECT_EQ(alternative_service,
588 alternative_service_info_vector[0].alternative_service());
589
590 impl_.Clear(base::OnceClosure());
591 EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
592 }
593
TEST_F(AlternateProtocolServerPropertiesTest,ExcludeOrigin)594 TEST_F(AlternateProtocolServerPropertiesTest, ExcludeOrigin) {
595 AlternativeServiceInfoVector alternative_service_info_vector;
596 base::Time expiration = test_clock_.Now() + base::Days(1);
597 // Same hostname, same port, TCP: should be ignored.
598 AlternativeServiceInfo alternative_service_info1 =
599 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
600 AlternativeService(kProtoHTTP2, "foo", 443), expiration);
601 alternative_service_info_vector.push_back(alternative_service_info1);
602 // Different hostname: GetAlternativeServiceInfos should return this one.
603 AlternativeServiceInfo alternative_service_info2 =
604 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
605 AlternativeService(kProtoHTTP2, "bar", 443), expiration);
606 alternative_service_info_vector.push_back(alternative_service_info2);
607 // Different port: GetAlternativeServiceInfos should return this one too.
608 AlternativeServiceInfo alternative_service_info3 =
609 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
610 AlternativeService(kProtoHTTP2, "foo", 80), expiration);
611 alternative_service_info_vector.push_back(alternative_service_info3);
612 // QUIC: GetAlternativeServices should return this one too.
613 AlternativeServiceInfo alternative_service_info4 =
614 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
615 AlternativeService(kProtoQUIC, "foo", 443), expiration,
616 DefaultSupportedQuicVersions());
617 alternative_service_info_vector.push_back(alternative_service_info4);
618
619 url::SchemeHostPort test_server("https", "foo", 443);
620 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
621 alternative_service_info_vector);
622
623 const AlternativeServiceInfoVector alternative_service_info_vector2 =
624 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
625 ASSERT_EQ(3u, alternative_service_info_vector2.size());
626 EXPECT_EQ(alternative_service_info2, alternative_service_info_vector2[0]);
627 EXPECT_EQ(alternative_service_info3, alternative_service_info_vector2[1]);
628 EXPECT_EQ(alternative_service_info4, alternative_service_info_vector2[2]);
629 }
630
TEST_F(AlternateProtocolServerPropertiesTest,Set)631 TEST_F(AlternateProtocolServerPropertiesTest, Set) {
632 // |test_server1| has an alternative service, which will not be
633 // affected by OnServerInfoLoadedForTesting(), because
634 // |server_info_map| does not have an entry for
635 // |test_server1|.
636 url::SchemeHostPort test_server1("http", "foo1", 80);
637 const AlternativeService alternative_service1(kProtoHTTP2, "bar1", 443);
638 const base::Time now = test_clock_.Now();
639 base::Time expiration1 = now + base::Days(1);
640 // 1st entry in the memory.
641 impl_.SetHttp2AlternativeService(test_server1, NetworkAnonymizationKey(),
642 alternative_service1, expiration1);
643
644 // |test_server2| has an alternative service, which will be
645 // overwritten by OnServerInfoLoadedForTesting(), because
646 // |server_info_map| has an entry for |test_server2|.
647 AlternativeServiceInfoVector alternative_service_info_vector;
648 const AlternativeService alternative_service2(kProtoHTTP2, "bar2", 443);
649 base::Time expiration2 = now + base::Days(2);
650 alternative_service_info_vector.push_back(
651 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
652 alternative_service2, expiration2));
653 url::SchemeHostPort test_server2("http", "foo2", 80);
654 // 0th entry in the memory.
655 impl_.SetAlternativeServices(test_server2, NetworkAnonymizationKey(),
656 alternative_service_info_vector);
657
658 // Prepare |server_info_map| to be loaded by OnServerInfoLoadedForTesting().
659 std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
660 std::make_unique<HttpServerProperties::ServerInfoMap>();
661 const AlternativeService alternative_service3(kProtoHTTP2, "bar3", 123);
662 base::Time expiration3 = now + base::Days(3);
663 const AlternativeServiceInfo alternative_service_info1 =
664 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
665 alternative_service3, expiration3);
666 // Simulate updating data for 0th entry with data from Preferences.
667 server_info_map->GetOrPut(CreateSimpleKey(test_server2))
668 ->second.alternative_services =
669 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info1);
670
671 url::SchemeHostPort test_server3("http", "foo3", 80);
672 const AlternativeService alternative_service4(kProtoHTTP2, "bar4", 1234);
673 base::Time expiration4 = now + base::Days(4);
674 const AlternativeServiceInfo alternative_service_info2 =
675 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
676 alternative_service4, expiration4);
677 // Add an old entry from Preferences, this will be added to end of recency
678 // list.
679 server_info_map->GetOrPut(CreateSimpleKey(test_server3))
680 ->second.alternative_services =
681 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info2);
682
683 // MRU list will be test_server2, test_server1, test_server3.
684 impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
685
686 // Verify server_info_map.
687 const HttpServerProperties::ServerInfoMap& map =
688 impl_.server_info_map_for_testing();
689 ASSERT_EQ(3u, map.size());
690 auto map_it = map.begin();
691
692 EXPECT_EQ(test_server2, map_it->first.server);
693 EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
694 ASSERT_TRUE(map_it->second.alternative_services.has_value());
695 const AlternativeServiceInfoVector* service_info =
696 &map_it->second.alternative_services.value();
697 ASSERT_EQ(1u, service_info->size());
698 EXPECT_EQ(alternative_service3, (*service_info)[0].alternative_service());
699 EXPECT_EQ(expiration3, (*service_info)[0].expiration());
700
701 ++map_it;
702 EXPECT_EQ(test_server1, map_it->first.server);
703 EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
704 ASSERT_TRUE(map_it->second.alternative_services.has_value());
705 service_info = &map_it->second.alternative_services.value();
706 ASSERT_EQ(1u, service_info->size());
707 EXPECT_EQ(alternative_service1, (*service_info)[0].alternative_service());
708 EXPECT_EQ(expiration1, (*service_info)[0].expiration());
709
710 ++map_it;
711 EXPECT_EQ(map_it->first.server, test_server3);
712 EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
713 ASSERT_TRUE(map_it->second.alternative_services.has_value());
714 service_info = &map_it->second.alternative_services.value();
715 ASSERT_EQ(1u, service_info->size());
716 EXPECT_EQ(alternative_service4, (*service_info)[0].alternative_service());
717 EXPECT_EQ(expiration4, (*service_info)[0].expiration());
718 }
719
TEST_F(AlternateProtocolServerPropertiesTest,SetWebSockets)720 TEST_F(AlternateProtocolServerPropertiesTest, SetWebSockets) {
721 // The https and wss servers should be treated as the same server, as should
722 // the http and ws servers.
723 url::SchemeHostPort https_server("https", "www.test.com", 443);
724 url::SchemeHostPort wss_server("wss", "www.test.com", 443);
725 url::SchemeHostPort http_server("http", "www.test.com", 443);
726 url::SchemeHostPort ws_server("ws", "www.test.com", 443);
727
728 AlternativeService alternative_service(kProtoHTTP2, "bar", 443);
729
730 EXPECT_EQ(
731 0u,
732 impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
733 .size());
734 EXPECT_EQ(
735 0u,
736 impl_.GetAlternativeServiceInfos(wss_server, NetworkAnonymizationKey())
737 .size());
738 EXPECT_EQ(
739 0u,
740 impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
741 .size());
742 EXPECT_EQ(
743 0u, impl_.GetAlternativeServiceInfos(ws_server, NetworkAnonymizationKey())
744 .size());
745
746 SetAlternativeService(wss_server, alternative_service);
747 EXPECT_EQ(
748 1u,
749 impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
750 .size());
751 EXPECT_EQ(
752 1u,
753 impl_.GetAlternativeServiceInfos(wss_server, NetworkAnonymizationKey())
754 .size());
755 EXPECT_EQ(
756 0u,
757 impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
758 .size());
759 EXPECT_EQ(
760 0u, impl_.GetAlternativeServiceInfos(ws_server, NetworkAnonymizationKey())
761 .size());
762
763 SetAlternativeService(http_server, alternative_service);
764 EXPECT_EQ(
765 1u,
766 impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
767 .size());
768 EXPECT_EQ(
769 1u,
770 impl_.GetAlternativeServiceInfos(wss_server, NetworkAnonymizationKey())
771 .size());
772 EXPECT_EQ(
773 1u,
774 impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
775 .size());
776 EXPECT_EQ(
777 1u, impl_.GetAlternativeServiceInfos(ws_server, NetworkAnonymizationKey())
778 .size());
779
780 impl_.SetAlternativeServices(https_server, NetworkAnonymizationKey(),
781 AlternativeServiceInfoVector());
782 EXPECT_EQ(
783 0u,
784 impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
785 .size());
786 EXPECT_EQ(
787 0u,
788 impl_.GetAlternativeServiceInfos(wss_server, NetworkAnonymizationKey())
789 .size());
790 EXPECT_EQ(
791 1u,
792 impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
793 .size());
794 EXPECT_EQ(
795 1u, impl_.GetAlternativeServiceInfos(ws_server, NetworkAnonymizationKey())
796 .size());
797
798 impl_.SetAlternativeServices(ws_server, NetworkAnonymizationKey(),
799 AlternativeServiceInfoVector());
800 EXPECT_EQ(
801 0u,
802 impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
803 .size());
804 EXPECT_EQ(
805 0u,
806 impl_.GetAlternativeServiceInfos(wss_server, NetworkAnonymizationKey())
807 .size());
808 EXPECT_EQ(
809 0u,
810 impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
811 .size());
812 EXPECT_EQ(
813 0u, impl_.GetAlternativeServiceInfos(ws_server, NetworkAnonymizationKey())
814 .size());
815 }
816
TEST_F(AlternateProtocolServerPropertiesTest,SetWithNetworkIsolationKey)817 TEST_F(AlternateProtocolServerPropertiesTest, SetWithNetworkIsolationKey) {
818 const url::SchemeHostPort kServer("https", "foo.test", 443);
819 const AlternativeServiceInfoVector kAlternativeServices(
820 {AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
821 AlternativeService(kProtoHTTP2, "foo", 443),
822 base::Time::Now() + base::Days(1) /* expiration */)});
823
824 EXPECT_TRUE(
825 impl_.GetAlternativeServiceInfos(kServer, network_anonymization_key1_)
826 .empty());
827 EXPECT_TRUE(
828 impl_.GetAlternativeServiceInfos(kServer, NetworkAnonymizationKey())
829 .empty());
830
831 // Without network isolation keys enabled for HttpServerProperties, passing in
832 // a NetworkAnonymizationKey should have no effect on behavior.
833 for (const auto& network_anonymization_key_to_set :
834 {NetworkAnonymizationKey(), network_anonymization_key1_}) {
835 impl_.SetAlternativeServices(kServer, network_anonymization_key_to_set,
836 kAlternativeServices);
837 EXPECT_EQ(kAlternativeServices, impl_.GetAlternativeServiceInfos(
838 kServer, network_anonymization_key1_));
839 EXPECT_EQ(kAlternativeServices, impl_.GetAlternativeServiceInfos(
840 kServer, NetworkAnonymizationKey()));
841
842 impl_.SetAlternativeServices(kServer, network_anonymization_key_to_set,
843 AlternativeServiceInfoVector());
844 EXPECT_TRUE(
845 impl_.GetAlternativeServiceInfos(kServer, network_anonymization_key1_)
846 .empty());
847 EXPECT_TRUE(
848 impl_.GetAlternativeServiceInfos(kServer, NetworkAnonymizationKey())
849 .empty());
850 }
851
852 // Check that with network isolation keys enabled for HttpServerProperties,
853 // the NetworkAnonymizationKey argument is respected.
854
855 base::test::ScopedFeatureList feature_list;
856 feature_list.InitAndEnableFeature(
857 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
858 // Since HttpServerProperties caches the feature value, have to create a new
859 // one.
860 HttpServerProperties properties(nullptr /* pref_delegate */,
861 nullptr /* net_log */, test_tick_clock_,
862 &test_clock_);
863
864 properties.SetAlternativeServices(kServer, network_anonymization_key1_,
865 kAlternativeServices);
866 EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
867 kServer, network_anonymization_key1_));
868 EXPECT_TRUE(
869 properties.GetAlternativeServiceInfos(kServer, NetworkAnonymizationKey())
870 .empty());
871
872 properties.SetAlternativeServices(kServer, NetworkAnonymizationKey(),
873 kAlternativeServices);
874 EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
875 kServer, network_anonymization_key1_));
876 EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
877 kServer, NetworkAnonymizationKey()));
878
879 properties.SetAlternativeServices(kServer, network_anonymization_key1_,
880 AlternativeServiceInfoVector());
881 EXPECT_TRUE(
882 properties
883 .GetAlternativeServiceInfos(kServer, network_anonymization_key1_)
884 .empty());
885 EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
886 kServer, NetworkAnonymizationKey()));
887
888 properties.SetAlternativeServices(kServer, NetworkAnonymizationKey(),
889 AlternativeServiceInfoVector());
890 EXPECT_TRUE(
891 properties
892 .GetAlternativeServiceInfos(kServer, network_anonymization_key1_)
893 .empty());
894 EXPECT_TRUE(
895 properties.GetAlternativeServiceInfos(kServer, NetworkAnonymizationKey())
896 .empty());
897 }
898
899 // Regression test for https://crbug.com/504032:
900 // OnServerInfoLoadedForTesting() should not crash if there is an
901 // empty hostname is the mapping.
TEST_F(AlternateProtocolServerPropertiesTest,SetWithEmptyHostname)902 TEST_F(AlternateProtocolServerPropertiesTest, SetWithEmptyHostname) {
903 url::SchemeHostPort server("https", "foo", 443);
904 const AlternativeService alternative_service_with_empty_hostname(kProtoHTTP2,
905 "", 1234);
906 const AlternativeService alternative_service_with_foo_hostname(kProtoHTTP2,
907 "foo", 1234);
908 SetAlternativeService(server, alternative_service_with_empty_hostname);
909 impl_.MarkAlternativeServiceBroken(alternative_service_with_foo_hostname,
910 NetworkAnonymizationKey());
911
912 std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
913 std::make_unique<HttpServerProperties::ServerInfoMap>();
914 impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
915
916 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(
917 alternative_service_with_foo_hostname, NetworkAnonymizationKey()));
918 const AlternativeServiceInfoVector alternative_service_info_vector =
919 impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey());
920 ASSERT_EQ(1u, alternative_service_info_vector.size());
921 EXPECT_EQ(alternative_service_with_foo_hostname,
922 alternative_service_info_vector[0].alternative_service());
923 }
924
925 // Regression test for https://crbug.com/516486:
926 // GetAlternativeServiceInfos() should remove |server_info_map_|
927 // elements with empty value.
TEST_F(AlternateProtocolServerPropertiesTest,DISABLED_EmptyVector)928 TEST_F(AlternateProtocolServerPropertiesTest, DISABLED_EmptyVector) {
929 url::SchemeHostPort server("https", "foo", 443);
930 const AlternativeService alternative_service(kProtoHTTP2, "bar", 443);
931 base::Time expiration = test_clock_.Now() - base::Days(1);
932 const AlternativeServiceInfo alternative_service_info =
933 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
934 alternative_service, expiration);
935 std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
936 std::make_unique<HttpServerProperties::ServerInfoMap>();
937 server_info_map->GetOrPut(CreateSimpleKey(server))
938 ->second.alternative_services = AlternativeServiceInfoVector(
939 /*size=*/1, alternative_service_info);
940
941 // Prepare |server_info_map_| with a single key that has a single
942 // AlternativeServiceInfo with identical hostname and port.
943 impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
944
945 // GetAlternativeServiceInfos() should remove such AlternativeServiceInfo from
946 // |server_info_map_|, emptying the AlternativeServiceInfoVector
947 // corresponding to |server|.
948 ASSERT_TRUE(
949 impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
950 .empty());
951
952 // GetAlternativeServiceInfos() should remove this key from
953 // |server_info_map_|, and SetAlternativeServices() should not crash.
954 impl_.SetAlternativeServices(
955 server, NetworkAnonymizationKey(),
956 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
957
958 // There should still be no alternative service assigned to |server|.
959 ASSERT_TRUE(
960 impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
961 .empty());
962 }
963
964 // Regression test for https://crbug.com/516486 for the canonical host case.
TEST_F(AlternateProtocolServerPropertiesTest,EmptyVectorForCanonical)965 TEST_F(AlternateProtocolServerPropertiesTest, EmptyVectorForCanonical) {
966 url::SchemeHostPort server("https", "foo.c.youtube.com", 443);
967 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
968 const AlternativeService alternative_service(kProtoHTTP2, "", 443);
969 base::Time expiration = test_clock_.Now() - base::Days(1);
970 const AlternativeServiceInfo alternative_service_info =
971 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
972 alternative_service, expiration);
973 std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
974 std::make_unique<HttpServerProperties::ServerInfoMap>();
975 server_info_map->GetOrPut(CreateSimpleKey(canonical_server))
976 ->second.alternative_services =
977 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info);
978
979 // Prepare |server_info_map_| with a single key that has a single
980 // AlternativeServiceInfo with identical hostname and port.
981 impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
982
983 // GetAlternativeServiceInfos() should remove such AlternativeServiceInfo from
984 // |server_info_map_|, emptying the AlternativeServiceInfoVector
985 // corresponding to |canonical_server|, even when looking up
986 // alternative services for |server|.
987 ASSERT_TRUE(
988 impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
989 .empty());
990
991 // GetAlternativeServiceInfos() should remove this key from
992 // |server_info_map_|, and SetAlternativeServices() should not crash.
993 impl_.SetAlternativeServices(
994 canonical_server, NetworkAnonymizationKey(),
995 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
996
997 // There should still be no alternative service assigned to
998 // |canonical_server|.
999 ASSERT_TRUE(impl_
1000 .GetAlternativeServiceInfos(canonical_server,
1001 NetworkAnonymizationKey())
1002 .empty());
1003 }
1004
TEST_F(AlternateProtocolServerPropertiesTest,ClearServerWithCanonical)1005 TEST_F(AlternateProtocolServerPropertiesTest, ClearServerWithCanonical) {
1006 url::SchemeHostPort server("https", "foo.c.youtube.com", 443);
1007 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1008 const AlternativeService alternative_service(kProtoQUIC, "", 443);
1009 base::Time expiration = test_clock_.Now() + base::Days(1);
1010 const AlternativeServiceInfo alternative_service_info =
1011 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
1012 alternative_service, expiration, DefaultSupportedQuicVersions());
1013
1014 impl_.SetAlternativeServices(
1015 canonical_server, NetworkAnonymizationKey(),
1016 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
1017
1018 // Make sure the canonical service is returned for the other server.
1019 const AlternativeServiceInfoVector alternative_service_info_vector =
1020 impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey());
1021 ASSERT_EQ(1u, alternative_service_info_vector.size());
1022 EXPECT_EQ(kProtoQUIC,
1023 alternative_service_info_vector[0].alternative_service().protocol);
1024 EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port);
1025
1026 // Now clear the alternatives for the other server and make sure it stays
1027 // cleared.
1028 // GetAlternativeServices() should remove this key from
1029 // |server_info_map_|, and SetAlternativeServices() should not crash.
1030 impl_.SetAlternativeServices(server, NetworkAnonymizationKey(),
1031 AlternativeServiceInfoVector());
1032
1033 ASSERT_TRUE(
1034 impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
1035 .empty());
1036 }
1037
TEST_F(AlternateProtocolServerPropertiesTest,MRUOfGetAlternativeServiceInfos)1038 TEST_F(AlternateProtocolServerPropertiesTest, MRUOfGetAlternativeServiceInfos) {
1039 url::SchemeHostPort test_server1("http", "foo1", 80);
1040 const AlternativeService alternative_service1(kProtoHTTP2, "foo1", 443);
1041 SetAlternativeService(test_server1, alternative_service1);
1042 url::SchemeHostPort test_server2("http", "foo2", 80);
1043 const AlternativeService alternative_service2(kProtoHTTP2, "foo2", 1234);
1044 SetAlternativeService(test_server2, alternative_service2);
1045
1046 const HttpServerProperties::ServerInfoMap& map =
1047 impl_.server_info_map_for_testing();
1048 auto it = map.begin();
1049 EXPECT_EQ(test_server2, it->first.server);
1050 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
1051 ASSERT_TRUE(it->second.alternative_services.has_value());
1052 ASSERT_EQ(1u, it->second.alternative_services->size());
1053 EXPECT_EQ(alternative_service2,
1054 it->second.alternative_services.value()[0].alternative_service());
1055
1056 const AlternativeServiceInfoVector alternative_service_info_vector =
1057 impl_.GetAlternativeServiceInfos(test_server1, NetworkAnonymizationKey());
1058 ASSERT_EQ(1u, alternative_service_info_vector.size());
1059 EXPECT_EQ(alternative_service1,
1060 alternative_service_info_vector[0].alternative_service());
1061
1062 // GetAlternativeServices should reorder the AlternateProtocol map.
1063 it = map.begin();
1064 EXPECT_EQ(test_server1, it->first.server);
1065 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
1066 ASSERT_TRUE(it->second.alternative_services.has_value());
1067 ASSERT_EQ(1u, it->second.alternative_services->size());
1068 EXPECT_EQ(alternative_service1,
1069 it->second.alternative_services.value()[0].alternative_service());
1070 }
1071
TEST_F(AlternateProtocolServerPropertiesTest,SetBroken)1072 TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) {
1073 url::SchemeHostPort test_server("http", "foo", 80);
1074 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1075 SetAlternativeService(test_server, alternative_service1);
1076 AlternativeServiceInfoVector alternative_service_info_vector =
1077 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1078 ASSERT_EQ(1u, alternative_service_info_vector.size());
1079 EXPECT_EQ(alternative_service1,
1080 alternative_service_info_vector[0].alternative_service());
1081 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
1082 NetworkAnonymizationKey()));
1083
1084 // GetAlternativeServiceInfos should return the broken alternative service.
1085 impl_.MarkAlternativeServiceBroken(alternative_service1,
1086 NetworkAnonymizationKey());
1087 alternative_service_info_vector =
1088 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1089 ASSERT_EQ(1u, alternative_service_info_vector.size());
1090 EXPECT_EQ(alternative_service1,
1091 alternative_service_info_vector[0].alternative_service());
1092 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1093 NetworkAnonymizationKey()));
1094
1095 // SetAlternativeServices should add a broken alternative service to the map.
1096 AlternativeServiceInfoVector alternative_service_info_vector2;
1097 base::Time expiration = test_clock_.Now() + base::Days(1);
1098 alternative_service_info_vector2.push_back(
1099 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1100 alternative_service1, expiration));
1101 const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234);
1102 alternative_service_info_vector2.push_back(
1103 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1104 alternative_service2, expiration));
1105 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1106 alternative_service_info_vector2);
1107 alternative_service_info_vector =
1108 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1109 ASSERT_EQ(2u, alternative_service_info_vector.size());
1110 EXPECT_EQ(alternative_service1,
1111 alternative_service_info_vector[0].alternative_service());
1112 EXPECT_EQ(alternative_service2,
1113 alternative_service_info_vector[1].alternative_service());
1114 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1115 NetworkAnonymizationKey()));
1116 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
1117 NetworkAnonymizationKey()));
1118
1119 // SetAlternativeService should add a broken alternative service to the map.
1120 SetAlternativeService(test_server, alternative_service1);
1121 alternative_service_info_vector =
1122 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1123 ASSERT_EQ(1u, alternative_service_info_vector.size());
1124 EXPECT_EQ(alternative_service1,
1125 alternative_service_info_vector[0].alternative_service());
1126 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1127 NetworkAnonymizationKey()));
1128 }
1129
TEST_F(AlternateProtocolServerPropertiesTest,SetBrokenUntilDefaultNetworkChanges)1130 TEST_F(AlternateProtocolServerPropertiesTest,
1131 SetBrokenUntilDefaultNetworkChanges) {
1132 url::SchemeHostPort test_server("http", "foo", 80);
1133 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1134 SetAlternativeService(test_server, alternative_service1);
1135 AlternativeServiceInfoVector alternative_service_info_vector =
1136 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1137 ASSERT_EQ(1u, alternative_service_info_vector.size());
1138 EXPECT_EQ(alternative_service1,
1139 alternative_service_info_vector[0].alternative_service());
1140 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
1141 NetworkAnonymizationKey()));
1142
1143 // Mark the alternative service as broken until the default network changes.
1144 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1145 alternative_service1, NetworkAnonymizationKey());
1146 // The alternative service should be persisted and marked as broken.
1147 alternative_service_info_vector =
1148 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1149 ASSERT_EQ(1u, alternative_service_info_vector.size());
1150 EXPECT_EQ(alternative_service1,
1151 alternative_service_info_vector[0].alternative_service());
1152 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1153 NetworkAnonymizationKey()));
1154
1155 // SetAlternativeServices should add a broken alternative service to the map.
1156 AlternativeServiceInfoVector alternative_service_info_vector2;
1157 base::Time expiration = test_clock_.Now() + base::Days(1);
1158 alternative_service_info_vector2.push_back(
1159 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1160 alternative_service1, expiration));
1161 const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234);
1162 alternative_service_info_vector2.push_back(
1163 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1164 alternative_service2, expiration));
1165 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1166 alternative_service_info_vector2);
1167 alternative_service_info_vector =
1168 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1169 ASSERT_EQ(2u, alternative_service_info_vector.size());
1170 EXPECT_EQ(alternative_service1,
1171 alternative_service_info_vector[0].alternative_service());
1172 EXPECT_EQ(alternative_service2,
1173 alternative_service_info_vector[1].alternative_service());
1174 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1175 NetworkAnonymizationKey()));
1176 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
1177 NetworkAnonymizationKey()));
1178
1179 // SetAlternativeService should add a broken alternative service to the map.
1180 SetAlternativeService(test_server, alternative_service1);
1181 alternative_service_info_vector =
1182 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1183 ASSERT_EQ(1u, alternative_service_info_vector.size());
1184 EXPECT_EQ(alternative_service1,
1185 alternative_service_info_vector[0].alternative_service());
1186 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1187 NetworkAnonymizationKey()));
1188 }
1189
TEST_F(AlternateProtocolServerPropertiesTest,MaxAge)1190 TEST_F(AlternateProtocolServerPropertiesTest, MaxAge) {
1191 AlternativeServiceInfoVector alternative_service_info_vector;
1192 base::Time now = test_clock_.Now();
1193 base::TimeDelta one_day = base::Days(1);
1194
1195 // First alternative service expired one day ago, should not be returned by
1196 // GetAlternativeServiceInfos().
1197 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1198 alternative_service_info_vector.push_back(
1199 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1200 alternative_service1, now - one_day));
1201
1202 // Second alterrnative service will expire one day from now, should be
1203 // returned by GetAlternativeSerices().
1204 const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
1205 alternative_service_info_vector.push_back(
1206 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1207 alternative_service2, now + one_day));
1208
1209 url::SchemeHostPort test_server("http", "foo", 80);
1210 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1211 alternative_service_info_vector);
1212
1213 AlternativeServiceInfoVector alternative_service_info_vector2 =
1214 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1215 ASSERT_EQ(1u, alternative_service_info_vector2.size());
1216 EXPECT_EQ(alternative_service2,
1217 alternative_service_info_vector2[0].alternative_service());
1218 }
1219
TEST_F(AlternateProtocolServerPropertiesTest,MaxAgeCanonical)1220 TEST_F(AlternateProtocolServerPropertiesTest, MaxAgeCanonical) {
1221 AlternativeServiceInfoVector alternative_service_info_vector;
1222 base::Time now = test_clock_.Now();
1223 base::TimeDelta one_day = base::Days(1);
1224
1225 // First alternative service expired one day ago, should not be returned by
1226 // GetAlternativeServiceInfos().
1227 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1228 alternative_service_info_vector.push_back(
1229 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1230 alternative_service1, now - one_day));
1231
1232 // Second alterrnative service will expire one day from now, should be
1233 // returned by GetAlternativeSerices().
1234 const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
1235 alternative_service_info_vector.push_back(
1236 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1237 alternative_service2, now + one_day));
1238
1239 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1240 impl_.SetAlternativeServices(canonical_server, NetworkAnonymizationKey(),
1241 alternative_service_info_vector);
1242
1243 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1244 AlternativeServiceInfoVector alternative_service_info_vector2 =
1245 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1246 ASSERT_EQ(1u, alternative_service_info_vector2.size());
1247 EXPECT_EQ(alternative_service2,
1248 alternative_service_info_vector2[0].alternative_service());
1249 }
1250
TEST_F(AlternateProtocolServerPropertiesTest,AlternativeServiceWithScheme)1251 TEST_F(AlternateProtocolServerPropertiesTest, AlternativeServiceWithScheme) {
1252 AlternativeServiceInfoVector alternative_service_info_vector;
1253 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1254 base::Time expiration = test_clock_.Now() + base::Days(1);
1255 alternative_service_info_vector.push_back(
1256 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1257 alternative_service1, expiration));
1258 const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
1259 alternative_service_info_vector.push_back(
1260 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1261 alternative_service2, expiration));
1262 // Set Alt-Svc list for |http_server|.
1263 url::SchemeHostPort http_server("http", "foo", 80);
1264 impl_.SetAlternativeServices(http_server, NetworkAnonymizationKey(),
1265 alternative_service_info_vector);
1266
1267 const net::HttpServerProperties::ServerInfoMap& map =
1268 impl_.server_info_map_for_testing();
1269 auto it = map.begin();
1270 EXPECT_EQ(http_server, it->first.server);
1271 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
1272 ASSERT_TRUE(it->second.alternative_services.has_value());
1273 ASSERT_EQ(2u, it->second.alternative_services->size());
1274 EXPECT_EQ(alternative_service1,
1275 it->second.alternative_services.value()[0].alternative_service());
1276 EXPECT_EQ(alternative_service2,
1277 it->second.alternative_services.value()[1].alternative_service());
1278
1279 // Check Alt-Svc list should not be set for |https_server|.
1280 url::SchemeHostPort https_server("https", "foo", 80);
1281 EXPECT_EQ(
1282 0u,
1283 impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
1284 .size());
1285
1286 // Set Alt-Svc list for |https_server|.
1287 impl_.SetAlternativeServices(https_server, NetworkAnonymizationKey(),
1288 alternative_service_info_vector);
1289 EXPECT_EQ(
1290 2u,
1291 impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
1292 .size());
1293 EXPECT_EQ(
1294 2u,
1295 impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
1296 .size());
1297
1298 // Clear Alt-Svc list for |http_server|.
1299 impl_.SetAlternativeServices(http_server, NetworkAnonymizationKey(),
1300 AlternativeServiceInfoVector());
1301
1302 EXPECT_EQ(
1303 0u,
1304 impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
1305 .size());
1306 EXPECT_EQ(
1307 2u,
1308 impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
1309 .size());
1310 }
1311
TEST_F(AlternateProtocolServerPropertiesTest,ClearAlternativeServices)1312 TEST_F(AlternateProtocolServerPropertiesTest, ClearAlternativeServices) {
1313 AlternativeServiceInfoVector alternative_service_info_vector;
1314 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1315 base::Time expiration = test_clock_.Now() + base::Days(1);
1316 alternative_service_info_vector.push_back(
1317 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1318 alternative_service1, expiration));
1319 const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
1320 alternative_service_info_vector.push_back(
1321 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1322 alternative_service2, expiration));
1323 url::SchemeHostPort test_server("http", "foo", 80);
1324 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1325 alternative_service_info_vector);
1326
1327 const net::HttpServerProperties::ServerInfoMap& map =
1328 impl_.server_info_map_for_testing();
1329 auto it = map.begin();
1330 EXPECT_EQ(test_server, it->first.server);
1331 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
1332 ASSERT_TRUE(it->second.alternative_services.has_value());
1333 ASSERT_EQ(2u, it->second.alternative_services->size());
1334 EXPECT_EQ(alternative_service1,
1335 it->second.alternative_services.value()[0].alternative_service());
1336 EXPECT_EQ(alternative_service2,
1337 it->second.alternative_services.value()[1].alternative_service());
1338
1339 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1340 AlternativeServiceInfoVector());
1341 EXPECT_TRUE(map.empty());
1342 }
1343
1344 // A broken alternative service in the mapping carries meaningful information,
1345 // therefore it should not be ignored by SetAlternativeService(). In
1346 // particular, an alternative service mapped to an origin shadows alternative
1347 // services of canonical hosts.
TEST_F(AlternateProtocolServerPropertiesTest,BrokenShadowsCanonical)1348 TEST_F(AlternateProtocolServerPropertiesTest, BrokenShadowsCanonical) {
1349 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1350 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1351 AlternativeService canonical_alternative_service(kProtoQUIC,
1352 "bar.c.youtube.com", 1234);
1353 SetAlternativeService(canonical_server, canonical_alternative_service);
1354 AlternativeServiceInfoVector alternative_service_info_vector =
1355 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1356 ASSERT_EQ(1u, alternative_service_info_vector.size());
1357 EXPECT_EQ(canonical_alternative_service,
1358 alternative_service_info_vector[0].alternative_service());
1359
1360 const AlternativeService broken_alternative_service(kProtoHTTP2, "foo", 443);
1361 impl_.MarkAlternativeServiceBroken(broken_alternative_service,
1362 NetworkAnonymizationKey());
1363 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service,
1364 NetworkAnonymizationKey()));
1365
1366 SetAlternativeService(test_server, broken_alternative_service);
1367 alternative_service_info_vector =
1368 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1369 ASSERT_EQ(1u, alternative_service_info_vector.size());
1370 EXPECT_EQ(broken_alternative_service,
1371 alternative_service_info_vector[0].alternative_service());
1372 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service,
1373 NetworkAnonymizationKey()));
1374 }
1375
TEST_F(AlternateProtocolServerPropertiesTest,ClearBroken)1376 TEST_F(AlternateProtocolServerPropertiesTest, ClearBroken) {
1377 url::SchemeHostPort test_server("http", "foo", 80);
1378 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1379 SetAlternativeService(test_server, alternative_service);
1380 impl_.MarkAlternativeServiceBroken(alternative_service,
1381 NetworkAnonymizationKey());
1382 ASSERT_TRUE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
1383 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1384 NetworkAnonymizationKey()));
1385 // SetAlternativeServices should leave a broken alternative service marked
1386 // as such.
1387 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1388 AlternativeServiceInfoVector());
1389 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1390 NetworkAnonymizationKey()));
1391 }
1392
TEST_F(AlternateProtocolServerPropertiesTest,MarkBrokenWithNetworkIsolationKey)1393 TEST_F(AlternateProtocolServerPropertiesTest,
1394 MarkBrokenWithNetworkIsolationKey) {
1395 url::SchemeHostPort server("http", "foo", 80);
1396 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1397 const base::Time expiration = test_clock_.Now() + base::Days(1);
1398
1399 // Without NetworkIsolationKeys enabled, the NetworkAnonymizationKey parameter
1400 // should be ignored.
1401 impl_.SetHttp2AlternativeService(server, network_anonymization_key1_,
1402 alternative_service, expiration);
1403 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1404 network_anonymization_key1_));
1405 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1406 alternative_service, network_anonymization_key1_));
1407 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1408 network_anonymization_key2_));
1409 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1410 alternative_service, network_anonymization_key2_));
1411
1412 impl_.MarkAlternativeServiceBroken(alternative_service,
1413 network_anonymization_key1_);
1414 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1415 network_anonymization_key1_));
1416 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1417 alternative_service, network_anonymization_key1_));
1418 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1419 network_anonymization_key2_));
1420 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1421 alternative_service, network_anonymization_key2_));
1422
1423 impl_.ConfirmAlternativeService(alternative_service,
1424 network_anonymization_key2_);
1425 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1426 network_anonymization_key1_));
1427 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1428 alternative_service, network_anonymization_key1_));
1429 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1430 network_anonymization_key2_));
1431 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1432 alternative_service, network_anonymization_key2_));
1433
1434 base::test::ScopedFeatureList feature_list;
1435 feature_list.InitAndEnableFeature(
1436 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1437 // Since HttpServerProperties caches the feature value, have to create a new
1438 // one.
1439 HttpServerProperties properties(nullptr /* pref_delegate */,
1440 nullptr /* net_log */, test_tick_clock_,
1441 &test_clock_);
1442
1443 properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
1444 alternative_service, expiration);
1445 properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
1446 alternative_service, expiration);
1447
1448 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1449 alternative_service, network_anonymization_key1_));
1450 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1451 alternative_service, network_anonymization_key1_));
1452 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1453 alternative_service, network_anonymization_key2_));
1454 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1455 alternative_service, network_anonymization_key2_));
1456
1457 properties.MarkAlternativeServiceBroken(alternative_service,
1458 network_anonymization_key1_);
1459 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1460 alternative_service, network_anonymization_key1_));
1461 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1462 alternative_service, network_anonymization_key1_));
1463 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1464 alternative_service, network_anonymization_key2_));
1465 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1466 alternative_service, network_anonymization_key2_));
1467
1468 properties.MarkAlternativeServiceBroken(alternative_service,
1469 network_anonymization_key2_);
1470 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1471 alternative_service, network_anonymization_key1_));
1472 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1473 alternative_service, network_anonymization_key1_));
1474 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1475 alternative_service, network_anonymization_key2_));
1476 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1477 alternative_service, network_anonymization_key2_));
1478
1479 properties.ConfirmAlternativeService(alternative_service,
1480 network_anonymization_key1_);
1481 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1482 alternative_service, network_anonymization_key1_));
1483 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1484 alternative_service, network_anonymization_key1_));
1485 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1486 alternative_service, network_anonymization_key2_));
1487 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1488 alternative_service, network_anonymization_key2_));
1489
1490 properties.ConfirmAlternativeService(alternative_service,
1491 network_anonymization_key2_);
1492 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1493 alternative_service, network_anonymization_key1_));
1494 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1495 alternative_service, network_anonymization_key1_));
1496 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1497 alternative_service, network_anonymization_key2_));
1498 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1499 alternative_service, network_anonymization_key2_));
1500 }
1501
TEST_F(AlternateProtocolServerPropertiesTest,MarkRecentlyBroken)1502 TEST_F(AlternateProtocolServerPropertiesTest, MarkRecentlyBroken) {
1503 url::SchemeHostPort server("http", "foo", 80);
1504 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1505 SetAlternativeService(server, alternative_service);
1506
1507 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1508 NetworkAnonymizationKey()));
1509 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1510 alternative_service, NetworkAnonymizationKey()));
1511
1512 impl_.MarkAlternativeServiceRecentlyBroken(alternative_service,
1513 NetworkAnonymizationKey());
1514 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1515 NetworkAnonymizationKey()));
1516 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1517 alternative_service, NetworkAnonymizationKey()));
1518
1519 impl_.ConfirmAlternativeService(alternative_service,
1520 NetworkAnonymizationKey());
1521 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1522 NetworkAnonymizationKey()));
1523 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1524 alternative_service, NetworkAnonymizationKey()));
1525 }
1526
TEST_F(AlternateProtocolServerPropertiesTest,MarkRecentlyBrokenWithNetworkIsolationKey)1527 TEST_F(AlternateProtocolServerPropertiesTest,
1528 MarkRecentlyBrokenWithNetworkIsolationKey) {
1529 url::SchemeHostPort server("http", "foo", 80);
1530 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1531 const base::Time expiration = test_clock_.Now() + base::Days(1);
1532
1533 // Without NetworkIsolationKeys enabled, the NetworkAnonymizationKey parameter
1534 // should be ignored.
1535 impl_.SetHttp2AlternativeService(server, network_anonymization_key1_,
1536 alternative_service, expiration);
1537 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1538 network_anonymization_key1_));
1539 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1540 alternative_service, network_anonymization_key1_));
1541 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1542 network_anonymization_key2_));
1543 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1544 alternative_service, network_anonymization_key2_));
1545
1546 impl_.MarkAlternativeServiceRecentlyBroken(alternative_service,
1547 network_anonymization_key1_);
1548 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1549 network_anonymization_key1_));
1550 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1551 alternative_service, network_anonymization_key1_));
1552 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1553 network_anonymization_key2_));
1554 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1555 alternative_service, network_anonymization_key2_));
1556
1557 impl_.ConfirmAlternativeService(alternative_service,
1558 network_anonymization_key2_);
1559 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1560 network_anonymization_key1_));
1561 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1562 alternative_service, network_anonymization_key1_));
1563 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1564 network_anonymization_key2_));
1565 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1566 alternative_service, network_anonymization_key2_));
1567
1568 base::test::ScopedFeatureList feature_list;
1569 feature_list.InitAndEnableFeature(
1570 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1571 // Since HttpServerProperties caches the feature value, have to create a new
1572 // one.
1573 HttpServerProperties properties(nullptr /* pref_delegate */,
1574 nullptr /* net_log */, test_tick_clock_,
1575 &test_clock_);
1576
1577 properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
1578 alternative_service, expiration);
1579 properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
1580 alternative_service, expiration);
1581 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1582 alternative_service, network_anonymization_key1_));
1583 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1584 alternative_service, network_anonymization_key1_));
1585 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1586 alternative_service, network_anonymization_key2_));
1587 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1588 alternative_service, network_anonymization_key2_));
1589
1590 properties.MarkAlternativeServiceRecentlyBroken(alternative_service,
1591 network_anonymization_key1_);
1592 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1593 alternative_service, network_anonymization_key1_));
1594 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1595 alternative_service, network_anonymization_key1_));
1596 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1597 alternative_service, network_anonymization_key2_));
1598 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1599 alternative_service, network_anonymization_key2_));
1600
1601 properties.MarkAlternativeServiceRecentlyBroken(alternative_service,
1602 network_anonymization_key2_);
1603 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1604 alternative_service, network_anonymization_key1_));
1605 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1606 alternative_service, network_anonymization_key1_));
1607 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1608 alternative_service, network_anonymization_key2_));
1609 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1610 alternative_service, network_anonymization_key2_));
1611
1612 properties.ConfirmAlternativeService(alternative_service,
1613 network_anonymization_key1_);
1614 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1615 alternative_service, network_anonymization_key1_));
1616 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1617 alternative_service, network_anonymization_key1_));
1618 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1619 alternative_service, network_anonymization_key2_));
1620 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1621 alternative_service, network_anonymization_key2_));
1622
1623 properties.ConfirmAlternativeService(alternative_service,
1624 network_anonymization_key2_);
1625 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1626 alternative_service, network_anonymization_key1_));
1627 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1628 alternative_service, network_anonymization_key1_));
1629 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1630 alternative_service, network_anonymization_key2_));
1631 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1632 alternative_service, network_anonymization_key2_));
1633 }
1634
TEST_F(AlternateProtocolServerPropertiesTest,MarkBrokenUntilDefaultNetworkChanges)1635 TEST_F(AlternateProtocolServerPropertiesTest,
1636 MarkBrokenUntilDefaultNetworkChanges) {
1637 url::SchemeHostPort server("http", "foo", 80);
1638 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1639 SetAlternativeService(server, alternative_service);
1640
1641 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1642 NetworkAnonymizationKey()));
1643 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1644 alternative_service, NetworkAnonymizationKey()));
1645
1646 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1647 alternative_service, NetworkAnonymizationKey());
1648 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1649 NetworkAnonymizationKey()));
1650 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1651 alternative_service, NetworkAnonymizationKey()));
1652
1653 impl_.ConfirmAlternativeService(alternative_service,
1654 NetworkAnonymizationKey());
1655 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1656 NetworkAnonymizationKey()));
1657 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1658 alternative_service, NetworkAnonymizationKey()));
1659 }
1660
TEST_F(AlternateProtocolServerPropertiesTest,MarkBrokenUntilDefaultNetworkChangesWithNetworkIsolationKey)1661 TEST_F(AlternateProtocolServerPropertiesTest,
1662 MarkBrokenUntilDefaultNetworkChangesWithNetworkIsolationKey) {
1663 url::SchemeHostPort server("http", "foo", 80);
1664 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1665 const base::Time expiration = test_clock_.Now() + base::Days(1);
1666
1667 // Without NetworkIsolationKeys enabled, the NetworkAnonymizationKey parameter
1668 // should be ignored.
1669 impl_.SetHttp2AlternativeService(server, network_anonymization_key1_,
1670 alternative_service, expiration);
1671
1672 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1673 network_anonymization_key1_));
1674 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1675 alternative_service, network_anonymization_key1_));
1676 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1677 network_anonymization_key2_));
1678 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1679 alternative_service, network_anonymization_key2_));
1680
1681 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1682 alternative_service, network_anonymization_key1_);
1683 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1684 network_anonymization_key1_));
1685 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1686 alternative_service, network_anonymization_key1_));
1687 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1688 network_anonymization_key2_));
1689 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1690 alternative_service, network_anonymization_key2_));
1691
1692 impl_.ConfirmAlternativeService(alternative_service,
1693 network_anonymization_key2_);
1694 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1695 network_anonymization_key1_));
1696 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1697 alternative_service, network_anonymization_key1_));
1698 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1699 network_anonymization_key2_));
1700 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1701 alternative_service, network_anonymization_key2_));
1702
1703 base::test::ScopedFeatureList feature_list;
1704 feature_list.InitAndEnableFeature(
1705 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1706 // Since HttpServerProperties caches the feature value, have to create a new
1707 // one.
1708 HttpServerProperties properties(nullptr /* pref_delegate */,
1709 nullptr /* net_log */, test_tick_clock_,
1710 &test_clock_);
1711
1712 properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
1713 alternative_service, expiration);
1714 properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
1715 alternative_service, expiration);
1716
1717 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1718 alternative_service, network_anonymization_key1_));
1719 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1720 alternative_service, network_anonymization_key1_));
1721 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1722 alternative_service, network_anonymization_key2_));
1723 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1724 alternative_service, network_anonymization_key2_));
1725
1726 properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1727 alternative_service, network_anonymization_key1_);
1728 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1729 alternative_service, network_anonymization_key1_));
1730 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1731 alternative_service, network_anonymization_key1_));
1732 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1733 alternative_service, network_anonymization_key2_));
1734 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1735 alternative_service, network_anonymization_key2_));
1736
1737 properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1738 alternative_service, network_anonymization_key2_);
1739 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1740 alternative_service, network_anonymization_key1_));
1741 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1742 alternative_service, network_anonymization_key1_));
1743 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1744 alternative_service, network_anonymization_key2_));
1745 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1746 alternative_service, network_anonymization_key2_));
1747
1748 properties.ConfirmAlternativeService(alternative_service,
1749 network_anonymization_key1_);
1750 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1751 alternative_service, network_anonymization_key1_));
1752 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1753 alternative_service, network_anonymization_key1_));
1754 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1755 alternative_service, network_anonymization_key2_));
1756 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1757 alternative_service, network_anonymization_key2_));
1758
1759 properties.ConfirmAlternativeService(alternative_service,
1760 network_anonymization_key2_);
1761 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1762 alternative_service, network_anonymization_key1_));
1763 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1764 alternative_service, network_anonymization_key1_));
1765 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1766 alternative_service, network_anonymization_key2_));
1767 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1768 alternative_service, network_anonymization_key2_));
1769 }
1770
TEST_F(AlternateProtocolServerPropertiesTest,OnDefaultNetworkChanged)1771 TEST_F(AlternateProtocolServerPropertiesTest, OnDefaultNetworkChanged) {
1772 url::SchemeHostPort server("http", "foo", 80);
1773 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1774
1775 SetAlternativeService(server, alternative_service);
1776 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1777 NetworkAnonymizationKey()));
1778 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1779 alternative_service, NetworkAnonymizationKey()));
1780
1781 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1782 alternative_service, NetworkAnonymizationKey());
1783 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1784 NetworkAnonymizationKey()));
1785 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1786 alternative_service, NetworkAnonymizationKey()));
1787
1788 // Default network change clears alt svc broken until default network changes.
1789 impl_.OnDefaultNetworkChanged();
1790 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1791 NetworkAnonymizationKey()));
1792 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1793 alternative_service, NetworkAnonymizationKey()));
1794
1795 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1796 alternative_service, NetworkAnonymizationKey());
1797 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1798 NetworkAnonymizationKey()));
1799 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1800 alternative_service, NetworkAnonymizationKey()));
1801
1802 impl_.MarkAlternativeServiceBroken(alternative_service,
1803 NetworkAnonymizationKey());
1804 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1805 NetworkAnonymizationKey()));
1806 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1807 alternative_service, NetworkAnonymizationKey()));
1808
1809 // Default network change doesn't affect alt svc that was simply marked broken
1810 // most recently.
1811 impl_.OnDefaultNetworkChanged();
1812 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1813 NetworkAnonymizationKey()));
1814 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1815 alternative_service, NetworkAnonymizationKey()));
1816
1817 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1818 alternative_service, NetworkAnonymizationKey());
1819 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1820 NetworkAnonymizationKey()));
1821 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1822 alternative_service, NetworkAnonymizationKey()));
1823
1824 // Default network change clears alt svc that was marked broken until default
1825 // network change most recently even if the alt svc was initially marked
1826 // broken.
1827 impl_.OnDefaultNetworkChanged();
1828 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1829 NetworkAnonymizationKey()));
1830 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1831 alternative_service, NetworkAnonymizationKey()));
1832 }
1833
TEST_F(AlternateProtocolServerPropertiesTest,OnDefaultNetworkChangedWithNetworkIsolationKey)1834 TEST_F(AlternateProtocolServerPropertiesTest,
1835 OnDefaultNetworkChangedWithNetworkIsolationKey) {
1836 url::SchemeHostPort server("http", "foo", 80);
1837 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1838
1839 base::test::ScopedFeatureList feature_list;
1840 feature_list.InitAndEnableFeature(
1841 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1842 // Since HttpServerProperties caches the feature value, have to create a new
1843 // one.
1844 HttpServerProperties properties(nullptr /* pref_delegate */,
1845 nullptr /* net_log */, test_tick_clock_,
1846 &test_clock_);
1847
1848 const base::Time expiration = test_clock_.Now() + base::Days(1);
1849 properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
1850 alternative_service, expiration);
1851 properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
1852 alternative_service, expiration);
1853
1854 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1855 alternative_service, network_anonymization_key1_));
1856 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1857 alternative_service, network_anonymization_key1_));
1858 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1859 alternative_service, network_anonymization_key2_));
1860 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1861 alternative_service, network_anonymization_key2_));
1862
1863 properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1864 alternative_service, network_anonymization_key1_);
1865 properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1866 alternative_service, network_anonymization_key2_);
1867 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1868 alternative_service, network_anonymization_key1_));
1869 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1870 alternative_service, network_anonymization_key1_));
1871 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1872 alternative_service, network_anonymization_key2_));
1873 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1874 alternative_service, network_anonymization_key2_));
1875
1876 // Default network change clears alt svc broken until default network changes.
1877 properties.OnDefaultNetworkChanged();
1878 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1879 alternative_service, network_anonymization_key1_));
1880 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1881 alternative_service, network_anonymization_key1_));
1882 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1883 alternative_service, network_anonymization_key2_));
1884 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1885 alternative_service, network_anonymization_key2_));
1886 }
1887
TEST_F(AlternateProtocolServerPropertiesTest,Canonical)1888 TEST_F(AlternateProtocolServerPropertiesTest, Canonical) {
1889 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1890 EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
1891
1892 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1893 EXPECT_FALSE(
1894 HasAlternativeService(canonical_server, NetworkAnonymizationKey()));
1895
1896 AlternativeServiceInfoVector alternative_service_info_vector;
1897 const AlternativeService canonical_alternative_service1(
1898 kProtoQUIC, "bar.c.youtube.com", 1234);
1899 base::Time expiration = test_clock_.Now() + base::Days(1);
1900 alternative_service_info_vector.push_back(
1901 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
1902 canonical_alternative_service1, expiration,
1903 DefaultSupportedQuicVersions()));
1904 const AlternativeService canonical_alternative_service2(kProtoHTTP2, "", 443);
1905 alternative_service_info_vector.push_back(
1906 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1907 canonical_alternative_service2, expiration));
1908 impl_.SetAlternativeServices(canonical_server, NetworkAnonymizationKey(),
1909 alternative_service_info_vector);
1910
1911 // Since |test_server| does not have an alternative service itself,
1912 // GetAlternativeServiceInfos should return those of |canonical_server|.
1913 AlternativeServiceInfoVector alternative_service_info_vector2 =
1914 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1915 ASSERT_EQ(2u, alternative_service_info_vector2.size());
1916 EXPECT_EQ(canonical_alternative_service1,
1917 alternative_service_info_vector2[0].alternative_service());
1918
1919 // Since |canonical_alternative_service2| has an empty host,
1920 // GetAlternativeServiceInfos should substitute the hostname of its |origin|
1921 // argument.
1922 EXPECT_EQ(test_server.host(),
1923 alternative_service_info_vector2[1].alternative_service().host);
1924 EXPECT_EQ(canonical_alternative_service2.protocol,
1925 alternative_service_info_vector2[1].alternative_service().protocol);
1926 EXPECT_EQ(canonical_alternative_service2.port,
1927 alternative_service_info_vector2[1].alternative_service().port);
1928
1929 // Verify the canonical suffix.
1930 EXPECT_EQ(".c.youtube.com",
1931 *impl_.GetCanonicalSuffixForTesting(test_server.host()));
1932 EXPECT_EQ(".c.youtube.com",
1933 *impl_.GetCanonicalSuffixForTesting(canonical_server.host()));
1934 }
1935
TEST_F(AlternateProtocolServerPropertiesTest,ClearCanonical)1936 TEST_F(AlternateProtocolServerPropertiesTest, ClearCanonical) {
1937 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1938 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1939 AlternativeService canonical_alternative_service(kProtoQUIC,
1940 "bar.c.youtube.com", 1234);
1941
1942 SetAlternativeService(canonical_server, canonical_alternative_service);
1943 impl_.SetAlternativeServices(canonical_server, NetworkAnonymizationKey(),
1944 AlternativeServiceInfoVector());
1945 EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
1946 }
1947
TEST_F(AlternateProtocolServerPropertiesTest,CanonicalWithNetworkIsolationKey)1948 TEST_F(AlternateProtocolServerPropertiesTest,
1949 CanonicalWithNetworkIsolationKey) {
1950 base::test::ScopedFeatureList feature_list;
1951 feature_list.InitAndEnableFeature(
1952 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1953 // Since HttpServerProperties caches the feature value, have to create a new
1954 // one.
1955 HttpServerProperties properties(nullptr /* pref_delegate */,
1956 nullptr /* net_log */, test_tick_clock_,
1957 &test_clock_);
1958
1959 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1960 EXPECT_FALSE(HasAlternativeService(test_server, network_anonymization_key1_));
1961
1962 url::SchemeHostPort canonical_server1("https", "bar.c.youtube.com", 443);
1963 EXPECT_FALSE(
1964 HasAlternativeService(canonical_server1, network_anonymization_key1_));
1965
1966 AlternativeServiceInfoVector alternative_service_info_vector;
1967 const AlternativeService canonical_alternative_service1(
1968 kProtoQUIC, "bar.c.youtube.com", 1234);
1969 base::Time expiration = test_clock_.Now() + base::Days(1);
1970 alternative_service_info_vector.push_back(
1971 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
1972 canonical_alternative_service1, expiration,
1973 DefaultSupportedQuicVersions()));
1974 const AlternativeService canonical_alternative_service2(kProtoHTTP2, "", 443);
1975 alternative_service_info_vector.push_back(
1976 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1977 canonical_alternative_service2, expiration));
1978 properties.SetAlternativeServices(canonical_server1,
1979 network_anonymization_key1_,
1980 alternative_service_info_vector);
1981
1982 // Since |test_server| does not have an alternative service itself,
1983 // GetAlternativeServiceInfos should return those of |canonical_server|.
1984 AlternativeServiceInfoVector alternative_service_info_vector2 =
1985 properties.GetAlternativeServiceInfos(test_server,
1986 network_anonymization_key1_);
1987 ASSERT_EQ(2u, alternative_service_info_vector2.size());
1988 EXPECT_EQ(canonical_alternative_service1,
1989 alternative_service_info_vector2[0].alternative_service());
1990
1991 // Canonical information should not be visible for other NetworkIsolationKeys.
1992 EXPECT_TRUE(
1993 properties
1994 .GetAlternativeServiceInfos(test_server, network_anonymization_key2_)
1995 .empty());
1996 EXPECT_TRUE(
1997 properties
1998 .GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
1999 .empty());
2000
2001 // Now add an alternative service entry for network_anonymization_key2_ for a
2002 // different server and different NetworkAnonymizationKey, but with the same
2003 // canonical suffix.
2004 url::SchemeHostPort canonical_server2("https", "shrimp.c.youtube.com", 443);
2005 properties.SetAlternativeServices(canonical_server2,
2006 network_anonymization_key2_,
2007 {alternative_service_info_vector[0]});
2008
2009 // The canonical server information should reachable, and different, for both
2010 // NetworkIsolationKeys.
2011 EXPECT_EQ(1u, properties
2012 .GetAlternativeServiceInfos(test_server,
2013 network_anonymization_key2_)
2014 .size());
2015 EXPECT_EQ(2u, properties
2016 .GetAlternativeServiceInfos(test_server,
2017 network_anonymization_key1_)
2018 .size());
2019 EXPECT_TRUE(
2020 properties
2021 .GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
2022 .empty());
2023
2024 // Clearing the alternate service state of network_anonymization_key1_'s
2025 // canonical server should only affect network_anonymization_key1_.
2026 properties.SetAlternativeServices(canonical_server1,
2027 network_anonymization_key1_, {});
2028 EXPECT_EQ(1u, properties
2029 .GetAlternativeServiceInfos(test_server,
2030 network_anonymization_key2_)
2031 .size());
2032 EXPECT_TRUE(
2033 properties
2034 .GetAlternativeServiceInfos(test_server, network_anonymization_key1_)
2035 .empty());
2036 EXPECT_TRUE(
2037 properties
2038 .GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
2039 .empty());
2040 }
2041
TEST_F(AlternateProtocolServerPropertiesTest,CanonicalBroken)2042 TEST_F(AlternateProtocolServerPropertiesTest, CanonicalBroken) {
2043 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
2044 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
2045 AlternativeService canonical_alternative_service(kProtoQUIC,
2046 "bar.c.youtube.com", 1234);
2047
2048 SetAlternativeService(canonical_server, canonical_alternative_service);
2049 EXPECT_TRUE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2050 impl_.MarkAlternativeServiceBroken(canonical_alternative_service,
2051 NetworkAnonymizationKey());
2052 EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2053 }
2054
TEST_F(AlternateProtocolServerPropertiesTest,CanonicalBrokenUntilDefaultNetworkChanges)2055 TEST_F(AlternateProtocolServerPropertiesTest,
2056 CanonicalBrokenUntilDefaultNetworkChanges) {
2057 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
2058 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
2059 AlternativeService canonical_alternative_service(kProtoQUIC,
2060 "bar.c.youtube.com", 1234);
2061
2062 SetAlternativeService(canonical_server, canonical_alternative_service);
2063 EXPECT_TRUE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2064 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
2065 canonical_alternative_service, NetworkAnonymizationKey());
2066 EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2067 }
2068
2069 // Adding an alternative service for a new host overrides canonical host.
TEST_F(AlternateProtocolServerPropertiesTest,CanonicalOverride)2070 TEST_F(AlternateProtocolServerPropertiesTest, CanonicalOverride) {
2071 url::SchemeHostPort foo_server("https", "foo.c.youtube.com", 443);
2072 url::SchemeHostPort bar_server("https", "bar.c.youtube.com", 443);
2073 AlternativeService bar_alternative_service(kProtoQUIC, "bar.c.youtube.com",
2074 1234);
2075 SetAlternativeService(bar_server, bar_alternative_service);
2076 AlternativeServiceInfoVector alternative_service_info_vector =
2077 impl_.GetAlternativeServiceInfos(foo_server, NetworkAnonymizationKey());
2078 ASSERT_EQ(1u, alternative_service_info_vector.size());
2079 EXPECT_EQ(bar_alternative_service,
2080 alternative_service_info_vector[0].alternative_service());
2081
2082 url::SchemeHostPort qux_server("https", "qux.c.youtube.com", 443);
2083 AlternativeService qux_alternative_service(kProtoQUIC, "qux.c.youtube.com",
2084 443);
2085 SetAlternativeService(qux_server, qux_alternative_service);
2086 alternative_service_info_vector =
2087 impl_.GetAlternativeServiceInfos(foo_server, NetworkAnonymizationKey());
2088 ASSERT_EQ(1u, alternative_service_info_vector.size());
2089 EXPECT_EQ(qux_alternative_service,
2090 alternative_service_info_vector[0].alternative_service());
2091 }
2092
TEST_F(AlternateProtocolServerPropertiesTest,ClearWithCanonical)2093 TEST_F(AlternateProtocolServerPropertiesTest, ClearWithCanonical) {
2094 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
2095 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
2096 AlternativeService canonical_alternative_service(kProtoQUIC,
2097 "bar.c.youtube.com", 1234);
2098
2099 SetAlternativeService(canonical_server, canonical_alternative_service);
2100 impl_.Clear(base::OnceClosure());
2101 EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2102 }
2103
TEST_F(AlternateProtocolServerPropertiesTest,ExpireBrokenAlternateProtocolMappings)2104 TEST_F(AlternateProtocolServerPropertiesTest,
2105 ExpireBrokenAlternateProtocolMappings) {
2106 url::SchemeHostPort server("https", "foo", 443);
2107 AlternativeService alternative_service(kProtoQUIC, "foo", 443);
2108 SetAlternativeService(server, alternative_service);
2109 EXPECT_TRUE(HasAlternativeService(server, NetworkAnonymizationKey()));
2110 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
2111 NetworkAnonymizationKey()));
2112 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
2113 alternative_service, NetworkAnonymizationKey()));
2114
2115 base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
2116 HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2117 &impl_, alternative_service, past);
2118 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
2119 NetworkAnonymizationKey()));
2120 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
2121 alternative_service, NetworkAnonymizationKey()));
2122
2123 HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
2124 EXPECT_FALSE(HasAlternativeService(server, NetworkAnonymizationKey()));
2125 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
2126 NetworkAnonymizationKey()));
2127 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
2128 alternative_service, NetworkAnonymizationKey()));
2129 }
2130
TEST_F(AlternateProtocolServerPropertiesTest,ExpireBrokenAlternateProtocolMappingsWithNetworkIsolationKey)2131 TEST_F(AlternateProtocolServerPropertiesTest,
2132 ExpireBrokenAlternateProtocolMappingsWithNetworkIsolationKey) {
2133 url::SchemeHostPort server("https", "foo", 443);
2134 AlternativeService alternative_service(kProtoHTTP2, "foo", 444);
2135 base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
2136 base::TimeTicks future = test_tick_clock_->NowTicks() + base::Seconds(42);
2137 const base::Time alt_service_expiration = test_clock_.Now() + base::Days(1);
2138
2139 base::test::ScopedFeatureList feature_list;
2140 feature_list.InitAndEnableFeature(
2141 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
2142 // Since HttpServerProperties caches the feature value, have to create a new
2143 // one.
2144 HttpServerProperties properties(nullptr /* pref_delegate */,
2145 nullptr /* net_log */, test_tick_clock_,
2146 &test_clock_);
2147
2148 properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
2149 alternative_service,
2150 alt_service_expiration);
2151 properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
2152 alternative_service,
2153 alt_service_expiration);
2154
2155 EXPECT_FALSE(
2156 properties.GetAlternativeServiceInfos(server, network_anonymization_key1_)
2157 .empty());
2158 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
2159 alternative_service, network_anonymization_key1_));
2160 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
2161 alternative_service, network_anonymization_key1_));
2162 EXPECT_FALSE(
2163 properties.GetAlternativeServiceInfos(server, network_anonymization_key2_)
2164 .empty());
2165 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
2166 alternative_service, network_anonymization_key2_));
2167 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
2168 alternative_service, network_anonymization_key2_));
2169
2170 // Set broken alternative service with expiration date in the past for
2171 // |network_anonymization_key1_|.
2172 HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2173 &properties, alternative_service, past, network_anonymization_key1_);
2174 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
2175 alternative_service, network_anonymization_key1_));
2176 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2177 alternative_service, network_anonymization_key1_));
2178 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
2179 alternative_service, network_anonymization_key2_));
2180 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
2181 alternative_service, network_anonymization_key2_));
2182
2183 // Set broken alternative service with expiration date in the future for
2184 // |network_anonymization_key1_|.
2185 HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2186 &properties, alternative_service, future, network_anonymization_key2_);
2187 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
2188 alternative_service, network_anonymization_key1_));
2189 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2190 alternative_service, network_anonymization_key1_));
2191 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
2192 alternative_service, network_anonymization_key2_));
2193 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2194 alternative_service, network_anonymization_key2_));
2195
2196 // Only the broken entry for |network_anonymization_key1_| should be expired.
2197 HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&properties);
2198 EXPECT_TRUE(
2199 properties.GetAlternativeServiceInfos(server, network_anonymization_key1_)
2200 .empty());
2201 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
2202 alternative_service, network_anonymization_key1_));
2203 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2204 alternative_service, network_anonymization_key1_));
2205 EXPECT_FALSE(
2206 properties.GetAlternativeServiceInfos(server, network_anonymization_key2_)
2207 .empty());
2208 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
2209 alternative_service, network_anonymization_key2_));
2210 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2211 alternative_service, network_anonymization_key2_));
2212 }
2213
2214 // Regression test for https://crbug.com/505413.
TEST_F(AlternateProtocolServerPropertiesTest,RemoveExpiredBrokenAltSvc)2215 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc) {
2216 url::SchemeHostPort foo_server("https", "foo", 443);
2217 AlternativeService bar_alternative_service(kProtoQUIC, "bar", 443);
2218 SetAlternativeService(foo_server, bar_alternative_service);
2219 EXPECT_TRUE(HasAlternativeService(foo_server, NetworkAnonymizationKey()));
2220
2221 url::SchemeHostPort bar_server1("http", "bar", 80);
2222 AlternativeService nohost_alternative_service(kProtoQUIC, "", 443);
2223 SetAlternativeService(bar_server1, nohost_alternative_service);
2224 EXPECT_TRUE(HasAlternativeService(bar_server1, NetworkAnonymizationKey()));
2225
2226 url::SchemeHostPort bar_server2("https", "bar", 443);
2227 AlternativeService baz_alternative_service(kProtoQUIC, "baz", 1234);
2228 SetAlternativeService(bar_server2, baz_alternative_service);
2229 EXPECT_TRUE(HasAlternativeService(bar_server2, NetworkAnonymizationKey()));
2230
2231 // Mark "bar:443" as broken.
2232 base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
2233 HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2234 &impl_, bar_alternative_service, past);
2235
2236 // Expire brokenness of "bar:443".
2237 HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
2238
2239 // "foo:443" should have no alternative service now.
2240 EXPECT_FALSE(HasAlternativeService(foo_server, NetworkAnonymizationKey()));
2241 // "bar:80" should have no alternative service now.
2242 EXPECT_FALSE(HasAlternativeService(bar_server1, NetworkAnonymizationKey()));
2243 // The alternative service of "bar:443" should be unaffected.
2244 EXPECT_TRUE(HasAlternativeService(bar_server2, NetworkAnonymizationKey()));
2245
2246 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
2247 bar_alternative_service, NetworkAnonymizationKey()));
2248 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
2249 baz_alternative_service, NetworkAnonymizationKey()));
2250 }
2251
TEST_F(AlternateProtocolServerPropertiesTest,SetBrokenAlternativeServicesDelayParams1)2252 TEST_F(AlternateProtocolServerPropertiesTest,
2253 SetBrokenAlternativeServicesDelayParams1) {
2254 url::SchemeHostPort server("https", "foo", 443);
2255 AlternativeService alternative_service(kProtoQUIC, "foo", 443);
2256 SetAlternativeService(server, alternative_service);
2257
2258 const base::TimeDelta initial_delay = base::Seconds(1);
2259 impl_.SetBrokenAlternativeServicesDelayParams(initial_delay, true);
2260 for (int i = 0; i < 10; ++i) {
2261 impl_.MarkAlternativeServiceBroken(alternative_service,
2262 NetworkAnonymizationKey());
2263 // |impl_| should have posted task to expire the brokenness of
2264 // |alternative_service|
2265 EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
2266 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
2267 NetworkAnonymizationKey()));
2268
2269 // Advance time by just enough so that |alternative_service|'s brokenness
2270 // expires.
2271 FastForwardBy(initial_delay * (1 << i));
2272
2273 // Ensure brokenness of |alternative_service| has expired.
2274 EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
2275 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
2276 NetworkAnonymizationKey()));
2277 }
2278 }
2279
TEST_F(AlternateProtocolServerPropertiesTest,SetBrokenAlternativeServicesDelayParams2)2280 TEST_F(AlternateProtocolServerPropertiesTest,
2281 SetBrokenAlternativeServicesDelayParams2) {
2282 url::SchemeHostPort server("https", "foo", 443);
2283 AlternativeService alternative_service(kProtoQUIC, "foo", 443);
2284 SetAlternativeService(server, alternative_service);
2285
2286 const base::TimeDelta initial_delay = base::Seconds(5);
2287 impl_.SetBrokenAlternativeServicesDelayParams(initial_delay, false);
2288 for (int i = 0; i < 10; ++i) {
2289 impl_.MarkAlternativeServiceBroken(alternative_service,
2290 NetworkAnonymizationKey());
2291 // |impl_| should have posted task to expire the brokenness of
2292 // |alternative_service|
2293 EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
2294 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
2295 NetworkAnonymizationKey()));
2296
2297 // Advance time by just enough so that |alternative_service|'s brokenness
2298 // expires.
2299 if (i == 0) {
2300 FastForwardBy(initial_delay);
2301 } else {
2302 FastForwardBy(base::Seconds(300) * (1 << (i - 1)));
2303 }
2304
2305 // Ensure brokenness of |alternative_service| has expired.
2306 EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
2307 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
2308 NetworkAnonymizationKey()));
2309 }
2310 }
2311
2312 // Regression test for https://crbug.com/724302
TEST_F(AlternateProtocolServerPropertiesTest,RemoveExpiredBrokenAltSvc2)2313 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc2) {
2314 // This test will mark an alternative service A that has already been marked
2315 // broken many times, then immediately mark another alternative service B as
2316 // broken for the first time. Because A's been marked broken many times
2317 // already, its brokenness will be scheduled to expire much further in the
2318 // future than B, even though it was marked broken before B. This test makes
2319 // sure that even though A was marked broken before B, B's brokenness should
2320 // expire before A.
2321
2322 url::SchemeHostPort server1("https", "foo", 443);
2323 AlternativeService alternative_service1(kProtoQUIC, "foo", 443);
2324 SetAlternativeService(server1, alternative_service1);
2325
2326 url::SchemeHostPort server2("https", "bar", 443);
2327 AlternativeService alternative_service2(kProtoQUIC, "bar", 443);
2328 SetAlternativeService(server2, alternative_service2);
2329
2330 // Repeatedly mark alt svc 1 broken and wait for its brokenness to expire.
2331 // This will increase its time until expiration.
2332 for (int i = 0; i < 3; ++i) {
2333 impl_.MarkAlternativeServiceBroken(alternative_service1,
2334 NetworkAnonymizationKey());
2335
2336 // |impl_| should have posted task to expire the brokenness of
2337 // |alternative_service1|
2338 EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
2339 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
2340 NetworkAnonymizationKey()));
2341
2342 // Advance time by just enough so that |alternative_service1|'s brokenness
2343 // expires.
2344 FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[i]);
2345
2346 // Ensure brokenness of |alternative_service1| has expired.
2347 EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
2348 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
2349 NetworkAnonymizationKey()));
2350 }
2351
2352 impl_.MarkAlternativeServiceBroken(alternative_service1,
2353 NetworkAnonymizationKey());
2354 impl_.MarkAlternativeServiceBroken(alternative_service2,
2355 NetworkAnonymizationKey());
2356
2357 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service2,
2358 NetworkAnonymizationKey()));
2359
2360 // Advance time by just enough so that |alternative_service2|'s brokennness
2361 // expires.
2362 FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[0]);
2363
2364 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
2365 NetworkAnonymizationKey()));
2366 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
2367 NetworkAnonymizationKey()));
2368
2369 // Advance time by enough so that |alternative_service1|'s brokenness expires.
2370 FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[3] -
2371 BROKEN_ALT_SVC_EXPIRE_DELAYS[0]);
2372
2373 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
2374 NetworkAnonymizationKey()));
2375 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
2376 NetworkAnonymizationKey()));
2377 }
2378
2379 // Regression test for https://crbug.com/994537. Having a ServerInfo entry
2380 // without a populated |alternative_services| value would cause
2381 // OnExpireBrokenAlternativeService() to hang..
TEST_F(AlternateProtocolServerPropertiesTest,RemoveExpiredBrokenAltSvc3)2382 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc3) {
2383 // Add an altertive service entry.
2384 const url::SchemeHostPort kServer1("https", "foo", 443);
2385 const AlternativeService kAltService(kProtoQUIC, "bar", 443);
2386 SetAlternativeService(kServer1, kAltService);
2387 EXPECT_TRUE(HasAlternativeService(kServer1, NetworkAnonymizationKey()));
2388
2389 // Add an entry to ServerInfo for another server, without an alternative
2390 // service value.
2391 const url::SchemeHostPort kServer2("http", "bar", 80);
2392 impl_.SetSupportsSpdy(kServer2, NetworkAnonymizationKey(), false);
2393
2394 // Mark kAltService as broken.
2395 base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
2396 HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2397 &impl_, kAltService, past);
2398
2399 // Expire brokenness of kAltService. This call should not hang.
2400 HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
2401
2402 EXPECT_FALSE(HasAlternativeService(kServer1, NetworkAnonymizationKey()));
2403 }
2404
TEST_F(AlternateProtocolServerPropertiesTest,GetAlternativeServiceInfoAsValue)2405 TEST_F(AlternateProtocolServerPropertiesTest,
2406 GetAlternativeServiceInfoAsValue) {
2407 base::Time::Exploded now_exploded;
2408 now_exploded.year = 2018;
2409 now_exploded.month = 1;
2410 now_exploded.day_of_week = 3;
2411 now_exploded.day_of_month = 24;
2412 now_exploded.hour = 15;
2413 now_exploded.minute = 12;
2414 now_exploded.second = 53;
2415 now_exploded.millisecond = 0;
2416 base::Time now;
2417 bool result = base::Time::FromLocalExploded(now_exploded, &now);
2418 DCHECK(result);
2419 test_clock_.SetNow(now);
2420
2421 AlternativeServiceInfoVector alternative_service_info_vector;
2422 alternative_service_info_vector.push_back(
2423 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
2424 AlternativeService(kProtoHTTP2, "foo", 443), now + base::Minutes(1)));
2425 alternative_service_info_vector.push_back(
2426 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
2427 AlternativeService(kProtoQUIC, "bar", 443), now + base::Hours(1),
2428 DefaultSupportedQuicVersions()));
2429 alternative_service_info_vector.push_back(
2430 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
2431 AlternativeService(kProtoQUIC, "baz", 443), now + base::Hours(1),
2432 DefaultSupportedQuicVersions()));
2433
2434 impl_.SetAlternativeServices(url::SchemeHostPort("https", "youtube.com", 443),
2435 NetworkAnonymizationKey(),
2436 alternative_service_info_vector);
2437
2438 impl_.MarkAlternativeServiceBroken(AlternativeService(kProtoQUIC, "bar", 443),
2439 NetworkAnonymizationKey());
2440
2441 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
2442 AlternativeService(kProtoQUIC, "baz", 443), NetworkAnonymizationKey());
2443
2444 alternative_service_info_vector.clear();
2445 alternative_service_info_vector.push_back(
2446 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
2447 AlternativeService(kProtoHTTP2, "foo2", 443), now + base::Days(1)));
2448 impl_.SetAlternativeServices(url::SchemeHostPort("http", "test.com", 80),
2449 NetworkAnonymizationKey(),
2450 alternative_service_info_vector);
2451
2452 const char expected_json[] =
2453 "["
2454 "{"
2455 "\"alternative_service\":"
2456 "[\"h2 foo2:443, expires 2018-01-25 15:12:53\"],"
2457 "\"network_anonymization_key\":\"null\","
2458 "\"server\":\"http://test.com\""
2459 "},"
2460 "{"
2461 "\"alternative_service\":"
2462 "[\"h2 foo:443, expires 2018-01-24 15:13:53\","
2463 "\"quic bar:443, expires 2018-01-24 16:12:53"
2464 " (broken until 2018-01-24 15:17:53)\","
2465 "\"quic baz:443, expires 2018-01-24 16:12:53"
2466 " (broken until 2018-01-24 15:17:53)\"],"
2467 "\"network_anonymization_key\":\"null\","
2468 "\"server\":\"https://youtube.com\""
2469 "}"
2470 "]";
2471
2472 base::Value alternative_service_info_value =
2473 impl_.GetAlternativeServiceInfoAsValue();
2474 std::string alternative_service_info_json;
2475 base::JSONWriter::Write(alternative_service_info_value,
2476 &alternative_service_info_json);
2477 EXPECT_EQ(expected_json, alternative_service_info_json);
2478 }
2479
TEST_F(HttpServerPropertiesTest,LoadLastLocalAddressWhenQuicWorked)2480 TEST_F(HttpServerPropertiesTest, LoadLastLocalAddressWhenQuicWorked) {
2481 const IPAddress kEmptyAddress;
2482 const IPAddress kValidAddress1 = IPAddress::IPv4Localhost();
2483 const IPAddress kValidAddress2 = IPAddress::IPv6Localhost();
2484
2485 // Check by initializing empty address.
2486 impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kEmptyAddress);
2487 EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2488 // Empty address should not be considered an address that was used when QUIC
2489 // worked.
2490 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2491 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2492 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2493
2494 // Check by initializing with a valid address.
2495 impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kValidAddress1);
2496 EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
2497 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2498 EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2499 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2500
2501 // Try another valid address.
2502 impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kValidAddress2);
2503 EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
2504 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2505 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2506 EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2507
2508 // And loading an empty address clears the current one.
2509 // TODO(mmenke): This seems like a bug, since if we've learned the current
2510 // network supports QUIC, surely we want to save that to disk? Seems like a
2511 // pre-existing value should take precedence, if non-empty, since if the
2512 // current network is already known to support QUIC, the loaded value is no
2513 // longer relevant.
2514 impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kEmptyAddress);
2515 EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2516 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2517 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2518 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2519 }
2520
TEST_F(HttpServerPropertiesTest,SetLastLocalAddressWhenQuicWorked)2521 TEST_F(HttpServerPropertiesTest, SetLastLocalAddressWhenQuicWorked) {
2522 const IPAddress kEmptyAddress;
2523 const IPAddress kValidAddress1 = IPAddress::IPv4Localhost();
2524 const IPAddress kValidAddress2 = IPAddress::IPv6Localhost();
2525
2526 EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2527 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2528 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2529 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2530
2531 // Set to a valid address.
2532 impl_.SetLastLocalAddressWhenQuicWorked(kValidAddress1);
2533 EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
2534 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2535 EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2536 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2537
2538 // Clear only this value.
2539 impl_.ClearLastLocalAddressWhenQuicWorked();
2540 EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2541 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2542 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2543 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2544
2545 // Try another valid address.
2546 impl_.SetLastLocalAddressWhenQuicWorked(kValidAddress2);
2547 EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
2548 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2549 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2550 EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2551
2552 // Clear all values.
2553 impl_.Clear(base::OnceClosure());
2554 EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2555 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2556 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2557 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2558 }
2559
TEST_F(HttpServerPropertiesTest,LoadServerNetworkStats)2560 TEST_F(HttpServerPropertiesTest, LoadServerNetworkStats) {
2561 url::SchemeHostPort google_server("https", "www.google.com", 443);
2562
2563 // Check by initializing empty ServerNetworkStats.
2564 std::unique_ptr<HttpServerProperties::ServerInfoMap> load_server_info_map =
2565 std::make_unique<HttpServerProperties::ServerInfoMap>();
2566 impl_.OnServerInfoLoadedForTesting(std::move(load_server_info_map));
2567 const ServerNetworkStats* stats =
2568 impl_.GetServerNetworkStats(google_server, NetworkAnonymizationKey());
2569 EXPECT_EQ(nullptr, stats);
2570
2571 // Check by initializing with www.google.com:443.
2572 ServerNetworkStats stats_google;
2573 stats_google.srtt = base::Microseconds(10);
2574 stats_google.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
2575 load_server_info_map =
2576 std::make_unique<HttpServerProperties::ServerInfoMap>();
2577 load_server_info_map->GetOrPut(CreateSimpleKey(google_server))
2578 ->second.server_network_stats = stats_google;
2579 impl_.OnServerInfoLoadedForTesting(std::move(load_server_info_map));
2580
2581 // Verify data for www.google.com:443.
2582 ASSERT_EQ(1u, impl_.server_info_map_for_testing().size());
2583 EXPECT_EQ(stats_google, *(impl_.GetServerNetworkStats(
2584 google_server, NetworkAnonymizationKey())));
2585
2586 // Test recency order and overwriting of data.
2587 //
2588 // |docs_server| has a ServerNetworkStats, which will be overwritten by
2589 // OnServerInfoLoadedForTesting(), because |server_network_stats_map| has an
2590 // entry for |docs_server|.
2591 url::SchemeHostPort docs_server("https", "docs.google.com", 443);
2592 ServerNetworkStats stats_docs;
2593 stats_docs.srtt = base::Microseconds(20);
2594 stats_docs.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(200);
2595 // Recency order will be |docs_server| and |google_server|.
2596 impl_.SetServerNetworkStats(docs_server, NetworkAnonymizationKey(),
2597 stats_docs);
2598
2599 // Prepare |server_info_map| to be loaded by OnServerInfoLoadedForTesting().
2600 std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
2601 std::make_unique<HttpServerProperties::ServerInfoMap>();
2602
2603 // Change the values for |docs_server|.
2604 ServerNetworkStats new_stats_docs;
2605 new_stats_docs.srtt = base::Microseconds(25);
2606 new_stats_docs.bandwidth_estimate =
2607 quic::QuicBandwidth::FromBitsPerSecond(250);
2608 server_info_map->GetOrPut(CreateSimpleKey(docs_server))
2609 ->second.server_network_stats = new_stats_docs;
2610 // Add data for mail.google.com:443.
2611 url::SchemeHostPort mail_server("https", "mail.google.com", 443);
2612 ServerNetworkStats stats_mail;
2613 stats_mail.srtt = base::Microseconds(30);
2614 stats_mail.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(300);
2615 server_info_map->GetOrPut(CreateSimpleKey(mail_server))
2616 ->second.server_network_stats = stats_mail;
2617
2618 // Recency order will be |docs_server|, |google_server| and |mail_server|.
2619 impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
2620
2621 const HttpServerProperties::ServerInfoMap& map =
2622 impl_.server_info_map_for_testing();
2623 ASSERT_EQ(3u, map.size());
2624 auto map_it = map.begin();
2625
2626 EXPECT_EQ(docs_server, map_it->first.server);
2627 EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
2628 ASSERT_TRUE(map_it->second.server_network_stats.has_value());
2629 EXPECT_EQ(new_stats_docs, *map_it->second.server_network_stats);
2630 ++map_it;
2631 EXPECT_EQ(google_server, map_it->first.server);
2632 EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
2633 ASSERT_TRUE(map_it->second.server_network_stats.has_value());
2634 EXPECT_EQ(stats_google, *map_it->second.server_network_stats);
2635 ++map_it;
2636 EXPECT_EQ(mail_server, map_it->first.server);
2637 EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
2638 ASSERT_TRUE(map_it->second.server_network_stats.has_value());
2639 EXPECT_EQ(stats_mail, *map_it->second.server_network_stats);
2640 }
2641
TEST_F(HttpServerPropertiesTest,SetServerNetworkStats)2642 TEST_F(HttpServerPropertiesTest, SetServerNetworkStats) {
2643 url::SchemeHostPort foo_http_server("http", "foo", 443);
2644 url::SchemeHostPort foo_https_server("https", "foo", 443);
2645 EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_http_server,
2646 NetworkAnonymizationKey()));
2647 EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
2648 NetworkAnonymizationKey()));
2649
2650 ServerNetworkStats stats1;
2651 stats1.srtt = base::Microseconds(10);
2652 stats1.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
2653 impl_.SetServerNetworkStats(foo_http_server, NetworkAnonymizationKey(),
2654 stats1);
2655
2656 const ServerNetworkStats* stats2 =
2657 impl_.GetServerNetworkStats(foo_http_server, NetworkAnonymizationKey());
2658 EXPECT_EQ(10, stats2->srtt.ToInternalValue());
2659 EXPECT_EQ(100, stats2->bandwidth_estimate.ToBitsPerSecond());
2660 // Https server should have nothing set for server network stats.
2661 EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
2662 NetworkAnonymizationKey()));
2663
2664 impl_.Clear(base::OnceClosure());
2665 EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_http_server,
2666 NetworkAnonymizationKey()));
2667 EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
2668 NetworkAnonymizationKey()));
2669 }
2670
TEST_F(HttpServerPropertiesTest,ClearServerNetworkStats)2671 TEST_F(HttpServerPropertiesTest, ClearServerNetworkStats) {
2672 ServerNetworkStats stats;
2673 stats.srtt = base::Microseconds(10);
2674 stats.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
2675 url::SchemeHostPort foo_https_server("https", "foo", 443);
2676 impl_.SetServerNetworkStats(foo_https_server, NetworkAnonymizationKey(),
2677 stats);
2678
2679 impl_.ClearServerNetworkStats(foo_https_server, NetworkAnonymizationKey());
2680 EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
2681 NetworkAnonymizationKey()));
2682 }
2683
TEST_F(HttpServerPropertiesTest,OnQuicServerInfoMapLoaded)2684 TEST_F(HttpServerPropertiesTest, OnQuicServerInfoMapLoaded) {
2685 quic::QuicServerId google_quic_server_id("www.google.com", 443, true);
2686 HttpServerProperties::QuicServerInfoMapKey google_key(
2687 google_quic_server_id, NetworkAnonymizationKey(),
2688 false /* use_network_anonymization_key */);
2689
2690 const int kMaxQuicServerEntries = 10;
2691 impl_.SetMaxServerConfigsStoredInProperties(kMaxQuicServerEntries);
2692 EXPECT_EQ(10u, impl_.quic_server_info_map().max_size());
2693
2694 // Check empty map.
2695 std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
2696 init_quic_server_info_map =
2697 std::make_unique<HttpServerProperties::QuicServerInfoMap>(
2698 kMaxQuicServerEntries);
2699 impl_.OnQuicServerInfoMapLoadedForTesting(
2700 std::move(init_quic_server_info_map));
2701 EXPECT_EQ(0u, impl_.quic_server_info_map().size());
2702
2703 // Check by initializing with www.google.com:443.
2704 std::string google_server_info("google_quic_server_info");
2705 init_quic_server_info_map =
2706 std::make_unique<HttpServerProperties::QuicServerInfoMap>(
2707 kMaxQuicServerEntries);
2708 init_quic_server_info_map->Put(google_key, google_server_info);
2709 impl_.OnQuicServerInfoMapLoadedForTesting(
2710 std::move(init_quic_server_info_map));
2711
2712 // Verify data for www.google.com:443.
2713 EXPECT_EQ(1u, impl_.quic_server_info_map().size());
2714 EXPECT_EQ(google_server_info,
2715 *impl_.GetQuicServerInfo(google_quic_server_id,
2716 NetworkAnonymizationKey()));
2717
2718 // Test recency order and overwriting of data.
2719 //
2720 // |docs_server| has a QuicServerInfo, which will be overwritten by
2721 // SetQuicServerInfoMap(), because |quic_server_info_map| has an
2722 // entry for |docs_server|.
2723 quic::QuicServerId docs_quic_server_id("docs.google.com", 443, true);
2724 HttpServerProperties::QuicServerInfoMapKey docs_key(
2725 docs_quic_server_id, NetworkAnonymizationKey(),
2726 false /* use_network_anonymization_key */);
2727 std::string docs_server_info("docs_quic_server_info");
2728 impl_.SetQuicServerInfo(docs_quic_server_id, NetworkAnonymizationKey(),
2729 docs_server_info);
2730
2731 // Recency order will be |docs_server| and |google_server|.
2732 const HttpServerProperties::QuicServerInfoMap& map =
2733 impl_.quic_server_info_map();
2734 ASSERT_EQ(2u, map.size());
2735 auto map_it = map.begin();
2736 EXPECT_EQ(map_it->first, docs_key);
2737 EXPECT_EQ(docs_server_info, map_it->second);
2738 ++map_it;
2739 EXPECT_EQ(map_it->first, google_key);
2740 EXPECT_EQ(google_server_info, map_it->second);
2741
2742 // Prepare |quic_server_info_map| to be loaded by
2743 // SetQuicServerInfoMap().
2744 std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
2745 quic_server_info_map =
2746 std::make_unique<HttpServerProperties::QuicServerInfoMap>(
2747 kMaxQuicServerEntries);
2748 // Change the values for |docs_server|.
2749 std::string new_docs_server_info("new_docs_quic_server_info");
2750 quic_server_info_map->Put(docs_key, new_docs_server_info);
2751 // Add data for mail.google.com:443.
2752 quic::QuicServerId mail_quic_server_id("mail.google.com", 443, true);
2753 HttpServerProperties::QuicServerInfoMapKey mail_key(
2754 mail_quic_server_id, NetworkAnonymizationKey(),
2755 false /* use_network_anonymization_key */);
2756 std::string mail_server_info("mail_quic_server_info");
2757 quic_server_info_map->Put(mail_key, mail_server_info);
2758 impl_.OnQuicServerInfoMapLoadedForTesting(std::move(quic_server_info_map));
2759
2760 // Recency order will be |docs_server|, |google_server| and |mail_server|.
2761 const HttpServerProperties::QuicServerInfoMap& memory_map =
2762 impl_.quic_server_info_map();
2763 ASSERT_EQ(3u, memory_map.size());
2764 auto memory_map_it = memory_map.begin();
2765 EXPECT_EQ(memory_map_it->first, docs_key);
2766 EXPECT_EQ(new_docs_server_info, memory_map_it->second);
2767 ++memory_map_it;
2768 EXPECT_EQ(memory_map_it->first, google_key);
2769 EXPECT_EQ(google_server_info, memory_map_it->second);
2770 ++memory_map_it;
2771 EXPECT_EQ(memory_map_it->first, mail_key);
2772 EXPECT_EQ(mail_server_info, memory_map_it->second);
2773
2774 // Shrink the size of |quic_server_info_map| and verify the MRU order is
2775 // maintained.
2776 impl_.SetMaxServerConfigsStoredInProperties(2);
2777 EXPECT_EQ(2u, impl_.quic_server_info_map().max_size());
2778
2779 const HttpServerProperties::QuicServerInfoMap& memory_map1 =
2780 impl_.quic_server_info_map();
2781 ASSERT_EQ(2u, memory_map1.size());
2782 auto memory_map1_it = memory_map1.begin();
2783 EXPECT_EQ(memory_map1_it->first, docs_key);
2784 EXPECT_EQ(new_docs_server_info, memory_map1_it->second);
2785 ++memory_map1_it;
2786 EXPECT_EQ(memory_map1_it->first, google_key);
2787 EXPECT_EQ(google_server_info, memory_map1_it->second);
2788 // |QuicServerInfo| for |mail_quic_server_id| shouldn't be there.
2789 EXPECT_EQ(nullptr, impl_.GetQuicServerInfo(mail_quic_server_id,
2790 NetworkAnonymizationKey()));
2791 }
2792
TEST_F(HttpServerPropertiesTest,SetQuicServerInfo)2793 TEST_F(HttpServerPropertiesTest, SetQuicServerInfo) {
2794 quic::QuicServerId server1("foo", 80, false /* privacy_mode_enabled */);
2795 quic::QuicServerId server2("foo", 80, true /* privacy_mode_enabled */);
2796
2797 std::string quic_server_info1("quic_server_info1");
2798 std::string quic_server_info2("quic_server_info2");
2799 std::string quic_server_info3("quic_server_info3");
2800
2801 // Without network isolation keys enabled for HttpServerProperties, passing in
2802 // a NetworkAnonymizationKey should have no effect on behavior.
2803 impl_.SetQuicServerInfo(server1, NetworkAnonymizationKey(),
2804 quic_server_info1);
2805 EXPECT_EQ(quic_server_info1,
2806 *(impl_.GetQuicServerInfo(server1, NetworkAnonymizationKey())));
2807 EXPECT_FALSE(impl_.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2808 EXPECT_EQ(quic_server_info1,
2809 *(impl_.GetQuicServerInfo(server1, network_anonymization_key1_)));
2810 EXPECT_FALSE(impl_.GetQuicServerInfo(server2, network_anonymization_key1_));
2811
2812 impl_.SetQuicServerInfo(server2, network_anonymization_key1_,
2813 quic_server_info2);
2814 EXPECT_EQ(quic_server_info1,
2815 *(impl_.GetQuicServerInfo(server1, NetworkAnonymizationKey())));
2816 EXPECT_EQ(quic_server_info2,
2817 *(impl_.GetQuicServerInfo(server2, NetworkAnonymizationKey())));
2818 EXPECT_EQ(quic_server_info1,
2819 *(impl_.GetQuicServerInfo(server1, network_anonymization_key1_)));
2820 EXPECT_EQ(quic_server_info2,
2821 *(impl_.GetQuicServerInfo(server2, network_anonymization_key1_)));
2822
2823 impl_.SetQuicServerInfo(server1, network_anonymization_key1_,
2824 quic_server_info3);
2825 EXPECT_EQ(quic_server_info3,
2826 *(impl_.GetQuicServerInfo(server1, NetworkAnonymizationKey())));
2827 EXPECT_EQ(quic_server_info2,
2828 *(impl_.GetQuicServerInfo(server2, NetworkAnonymizationKey())));
2829 EXPECT_EQ(quic_server_info3,
2830 *(impl_.GetQuicServerInfo(server1, network_anonymization_key1_)));
2831 EXPECT_EQ(quic_server_info2,
2832 *(impl_.GetQuicServerInfo(server2, network_anonymization_key1_)));
2833
2834 impl_.Clear(base::OnceClosure());
2835 EXPECT_FALSE(impl_.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2836 EXPECT_FALSE(impl_.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2837 EXPECT_FALSE(impl_.GetQuicServerInfo(server1, network_anonymization_key1_));
2838 EXPECT_FALSE(impl_.GetQuicServerInfo(server2, network_anonymization_key1_));
2839
2840 base::test::ScopedFeatureList feature_list;
2841 feature_list.InitAndEnableFeature(
2842 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
2843 // Since HttpServerProperties caches the feature value, have to create a new
2844 // one.
2845 HttpServerProperties properties(nullptr /* pref_delegate */,
2846 nullptr /* net_log */, test_tick_clock_,
2847 &test_clock_);
2848
2849 properties.SetQuicServerInfo(server1, NetworkAnonymizationKey(),
2850 quic_server_info1);
2851 EXPECT_EQ(quic_server_info1, *(properties.GetQuicServerInfo(
2852 server1, NetworkAnonymizationKey())));
2853 EXPECT_FALSE(
2854 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2855 EXPECT_FALSE(
2856 properties.GetQuicServerInfo(server1, network_anonymization_key1_));
2857 EXPECT_FALSE(
2858 properties.GetQuicServerInfo(server2, network_anonymization_key1_));
2859
2860 properties.SetQuicServerInfo(server1, network_anonymization_key1_,
2861 quic_server_info2);
2862 EXPECT_EQ(quic_server_info1, *(properties.GetQuicServerInfo(
2863 server1, NetworkAnonymizationKey())));
2864 EXPECT_FALSE(
2865 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2866 EXPECT_EQ(quic_server_info2, *(properties.GetQuicServerInfo(
2867 server1, network_anonymization_key1_)));
2868 EXPECT_FALSE(
2869 properties.GetQuicServerInfo(server2, network_anonymization_key1_));
2870
2871 properties.SetQuicServerInfo(server2, network_anonymization_key1_,
2872 quic_server_info3);
2873 EXPECT_EQ(quic_server_info1, *(properties.GetQuicServerInfo(
2874 server1, NetworkAnonymizationKey())));
2875 EXPECT_FALSE(
2876 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2877 EXPECT_EQ(quic_server_info2, *(properties.GetQuicServerInfo(
2878 server1, network_anonymization_key1_)));
2879 EXPECT_EQ(quic_server_info3, *(properties.GetQuicServerInfo(
2880 server2, network_anonymization_key1_)));
2881
2882 properties.Clear(base::OnceClosure());
2883 EXPECT_FALSE(
2884 properties.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2885 EXPECT_FALSE(
2886 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2887 EXPECT_FALSE(
2888 properties.GetQuicServerInfo(server1, network_anonymization_key1_));
2889 EXPECT_FALSE(
2890 properties.GetQuicServerInfo(server2, network_anonymization_key1_));
2891 }
2892
2893 // Tests that GetQuicServerInfo() returns server info of a host
2894 // with the same canonical suffix when there is no exact host match.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatch)2895 TEST_F(HttpServerPropertiesTest, QuicServerInfoCanonicalSuffixMatch) {
2896 // Set up HttpServerProperties.
2897 // Add a host with a canonical suffix.
2898 quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
2899 std::string foo_server_info("foo_server_info");
2900 impl_.SetQuicServerInfo(foo_server_id, NetworkAnonymizationKey(),
2901 foo_server_info);
2902
2903 // Add a host that has a different canonical suffix.
2904 quic::QuicServerId baz_server_id("baz.video.com", 443, false);
2905 std::string baz_server_info("baz_server_info");
2906 impl_.SetQuicServerInfo(baz_server_id, NetworkAnonymizationKey(),
2907 baz_server_info);
2908
2909 // Create SchemeHostPort with a host that has the initial canonical suffix.
2910 quic::QuicServerId bar_server_id("bar.googlevideo.com", 443, false);
2911
2912 // Check the the server info associated with "foo" is returned for "bar".
2913 const std::string* bar_server_info =
2914 impl_.GetQuicServerInfo(bar_server_id, NetworkAnonymizationKey());
2915 ASSERT_TRUE(bar_server_info != nullptr);
2916 EXPECT_EQ(foo_server_info, *bar_server_info);
2917 }
2918
2919 // Make sure that canonical suffices respect NetworkIsolationKeys when using
2920 // QuicServerInfo methods.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatchWithNetworkIsolationKey)2921 TEST_F(HttpServerPropertiesTest,
2922 QuicServerInfoCanonicalSuffixMatchWithNetworkIsolationKey) {
2923 // Two servers with same canonical suffix.
2924 quic::QuicServerId server1("foo.googlevideo.com", 80,
2925 false /* privacy_mode_enabled */);
2926 quic::QuicServerId server2("bar.googlevideo.com", 80,
2927 false /* privacy_mode_enabled */);
2928
2929 std::string server_info1("server_info1");
2930 std::string server_info2("server_info2");
2931
2932 base::test::ScopedFeatureList feature_list;
2933 feature_list.InitAndEnableFeature(
2934 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
2935 // Since HttpServerProperties caches the feature value, have to create a new
2936 // one.
2937 HttpServerProperties properties(nullptr /* pref_delegate */,
2938 nullptr /* net_log */, test_tick_clock_,
2939 &test_clock_);
2940
2941 // Set QuicServerInfo for one canononical suffix and
2942 // |network_anonymization_key1_|. It should be accessible via another
2943 // SchemeHostPort, but only when the NetworkIsolationKeys match.
2944 properties.SetQuicServerInfo(server1, network_anonymization_key1_,
2945 server_info1);
2946 const std::string* fetched_server_info =
2947 properties.GetQuicServerInfo(server1, network_anonymization_key1_);
2948 ASSERT_TRUE(fetched_server_info);
2949 EXPECT_EQ(server_info1, *fetched_server_info);
2950 fetched_server_info =
2951 properties.GetQuicServerInfo(server2, network_anonymization_key1_);
2952 ASSERT_TRUE(fetched_server_info);
2953 EXPECT_EQ(server_info1, *fetched_server_info);
2954 EXPECT_FALSE(
2955 properties.GetQuicServerInfo(server1, network_anonymization_key2_));
2956 EXPECT_FALSE(
2957 properties.GetQuicServerInfo(server2, network_anonymization_key2_));
2958 EXPECT_FALSE(
2959 properties.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2960 EXPECT_FALSE(
2961 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2962
2963 // Set different QuicServerInfo for the same canononical suffix and
2964 // |network_anonymization_key2_|. Both infos should be retriveable by using
2965 // the different NetworkIsolationKeys.
2966 properties.SetQuicServerInfo(server1, network_anonymization_key2_,
2967 server_info2);
2968 fetched_server_info =
2969 properties.GetQuicServerInfo(server1, network_anonymization_key1_);
2970 ASSERT_TRUE(fetched_server_info);
2971 EXPECT_EQ(server_info1, *fetched_server_info);
2972 fetched_server_info =
2973 properties.GetQuicServerInfo(server2, network_anonymization_key1_);
2974 ASSERT_TRUE(fetched_server_info);
2975 EXPECT_EQ(server_info1, *fetched_server_info);
2976 fetched_server_info =
2977 properties.GetQuicServerInfo(server1, network_anonymization_key2_);
2978 ASSERT_TRUE(fetched_server_info);
2979 EXPECT_EQ(server_info2, *fetched_server_info);
2980 fetched_server_info =
2981 properties.GetQuicServerInfo(server2, network_anonymization_key2_);
2982 ASSERT_TRUE(fetched_server_info);
2983 EXPECT_EQ(server_info2, *fetched_server_info);
2984 EXPECT_FALSE(
2985 properties.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2986 EXPECT_FALSE(
2987 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2988
2989 // Clearing should destroy all information.
2990 properties.Clear(base::OnceClosure());
2991 EXPECT_FALSE(
2992 properties.GetQuicServerInfo(server1, network_anonymization_key1_));
2993 EXPECT_FALSE(
2994 properties.GetQuicServerInfo(server2, network_anonymization_key1_));
2995 EXPECT_FALSE(
2996 properties.GetQuicServerInfo(server1, network_anonymization_key2_));
2997 EXPECT_FALSE(
2998 properties.GetQuicServerInfo(server2, network_anonymization_key2_));
2999 EXPECT_FALSE(
3000 properties.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
3001 EXPECT_FALSE(
3002 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
3003 }
3004
3005 // Verifies that GetQuicServerInfo() returns the MRU entry if multiple records
3006 // match a given canonical host.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatchReturnsMruEntry)3007 TEST_F(HttpServerPropertiesTest,
3008 QuicServerInfoCanonicalSuffixMatchReturnsMruEntry) {
3009 // Set up HttpServerProperties by adding two hosts with the same canonical
3010 // suffixes.
3011 quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
3012 std::string h1_server_info("h1_server_info");
3013 impl_.SetQuicServerInfo(h1_server_id, NetworkAnonymizationKey(),
3014 h1_server_info);
3015
3016 quic::QuicServerId h2_server_id("h2.googlevideo.com", 443, false);
3017 std::string h2_server_info("h2_server_info");
3018 impl_.SetQuicServerInfo(h2_server_id, NetworkAnonymizationKey(),
3019 h2_server_info);
3020
3021 // Create quic::QuicServerId to use for the search.
3022 quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
3023
3024 // Check that 'h2' info is returned since it is MRU.
3025 const std::string* server_info =
3026 impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3027 ASSERT_TRUE(server_info != nullptr);
3028 EXPECT_EQ(h2_server_info, *server_info);
3029
3030 // Access 'h1' info, so it becomes MRU.
3031 impl_.GetQuicServerInfo(h1_server_id, NetworkAnonymizationKey());
3032
3033 // Check that 'h1' info is returned since it is MRU now.
3034 server_info =
3035 impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3036 ASSERT_TRUE(server_info != nullptr);
3037 EXPECT_EQ(h1_server_info, *server_info);
3038 }
3039
3040 // Verifies that |GetQuicServerInfo| doesn't change the MRU order of the server
3041 // info map when a record is matched based on a canonical name.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatchDoesntChangeOrder)3042 TEST_F(HttpServerPropertiesTest,
3043 QuicServerInfoCanonicalSuffixMatchDoesntChangeOrder) {
3044 // Add a host with a matching canonical name.
3045 quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
3046 HttpServerProperties::QuicServerInfoMapKey h1_key(
3047 h1_server_id, NetworkAnonymizationKey(),
3048 false /* use_network_anonymization_key */);
3049 std::string h1_server_info("h1_server_info");
3050 impl_.SetQuicServerInfo(h1_server_id, NetworkAnonymizationKey(),
3051 h1_server_info);
3052
3053 // Add a host hosts with a non-matching canonical name.
3054 quic::QuicServerId h2_server_id("h2.video.com", 443, false);
3055 HttpServerProperties::QuicServerInfoMapKey h2_key(
3056 h2_server_id, NetworkAnonymizationKey(),
3057 false /* use_network_anonymization_key */);
3058 std::string h2_server_info("h2_server_info");
3059 impl_.SetQuicServerInfo(h2_server_id, NetworkAnonymizationKey(),
3060 h2_server_info);
3061
3062 // Check that "h2.video.com" is the MRU entry in the map.
3063 EXPECT_EQ(h2_key, impl_.quic_server_info_map().begin()->first);
3064
3065 // Search for the entry that matches the canonical name
3066 // ("h1.googlevideo.com").
3067 quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
3068 const std::string* server_info =
3069 impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3070 ASSERT_TRUE(server_info != nullptr);
3071
3072 // Check that the search (although successful) hasn't changed the MRU order of
3073 // the map.
3074 EXPECT_EQ(h2_key, impl_.quic_server_info_map().begin()->first);
3075
3076 // Search for "h1.googlevideo.com" directly, so it becomes MRU
3077 impl_.GetQuicServerInfo(h1_server_id, NetworkAnonymizationKey());
3078
3079 // Check that "h1.googlevideo.com" is the MRU entry now.
3080 EXPECT_EQ(h1_key, impl_.quic_server_info_map().begin()->first);
3081 }
3082
3083 // Tests that the canonical host matching works for hosts stored in memory cache
3084 // and the ones loaded from persistent storage, i.e. server info added
3085 // using SetQuicServerInfo() and SetQuicServerInfoMap() is taken into
3086 // cosideration when searching for server info for a host with the same
3087 // canonical suffix.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatchSetInfoMap)3088 TEST_F(HttpServerPropertiesTest, QuicServerInfoCanonicalSuffixMatchSetInfoMap) {
3089 // Add a host info using SetQuicServerInfo(). That will simulate an info
3090 // entry stored in memory cache.
3091 quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
3092 std::string h1_server_info("h1_server_info_memory_cache");
3093 impl_.SetQuicServerInfo(h1_server_id, NetworkAnonymizationKey(),
3094 h1_server_info);
3095
3096 // Prepare a map with host info and add it using SetQuicServerInfoMap(). That
3097 // will simulate info records read from the persistence storage.
3098 quic::QuicServerId h2_server_id("h2.googlevideo.com", 443, false);
3099 HttpServerProperties::QuicServerInfoMapKey h2_key(
3100 h2_server_id, NetworkAnonymizationKey(),
3101 false /* use_network_anonymization_key */);
3102 std::string h2_server_info("h2_server_info_from_disk");
3103
3104 quic::QuicServerId h3_server_id("h3.ggpht.com", 443, false);
3105 HttpServerProperties::QuicServerInfoMapKey h3_key(
3106 h3_server_id, NetworkAnonymizationKey(),
3107 false /* use_network_anonymization_key */);
3108 std::string h3_server_info("h3_server_info_from_disk");
3109
3110 const int kMaxQuicServerEntries = 10;
3111 impl_.SetMaxServerConfigsStoredInProperties(kMaxQuicServerEntries);
3112
3113 std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
3114 quic_server_info_map =
3115 std::make_unique<HttpServerProperties::QuicServerInfoMap>(
3116 kMaxQuicServerEntries);
3117 quic_server_info_map->Put(h2_key, h2_server_info);
3118 quic_server_info_map->Put(h3_key, h3_server_info);
3119 impl_.OnQuicServerInfoMapLoadedForTesting(std::move(quic_server_info_map));
3120
3121 // Check that the server info from the memory cache is returned since unique
3122 // entries from the memory cache are added after entries from the
3123 // persistence storage and, therefore, are most recently used.
3124 quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
3125 const std::string* server_info =
3126 impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3127 ASSERT_TRUE(server_info != nullptr);
3128 EXPECT_EQ(h1_server_info, *server_info);
3129
3130 // Check that server info that was added using SetQuicServerInfoMap() can be
3131 // found.
3132 foo_server_id = quic::QuicServerId("foo.ggpht.com", 443, false);
3133 server_info =
3134 impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3135 ASSERT_TRUE(server_info != nullptr);
3136 EXPECT_EQ(h3_server_info, *server_info);
3137 }
3138
3139 } // namespace
3140
3141 } // namespace net
3142