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 // GetAlternativeServiceInfos() should remove |server_info_map_|
926 // elements with empty value.
TEST_F(AlternateProtocolServerPropertiesTest,EmptyVector)927 TEST_F(AlternateProtocolServerPropertiesTest, EmptyVector) {
928 url::SchemeHostPort server("https", "foo", 443);
929 const AlternativeService alternative_service(kProtoHTTP2, "bar", 443);
930 base::Time expiration = test_clock_.Now() - base::Days(1);
931 const AlternativeServiceInfo alternative_service_info =
932 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
933 alternative_service, expiration);
934 std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
935 std::make_unique<HttpServerProperties::ServerInfoMap>();
936 server_info_map->GetOrPut(CreateSimpleKey(server))
937 ->second.alternative_services = AlternativeServiceInfoVector(
938 /*size=*/1, alternative_service_info);
939
940 // Prepare |server_info_map_| with a single key that has a single
941 // AlternativeServiceInfo with identical hostname and port.
942 impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
943
944 // GetAlternativeServiceInfos() should remove such AlternativeServiceInfo from
945 // |server_info_map_|, emptying the AlternativeServiceInfoVector
946 // corresponding to |server|.
947 ASSERT_TRUE(
948 impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
949 .empty());
950
951 // GetAlternativeServiceInfos() should remove this key from
952 // |server_info_map_|, and SetAlternativeServices() should not crash.
953 impl_.SetAlternativeServices(
954 server, NetworkAnonymizationKey(),
955 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
956
957 // There should still be no alternative service assigned to |server|.
958 ASSERT_TRUE(
959 impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
960 .empty());
961 }
962
963 // Regression test for https://crbug.com/516486 for the canonical host case.
TEST_F(AlternateProtocolServerPropertiesTest,EmptyVectorForCanonical)964 TEST_F(AlternateProtocolServerPropertiesTest, EmptyVectorForCanonical) {
965 url::SchemeHostPort server("https", "foo.c.youtube.com", 443);
966 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
967 const AlternativeService alternative_service(kProtoHTTP2, "", 443);
968 base::Time expiration = test_clock_.Now() - base::Days(1);
969 const AlternativeServiceInfo alternative_service_info =
970 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
971 alternative_service, expiration);
972 std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
973 std::make_unique<HttpServerProperties::ServerInfoMap>();
974 server_info_map->GetOrPut(CreateSimpleKey(canonical_server))
975 ->second.alternative_services =
976 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info);
977
978 // Prepare |server_info_map_| with a single key that has a single
979 // AlternativeServiceInfo with identical hostname and port.
980 impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
981
982 // GetAlternativeServiceInfos() should remove such AlternativeServiceInfo from
983 // |server_info_map_|, emptying the AlternativeServiceInfoVector
984 // corresponding to |canonical_server|, even when looking up
985 // alternative services for |server|.
986 ASSERT_TRUE(
987 impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
988 .empty());
989
990 // GetAlternativeServiceInfos() should remove this key from
991 // |server_info_map_|, and SetAlternativeServices() should not crash.
992 impl_.SetAlternativeServices(
993 canonical_server, NetworkAnonymizationKey(),
994 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
995
996 // There should still be no alternative service assigned to
997 // |canonical_server|.
998 ASSERT_TRUE(impl_
999 .GetAlternativeServiceInfos(canonical_server,
1000 NetworkAnonymizationKey())
1001 .empty());
1002 }
1003
TEST_F(AlternateProtocolServerPropertiesTest,ClearServerWithCanonical)1004 TEST_F(AlternateProtocolServerPropertiesTest, ClearServerWithCanonical) {
1005 url::SchemeHostPort server("https", "foo.c.youtube.com", 443);
1006 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1007 const AlternativeService alternative_service(kProtoQUIC, "", 443);
1008 base::Time expiration = test_clock_.Now() + base::Days(1);
1009 const AlternativeServiceInfo alternative_service_info =
1010 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
1011 alternative_service, expiration, DefaultSupportedQuicVersions());
1012
1013 impl_.SetAlternativeServices(
1014 canonical_server, NetworkAnonymizationKey(),
1015 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
1016
1017 // Make sure the canonical service is returned for the other server.
1018 const AlternativeServiceInfoVector alternative_service_info_vector =
1019 impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey());
1020 ASSERT_EQ(1u, alternative_service_info_vector.size());
1021 EXPECT_EQ(kProtoQUIC,
1022 alternative_service_info_vector[0].alternative_service().protocol);
1023 EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port);
1024
1025 // Now clear the alternatives for the other server and make sure it stays
1026 // cleared.
1027 // GetAlternativeServices() should remove this key from
1028 // |server_info_map_|, and SetAlternativeServices() should not crash.
1029 impl_.SetAlternativeServices(server, NetworkAnonymizationKey(),
1030 AlternativeServiceInfoVector());
1031
1032 ASSERT_TRUE(
1033 impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
1034 .empty());
1035 }
1036
TEST_F(AlternateProtocolServerPropertiesTest,MRUOfGetAlternativeServiceInfos)1037 TEST_F(AlternateProtocolServerPropertiesTest, MRUOfGetAlternativeServiceInfos) {
1038 url::SchemeHostPort test_server1("http", "foo1", 80);
1039 const AlternativeService alternative_service1(kProtoHTTP2, "foo1", 443);
1040 SetAlternativeService(test_server1, alternative_service1);
1041 url::SchemeHostPort test_server2("http", "foo2", 80);
1042 const AlternativeService alternative_service2(kProtoHTTP2, "foo2", 1234);
1043 SetAlternativeService(test_server2, alternative_service2);
1044
1045 const HttpServerProperties::ServerInfoMap& map =
1046 impl_.server_info_map_for_testing();
1047 auto it = map.begin();
1048 EXPECT_EQ(test_server2, it->first.server);
1049 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
1050 ASSERT_TRUE(it->second.alternative_services.has_value());
1051 ASSERT_EQ(1u, it->second.alternative_services->size());
1052 EXPECT_EQ(alternative_service2,
1053 it->second.alternative_services.value()[0].alternative_service());
1054
1055 const AlternativeServiceInfoVector alternative_service_info_vector =
1056 impl_.GetAlternativeServiceInfos(test_server1, NetworkAnonymizationKey());
1057 ASSERT_EQ(1u, alternative_service_info_vector.size());
1058 EXPECT_EQ(alternative_service1,
1059 alternative_service_info_vector[0].alternative_service());
1060
1061 // GetAlternativeServices should reorder the AlternateProtocol map.
1062 it = map.begin();
1063 EXPECT_EQ(test_server1, it->first.server);
1064 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
1065 ASSERT_TRUE(it->second.alternative_services.has_value());
1066 ASSERT_EQ(1u, it->second.alternative_services->size());
1067 EXPECT_EQ(alternative_service1,
1068 it->second.alternative_services.value()[0].alternative_service());
1069 }
1070
TEST_F(AlternateProtocolServerPropertiesTest,SetBroken)1071 TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) {
1072 url::SchemeHostPort test_server("http", "foo", 80);
1073 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1074 SetAlternativeService(test_server, alternative_service1);
1075 AlternativeServiceInfoVector alternative_service_info_vector =
1076 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1077 ASSERT_EQ(1u, alternative_service_info_vector.size());
1078 EXPECT_EQ(alternative_service1,
1079 alternative_service_info_vector[0].alternative_service());
1080 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
1081 NetworkAnonymizationKey()));
1082
1083 // GetAlternativeServiceInfos should return the broken alternative service.
1084 impl_.MarkAlternativeServiceBroken(alternative_service1,
1085 NetworkAnonymizationKey());
1086 alternative_service_info_vector =
1087 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1088 ASSERT_EQ(1u, alternative_service_info_vector.size());
1089 EXPECT_EQ(alternative_service1,
1090 alternative_service_info_vector[0].alternative_service());
1091 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1092 NetworkAnonymizationKey()));
1093
1094 // SetAlternativeServices should add a broken alternative service to the map.
1095 AlternativeServiceInfoVector alternative_service_info_vector2;
1096 base::Time expiration = test_clock_.Now() + base::Days(1);
1097 alternative_service_info_vector2.push_back(
1098 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1099 alternative_service1, expiration));
1100 const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234);
1101 alternative_service_info_vector2.push_back(
1102 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1103 alternative_service2, expiration));
1104 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1105 alternative_service_info_vector2);
1106 alternative_service_info_vector =
1107 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1108 ASSERT_EQ(2u, alternative_service_info_vector.size());
1109 EXPECT_EQ(alternative_service1,
1110 alternative_service_info_vector[0].alternative_service());
1111 EXPECT_EQ(alternative_service2,
1112 alternative_service_info_vector[1].alternative_service());
1113 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1114 NetworkAnonymizationKey()));
1115 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
1116 NetworkAnonymizationKey()));
1117
1118 // SetAlternativeService should add a broken alternative service to the map.
1119 SetAlternativeService(test_server, alternative_service1);
1120 alternative_service_info_vector =
1121 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1122 ASSERT_EQ(1u, alternative_service_info_vector.size());
1123 EXPECT_EQ(alternative_service1,
1124 alternative_service_info_vector[0].alternative_service());
1125 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1126 NetworkAnonymizationKey()));
1127 }
1128
TEST_F(AlternateProtocolServerPropertiesTest,SetBrokenUntilDefaultNetworkChanges)1129 TEST_F(AlternateProtocolServerPropertiesTest,
1130 SetBrokenUntilDefaultNetworkChanges) {
1131 url::SchemeHostPort test_server("http", "foo", 80);
1132 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1133 SetAlternativeService(test_server, alternative_service1);
1134 AlternativeServiceInfoVector alternative_service_info_vector =
1135 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1136 ASSERT_EQ(1u, alternative_service_info_vector.size());
1137 EXPECT_EQ(alternative_service1,
1138 alternative_service_info_vector[0].alternative_service());
1139 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
1140 NetworkAnonymizationKey()));
1141
1142 // Mark the alternative service as broken until the default network changes.
1143 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1144 alternative_service1, NetworkAnonymizationKey());
1145 // The alternative service should be persisted and marked as broken.
1146 alternative_service_info_vector =
1147 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1148 ASSERT_EQ(1u, alternative_service_info_vector.size());
1149 EXPECT_EQ(alternative_service1,
1150 alternative_service_info_vector[0].alternative_service());
1151 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1152 NetworkAnonymizationKey()));
1153
1154 // SetAlternativeServices should add a broken alternative service to the map.
1155 AlternativeServiceInfoVector alternative_service_info_vector2;
1156 base::Time expiration = test_clock_.Now() + base::Days(1);
1157 alternative_service_info_vector2.push_back(
1158 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1159 alternative_service1, expiration));
1160 const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234);
1161 alternative_service_info_vector2.push_back(
1162 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1163 alternative_service2, expiration));
1164 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1165 alternative_service_info_vector2);
1166 alternative_service_info_vector =
1167 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1168 ASSERT_EQ(2u, alternative_service_info_vector.size());
1169 EXPECT_EQ(alternative_service1,
1170 alternative_service_info_vector[0].alternative_service());
1171 EXPECT_EQ(alternative_service2,
1172 alternative_service_info_vector[1].alternative_service());
1173 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1174 NetworkAnonymizationKey()));
1175 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
1176 NetworkAnonymizationKey()));
1177
1178 // SetAlternativeService should add a broken alternative service to the map.
1179 SetAlternativeService(test_server, alternative_service1);
1180 alternative_service_info_vector =
1181 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1182 ASSERT_EQ(1u, alternative_service_info_vector.size());
1183 EXPECT_EQ(alternative_service1,
1184 alternative_service_info_vector[0].alternative_service());
1185 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1186 NetworkAnonymizationKey()));
1187 }
1188
TEST_F(AlternateProtocolServerPropertiesTest,MaxAge)1189 TEST_F(AlternateProtocolServerPropertiesTest, MaxAge) {
1190 AlternativeServiceInfoVector alternative_service_info_vector;
1191 base::Time now = test_clock_.Now();
1192 base::TimeDelta one_day = base::Days(1);
1193
1194 // First alternative service expired one day ago, should not be returned by
1195 // GetAlternativeServiceInfos().
1196 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1197 alternative_service_info_vector.push_back(
1198 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1199 alternative_service1, now - one_day));
1200
1201 // Second alterrnative service will expire one day from now, should be
1202 // returned by GetAlternativeSerices().
1203 const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
1204 alternative_service_info_vector.push_back(
1205 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1206 alternative_service2, now + one_day));
1207
1208 url::SchemeHostPort test_server("http", "foo", 80);
1209 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1210 alternative_service_info_vector);
1211
1212 AlternativeServiceInfoVector alternative_service_info_vector2 =
1213 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1214 ASSERT_EQ(1u, alternative_service_info_vector2.size());
1215 EXPECT_EQ(alternative_service2,
1216 alternative_service_info_vector2[0].alternative_service());
1217 }
1218
TEST_F(AlternateProtocolServerPropertiesTest,MaxAgeCanonical)1219 TEST_F(AlternateProtocolServerPropertiesTest, MaxAgeCanonical) {
1220 AlternativeServiceInfoVector alternative_service_info_vector;
1221 base::Time now = test_clock_.Now();
1222 base::TimeDelta one_day = base::Days(1);
1223
1224 // First alternative service expired one day ago, should not be returned by
1225 // GetAlternativeServiceInfos().
1226 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1227 alternative_service_info_vector.push_back(
1228 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1229 alternative_service1, now - one_day));
1230
1231 // Second alterrnative service will expire one day from now, should be
1232 // returned by GetAlternativeSerices().
1233 const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
1234 alternative_service_info_vector.push_back(
1235 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1236 alternative_service2, now + one_day));
1237
1238 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1239 impl_.SetAlternativeServices(canonical_server, NetworkAnonymizationKey(),
1240 alternative_service_info_vector);
1241
1242 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1243 AlternativeServiceInfoVector alternative_service_info_vector2 =
1244 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1245 ASSERT_EQ(1u, alternative_service_info_vector2.size());
1246 EXPECT_EQ(alternative_service2,
1247 alternative_service_info_vector2[0].alternative_service());
1248 }
1249
TEST_F(AlternateProtocolServerPropertiesTest,AlternativeServiceWithScheme)1250 TEST_F(AlternateProtocolServerPropertiesTest, AlternativeServiceWithScheme) {
1251 AlternativeServiceInfoVector alternative_service_info_vector;
1252 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1253 base::Time expiration = test_clock_.Now() + base::Days(1);
1254 alternative_service_info_vector.push_back(
1255 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1256 alternative_service1, expiration));
1257 const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
1258 alternative_service_info_vector.push_back(
1259 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1260 alternative_service2, expiration));
1261 // Set Alt-Svc list for |http_server|.
1262 url::SchemeHostPort http_server("http", "foo", 80);
1263 impl_.SetAlternativeServices(http_server, NetworkAnonymizationKey(),
1264 alternative_service_info_vector);
1265
1266 const net::HttpServerProperties::ServerInfoMap& map =
1267 impl_.server_info_map_for_testing();
1268 auto it = map.begin();
1269 EXPECT_EQ(http_server, it->first.server);
1270 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
1271 ASSERT_TRUE(it->second.alternative_services.has_value());
1272 ASSERT_EQ(2u, it->second.alternative_services->size());
1273 EXPECT_EQ(alternative_service1,
1274 it->second.alternative_services.value()[0].alternative_service());
1275 EXPECT_EQ(alternative_service2,
1276 it->second.alternative_services.value()[1].alternative_service());
1277
1278 // Check Alt-Svc list should not be set for |https_server|.
1279 url::SchemeHostPort https_server("https", "foo", 80);
1280 EXPECT_EQ(
1281 0u,
1282 impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
1283 .size());
1284
1285 // Set Alt-Svc list for |https_server|.
1286 impl_.SetAlternativeServices(https_server, NetworkAnonymizationKey(),
1287 alternative_service_info_vector);
1288 EXPECT_EQ(
1289 2u,
1290 impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
1291 .size());
1292 EXPECT_EQ(
1293 2u,
1294 impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
1295 .size());
1296
1297 // Clear Alt-Svc list for |http_server|.
1298 impl_.SetAlternativeServices(http_server, NetworkAnonymizationKey(),
1299 AlternativeServiceInfoVector());
1300
1301 EXPECT_EQ(
1302 0u,
1303 impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
1304 .size());
1305 EXPECT_EQ(
1306 2u,
1307 impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
1308 .size());
1309 }
1310
TEST_F(AlternateProtocolServerPropertiesTest,ClearAlternativeServices)1311 TEST_F(AlternateProtocolServerPropertiesTest, ClearAlternativeServices) {
1312 AlternativeServiceInfoVector alternative_service_info_vector;
1313 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1314 base::Time expiration = test_clock_.Now() + base::Days(1);
1315 alternative_service_info_vector.push_back(
1316 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1317 alternative_service1, expiration));
1318 const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
1319 alternative_service_info_vector.push_back(
1320 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1321 alternative_service2, expiration));
1322 url::SchemeHostPort test_server("http", "foo", 80);
1323 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1324 alternative_service_info_vector);
1325
1326 const net::HttpServerProperties::ServerInfoMap& map =
1327 impl_.server_info_map_for_testing();
1328 auto it = map.begin();
1329 EXPECT_EQ(test_server, it->first.server);
1330 EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
1331 ASSERT_TRUE(it->second.alternative_services.has_value());
1332 ASSERT_EQ(2u, it->second.alternative_services->size());
1333 EXPECT_EQ(alternative_service1,
1334 it->second.alternative_services.value()[0].alternative_service());
1335 EXPECT_EQ(alternative_service2,
1336 it->second.alternative_services.value()[1].alternative_service());
1337
1338 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1339 AlternativeServiceInfoVector());
1340 EXPECT_TRUE(map.empty());
1341 }
1342
1343 // A broken alternative service in the mapping carries meaningful information,
1344 // therefore it should not be ignored by SetAlternativeService(). In
1345 // particular, an alternative service mapped to an origin shadows alternative
1346 // services of canonical hosts.
TEST_F(AlternateProtocolServerPropertiesTest,BrokenShadowsCanonical)1347 TEST_F(AlternateProtocolServerPropertiesTest, BrokenShadowsCanonical) {
1348 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1349 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1350 AlternativeService canonical_alternative_service(kProtoQUIC,
1351 "bar.c.youtube.com", 1234);
1352 SetAlternativeService(canonical_server, canonical_alternative_service);
1353 AlternativeServiceInfoVector alternative_service_info_vector =
1354 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1355 ASSERT_EQ(1u, alternative_service_info_vector.size());
1356 EXPECT_EQ(canonical_alternative_service,
1357 alternative_service_info_vector[0].alternative_service());
1358
1359 const AlternativeService broken_alternative_service(kProtoHTTP2, "foo", 443);
1360 impl_.MarkAlternativeServiceBroken(broken_alternative_service,
1361 NetworkAnonymizationKey());
1362 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service,
1363 NetworkAnonymizationKey()));
1364
1365 SetAlternativeService(test_server, broken_alternative_service);
1366 alternative_service_info_vector =
1367 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1368 ASSERT_EQ(1u, alternative_service_info_vector.size());
1369 EXPECT_EQ(broken_alternative_service,
1370 alternative_service_info_vector[0].alternative_service());
1371 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service,
1372 NetworkAnonymizationKey()));
1373 }
1374
TEST_F(AlternateProtocolServerPropertiesTest,ClearBroken)1375 TEST_F(AlternateProtocolServerPropertiesTest, ClearBroken) {
1376 url::SchemeHostPort test_server("http", "foo", 80);
1377 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1378 SetAlternativeService(test_server, alternative_service);
1379 impl_.MarkAlternativeServiceBroken(alternative_service,
1380 NetworkAnonymizationKey());
1381 ASSERT_TRUE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
1382 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1383 NetworkAnonymizationKey()));
1384 // SetAlternativeServices should leave a broken alternative service marked
1385 // as such.
1386 impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1387 AlternativeServiceInfoVector());
1388 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1389 NetworkAnonymizationKey()));
1390 }
1391
TEST_F(AlternateProtocolServerPropertiesTest,MarkBrokenWithNetworkIsolationKey)1392 TEST_F(AlternateProtocolServerPropertiesTest,
1393 MarkBrokenWithNetworkIsolationKey) {
1394 url::SchemeHostPort server("http", "foo", 80);
1395 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1396 const base::Time expiration = test_clock_.Now() + base::Days(1);
1397
1398 // Without NetworkIsolationKeys enabled, the NetworkAnonymizationKey parameter
1399 // should be ignored.
1400 impl_.SetHttp2AlternativeService(server, network_anonymization_key1_,
1401 alternative_service, expiration);
1402 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1403 network_anonymization_key1_));
1404 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1405 alternative_service, network_anonymization_key1_));
1406 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1407 network_anonymization_key2_));
1408 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1409 alternative_service, network_anonymization_key2_));
1410
1411 impl_.MarkAlternativeServiceBroken(alternative_service,
1412 network_anonymization_key1_);
1413 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1414 network_anonymization_key1_));
1415 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1416 alternative_service, network_anonymization_key1_));
1417 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1418 network_anonymization_key2_));
1419 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1420 alternative_service, network_anonymization_key2_));
1421
1422 impl_.ConfirmAlternativeService(alternative_service,
1423 network_anonymization_key2_);
1424 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1425 network_anonymization_key1_));
1426 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1427 alternative_service, network_anonymization_key1_));
1428 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1429 network_anonymization_key2_));
1430 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1431 alternative_service, network_anonymization_key2_));
1432
1433 base::test::ScopedFeatureList feature_list;
1434 feature_list.InitAndEnableFeature(
1435 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1436 // Since HttpServerProperties caches the feature value, have to create a new
1437 // one.
1438 HttpServerProperties properties(nullptr /* pref_delegate */,
1439 nullptr /* net_log */, test_tick_clock_,
1440 &test_clock_);
1441
1442 properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
1443 alternative_service, expiration);
1444 properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
1445 alternative_service, expiration);
1446
1447 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1448 alternative_service, network_anonymization_key1_));
1449 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1450 alternative_service, network_anonymization_key1_));
1451 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1452 alternative_service, network_anonymization_key2_));
1453 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1454 alternative_service, network_anonymization_key2_));
1455
1456 properties.MarkAlternativeServiceBroken(alternative_service,
1457 network_anonymization_key1_);
1458 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1459 alternative_service, network_anonymization_key1_));
1460 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1461 alternative_service, network_anonymization_key1_));
1462 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1463 alternative_service, network_anonymization_key2_));
1464 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1465 alternative_service, network_anonymization_key2_));
1466
1467 properties.MarkAlternativeServiceBroken(alternative_service,
1468 network_anonymization_key2_);
1469 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1470 alternative_service, network_anonymization_key1_));
1471 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1472 alternative_service, network_anonymization_key1_));
1473 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1474 alternative_service, network_anonymization_key2_));
1475 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1476 alternative_service, network_anonymization_key2_));
1477
1478 properties.ConfirmAlternativeService(alternative_service,
1479 network_anonymization_key1_);
1480 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1481 alternative_service, network_anonymization_key1_));
1482 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1483 alternative_service, network_anonymization_key1_));
1484 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1485 alternative_service, network_anonymization_key2_));
1486 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1487 alternative_service, network_anonymization_key2_));
1488
1489 properties.ConfirmAlternativeService(alternative_service,
1490 network_anonymization_key2_);
1491 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1492 alternative_service, network_anonymization_key1_));
1493 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1494 alternative_service, network_anonymization_key1_));
1495 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1496 alternative_service, network_anonymization_key2_));
1497 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1498 alternative_service, network_anonymization_key2_));
1499 }
1500
TEST_F(AlternateProtocolServerPropertiesTest,MarkRecentlyBroken)1501 TEST_F(AlternateProtocolServerPropertiesTest, MarkRecentlyBroken) {
1502 url::SchemeHostPort server("http", "foo", 80);
1503 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1504 SetAlternativeService(server, alternative_service);
1505
1506 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1507 NetworkAnonymizationKey()));
1508 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1509 alternative_service, NetworkAnonymizationKey()));
1510
1511 impl_.MarkAlternativeServiceRecentlyBroken(alternative_service,
1512 NetworkAnonymizationKey());
1513 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1514 NetworkAnonymizationKey()));
1515 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1516 alternative_service, NetworkAnonymizationKey()));
1517
1518 impl_.ConfirmAlternativeService(alternative_service,
1519 NetworkAnonymizationKey());
1520 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1521 NetworkAnonymizationKey()));
1522 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1523 alternative_service, NetworkAnonymizationKey()));
1524 }
1525
TEST_F(AlternateProtocolServerPropertiesTest,MarkRecentlyBrokenWithNetworkIsolationKey)1526 TEST_F(AlternateProtocolServerPropertiesTest,
1527 MarkRecentlyBrokenWithNetworkIsolationKey) {
1528 url::SchemeHostPort server("http", "foo", 80);
1529 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1530 const base::Time expiration = test_clock_.Now() + base::Days(1);
1531
1532 // Without NetworkIsolationKeys enabled, the NetworkAnonymizationKey parameter
1533 // should be ignored.
1534 impl_.SetHttp2AlternativeService(server, network_anonymization_key1_,
1535 alternative_service, expiration);
1536 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1537 network_anonymization_key1_));
1538 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1539 alternative_service, network_anonymization_key1_));
1540 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1541 network_anonymization_key2_));
1542 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1543 alternative_service, network_anonymization_key2_));
1544
1545 impl_.MarkAlternativeServiceRecentlyBroken(alternative_service,
1546 network_anonymization_key1_);
1547 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1548 network_anonymization_key1_));
1549 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1550 alternative_service, network_anonymization_key1_));
1551 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1552 network_anonymization_key2_));
1553 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1554 alternative_service, network_anonymization_key2_));
1555
1556 impl_.ConfirmAlternativeService(alternative_service,
1557 network_anonymization_key2_);
1558 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1559 network_anonymization_key1_));
1560 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1561 alternative_service, network_anonymization_key1_));
1562 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1563 network_anonymization_key2_));
1564 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1565 alternative_service, network_anonymization_key2_));
1566
1567 base::test::ScopedFeatureList feature_list;
1568 feature_list.InitAndEnableFeature(
1569 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1570 // Since HttpServerProperties caches the feature value, have to create a new
1571 // one.
1572 HttpServerProperties properties(nullptr /* pref_delegate */,
1573 nullptr /* net_log */, test_tick_clock_,
1574 &test_clock_);
1575
1576 properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
1577 alternative_service, expiration);
1578 properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
1579 alternative_service, expiration);
1580 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1581 alternative_service, network_anonymization_key1_));
1582 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1583 alternative_service, network_anonymization_key1_));
1584 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1585 alternative_service, network_anonymization_key2_));
1586 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1587 alternative_service, network_anonymization_key2_));
1588
1589 properties.MarkAlternativeServiceRecentlyBroken(alternative_service,
1590 network_anonymization_key1_);
1591 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1592 alternative_service, network_anonymization_key1_));
1593 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1594 alternative_service, network_anonymization_key1_));
1595 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1596 alternative_service, network_anonymization_key2_));
1597 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1598 alternative_service, network_anonymization_key2_));
1599
1600 properties.MarkAlternativeServiceRecentlyBroken(alternative_service,
1601 network_anonymization_key2_);
1602 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1603 alternative_service, network_anonymization_key1_));
1604 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1605 alternative_service, network_anonymization_key1_));
1606 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1607 alternative_service, network_anonymization_key2_));
1608 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1609 alternative_service, network_anonymization_key2_));
1610
1611 properties.ConfirmAlternativeService(alternative_service,
1612 network_anonymization_key1_);
1613 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1614 alternative_service, network_anonymization_key1_));
1615 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1616 alternative_service, network_anonymization_key1_));
1617 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1618 alternative_service, network_anonymization_key2_));
1619 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1620 alternative_service, network_anonymization_key2_));
1621
1622 properties.ConfirmAlternativeService(alternative_service,
1623 network_anonymization_key2_);
1624 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1625 alternative_service, network_anonymization_key1_));
1626 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1627 alternative_service, network_anonymization_key1_));
1628 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1629 alternative_service, network_anonymization_key2_));
1630 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1631 alternative_service, network_anonymization_key2_));
1632 }
1633
TEST_F(AlternateProtocolServerPropertiesTest,MarkBrokenUntilDefaultNetworkChanges)1634 TEST_F(AlternateProtocolServerPropertiesTest,
1635 MarkBrokenUntilDefaultNetworkChanges) {
1636 url::SchemeHostPort server("http", "foo", 80);
1637 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1638 SetAlternativeService(server, alternative_service);
1639
1640 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1641 NetworkAnonymizationKey()));
1642 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1643 alternative_service, NetworkAnonymizationKey()));
1644
1645 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1646 alternative_service, NetworkAnonymizationKey());
1647 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1648 NetworkAnonymizationKey()));
1649 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1650 alternative_service, NetworkAnonymizationKey()));
1651
1652 impl_.ConfirmAlternativeService(alternative_service,
1653 NetworkAnonymizationKey());
1654 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1655 NetworkAnonymizationKey()));
1656 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1657 alternative_service, NetworkAnonymizationKey()));
1658 }
1659
TEST_F(AlternateProtocolServerPropertiesTest,MarkBrokenUntilDefaultNetworkChangesWithNetworkIsolationKey)1660 TEST_F(AlternateProtocolServerPropertiesTest,
1661 MarkBrokenUntilDefaultNetworkChangesWithNetworkIsolationKey) {
1662 url::SchemeHostPort server("http", "foo", 80);
1663 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1664 const base::Time expiration = test_clock_.Now() + base::Days(1);
1665
1666 // Without NetworkIsolationKeys enabled, the NetworkAnonymizationKey parameter
1667 // should be ignored.
1668 impl_.SetHttp2AlternativeService(server, network_anonymization_key1_,
1669 alternative_service, expiration);
1670
1671 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1672 network_anonymization_key1_));
1673 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1674 alternative_service, network_anonymization_key1_));
1675 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1676 network_anonymization_key2_));
1677 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1678 alternative_service, network_anonymization_key2_));
1679
1680 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1681 alternative_service, network_anonymization_key1_);
1682 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1683 network_anonymization_key1_));
1684 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1685 alternative_service, network_anonymization_key1_));
1686 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1687 network_anonymization_key2_));
1688 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1689 alternative_service, network_anonymization_key2_));
1690
1691 impl_.ConfirmAlternativeService(alternative_service,
1692 network_anonymization_key2_);
1693 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1694 network_anonymization_key1_));
1695 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1696 alternative_service, network_anonymization_key1_));
1697 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1698 network_anonymization_key2_));
1699 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1700 alternative_service, network_anonymization_key2_));
1701
1702 base::test::ScopedFeatureList feature_list;
1703 feature_list.InitAndEnableFeature(
1704 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1705 // Since HttpServerProperties caches the feature value, have to create a new
1706 // one.
1707 HttpServerProperties properties(nullptr /* pref_delegate */,
1708 nullptr /* net_log */, test_tick_clock_,
1709 &test_clock_);
1710
1711 properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
1712 alternative_service, expiration);
1713 properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
1714 alternative_service, expiration);
1715
1716 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1717 alternative_service, network_anonymization_key1_));
1718 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1719 alternative_service, network_anonymization_key1_));
1720 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1721 alternative_service, network_anonymization_key2_));
1722 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1723 alternative_service, network_anonymization_key2_));
1724
1725 properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1726 alternative_service, network_anonymization_key1_);
1727 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1728 alternative_service, network_anonymization_key1_));
1729 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1730 alternative_service, network_anonymization_key1_));
1731 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1732 alternative_service, network_anonymization_key2_));
1733 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1734 alternative_service, network_anonymization_key2_));
1735
1736 properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1737 alternative_service, network_anonymization_key2_);
1738 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1739 alternative_service, network_anonymization_key1_));
1740 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1741 alternative_service, network_anonymization_key1_));
1742 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1743 alternative_service, network_anonymization_key2_));
1744 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1745 alternative_service, network_anonymization_key2_));
1746
1747 properties.ConfirmAlternativeService(alternative_service,
1748 network_anonymization_key1_);
1749 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1750 alternative_service, network_anonymization_key1_));
1751 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1752 alternative_service, network_anonymization_key1_));
1753 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1754 alternative_service, network_anonymization_key2_));
1755 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1756 alternative_service, network_anonymization_key2_));
1757
1758 properties.ConfirmAlternativeService(alternative_service,
1759 network_anonymization_key2_);
1760 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1761 alternative_service, network_anonymization_key1_));
1762 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1763 alternative_service, network_anonymization_key1_));
1764 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1765 alternative_service, network_anonymization_key2_));
1766 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1767 alternative_service, network_anonymization_key2_));
1768 }
1769
TEST_F(AlternateProtocolServerPropertiesTest,OnDefaultNetworkChanged)1770 TEST_F(AlternateProtocolServerPropertiesTest, OnDefaultNetworkChanged) {
1771 url::SchemeHostPort server("http", "foo", 80);
1772 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1773
1774 SetAlternativeService(server, alternative_service);
1775 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1776 NetworkAnonymizationKey()));
1777 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1778 alternative_service, NetworkAnonymizationKey()));
1779
1780 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1781 alternative_service, NetworkAnonymizationKey());
1782 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1783 NetworkAnonymizationKey()));
1784 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1785 alternative_service, NetworkAnonymizationKey()));
1786
1787 // Default network change clears alt svc broken until default network changes.
1788 impl_.OnDefaultNetworkChanged();
1789 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1790 NetworkAnonymizationKey()));
1791 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1792 alternative_service, NetworkAnonymizationKey()));
1793
1794 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1795 alternative_service, NetworkAnonymizationKey());
1796 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1797 NetworkAnonymizationKey()));
1798 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1799 alternative_service, NetworkAnonymizationKey()));
1800
1801 impl_.MarkAlternativeServiceBroken(alternative_service,
1802 NetworkAnonymizationKey());
1803 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1804 NetworkAnonymizationKey()));
1805 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1806 alternative_service, NetworkAnonymizationKey()));
1807
1808 // Default network change doesn't affect alt svc that was simply marked broken
1809 // most recently.
1810 impl_.OnDefaultNetworkChanged();
1811 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1812 NetworkAnonymizationKey()));
1813 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1814 alternative_service, NetworkAnonymizationKey()));
1815
1816 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1817 alternative_service, NetworkAnonymizationKey());
1818 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1819 NetworkAnonymizationKey()));
1820 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1821 alternative_service, NetworkAnonymizationKey()));
1822
1823 // Default network change clears alt svc that was marked broken until default
1824 // network change most recently even if the alt svc was initially marked
1825 // broken.
1826 impl_.OnDefaultNetworkChanged();
1827 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1828 NetworkAnonymizationKey()));
1829 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1830 alternative_service, NetworkAnonymizationKey()));
1831 }
1832
TEST_F(AlternateProtocolServerPropertiesTest,OnDefaultNetworkChangedWithNetworkIsolationKey)1833 TEST_F(AlternateProtocolServerPropertiesTest,
1834 OnDefaultNetworkChangedWithNetworkIsolationKey) {
1835 url::SchemeHostPort server("http", "foo", 80);
1836 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1837
1838 base::test::ScopedFeatureList feature_list;
1839 feature_list.InitAndEnableFeature(
1840 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1841 // Since HttpServerProperties caches the feature value, have to create a new
1842 // one.
1843 HttpServerProperties properties(nullptr /* pref_delegate */,
1844 nullptr /* net_log */, test_tick_clock_,
1845 &test_clock_);
1846
1847 const base::Time expiration = test_clock_.Now() + base::Days(1);
1848 properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
1849 alternative_service, expiration);
1850 properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
1851 alternative_service, expiration);
1852
1853 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1854 alternative_service, network_anonymization_key1_));
1855 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1856 alternative_service, network_anonymization_key1_));
1857 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1858 alternative_service, network_anonymization_key2_));
1859 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1860 alternative_service, network_anonymization_key2_));
1861
1862 properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1863 alternative_service, network_anonymization_key1_);
1864 properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1865 alternative_service, network_anonymization_key2_);
1866 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1867 alternative_service, network_anonymization_key1_));
1868 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1869 alternative_service, network_anonymization_key1_));
1870 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1871 alternative_service, network_anonymization_key2_));
1872 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1873 alternative_service, network_anonymization_key2_));
1874
1875 // Default network change clears alt svc broken until default network changes.
1876 properties.OnDefaultNetworkChanged();
1877 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1878 alternative_service, network_anonymization_key1_));
1879 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1880 alternative_service, network_anonymization_key1_));
1881 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1882 alternative_service, network_anonymization_key2_));
1883 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1884 alternative_service, network_anonymization_key2_));
1885 }
1886
TEST_F(AlternateProtocolServerPropertiesTest,Canonical)1887 TEST_F(AlternateProtocolServerPropertiesTest, Canonical) {
1888 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1889 EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
1890
1891 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1892 EXPECT_FALSE(
1893 HasAlternativeService(canonical_server, NetworkAnonymizationKey()));
1894
1895 AlternativeServiceInfoVector alternative_service_info_vector;
1896 const AlternativeService canonical_alternative_service1(
1897 kProtoQUIC, "bar.c.youtube.com", 1234);
1898 base::Time expiration = test_clock_.Now() + base::Days(1);
1899 alternative_service_info_vector.push_back(
1900 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
1901 canonical_alternative_service1, expiration,
1902 DefaultSupportedQuicVersions()));
1903 const AlternativeService canonical_alternative_service2(kProtoHTTP2, "", 443);
1904 alternative_service_info_vector.push_back(
1905 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1906 canonical_alternative_service2, expiration));
1907 impl_.SetAlternativeServices(canonical_server, NetworkAnonymizationKey(),
1908 alternative_service_info_vector);
1909
1910 // Since |test_server| does not have an alternative service itself,
1911 // GetAlternativeServiceInfos should return those of |canonical_server|.
1912 AlternativeServiceInfoVector alternative_service_info_vector2 =
1913 impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1914 ASSERT_EQ(2u, alternative_service_info_vector2.size());
1915 EXPECT_EQ(canonical_alternative_service1,
1916 alternative_service_info_vector2[0].alternative_service());
1917
1918 // Since |canonical_alternative_service2| has an empty host,
1919 // GetAlternativeServiceInfos should substitute the hostname of its |origin|
1920 // argument.
1921 EXPECT_EQ(test_server.host(),
1922 alternative_service_info_vector2[1].alternative_service().host);
1923 EXPECT_EQ(canonical_alternative_service2.protocol,
1924 alternative_service_info_vector2[1].alternative_service().protocol);
1925 EXPECT_EQ(canonical_alternative_service2.port,
1926 alternative_service_info_vector2[1].alternative_service().port);
1927
1928 // Verify the canonical suffix.
1929 EXPECT_EQ(".c.youtube.com",
1930 *impl_.GetCanonicalSuffixForTesting(test_server.host()));
1931 EXPECT_EQ(".c.youtube.com",
1932 *impl_.GetCanonicalSuffixForTesting(canonical_server.host()));
1933 }
1934
TEST_F(AlternateProtocolServerPropertiesTest,ClearCanonical)1935 TEST_F(AlternateProtocolServerPropertiesTest, ClearCanonical) {
1936 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1937 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1938 AlternativeService canonical_alternative_service(kProtoQUIC,
1939 "bar.c.youtube.com", 1234);
1940
1941 SetAlternativeService(canonical_server, canonical_alternative_service);
1942 impl_.SetAlternativeServices(canonical_server, NetworkAnonymizationKey(),
1943 AlternativeServiceInfoVector());
1944 EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
1945 }
1946
TEST_F(AlternateProtocolServerPropertiesTest,CanonicalWithNetworkIsolationKey)1947 TEST_F(AlternateProtocolServerPropertiesTest,
1948 CanonicalWithNetworkIsolationKey) {
1949 base::test::ScopedFeatureList feature_list;
1950 feature_list.InitAndEnableFeature(
1951 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1952 // Since HttpServerProperties caches the feature value, have to create a new
1953 // one.
1954 HttpServerProperties properties(nullptr /* pref_delegate */,
1955 nullptr /* net_log */, test_tick_clock_,
1956 &test_clock_);
1957
1958 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1959 EXPECT_FALSE(HasAlternativeService(test_server, network_anonymization_key1_));
1960
1961 url::SchemeHostPort canonical_server1("https", "bar.c.youtube.com", 443);
1962 EXPECT_FALSE(
1963 HasAlternativeService(canonical_server1, network_anonymization_key1_));
1964
1965 AlternativeServiceInfoVector alternative_service_info_vector;
1966 const AlternativeService canonical_alternative_service1(
1967 kProtoQUIC, "bar.c.youtube.com", 1234);
1968 base::Time expiration = test_clock_.Now() + base::Days(1);
1969 alternative_service_info_vector.push_back(
1970 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
1971 canonical_alternative_service1, expiration,
1972 DefaultSupportedQuicVersions()));
1973 const AlternativeService canonical_alternative_service2(kProtoHTTP2, "", 443);
1974 alternative_service_info_vector.push_back(
1975 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1976 canonical_alternative_service2, expiration));
1977 properties.SetAlternativeServices(canonical_server1,
1978 network_anonymization_key1_,
1979 alternative_service_info_vector);
1980
1981 // Since |test_server| does not have an alternative service itself,
1982 // GetAlternativeServiceInfos should return those of |canonical_server|.
1983 AlternativeServiceInfoVector alternative_service_info_vector2 =
1984 properties.GetAlternativeServiceInfos(test_server,
1985 network_anonymization_key1_);
1986 ASSERT_EQ(2u, alternative_service_info_vector2.size());
1987 EXPECT_EQ(canonical_alternative_service1,
1988 alternative_service_info_vector2[0].alternative_service());
1989
1990 // Canonical information should not be visible for other NetworkIsolationKeys.
1991 EXPECT_TRUE(
1992 properties
1993 .GetAlternativeServiceInfos(test_server, network_anonymization_key2_)
1994 .empty());
1995 EXPECT_TRUE(
1996 properties
1997 .GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
1998 .empty());
1999
2000 // Now add an alternative service entry for network_anonymization_key2_ for a
2001 // different server and different NetworkAnonymizationKey, but with the same
2002 // canonical suffix.
2003 url::SchemeHostPort canonical_server2("https", "shrimp.c.youtube.com", 443);
2004 properties.SetAlternativeServices(canonical_server2,
2005 network_anonymization_key2_,
2006 {alternative_service_info_vector[0]});
2007
2008 // The canonical server information should reachable, and different, for both
2009 // NetworkIsolationKeys.
2010 EXPECT_EQ(1u, properties
2011 .GetAlternativeServiceInfos(test_server,
2012 network_anonymization_key2_)
2013 .size());
2014 EXPECT_EQ(2u, properties
2015 .GetAlternativeServiceInfos(test_server,
2016 network_anonymization_key1_)
2017 .size());
2018 EXPECT_TRUE(
2019 properties
2020 .GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
2021 .empty());
2022
2023 // Clearing the alternate service state of network_anonymization_key1_'s
2024 // canonical server should only affect network_anonymization_key1_.
2025 properties.SetAlternativeServices(canonical_server1,
2026 network_anonymization_key1_, {});
2027 EXPECT_EQ(1u, properties
2028 .GetAlternativeServiceInfos(test_server,
2029 network_anonymization_key2_)
2030 .size());
2031 EXPECT_TRUE(
2032 properties
2033 .GetAlternativeServiceInfos(test_server, network_anonymization_key1_)
2034 .empty());
2035 EXPECT_TRUE(
2036 properties
2037 .GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
2038 .empty());
2039 }
2040
TEST_F(AlternateProtocolServerPropertiesTest,CanonicalBroken)2041 TEST_F(AlternateProtocolServerPropertiesTest, CanonicalBroken) {
2042 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
2043 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
2044 AlternativeService canonical_alternative_service(kProtoQUIC,
2045 "bar.c.youtube.com", 1234);
2046
2047 SetAlternativeService(canonical_server, canonical_alternative_service);
2048 EXPECT_TRUE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2049 impl_.MarkAlternativeServiceBroken(canonical_alternative_service,
2050 NetworkAnonymizationKey());
2051 EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2052 }
2053
TEST_F(AlternateProtocolServerPropertiesTest,CanonicalBrokenUntilDefaultNetworkChanges)2054 TEST_F(AlternateProtocolServerPropertiesTest,
2055 CanonicalBrokenUntilDefaultNetworkChanges) {
2056 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
2057 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
2058 AlternativeService canonical_alternative_service(kProtoQUIC,
2059 "bar.c.youtube.com", 1234);
2060
2061 SetAlternativeService(canonical_server, canonical_alternative_service);
2062 EXPECT_TRUE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2063 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
2064 canonical_alternative_service, NetworkAnonymizationKey());
2065 EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2066 }
2067
2068 // Adding an alternative service for a new host overrides canonical host.
TEST_F(AlternateProtocolServerPropertiesTest,CanonicalOverride)2069 TEST_F(AlternateProtocolServerPropertiesTest, CanonicalOverride) {
2070 url::SchemeHostPort foo_server("https", "foo.c.youtube.com", 443);
2071 url::SchemeHostPort bar_server("https", "bar.c.youtube.com", 443);
2072 AlternativeService bar_alternative_service(kProtoQUIC, "bar.c.youtube.com",
2073 1234);
2074 SetAlternativeService(bar_server, bar_alternative_service);
2075 AlternativeServiceInfoVector alternative_service_info_vector =
2076 impl_.GetAlternativeServiceInfos(foo_server, NetworkAnonymizationKey());
2077 ASSERT_EQ(1u, alternative_service_info_vector.size());
2078 EXPECT_EQ(bar_alternative_service,
2079 alternative_service_info_vector[0].alternative_service());
2080
2081 url::SchemeHostPort qux_server("https", "qux.c.youtube.com", 443);
2082 AlternativeService qux_alternative_service(kProtoQUIC, "qux.c.youtube.com",
2083 443);
2084 SetAlternativeService(qux_server, qux_alternative_service);
2085 alternative_service_info_vector =
2086 impl_.GetAlternativeServiceInfos(foo_server, NetworkAnonymizationKey());
2087 ASSERT_EQ(1u, alternative_service_info_vector.size());
2088 EXPECT_EQ(qux_alternative_service,
2089 alternative_service_info_vector[0].alternative_service());
2090 }
2091
TEST_F(AlternateProtocolServerPropertiesTest,ClearWithCanonical)2092 TEST_F(AlternateProtocolServerPropertiesTest, ClearWithCanonical) {
2093 url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
2094 url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
2095 AlternativeService canonical_alternative_service(kProtoQUIC,
2096 "bar.c.youtube.com", 1234);
2097
2098 SetAlternativeService(canonical_server, canonical_alternative_service);
2099 impl_.Clear(base::OnceClosure());
2100 EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2101 }
2102
TEST_F(AlternateProtocolServerPropertiesTest,ExpireBrokenAlternateProtocolMappings)2103 TEST_F(AlternateProtocolServerPropertiesTest,
2104 ExpireBrokenAlternateProtocolMappings) {
2105 url::SchemeHostPort server("https", "foo", 443);
2106 AlternativeService alternative_service(kProtoQUIC, "foo", 443);
2107 SetAlternativeService(server, alternative_service);
2108 EXPECT_TRUE(HasAlternativeService(server, NetworkAnonymizationKey()));
2109 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
2110 NetworkAnonymizationKey()));
2111 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
2112 alternative_service, NetworkAnonymizationKey()));
2113
2114 base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
2115 HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2116 &impl_, alternative_service, past);
2117 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
2118 NetworkAnonymizationKey()));
2119 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
2120 alternative_service, NetworkAnonymizationKey()));
2121
2122 HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
2123 EXPECT_FALSE(HasAlternativeService(server, NetworkAnonymizationKey()));
2124 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
2125 NetworkAnonymizationKey()));
2126 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
2127 alternative_service, NetworkAnonymizationKey()));
2128 }
2129
TEST_F(AlternateProtocolServerPropertiesTest,ExpireBrokenAlternateProtocolMappingsWithNetworkIsolationKey)2130 TEST_F(AlternateProtocolServerPropertiesTest,
2131 ExpireBrokenAlternateProtocolMappingsWithNetworkIsolationKey) {
2132 url::SchemeHostPort server("https", "foo", 443);
2133 AlternativeService alternative_service(kProtoHTTP2, "foo", 444);
2134 base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
2135 base::TimeTicks future = test_tick_clock_->NowTicks() + base::Seconds(42);
2136 const base::Time alt_service_expiration = test_clock_.Now() + base::Days(1);
2137
2138 base::test::ScopedFeatureList feature_list;
2139 feature_list.InitAndEnableFeature(
2140 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
2141 // Since HttpServerProperties caches the feature value, have to create a new
2142 // one.
2143 HttpServerProperties properties(nullptr /* pref_delegate */,
2144 nullptr /* net_log */, test_tick_clock_,
2145 &test_clock_);
2146
2147 properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
2148 alternative_service,
2149 alt_service_expiration);
2150 properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
2151 alternative_service,
2152 alt_service_expiration);
2153
2154 EXPECT_FALSE(
2155 properties.GetAlternativeServiceInfos(server, network_anonymization_key1_)
2156 .empty());
2157 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
2158 alternative_service, network_anonymization_key1_));
2159 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
2160 alternative_service, network_anonymization_key1_));
2161 EXPECT_FALSE(
2162 properties.GetAlternativeServiceInfos(server, network_anonymization_key2_)
2163 .empty());
2164 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
2165 alternative_service, network_anonymization_key2_));
2166 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
2167 alternative_service, network_anonymization_key2_));
2168
2169 // Set broken alternative service with expiration date in the past for
2170 // |network_anonymization_key1_|.
2171 HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2172 &properties, alternative_service, past, network_anonymization_key1_);
2173 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
2174 alternative_service, network_anonymization_key1_));
2175 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2176 alternative_service, network_anonymization_key1_));
2177 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
2178 alternative_service, network_anonymization_key2_));
2179 EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
2180 alternative_service, network_anonymization_key2_));
2181
2182 // Set broken alternative service with expiration date in the future for
2183 // |network_anonymization_key1_|.
2184 HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2185 &properties, alternative_service, future, network_anonymization_key2_);
2186 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
2187 alternative_service, network_anonymization_key1_));
2188 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2189 alternative_service, network_anonymization_key1_));
2190 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
2191 alternative_service, network_anonymization_key2_));
2192 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2193 alternative_service, network_anonymization_key2_));
2194
2195 // Only the broken entry for |network_anonymization_key1_| should be expired.
2196 HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&properties);
2197 EXPECT_TRUE(
2198 properties.GetAlternativeServiceInfos(server, network_anonymization_key1_)
2199 .empty());
2200 EXPECT_FALSE(properties.IsAlternativeServiceBroken(
2201 alternative_service, network_anonymization_key1_));
2202 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2203 alternative_service, network_anonymization_key1_));
2204 EXPECT_FALSE(
2205 properties.GetAlternativeServiceInfos(server, network_anonymization_key2_)
2206 .empty());
2207 EXPECT_TRUE(properties.IsAlternativeServiceBroken(
2208 alternative_service, network_anonymization_key2_));
2209 EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2210 alternative_service, network_anonymization_key2_));
2211 }
2212
2213 // Regression test for https://crbug.com/505413.
TEST_F(AlternateProtocolServerPropertiesTest,RemoveExpiredBrokenAltSvc)2214 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc) {
2215 url::SchemeHostPort foo_server("https", "foo", 443);
2216 AlternativeService bar_alternative_service(kProtoQUIC, "bar", 443);
2217 SetAlternativeService(foo_server, bar_alternative_service);
2218 EXPECT_TRUE(HasAlternativeService(foo_server, NetworkAnonymizationKey()));
2219
2220 url::SchemeHostPort bar_server1("http", "bar", 80);
2221 AlternativeService nohost_alternative_service(kProtoQUIC, "", 443);
2222 SetAlternativeService(bar_server1, nohost_alternative_service);
2223 EXPECT_TRUE(HasAlternativeService(bar_server1, NetworkAnonymizationKey()));
2224
2225 url::SchemeHostPort bar_server2("https", "bar", 443);
2226 AlternativeService baz_alternative_service(kProtoQUIC, "baz", 1234);
2227 SetAlternativeService(bar_server2, baz_alternative_service);
2228 EXPECT_TRUE(HasAlternativeService(bar_server2, NetworkAnonymizationKey()));
2229
2230 // Mark "bar:443" as broken.
2231 base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
2232 HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2233 &impl_, bar_alternative_service, past);
2234
2235 // Expire brokenness of "bar:443".
2236 HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
2237
2238 // "foo:443" should have no alternative service now.
2239 EXPECT_FALSE(HasAlternativeService(foo_server, NetworkAnonymizationKey()));
2240 // "bar:80" should have no alternative service now.
2241 EXPECT_FALSE(HasAlternativeService(bar_server1, NetworkAnonymizationKey()));
2242 // The alternative service of "bar:443" should be unaffected.
2243 EXPECT_TRUE(HasAlternativeService(bar_server2, NetworkAnonymizationKey()));
2244
2245 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
2246 bar_alternative_service, NetworkAnonymizationKey()));
2247 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
2248 baz_alternative_service, NetworkAnonymizationKey()));
2249 }
2250
TEST_F(AlternateProtocolServerPropertiesTest,SetBrokenAlternativeServicesDelayParams1)2251 TEST_F(AlternateProtocolServerPropertiesTest,
2252 SetBrokenAlternativeServicesDelayParams1) {
2253 url::SchemeHostPort server("https", "foo", 443);
2254 AlternativeService alternative_service(kProtoQUIC, "foo", 443);
2255 SetAlternativeService(server, alternative_service);
2256
2257 const base::TimeDelta initial_delay = base::Seconds(1);
2258 impl_.SetBrokenAlternativeServicesDelayParams(initial_delay, true);
2259 for (int i = 0; i < 10; ++i) {
2260 impl_.MarkAlternativeServiceBroken(alternative_service,
2261 NetworkAnonymizationKey());
2262 // |impl_| should have posted task to expire the brokenness of
2263 // |alternative_service|
2264 EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
2265 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
2266 NetworkAnonymizationKey()));
2267
2268 // Advance time by just enough so that |alternative_service|'s brokenness
2269 // expires.
2270 FastForwardBy(initial_delay * (1 << i));
2271
2272 // Ensure brokenness of |alternative_service| has expired.
2273 EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
2274 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
2275 NetworkAnonymizationKey()));
2276 }
2277 }
2278
TEST_F(AlternateProtocolServerPropertiesTest,SetBrokenAlternativeServicesDelayParams2)2279 TEST_F(AlternateProtocolServerPropertiesTest,
2280 SetBrokenAlternativeServicesDelayParams2) {
2281 url::SchemeHostPort server("https", "foo", 443);
2282 AlternativeService alternative_service(kProtoQUIC, "foo", 443);
2283 SetAlternativeService(server, alternative_service);
2284
2285 const base::TimeDelta initial_delay = base::Seconds(5);
2286 impl_.SetBrokenAlternativeServicesDelayParams(initial_delay, false);
2287 for (int i = 0; i < 10; ++i) {
2288 impl_.MarkAlternativeServiceBroken(alternative_service,
2289 NetworkAnonymizationKey());
2290 // |impl_| should have posted task to expire the brokenness of
2291 // |alternative_service|
2292 EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
2293 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
2294 NetworkAnonymizationKey()));
2295
2296 // Advance time by just enough so that |alternative_service|'s brokenness
2297 // expires.
2298 if (i == 0) {
2299 FastForwardBy(initial_delay);
2300 } else {
2301 FastForwardBy(base::Seconds(300) * (1 << (i - 1)));
2302 }
2303
2304 // Ensure brokenness of |alternative_service| has expired.
2305 EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
2306 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
2307 NetworkAnonymizationKey()));
2308 }
2309 }
2310
2311 // Regression test for https://crbug.com/724302
TEST_F(AlternateProtocolServerPropertiesTest,RemoveExpiredBrokenAltSvc2)2312 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc2) {
2313 // This test will mark an alternative service A that has already been marked
2314 // broken many times, then immediately mark another alternative service B as
2315 // broken for the first time. Because A's been marked broken many times
2316 // already, its brokenness will be scheduled to expire much further in the
2317 // future than B, even though it was marked broken before B. This test makes
2318 // sure that even though A was marked broken before B, B's brokenness should
2319 // expire before A.
2320
2321 url::SchemeHostPort server1("https", "foo", 443);
2322 AlternativeService alternative_service1(kProtoQUIC, "foo", 443);
2323 SetAlternativeService(server1, alternative_service1);
2324
2325 url::SchemeHostPort server2("https", "bar", 443);
2326 AlternativeService alternative_service2(kProtoQUIC, "bar", 443);
2327 SetAlternativeService(server2, alternative_service2);
2328
2329 // Repeatedly mark alt svc 1 broken and wait for its brokenness to expire.
2330 // This will increase its time until expiration.
2331 for (int i = 0; i < 3; ++i) {
2332 impl_.MarkAlternativeServiceBroken(alternative_service1,
2333 NetworkAnonymizationKey());
2334
2335 // |impl_| should have posted task to expire the brokenness of
2336 // |alternative_service1|
2337 EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
2338 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
2339 NetworkAnonymizationKey()));
2340
2341 // Advance time by just enough so that |alternative_service1|'s brokenness
2342 // expires.
2343 FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[i]);
2344
2345 // Ensure brokenness of |alternative_service1| has expired.
2346 EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
2347 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
2348 NetworkAnonymizationKey()));
2349 }
2350
2351 impl_.MarkAlternativeServiceBroken(alternative_service1,
2352 NetworkAnonymizationKey());
2353 impl_.MarkAlternativeServiceBroken(alternative_service2,
2354 NetworkAnonymizationKey());
2355
2356 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service2,
2357 NetworkAnonymizationKey()));
2358
2359 // Advance time by just enough so that |alternative_service2|'s brokennness
2360 // expires.
2361 FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[0]);
2362
2363 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
2364 NetworkAnonymizationKey()));
2365 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
2366 NetworkAnonymizationKey()));
2367
2368 // Advance time by enough so that |alternative_service1|'s brokenness expires.
2369 FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[3] -
2370 BROKEN_ALT_SVC_EXPIRE_DELAYS[0]);
2371
2372 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
2373 NetworkAnonymizationKey()));
2374 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
2375 NetworkAnonymizationKey()));
2376 }
2377
2378 // Regression test for https://crbug.com/994537. Having a ServerInfo entry
2379 // without a populated |alternative_services| value would cause
2380 // OnExpireBrokenAlternativeService() to hang..
TEST_F(AlternateProtocolServerPropertiesTest,RemoveExpiredBrokenAltSvc3)2381 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc3) {
2382 // Add an altertive service entry.
2383 const url::SchemeHostPort kServer1("https", "foo", 443);
2384 const AlternativeService kAltService(kProtoQUIC, "bar", 443);
2385 SetAlternativeService(kServer1, kAltService);
2386 EXPECT_TRUE(HasAlternativeService(kServer1, NetworkAnonymizationKey()));
2387
2388 // Add an entry to ServerInfo for another server, without an alternative
2389 // service value.
2390 const url::SchemeHostPort kServer2("http", "bar", 80);
2391 impl_.SetSupportsSpdy(kServer2, NetworkAnonymizationKey(), false);
2392
2393 // Mark kAltService as broken.
2394 base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
2395 HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2396 &impl_, kAltService, past);
2397
2398 // Expire brokenness of kAltService. This call should not hang.
2399 HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
2400
2401 EXPECT_FALSE(HasAlternativeService(kServer1, NetworkAnonymizationKey()));
2402 }
2403
TEST_F(AlternateProtocolServerPropertiesTest,GetAlternativeServiceInfoAsValue)2404 TEST_F(AlternateProtocolServerPropertiesTest,
2405 GetAlternativeServiceInfoAsValue) {
2406 constexpr base::Time::Exploded kNowExploded = {.year = 2018,
2407 .month = 1,
2408 .day_of_week = 3,
2409 .day_of_month = 24,
2410 .hour = 15,
2411 .minute = 12,
2412 .second = 53};
2413 base::Time now;
2414 bool result = base::Time::FromLocalExploded(kNowExploded, &now);
2415 DCHECK(result);
2416 test_clock_.SetNow(now);
2417
2418 AlternativeServiceInfoVector alternative_service_info_vector;
2419 alternative_service_info_vector.push_back(
2420 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
2421 AlternativeService(kProtoHTTP2, "foo", 443), now + base::Minutes(1)));
2422 alternative_service_info_vector.push_back(
2423 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
2424 AlternativeService(kProtoQUIC, "bar", 443), now + base::Hours(1),
2425 DefaultSupportedQuicVersions()));
2426 alternative_service_info_vector.push_back(
2427 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
2428 AlternativeService(kProtoQUIC, "baz", 443), now + base::Hours(1),
2429 DefaultSupportedQuicVersions()));
2430
2431 impl_.SetAlternativeServices(url::SchemeHostPort("https", "youtube.com", 443),
2432 NetworkAnonymizationKey(),
2433 alternative_service_info_vector);
2434
2435 impl_.MarkAlternativeServiceBroken(AlternativeService(kProtoQUIC, "bar", 443),
2436 NetworkAnonymizationKey());
2437
2438 impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
2439 AlternativeService(kProtoQUIC, "baz", 443), NetworkAnonymizationKey());
2440
2441 alternative_service_info_vector.clear();
2442 alternative_service_info_vector.push_back(
2443 AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
2444 AlternativeService(kProtoHTTP2, "foo2", 443), now + base::Days(1)));
2445 impl_.SetAlternativeServices(url::SchemeHostPort("http", "test.com", 80),
2446 NetworkAnonymizationKey(),
2447 alternative_service_info_vector);
2448
2449 const char expected_json[] =
2450 "["
2451 "{"
2452 "\"alternative_service\":"
2453 "[\"h2 foo2:443, expires 2018-01-25 15:12:53\"],"
2454 "\"network_anonymization_key\":\"null\","
2455 "\"server\":\"http://test.com\""
2456 "},"
2457 "{"
2458 "\"alternative_service\":"
2459 "[\"h2 foo:443, expires 2018-01-24 15:13:53\","
2460 "\"quic bar:443, expires 2018-01-24 16:12:53"
2461 " (broken until 2018-01-24 15:17:53)\","
2462 "\"quic baz:443, expires 2018-01-24 16:12:53"
2463 " (broken until 2018-01-24 15:17:53)\"],"
2464 "\"network_anonymization_key\":\"null\","
2465 "\"server\":\"https://youtube.com\""
2466 "}"
2467 "]";
2468
2469 base::Value alternative_service_info_value =
2470 impl_.GetAlternativeServiceInfoAsValue();
2471 std::string alternative_service_info_json;
2472 base::JSONWriter::Write(alternative_service_info_value,
2473 &alternative_service_info_json);
2474 EXPECT_EQ(expected_json, alternative_service_info_json);
2475 }
2476
TEST_F(HttpServerPropertiesTest,LoadLastLocalAddressWhenQuicWorked)2477 TEST_F(HttpServerPropertiesTest, LoadLastLocalAddressWhenQuicWorked) {
2478 const IPAddress kEmptyAddress;
2479 const IPAddress kValidAddress1 = IPAddress::IPv4Localhost();
2480 const IPAddress kValidAddress2 = IPAddress::IPv6Localhost();
2481
2482 // Check by initializing empty address.
2483 impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kEmptyAddress);
2484 EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2485 // Empty address should not be considered an address that was used when QUIC
2486 // worked.
2487 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2488 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2489 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2490
2491 // Check by initializing with a valid address.
2492 impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kValidAddress1);
2493 EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
2494 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2495 EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2496 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2497
2498 // Try another valid address.
2499 impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kValidAddress2);
2500 EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
2501 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2502 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2503 EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2504
2505 // And loading an empty address clears the current one.
2506 // TODO(mmenke): This seems like a bug, since if we've learned the current
2507 // network supports QUIC, surely we want to save that to disk? Seems like a
2508 // pre-existing value should take precedence, if non-empty, since if the
2509 // current network is already known to support QUIC, the loaded value is no
2510 // longer relevant.
2511 impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kEmptyAddress);
2512 EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2513 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2514 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2515 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2516 }
2517
TEST_F(HttpServerPropertiesTest,SetLastLocalAddressWhenQuicWorked)2518 TEST_F(HttpServerPropertiesTest, SetLastLocalAddressWhenQuicWorked) {
2519 const IPAddress kEmptyAddress;
2520 const IPAddress kValidAddress1 = IPAddress::IPv4Localhost();
2521 const IPAddress kValidAddress2 = IPAddress::IPv6Localhost();
2522
2523 EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2524 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2525 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2526 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2527
2528 // Set to a valid address.
2529 impl_.SetLastLocalAddressWhenQuicWorked(kValidAddress1);
2530 EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
2531 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2532 EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2533 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2534
2535 // Clear only this value.
2536 impl_.ClearLastLocalAddressWhenQuicWorked();
2537 EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2538 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2539 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2540 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2541
2542 // Try another valid address.
2543 impl_.SetLastLocalAddressWhenQuicWorked(kValidAddress2);
2544 EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
2545 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2546 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2547 EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2548
2549 // Clear all values.
2550 impl_.Clear(base::OnceClosure());
2551 EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2552 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2553 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2554 EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2555 }
2556
TEST_F(HttpServerPropertiesTest,LoadServerNetworkStats)2557 TEST_F(HttpServerPropertiesTest, LoadServerNetworkStats) {
2558 url::SchemeHostPort google_server("https", "www.google.com", 443);
2559
2560 // Check by initializing empty ServerNetworkStats.
2561 std::unique_ptr<HttpServerProperties::ServerInfoMap> load_server_info_map =
2562 std::make_unique<HttpServerProperties::ServerInfoMap>();
2563 impl_.OnServerInfoLoadedForTesting(std::move(load_server_info_map));
2564 const ServerNetworkStats* stats =
2565 impl_.GetServerNetworkStats(google_server, NetworkAnonymizationKey());
2566 EXPECT_EQ(nullptr, stats);
2567
2568 // Check by initializing with www.google.com:443.
2569 ServerNetworkStats stats_google;
2570 stats_google.srtt = base::Microseconds(10);
2571 stats_google.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
2572 load_server_info_map =
2573 std::make_unique<HttpServerProperties::ServerInfoMap>();
2574 load_server_info_map->GetOrPut(CreateSimpleKey(google_server))
2575 ->second.server_network_stats = stats_google;
2576 impl_.OnServerInfoLoadedForTesting(std::move(load_server_info_map));
2577
2578 // Verify data for www.google.com:443.
2579 ASSERT_EQ(1u, impl_.server_info_map_for_testing().size());
2580 EXPECT_EQ(stats_google, *(impl_.GetServerNetworkStats(
2581 google_server, NetworkAnonymizationKey())));
2582
2583 // Test recency order and overwriting of data.
2584 //
2585 // |docs_server| has a ServerNetworkStats, which will be overwritten by
2586 // OnServerInfoLoadedForTesting(), because |server_network_stats_map| has an
2587 // entry for |docs_server|.
2588 url::SchemeHostPort docs_server("https", "docs.google.com", 443);
2589 ServerNetworkStats stats_docs;
2590 stats_docs.srtt = base::Microseconds(20);
2591 stats_docs.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(200);
2592 // Recency order will be |docs_server| and |google_server|.
2593 impl_.SetServerNetworkStats(docs_server, NetworkAnonymizationKey(),
2594 stats_docs);
2595
2596 // Prepare |server_info_map| to be loaded by OnServerInfoLoadedForTesting().
2597 std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
2598 std::make_unique<HttpServerProperties::ServerInfoMap>();
2599
2600 // Change the values for |docs_server|.
2601 ServerNetworkStats new_stats_docs;
2602 new_stats_docs.srtt = base::Microseconds(25);
2603 new_stats_docs.bandwidth_estimate =
2604 quic::QuicBandwidth::FromBitsPerSecond(250);
2605 server_info_map->GetOrPut(CreateSimpleKey(docs_server))
2606 ->second.server_network_stats = new_stats_docs;
2607 // Add data for mail.google.com:443.
2608 url::SchemeHostPort mail_server("https", "mail.google.com", 443);
2609 ServerNetworkStats stats_mail;
2610 stats_mail.srtt = base::Microseconds(30);
2611 stats_mail.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(300);
2612 server_info_map->GetOrPut(CreateSimpleKey(mail_server))
2613 ->second.server_network_stats = stats_mail;
2614
2615 // Recency order will be |docs_server|, |google_server| and |mail_server|.
2616 impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
2617
2618 const HttpServerProperties::ServerInfoMap& map =
2619 impl_.server_info_map_for_testing();
2620 ASSERT_EQ(3u, map.size());
2621 auto map_it = map.begin();
2622
2623 EXPECT_EQ(docs_server, map_it->first.server);
2624 EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
2625 ASSERT_TRUE(map_it->second.server_network_stats.has_value());
2626 EXPECT_EQ(new_stats_docs, *map_it->second.server_network_stats);
2627 ++map_it;
2628 EXPECT_EQ(google_server, map_it->first.server);
2629 EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
2630 ASSERT_TRUE(map_it->second.server_network_stats.has_value());
2631 EXPECT_EQ(stats_google, *map_it->second.server_network_stats);
2632 ++map_it;
2633 EXPECT_EQ(mail_server, map_it->first.server);
2634 EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
2635 ASSERT_TRUE(map_it->second.server_network_stats.has_value());
2636 EXPECT_EQ(stats_mail, *map_it->second.server_network_stats);
2637 }
2638
TEST_F(HttpServerPropertiesTest,SetServerNetworkStats)2639 TEST_F(HttpServerPropertiesTest, SetServerNetworkStats) {
2640 url::SchemeHostPort foo_http_server("http", "foo", 443);
2641 url::SchemeHostPort foo_https_server("https", "foo", 443);
2642 EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_http_server,
2643 NetworkAnonymizationKey()));
2644 EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
2645 NetworkAnonymizationKey()));
2646
2647 ServerNetworkStats stats1;
2648 stats1.srtt = base::Microseconds(10);
2649 stats1.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
2650 impl_.SetServerNetworkStats(foo_http_server, NetworkAnonymizationKey(),
2651 stats1);
2652
2653 const ServerNetworkStats* stats2 =
2654 impl_.GetServerNetworkStats(foo_http_server, NetworkAnonymizationKey());
2655 EXPECT_EQ(10, stats2->srtt.ToInternalValue());
2656 EXPECT_EQ(100, stats2->bandwidth_estimate.ToBitsPerSecond());
2657 // Https server should have nothing set for server network stats.
2658 EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
2659 NetworkAnonymizationKey()));
2660
2661 impl_.Clear(base::OnceClosure());
2662 EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_http_server,
2663 NetworkAnonymizationKey()));
2664 EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
2665 NetworkAnonymizationKey()));
2666 }
2667
TEST_F(HttpServerPropertiesTest,ClearServerNetworkStats)2668 TEST_F(HttpServerPropertiesTest, ClearServerNetworkStats) {
2669 ServerNetworkStats stats;
2670 stats.srtt = base::Microseconds(10);
2671 stats.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
2672 url::SchemeHostPort foo_https_server("https", "foo", 443);
2673 impl_.SetServerNetworkStats(foo_https_server, NetworkAnonymizationKey(),
2674 stats);
2675
2676 impl_.ClearServerNetworkStats(foo_https_server, NetworkAnonymizationKey());
2677 EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
2678 NetworkAnonymizationKey()));
2679 }
2680
TEST_F(HttpServerPropertiesTest,OnQuicServerInfoMapLoaded)2681 TEST_F(HttpServerPropertiesTest, OnQuicServerInfoMapLoaded) {
2682 quic::QuicServerId google_quic_server_id("www.google.com", 443, true);
2683 HttpServerProperties::QuicServerInfoMapKey google_key(
2684 google_quic_server_id, NetworkAnonymizationKey(),
2685 false /* use_network_anonymization_key */);
2686
2687 const int kMaxQuicServerEntries = 10;
2688 impl_.SetMaxServerConfigsStoredInProperties(kMaxQuicServerEntries);
2689 EXPECT_EQ(10u, impl_.quic_server_info_map().max_size());
2690
2691 // Check empty map.
2692 std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
2693 init_quic_server_info_map =
2694 std::make_unique<HttpServerProperties::QuicServerInfoMap>(
2695 kMaxQuicServerEntries);
2696 impl_.OnQuicServerInfoMapLoadedForTesting(
2697 std::move(init_quic_server_info_map));
2698 EXPECT_EQ(0u, impl_.quic_server_info_map().size());
2699
2700 // Check by initializing with www.google.com:443.
2701 std::string google_server_info("google_quic_server_info");
2702 init_quic_server_info_map =
2703 std::make_unique<HttpServerProperties::QuicServerInfoMap>(
2704 kMaxQuicServerEntries);
2705 init_quic_server_info_map->Put(google_key, google_server_info);
2706 impl_.OnQuicServerInfoMapLoadedForTesting(
2707 std::move(init_quic_server_info_map));
2708
2709 // Verify data for www.google.com:443.
2710 EXPECT_EQ(1u, impl_.quic_server_info_map().size());
2711 EXPECT_EQ(google_server_info,
2712 *impl_.GetQuicServerInfo(google_quic_server_id,
2713 NetworkAnonymizationKey()));
2714
2715 // Test recency order and overwriting of data.
2716 //
2717 // |docs_server| has a QuicServerInfo, which will be overwritten by
2718 // SetQuicServerInfoMap(), because |quic_server_info_map| has an
2719 // entry for |docs_server|.
2720 quic::QuicServerId docs_quic_server_id("docs.google.com", 443, true);
2721 HttpServerProperties::QuicServerInfoMapKey docs_key(
2722 docs_quic_server_id, NetworkAnonymizationKey(),
2723 false /* use_network_anonymization_key */);
2724 std::string docs_server_info("docs_quic_server_info");
2725 impl_.SetQuicServerInfo(docs_quic_server_id, NetworkAnonymizationKey(),
2726 docs_server_info);
2727
2728 // Recency order will be |docs_server| and |google_server|.
2729 const HttpServerProperties::QuicServerInfoMap& map =
2730 impl_.quic_server_info_map();
2731 ASSERT_EQ(2u, map.size());
2732 auto map_it = map.begin();
2733 EXPECT_EQ(map_it->first, docs_key);
2734 EXPECT_EQ(docs_server_info, map_it->second);
2735 ++map_it;
2736 EXPECT_EQ(map_it->first, google_key);
2737 EXPECT_EQ(google_server_info, map_it->second);
2738
2739 // Prepare |quic_server_info_map| to be loaded by
2740 // SetQuicServerInfoMap().
2741 std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
2742 quic_server_info_map =
2743 std::make_unique<HttpServerProperties::QuicServerInfoMap>(
2744 kMaxQuicServerEntries);
2745 // Change the values for |docs_server|.
2746 std::string new_docs_server_info("new_docs_quic_server_info");
2747 quic_server_info_map->Put(docs_key, new_docs_server_info);
2748 // Add data for mail.google.com:443.
2749 quic::QuicServerId mail_quic_server_id("mail.google.com", 443, true);
2750 HttpServerProperties::QuicServerInfoMapKey mail_key(
2751 mail_quic_server_id, NetworkAnonymizationKey(),
2752 false /* use_network_anonymization_key */);
2753 std::string mail_server_info("mail_quic_server_info");
2754 quic_server_info_map->Put(mail_key, mail_server_info);
2755 impl_.OnQuicServerInfoMapLoadedForTesting(std::move(quic_server_info_map));
2756
2757 // Recency order will be |docs_server|, |google_server| and |mail_server|.
2758 const HttpServerProperties::QuicServerInfoMap& memory_map =
2759 impl_.quic_server_info_map();
2760 ASSERT_EQ(3u, memory_map.size());
2761 auto memory_map_it = memory_map.begin();
2762 EXPECT_EQ(memory_map_it->first, docs_key);
2763 EXPECT_EQ(new_docs_server_info, memory_map_it->second);
2764 ++memory_map_it;
2765 EXPECT_EQ(memory_map_it->first, google_key);
2766 EXPECT_EQ(google_server_info, memory_map_it->second);
2767 ++memory_map_it;
2768 EXPECT_EQ(memory_map_it->first, mail_key);
2769 EXPECT_EQ(mail_server_info, memory_map_it->second);
2770
2771 // Shrink the size of |quic_server_info_map| and verify the MRU order is
2772 // maintained.
2773 impl_.SetMaxServerConfigsStoredInProperties(2);
2774 EXPECT_EQ(2u, impl_.quic_server_info_map().max_size());
2775
2776 const HttpServerProperties::QuicServerInfoMap& memory_map1 =
2777 impl_.quic_server_info_map();
2778 ASSERT_EQ(2u, memory_map1.size());
2779 auto memory_map1_it = memory_map1.begin();
2780 EXPECT_EQ(memory_map1_it->first, docs_key);
2781 EXPECT_EQ(new_docs_server_info, memory_map1_it->second);
2782 ++memory_map1_it;
2783 EXPECT_EQ(memory_map1_it->first, google_key);
2784 EXPECT_EQ(google_server_info, memory_map1_it->second);
2785 // |QuicServerInfo| for |mail_quic_server_id| shouldn't be there.
2786 EXPECT_EQ(nullptr, impl_.GetQuicServerInfo(mail_quic_server_id,
2787 NetworkAnonymizationKey()));
2788 }
2789
TEST_F(HttpServerPropertiesTest,SetQuicServerInfo)2790 TEST_F(HttpServerPropertiesTest, SetQuicServerInfo) {
2791 quic::QuicServerId server1("foo", 80, false /* privacy_mode_enabled */);
2792 quic::QuicServerId server2("foo", 80, true /* privacy_mode_enabled */);
2793
2794 std::string quic_server_info1("quic_server_info1");
2795 std::string quic_server_info2("quic_server_info2");
2796 std::string quic_server_info3("quic_server_info3");
2797
2798 // Without network isolation keys enabled for HttpServerProperties, passing in
2799 // a NetworkAnonymizationKey should have no effect on behavior.
2800 impl_.SetQuicServerInfo(server1, NetworkAnonymizationKey(),
2801 quic_server_info1);
2802 EXPECT_EQ(quic_server_info1,
2803 *(impl_.GetQuicServerInfo(server1, NetworkAnonymizationKey())));
2804 EXPECT_FALSE(impl_.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2805 EXPECT_EQ(quic_server_info1,
2806 *(impl_.GetQuicServerInfo(server1, network_anonymization_key1_)));
2807 EXPECT_FALSE(impl_.GetQuicServerInfo(server2, network_anonymization_key1_));
2808
2809 impl_.SetQuicServerInfo(server2, network_anonymization_key1_,
2810 quic_server_info2);
2811 EXPECT_EQ(quic_server_info1,
2812 *(impl_.GetQuicServerInfo(server1, NetworkAnonymizationKey())));
2813 EXPECT_EQ(quic_server_info2,
2814 *(impl_.GetQuicServerInfo(server2, NetworkAnonymizationKey())));
2815 EXPECT_EQ(quic_server_info1,
2816 *(impl_.GetQuicServerInfo(server1, network_anonymization_key1_)));
2817 EXPECT_EQ(quic_server_info2,
2818 *(impl_.GetQuicServerInfo(server2, network_anonymization_key1_)));
2819
2820 impl_.SetQuicServerInfo(server1, network_anonymization_key1_,
2821 quic_server_info3);
2822 EXPECT_EQ(quic_server_info3,
2823 *(impl_.GetQuicServerInfo(server1, NetworkAnonymizationKey())));
2824 EXPECT_EQ(quic_server_info2,
2825 *(impl_.GetQuicServerInfo(server2, NetworkAnonymizationKey())));
2826 EXPECT_EQ(quic_server_info3,
2827 *(impl_.GetQuicServerInfo(server1, network_anonymization_key1_)));
2828 EXPECT_EQ(quic_server_info2,
2829 *(impl_.GetQuicServerInfo(server2, network_anonymization_key1_)));
2830
2831 impl_.Clear(base::OnceClosure());
2832 EXPECT_FALSE(impl_.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2833 EXPECT_FALSE(impl_.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2834 EXPECT_FALSE(impl_.GetQuicServerInfo(server1, network_anonymization_key1_));
2835 EXPECT_FALSE(impl_.GetQuicServerInfo(server2, network_anonymization_key1_));
2836
2837 base::test::ScopedFeatureList feature_list;
2838 feature_list.InitAndEnableFeature(
2839 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
2840 // Since HttpServerProperties caches the feature value, have to create a new
2841 // one.
2842 HttpServerProperties properties(nullptr /* pref_delegate */,
2843 nullptr /* net_log */, test_tick_clock_,
2844 &test_clock_);
2845
2846 properties.SetQuicServerInfo(server1, NetworkAnonymizationKey(),
2847 quic_server_info1);
2848 EXPECT_EQ(quic_server_info1, *(properties.GetQuicServerInfo(
2849 server1, NetworkAnonymizationKey())));
2850 EXPECT_FALSE(
2851 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2852 EXPECT_FALSE(
2853 properties.GetQuicServerInfo(server1, network_anonymization_key1_));
2854 EXPECT_FALSE(
2855 properties.GetQuicServerInfo(server2, network_anonymization_key1_));
2856
2857 properties.SetQuicServerInfo(server1, network_anonymization_key1_,
2858 quic_server_info2);
2859 EXPECT_EQ(quic_server_info1, *(properties.GetQuicServerInfo(
2860 server1, NetworkAnonymizationKey())));
2861 EXPECT_FALSE(
2862 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2863 EXPECT_EQ(quic_server_info2, *(properties.GetQuicServerInfo(
2864 server1, network_anonymization_key1_)));
2865 EXPECT_FALSE(
2866 properties.GetQuicServerInfo(server2, network_anonymization_key1_));
2867
2868 properties.SetQuicServerInfo(server2, network_anonymization_key1_,
2869 quic_server_info3);
2870 EXPECT_EQ(quic_server_info1, *(properties.GetQuicServerInfo(
2871 server1, NetworkAnonymizationKey())));
2872 EXPECT_FALSE(
2873 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2874 EXPECT_EQ(quic_server_info2, *(properties.GetQuicServerInfo(
2875 server1, network_anonymization_key1_)));
2876 EXPECT_EQ(quic_server_info3, *(properties.GetQuicServerInfo(
2877 server2, network_anonymization_key1_)));
2878
2879 properties.Clear(base::OnceClosure());
2880 EXPECT_FALSE(
2881 properties.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2882 EXPECT_FALSE(
2883 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2884 EXPECT_FALSE(
2885 properties.GetQuicServerInfo(server1, network_anonymization_key1_));
2886 EXPECT_FALSE(
2887 properties.GetQuicServerInfo(server2, network_anonymization_key1_));
2888 }
2889
2890 // Tests that GetQuicServerInfo() returns server info of a host
2891 // with the same canonical suffix when there is no exact host match.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatch)2892 TEST_F(HttpServerPropertiesTest, QuicServerInfoCanonicalSuffixMatch) {
2893 // Set up HttpServerProperties.
2894 // Add a host with a canonical suffix.
2895 quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
2896 std::string foo_server_info("foo_server_info");
2897 impl_.SetQuicServerInfo(foo_server_id, NetworkAnonymizationKey(),
2898 foo_server_info);
2899
2900 // Add a host that has a different canonical suffix.
2901 quic::QuicServerId baz_server_id("baz.video.com", 443, false);
2902 std::string baz_server_info("baz_server_info");
2903 impl_.SetQuicServerInfo(baz_server_id, NetworkAnonymizationKey(),
2904 baz_server_info);
2905
2906 // Create SchemeHostPort with a host that has the initial canonical suffix.
2907 quic::QuicServerId bar_server_id("bar.googlevideo.com", 443, false);
2908
2909 // Check the the server info associated with "foo" is returned for "bar".
2910 const std::string* bar_server_info =
2911 impl_.GetQuicServerInfo(bar_server_id, NetworkAnonymizationKey());
2912 ASSERT_TRUE(bar_server_info != nullptr);
2913 EXPECT_EQ(foo_server_info, *bar_server_info);
2914 }
2915
2916 // Make sure that canonical suffices respect NetworkIsolationKeys when using
2917 // QuicServerInfo methods.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatchWithNetworkIsolationKey)2918 TEST_F(HttpServerPropertiesTest,
2919 QuicServerInfoCanonicalSuffixMatchWithNetworkIsolationKey) {
2920 // Two servers with same canonical suffix.
2921 quic::QuicServerId server1("foo.googlevideo.com", 80,
2922 false /* privacy_mode_enabled */);
2923 quic::QuicServerId server2("bar.googlevideo.com", 80,
2924 false /* privacy_mode_enabled */);
2925
2926 std::string server_info1("server_info1");
2927 std::string server_info2("server_info2");
2928
2929 base::test::ScopedFeatureList feature_list;
2930 feature_list.InitAndEnableFeature(
2931 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
2932 // Since HttpServerProperties caches the feature value, have to create a new
2933 // one.
2934 HttpServerProperties properties(nullptr /* pref_delegate */,
2935 nullptr /* net_log */, test_tick_clock_,
2936 &test_clock_);
2937
2938 // Set QuicServerInfo for one canononical suffix and
2939 // |network_anonymization_key1_|. It should be accessible via another
2940 // SchemeHostPort, but only when the NetworkIsolationKeys match.
2941 properties.SetQuicServerInfo(server1, network_anonymization_key1_,
2942 server_info1);
2943 const std::string* fetched_server_info =
2944 properties.GetQuicServerInfo(server1, network_anonymization_key1_);
2945 ASSERT_TRUE(fetched_server_info);
2946 EXPECT_EQ(server_info1, *fetched_server_info);
2947 fetched_server_info =
2948 properties.GetQuicServerInfo(server2, network_anonymization_key1_);
2949 ASSERT_TRUE(fetched_server_info);
2950 EXPECT_EQ(server_info1, *fetched_server_info);
2951 EXPECT_FALSE(
2952 properties.GetQuicServerInfo(server1, network_anonymization_key2_));
2953 EXPECT_FALSE(
2954 properties.GetQuicServerInfo(server2, network_anonymization_key2_));
2955 EXPECT_FALSE(
2956 properties.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2957 EXPECT_FALSE(
2958 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2959
2960 // Set different QuicServerInfo for the same canononical suffix and
2961 // |network_anonymization_key2_|. Both infos should be retriveable by using
2962 // the different NetworkIsolationKeys.
2963 properties.SetQuicServerInfo(server1, network_anonymization_key2_,
2964 server_info2);
2965 fetched_server_info =
2966 properties.GetQuicServerInfo(server1, network_anonymization_key1_);
2967 ASSERT_TRUE(fetched_server_info);
2968 EXPECT_EQ(server_info1, *fetched_server_info);
2969 fetched_server_info =
2970 properties.GetQuicServerInfo(server2, network_anonymization_key1_);
2971 ASSERT_TRUE(fetched_server_info);
2972 EXPECT_EQ(server_info1, *fetched_server_info);
2973 fetched_server_info =
2974 properties.GetQuicServerInfo(server1, network_anonymization_key2_);
2975 ASSERT_TRUE(fetched_server_info);
2976 EXPECT_EQ(server_info2, *fetched_server_info);
2977 fetched_server_info =
2978 properties.GetQuicServerInfo(server2, network_anonymization_key2_);
2979 ASSERT_TRUE(fetched_server_info);
2980 EXPECT_EQ(server_info2, *fetched_server_info);
2981 EXPECT_FALSE(
2982 properties.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2983 EXPECT_FALSE(
2984 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2985
2986 // Clearing should destroy all information.
2987 properties.Clear(base::OnceClosure());
2988 EXPECT_FALSE(
2989 properties.GetQuicServerInfo(server1, network_anonymization_key1_));
2990 EXPECT_FALSE(
2991 properties.GetQuicServerInfo(server2, network_anonymization_key1_));
2992 EXPECT_FALSE(
2993 properties.GetQuicServerInfo(server1, network_anonymization_key2_));
2994 EXPECT_FALSE(
2995 properties.GetQuicServerInfo(server2, network_anonymization_key2_));
2996 EXPECT_FALSE(
2997 properties.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2998 EXPECT_FALSE(
2999 properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
3000 }
3001
3002 // Verifies that GetQuicServerInfo() returns the MRU entry if multiple records
3003 // match a given canonical host.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatchReturnsMruEntry)3004 TEST_F(HttpServerPropertiesTest,
3005 QuicServerInfoCanonicalSuffixMatchReturnsMruEntry) {
3006 // Set up HttpServerProperties by adding two hosts with the same canonical
3007 // suffixes.
3008 quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
3009 std::string h1_server_info("h1_server_info");
3010 impl_.SetQuicServerInfo(h1_server_id, NetworkAnonymizationKey(),
3011 h1_server_info);
3012
3013 quic::QuicServerId h2_server_id("h2.googlevideo.com", 443, false);
3014 std::string h2_server_info("h2_server_info");
3015 impl_.SetQuicServerInfo(h2_server_id, NetworkAnonymizationKey(),
3016 h2_server_info);
3017
3018 // Create quic::QuicServerId to use for the search.
3019 quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
3020
3021 // Check that 'h2' info is returned since it is MRU.
3022 const std::string* server_info =
3023 impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3024 ASSERT_TRUE(server_info != nullptr);
3025 EXPECT_EQ(h2_server_info, *server_info);
3026
3027 // Access 'h1' info, so it becomes MRU.
3028 impl_.GetQuicServerInfo(h1_server_id, NetworkAnonymizationKey());
3029
3030 // Check that 'h1' info is returned since it is MRU now.
3031 server_info =
3032 impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3033 ASSERT_TRUE(server_info != nullptr);
3034 EXPECT_EQ(h1_server_info, *server_info);
3035 }
3036
3037 // Verifies that |GetQuicServerInfo| doesn't change the MRU order of the server
3038 // info map when a record is matched based on a canonical name.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatchDoesntChangeOrder)3039 TEST_F(HttpServerPropertiesTest,
3040 QuicServerInfoCanonicalSuffixMatchDoesntChangeOrder) {
3041 // Add a host with a matching canonical name.
3042 quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
3043 HttpServerProperties::QuicServerInfoMapKey h1_key(
3044 h1_server_id, NetworkAnonymizationKey(),
3045 false /* use_network_anonymization_key */);
3046 std::string h1_server_info("h1_server_info");
3047 impl_.SetQuicServerInfo(h1_server_id, NetworkAnonymizationKey(),
3048 h1_server_info);
3049
3050 // Add a host hosts with a non-matching canonical name.
3051 quic::QuicServerId h2_server_id("h2.video.com", 443, false);
3052 HttpServerProperties::QuicServerInfoMapKey h2_key(
3053 h2_server_id, NetworkAnonymizationKey(),
3054 false /* use_network_anonymization_key */);
3055 std::string h2_server_info("h2_server_info");
3056 impl_.SetQuicServerInfo(h2_server_id, NetworkAnonymizationKey(),
3057 h2_server_info);
3058
3059 // Check that "h2.video.com" is the MRU entry in the map.
3060 EXPECT_EQ(h2_key, impl_.quic_server_info_map().begin()->first);
3061
3062 // Search for the entry that matches the canonical name
3063 // ("h1.googlevideo.com").
3064 quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
3065 const std::string* server_info =
3066 impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3067 ASSERT_TRUE(server_info != nullptr);
3068
3069 // Check that the search (although successful) hasn't changed the MRU order of
3070 // the map.
3071 EXPECT_EQ(h2_key, impl_.quic_server_info_map().begin()->first);
3072
3073 // Search for "h1.googlevideo.com" directly, so it becomes MRU
3074 impl_.GetQuicServerInfo(h1_server_id, NetworkAnonymizationKey());
3075
3076 // Check that "h1.googlevideo.com" is the MRU entry now.
3077 EXPECT_EQ(h1_key, impl_.quic_server_info_map().begin()->first);
3078 }
3079
3080 // Tests that the canonical host matching works for hosts stored in memory cache
3081 // and the ones loaded from persistent storage, i.e. server info added
3082 // using SetQuicServerInfo() and SetQuicServerInfoMap() is taken into
3083 // cosideration when searching for server info for a host with the same
3084 // canonical suffix.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatchSetInfoMap)3085 TEST_F(HttpServerPropertiesTest, QuicServerInfoCanonicalSuffixMatchSetInfoMap) {
3086 // Add a host info using SetQuicServerInfo(). That will simulate an info
3087 // entry stored in memory cache.
3088 quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
3089 std::string h1_server_info("h1_server_info_memory_cache");
3090 impl_.SetQuicServerInfo(h1_server_id, NetworkAnonymizationKey(),
3091 h1_server_info);
3092
3093 // Prepare a map with host info and add it using SetQuicServerInfoMap(). That
3094 // will simulate info records read from the persistence storage.
3095 quic::QuicServerId h2_server_id("h2.googlevideo.com", 443, false);
3096 HttpServerProperties::QuicServerInfoMapKey h2_key(
3097 h2_server_id, NetworkAnonymizationKey(),
3098 false /* use_network_anonymization_key */);
3099 std::string h2_server_info("h2_server_info_from_disk");
3100
3101 quic::QuicServerId h3_server_id("h3.ggpht.com", 443, false);
3102 HttpServerProperties::QuicServerInfoMapKey h3_key(
3103 h3_server_id, NetworkAnonymizationKey(),
3104 false /* use_network_anonymization_key */);
3105 std::string h3_server_info("h3_server_info_from_disk");
3106
3107 const int kMaxQuicServerEntries = 10;
3108 impl_.SetMaxServerConfigsStoredInProperties(kMaxQuicServerEntries);
3109
3110 std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
3111 quic_server_info_map =
3112 std::make_unique<HttpServerProperties::QuicServerInfoMap>(
3113 kMaxQuicServerEntries);
3114 quic_server_info_map->Put(h2_key, h2_server_info);
3115 quic_server_info_map->Put(h3_key, h3_server_info);
3116 impl_.OnQuicServerInfoMapLoadedForTesting(std::move(quic_server_info_map));
3117
3118 // Check that the server info from the memory cache is returned since unique
3119 // entries from the memory cache are added after entries from the
3120 // persistence storage and, therefore, are most recently used.
3121 quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
3122 const std::string* server_info =
3123 impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3124 ASSERT_TRUE(server_info != nullptr);
3125 EXPECT_EQ(h1_server_info, *server_info);
3126
3127 // Check that server info that was added using SetQuicServerInfoMap() can be
3128 // found.
3129 foo_server_id = quic::QuicServerId("foo.ggpht.com", 443, false);
3130 server_info =
3131 impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3132 ASSERT_TRUE(server_info != nullptr);
3133 EXPECT_EQ(h3_server_info, *server_info);
3134 }
3135
3136 } // namespace
3137
3138 } // namespace net
3139