Commit 977f0279 authored by Matt Menke's avatar Matt Menke Committed by Commit Bot

HttpServerProperties: Hook NetworkIsolationKeys to broken alt service API

This CL makes HttpServerProperties methods that deal with broken alt
services take NetworkIsolationKeys, and wires through through to the
BrokenAlternativeServices object it owns. This CL also updates
HttpServerPropertiesManager to save/load the NetworkIsolationKey
associated with each broken alt service.

Bug: 969890
Change-Id: I81909c8a3965d510fe775e7ccadebd4d88e5a7da
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1775260
Commit-Queue: Matt Menke <mmenke@chromium.org>
Reviewed-by: default avatarZhongyi Shi <zhongyi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#695200}
parent 4b1282ab
...@@ -113,12 +113,6 @@ NET_EXPORT_PRIVATE std::ostream& operator<<( ...@@ -113,12 +113,6 @@ NET_EXPORT_PRIVATE std::ostream& operator<<(
std::ostream& os, std::ostream& os,
const AlternativeService& alternative_service); const AlternativeService& alternative_service);
struct AlternativeServiceHash {
size_t operator()(const net::AlternativeService& entry) const {
return entry.protocol ^ std::hash<std::string>()(entry.host) ^ entry.port;
}
};
class NET_EXPORT_PRIVATE AlternativeServiceInfo { class NET_EXPORT_PRIVATE AlternativeServiceInfo {
public: public:
static AlternativeServiceInfo CreateHttp2AlternativeServiceInfo( static AlternativeServiceInfo CreateHttp2AlternativeServiceInfo(
......
...@@ -487,46 +487,52 @@ void HttpServerProperties::SetAlternativeServices( ...@@ -487,46 +487,52 @@ void HttpServerProperties::SetAlternativeServices(
} }
void HttpServerProperties::MarkAlternativeServiceBroken( void HttpServerProperties::MarkAlternativeServiceBroken(
const AlternativeService& alternative_service) { const AlternativeService& alternative_service,
const net::NetworkIsolationKey& network_isolation_key) {
broken_alternative_services_.MarkBroken(BrokenAlternativeService( broken_alternative_services_.MarkBroken(BrokenAlternativeService(
alternative_service, NetworkIsolationKey(), use_network_isolation_key_)); alternative_service, network_isolation_key, use_network_isolation_key_));
MaybeQueueWriteProperties(); MaybeQueueWriteProperties();
} }
void HttpServerProperties:: void HttpServerProperties::
MarkAlternativeServiceBrokenUntilDefaultNetworkChanges( MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
const AlternativeService& alternative_service) { const AlternativeService& alternative_service,
const net::NetworkIsolationKey& network_isolation_key) {
broken_alternative_services_.MarkBrokenUntilDefaultNetworkChanges( broken_alternative_services_.MarkBrokenUntilDefaultNetworkChanges(
BrokenAlternativeService(alternative_service, NetworkIsolationKey(), BrokenAlternativeService(alternative_service, network_isolation_key,
use_network_isolation_key_)); use_network_isolation_key_));
MaybeQueueWriteProperties(); MaybeQueueWriteProperties();
} }
void HttpServerProperties::MarkAlternativeServiceRecentlyBroken( void HttpServerProperties::MarkAlternativeServiceRecentlyBroken(
const AlternativeService& alternative_service) { const AlternativeService& alternative_service,
const net::NetworkIsolationKey& network_isolation_key) {
broken_alternative_services_.MarkRecentlyBroken(BrokenAlternativeService( broken_alternative_services_.MarkRecentlyBroken(BrokenAlternativeService(
alternative_service, NetworkIsolationKey(), use_network_isolation_key_)); alternative_service, network_isolation_key, use_network_isolation_key_));
MaybeQueueWriteProperties(); MaybeQueueWriteProperties();
} }
bool HttpServerProperties::IsAlternativeServiceBroken( bool HttpServerProperties::IsAlternativeServiceBroken(
const AlternativeService& alternative_service) const { const AlternativeService& alternative_service,
const net::NetworkIsolationKey& network_isolation_key) const {
return broken_alternative_services_.IsBroken(BrokenAlternativeService( return broken_alternative_services_.IsBroken(BrokenAlternativeService(
alternative_service, NetworkIsolationKey(), use_network_isolation_key_)); alternative_service, network_isolation_key, use_network_isolation_key_));
} }
bool HttpServerProperties::WasAlternativeServiceRecentlyBroken( bool HttpServerProperties::WasAlternativeServiceRecentlyBroken(
const AlternativeService& alternative_service) { const AlternativeService& alternative_service,
const net::NetworkIsolationKey& network_isolation_key) {
return broken_alternative_services_.WasRecentlyBroken( return broken_alternative_services_.WasRecentlyBroken(
BrokenAlternativeService(alternative_service, NetworkIsolationKey(), BrokenAlternativeService(alternative_service, network_isolation_key,
use_network_isolation_key_)); use_network_isolation_key_));
} }
void HttpServerProperties::ConfirmAlternativeService( void HttpServerProperties::ConfirmAlternativeService(
const AlternativeService& alternative_service) { const AlternativeService& alternative_service,
const net::NetworkIsolationKey& network_isolation_key) {
bool old_value = IsAlternativeServiceBroken(alternative_service); bool old_value = IsAlternativeServiceBroken(alternative_service);
broken_alternative_services_.Confirm(BrokenAlternativeService( broken_alternative_services_.Confirm(BrokenAlternativeService(
alternative_service, NetworkIsolationKey(), use_network_isolation_key_)); alternative_service, network_isolation_key, use_network_isolation_key_));
bool new_value = IsAlternativeServiceBroken(alternative_service); bool new_value = IsAlternativeServiceBroken(alternative_service);
// For persisting, we only care about the value returned by // For persisting, we only care about the value returned by
......
...@@ -297,34 +297,48 @@ class NET_EXPORT HttpServerProperties ...@@ -297,34 +297,48 @@ class NET_EXPORT HttpServerProperties
const net::NetworkIsolationKey& network_isolation_key, const net::NetworkIsolationKey& network_isolation_key,
const AlternativeServiceInfoVector& alternative_service_info_vector); const AlternativeServiceInfoVector& alternative_service_info_vector);
// Marks |alternative_service| as broken. // Marks |alternative_service| as broken in the context of
// |alternative_service.host| must not be empty. // |network_isolation_key|. |alternative_service.host| must not be empty.
void MarkAlternativeServiceBroken( void MarkAlternativeServiceBroken(
const AlternativeService& alternative_service); const AlternativeService& alternative_service,
const net::NetworkIsolationKey& network_isolation_key =
NetworkIsolationKey());
// Marks |alternative_service| as broken until the default network changes. // Marks |alternative_service| as broken in the context of
// |network_isolation_key| until the default network changes.
// |alternative_service.host| must not be empty. // |alternative_service.host| must not be empty.
void MarkAlternativeServiceBrokenUntilDefaultNetworkChanges( void MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
const AlternativeService& alternative_service); const AlternativeService& alternative_service,
const net::NetworkIsolationKey& network_isolation_key =
NetworkIsolationKey());
// Marks |alternative_service| as recently broken. // Marks |alternative_service| as recently broken in the context of
// |alternative_service.host| must not be empty. // |network_isolation_key|. |alternative_service.host| must not be empty.
void MarkAlternativeServiceRecentlyBroken( void MarkAlternativeServiceRecentlyBroken(
const AlternativeService& alternative_service); const AlternativeService& alternative_service,
const net::NetworkIsolationKey& network_isolation_key =
NetworkIsolationKey());
// Returns true iff |alternative_service| is currently broken. // Returns true iff |alternative_service| is currently broken in the context
// |alternative_service.host| must not be empty. // of |network_isolation_key|. |alternative_service.host| must not be empty.
bool IsAlternativeServiceBroken( bool IsAlternativeServiceBroken(
const AlternativeService& alternative_service) const; const AlternativeService& alternative_service,
const net::NetworkIsolationKey& network_isolation_key =
NetworkIsolationKey()) const;
// Returns true iff |alternative_service| was recently broken. // Returns true iff |alternative_service| was recently broken in the context
// |alternative_service.host| must not be empty. // of |network_isolation_key|. |alternative_service.host| must not be empty.
bool WasAlternativeServiceRecentlyBroken( bool WasAlternativeServiceRecentlyBroken(
const AlternativeService& alternative_service); const AlternativeService& alternative_service,
const net::NetworkIsolationKey& network_isolation_key =
NetworkIsolationKey());
// Confirms that |alternative_service| is working. // Confirms that |alternative_service| is working in the context of
// |alternative_service.host| must not be empty. // |network_isolation_key|. |alternative_service.host| must not be empty.
void ConfirmAlternativeService(const AlternativeService& alternative_service); void ConfirmAlternativeService(
const AlternativeService& alternative_service,
const net::NetworkIsolationKey& network_isolation_key =
NetworkIsolationKey());
// Called when the default network changes. // Called when the default network changes.
// Clears all the alternative services that were marked broken until the // Clears all the alternative services that were marked broken until the
......
...@@ -113,6 +113,23 @@ void AddAlternativeServiceFieldsToDictionaryValue( ...@@ -113,6 +113,23 @@ void AddAlternativeServiceFieldsToDictionaryValue(
NextProtoToString(alternative_service.protocol)); NextProtoToString(alternative_service.protocol));
} }
// Fails in the case of NetworkIsolationKeys that can't be persisted to disk,
// like unique origins.
bool TryAddBrokenAlternativeServiceFieldsToDictionaryValue(
const BrokenAlternativeService& broken_alt_service,
base::DictionaryValue* dict) {
base::Value network_isolation_key_value;
if (!broken_alt_service.network_isolation_key.ToValue(
&network_isolation_key_value)) {
return false;
}
dict->SetKey(kNetworkIsolationKey, std::move(network_isolation_key_value));
AddAlternativeServiceFieldsToDictionaryValue(
broken_alt_service.alternative_service, dict);
return true;
}
quic::QuicServerId QuicServerIdFromString(const std::string& str) { quic::QuicServerId QuicServerIdFromString(const std::string& str) {
GURL url(str); GURL url(str);
if (!url.is_valid()) { if (!url.is_valid()) {
...@@ -298,6 +315,20 @@ void HttpServerPropertiesManager::AddToBrokenAlternativeServices( ...@@ -298,6 +315,20 @@ void HttpServerPropertiesManager::AddToBrokenAlternativeServices(
return; return;
} }
const base::Value* network_isolation_key_value =
broken_alt_svc_entry_dict.FindKey(kNetworkIsolationKey);
NetworkIsolationKey network_isolation_key;
if (!network_isolation_key_value ||
!NetworkIsolationKey::FromValue(*network_isolation_key_value,
&network_isolation_key)) {
return;
}
// Fail if NetworkIsolationKeys are disabled, but the entry has a non-empty
// NetworkIsolationKey.
if (!use_network_isolation_key && !network_isolation_key.IsEmpty())
return;
// Each entry must contain either broken-count and/or broken-until fields. // Each entry must contain either broken-count and/or broken-until fields.
bool contains_broken_count_or_broken_until = false; bool contains_broken_count_or_broken_until = false;
...@@ -316,7 +347,7 @@ void HttpServerPropertiesManager::AddToBrokenAlternativeServices( ...@@ -316,7 +347,7 @@ void HttpServerPropertiesManager::AddToBrokenAlternativeServices(
return; return;
} }
recently_broken_alternative_services->Put( recently_broken_alternative_services->Put(
BrokenAlternativeService(alt_service, NetworkIsolationKey(), BrokenAlternativeService(alt_service, network_isolation_key,
use_network_isolation_key), use_network_isolation_key),
broken_count); broken_count);
contains_broken_count_or_broken_until = true; contains_broken_count_or_broken_until = true;
...@@ -341,7 +372,7 @@ void HttpServerPropertiesManager::AddToBrokenAlternativeServices( ...@@ -341,7 +372,7 @@ void HttpServerPropertiesManager::AddToBrokenAlternativeServices(
clock_->NowTicks() + clock_->NowTicks() +
(base::Time::FromTimeT(expiration_time_t) - base::Time::Now()); (base::Time::FromTimeT(expiration_time_t) - base::Time::Now());
broken_alternative_service_list->push_back(std::make_pair( broken_alternative_service_list->push_back(std::make_pair(
BrokenAlternativeService(alt_service, NetworkIsolationKey(), BrokenAlternativeService(alt_service, network_isolation_key,
use_network_isolation_key), use_network_isolation_key),
expiration_time_ticks)); expiration_time_ticks));
contains_broken_count_or_broken_until = true; contains_broken_count_or_broken_until = true;
...@@ -804,8 +835,9 @@ void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs( ...@@ -804,8 +835,9 @@ void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs(
recently_broken_alternative_services, recently_broken_alternative_services,
base::DictionaryValue* http_server_properties_dict) { base::DictionaryValue* http_server_properties_dict) {
if (broken_alternative_service_list.empty() && if (broken_alternative_service_list.empty() &&
recently_broken_alternative_services.empty()) recently_broken_alternative_services.empty()) {
return; return;
}
// JSON list will be in MRU order according to // JSON list will be in MRU order according to
// |recently_broken_alternative_services|. // |recently_broken_alternative_services|.
...@@ -814,20 +846,21 @@ void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs( ...@@ -814,20 +846,21 @@ void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs(
// Maps recently-broken alternative services to the index where it's stored // Maps recently-broken alternative services to the index where it's stored
// in |json_list|. // in |json_list|.
std::unordered_map<AlternativeService, size_t, AlternativeServiceHash> std::map<BrokenAlternativeService, size_t> json_list_index_map;
json_list_index_map;
if (!recently_broken_alternative_services.empty()) { if (!recently_broken_alternative_services.empty()) {
for (auto it = recently_broken_alternative_services.rbegin(); for (auto it = recently_broken_alternative_services.rbegin();
it != recently_broken_alternative_services.rend(); ++it) { it != recently_broken_alternative_services.rend(); ++it) {
const BrokenAlternativeService& broken_alt_service_info = it->first; const BrokenAlternativeService& broken_alt_service = it->first;
int broken_count = it->second; int broken_count = it->second;
base::DictionaryValue entry_dict; base::DictionaryValue entry_dict;
AddAlternativeServiceFieldsToDictionaryValue( if (!TryAddBrokenAlternativeServiceFieldsToDictionaryValue(
broken_alt_service_info.alternative_service, &entry_dict); broken_alt_service, &entry_dict)) {
continue;
}
entry_dict.SetKey(kBrokenCountKey, base::Value(broken_count)); entry_dict.SetKey(kBrokenCountKey, base::Value(broken_count));
json_list_index_map[broken_alt_service_info.alternative_service] = json_list_index_map[broken_alt_service] = json_list->GetList().size();
json_list->GetList().size();
json_list->GetList().push_back(std::move(entry_dict)); json_list->GetList().push_back(std::move(entry_dict));
} }
} }
...@@ -848,8 +881,7 @@ void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs( ...@@ -848,8 +881,7 @@ void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs(
.ToTimeT(); .ToTimeT();
int64_t expiration_int64 = static_cast<int64_t>(expiration_time_t); int64_t expiration_int64 = static_cast<int64_t>(expiration_time_t);
auto index_map_it = auto index_map_it = json_list_index_map.find(broken_alt_service);
json_list_index_map.find(broken_alt_service.alternative_service);
if (index_map_it != json_list_index_map.end()) { if (index_map_it != json_list_index_map.end()) {
size_t json_list_index = index_map_it->second; size_t json_list_index = index_map_it->second;
base::DictionaryValue* entry_dict = nullptr; base::DictionaryValue* entry_dict = nullptr;
...@@ -860,8 +892,10 @@ void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs( ...@@ -860,8 +892,10 @@ void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs(
base::Value(base::NumberToString(expiration_int64))); base::Value(base::NumberToString(expiration_int64)));
} else { } else {
base::DictionaryValue entry_dict; base::DictionaryValue entry_dict;
AddAlternativeServiceFieldsToDictionaryValue( if (!TryAddBrokenAlternativeServiceFieldsToDictionaryValue(
broken_alt_service.alternative_service, &entry_dict); broken_alt_service, &entry_dict)) {
continue;
}
entry_dict.SetKey(kBrokenUntilKey, entry_dict.SetKey(kBrokenUntilKey,
base::Value(base::NumberToString(expiration_int64))); base::Value(base::NumberToString(expiration_int64)));
json_list->GetList().push_back(std::move(entry_dict)); json_list->GetList().push_back(std::move(entry_dict));
...@@ -869,7 +903,11 @@ void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs( ...@@ -869,7 +903,11 @@ void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs(
} }
} }
DCHECK(!json_list->empty()); // This can happen if all the entries are for NetworkIsolationKeys for opaque
// origins, which isn't exactly common, but can theoretically happen.
if (json_list->empty())
return;
http_server_properties_dict->SetWithoutPathExpansion( http_server_properties_dict->SetWithoutPathExpansion(
kBrokenAlternativeServicesKey, std::move(json_list)); kBrokenAlternativeServicesKey, std::move(json_list));
} }
......
...@@ -1209,10 +1209,10 @@ TEST_F(HttpServerPropertiesManagerTest, UpdatePrefsWithCache) { ...@@ -1209,10 +1209,10 @@ TEST_F(HttpServerPropertiesManagerTest, UpdatePrefsWithCache) {
const char expected_json[] = const char expected_json[] =
"{" "{"
"\"broken_alternative_services\":" "\"broken_alternative_services\":"
"[{\"broken_count\":1,\"host\":\"www.google.com\",\"port\":1234," "[{\"broken_count\":1,\"host\":\"www.google.com\",\"isolation\":[],"
"\"protocol_str\":\"h2\"}," "\"port\":1234,\"protocol_str\":\"h2\"},"
"{\"broken_count\":1,\"host\":\"foo.google.com\",\"port\":444," "{\"broken_count\":1,\"host\":\"foo.google.com\",\"isolation\":[],"
"\"protocol_str\":\"h2\"}]," "\"port\":444,\"protocol_str\":\"h2\"}],"
"\"quic_servers\":" "\"quic_servers\":"
"{\"https://mail.google.com:80\":" "{\"https://mail.google.com:80\":"
"{\"server_info\":\"quic_server_info1\"}}," "{\"server_info\":\"quic_server_info1\"}},"
...@@ -1737,13 +1737,16 @@ TEST_F(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) { ...@@ -1737,13 +1737,16 @@ TEST_F(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) {
"{\"broken_until\":\"" + "{\"broken_until\":\"" +
expiration_str + expiration_str +
"\"," "\","
"\"host\":\"www.google.com\",\"port\":1234,\"protocol_str\":\"h2\"}," "\"host\":\"www.google.com\",\"isolation\":[],"
"\"port\":1234,\"protocol_str\":\"h2\"},"
"{\"broken_count\":2,\"broken_until\":\"" + "{\"broken_count\":2,\"broken_until\":\"" +
expiration_str + expiration_str +
"\"," "\","
"\"host\":\"cached_broken\",\"port\":443,\"protocol_str\":\"quic\"}," "\"host\":\"cached_broken\",\"isolation\":[],"
"\"port\":443,\"protocol_str\":\"quic\"},"
"{\"broken_count\":3," "{\"broken_count\":3,"
"\"host\":\"cached_rbroken\",\"port\":443,\"protocol_str\":\"quic\"}]," "\"host\":\"cached_rbroken\",\"isolation\":[],"
"\"port\":443,\"protocol_str\":\"quic\"}],"
"\"quic_servers\":{" "\"quic_servers\":{"
"\"https://mail.google.com:80\":{" "\"https://mail.google.com:80\":{"
"\"server_info\":\"quic_server_info1\"}" "\"server_info\":\"quic_server_info1\"}"
...@@ -2389,4 +2392,258 @@ TEST_F(HttpServerPropertiesManagerTest, ...@@ -2389,4 +2392,258 @@ TEST_F(HttpServerPropertiesManagerTest,
.size()); .size());
} }
// Tests a full round trip with a NetworkIsolationKey, using the
// HttpServerProperties interface and setting alternative services as broken.
TEST_F(HttpServerPropertiesManagerTest,
NetworkIsolationKeyBrokenAltServiceRoundTrip) {
const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo1.test/"));
const url::Origin kOrigin2 = url::Origin::Create(GURL("https://foo2.test/"));
const AlternativeService kAlternativeService1(kProtoHTTP2,
"alt.service1.test", 443);
const AlternativeService kAlternativeService2(kProtoHTTP2,
"alt.service2.test", 443);
for (auto save_network_isolation_key_mode : kNetworkIsolationKeyModes) {
SCOPED_TRACE(static_cast<int>(save_network_isolation_key_mode));
// Save prefs using |save_network_isolation_key_mode|.
std::unique_ptr<base::DictionaryValue> saved_value;
{
// Configure the the feature.
std::unique_ptr<base::test::ScopedFeatureList> feature_list =
SetNetworkIsolationKeyMode(save_network_isolation_key_mode);
// The NetworkIsolationKey constructor checks the field trial state, so
// need to create the keys only after setting up the field trials.
const NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
const NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
// Create and initialize an HttpServerProperties, must be done after
// setting the feature.
std::unique_ptr<MockPrefDelegate> pref_delegate =
std::make_unique<MockPrefDelegate>();
MockPrefDelegate* unowned_pref_delegate = pref_delegate.get();
std::unique_ptr<HttpServerProperties> properties =
std::make_unique<HttpServerProperties>(std::move(pref_delegate),
/*net_log=*/nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(base::DictionaryValue());
// Set kAlternativeService1 as broken in the context of
// kNetworkIsolationKey1, and kAlternativeService2 as broken in the
// context of the empty NetworkIsolationKey2, and recently broken in the
// context of the empty NetworkIsolationKey.
properties->MarkAlternativeServiceBroken(kAlternativeService1,
kNetworkIsolationKey1);
properties->MarkAlternativeServiceRecentlyBroken(kAlternativeService2,
NetworkIsolationKey());
properties->MarkAlternativeServiceBroken(kAlternativeService2,
kNetworkIsolationKey2);
// Verify values were set.
EXPECT_TRUE(properties->IsAlternativeServiceBroken(
kAlternativeService1, kNetworkIsolationKey1));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, kNetworkIsolationKey1));
// When NetworkIsolationKeys are disabled, kAlternativeService2 is marked
// as broken regardless of the values passed to NetworkIsolationKey's
// constructor.
EXPECT_EQ(
save_network_isolation_key_mode == NetworkIsolationKeyMode::kDisabled,
properties->IsAlternativeServiceBroken(kAlternativeService2,
NetworkIsolationKey()));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, NetworkIsolationKey()));
EXPECT_TRUE(properties->IsAlternativeServiceBroken(
kAlternativeService2, kNetworkIsolationKey2));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, kNetworkIsolationKey2));
// If NetworkIsolationKeys are enabled, there should be no
// cross-contamination of the NetworkIsolationKeys.
if (save_network_isolation_key_mode !=
NetworkIsolationKeyMode::kDisabled) {
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService2, kNetworkIsolationKey1));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, kNetworkIsolationKey1));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, NetworkIsolationKey()));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, NetworkIsolationKey()));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, kNetworkIsolationKey2));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, kNetworkIsolationKey2));
}
// Wait until the data's been written to prefs, and then create a copy of
// the prefs data.
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
saved_value =
unowned_pref_delegate->GetServerProperties()->CreateDeepCopy();
}
// Now try and load the data in each of the feature modes.
for (auto load_network_isolation_key_mode : kNetworkIsolationKeyModes) {
SCOPED_TRACE(static_cast<int>(load_network_isolation_key_mode));
std::unique_ptr<base::test::ScopedFeatureList> feature_list =
SetNetworkIsolationKeyMode(load_network_isolation_key_mode);
// The NetworkIsolationKey constructor checks the field trial state, so
// need to create the keys only after setting up the field trials.
const NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
const NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
// Create a new HttpServerProperties, loading the data from before.
std::unique_ptr<MockPrefDelegate> pref_delegate =
std::make_unique<MockPrefDelegate>();
MockPrefDelegate* unowned_pref_delegate = pref_delegate.get();
std::unique_ptr<HttpServerProperties> properties =
std::make_unique<HttpServerProperties>(std::move(pref_delegate),
/*net_log=*/nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(*saved_value);
if (save_network_isolation_key_mode ==
NetworkIsolationKeyMode::kDisabled) {
// If NetworkIsolationKey was disabled when saving, it was saved with an
// empty NetworkIsolationKey, which should always be loaded
// successfully. This is needed to continue to support consumers that
// don't use NetworkIsolationKeys.
EXPECT_TRUE(properties->IsAlternativeServiceBroken(
kAlternativeService1, NetworkIsolationKey()));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, NetworkIsolationKey()));
EXPECT_TRUE(properties->IsAlternativeServiceBroken(
kAlternativeService2, NetworkIsolationKey()));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, NetworkIsolationKey()));
} else if (save_network_isolation_key_mode ==
load_network_isolation_key_mode) {
// If the save and load modes are the same, the load should succeed, and
// the network isolation keys should match.
EXPECT_TRUE(properties->IsAlternativeServiceBroken(
kAlternativeService1, kNetworkIsolationKey1));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, kNetworkIsolationKey1));
// When NetworkIsolationKeys are disabled, kAlternativeService2 is
// marked as broken regardless of the values passed to
// NetworkIsolationKey's constructor.
EXPECT_EQ(save_network_isolation_key_mode ==
NetworkIsolationKeyMode::kDisabled,
properties->IsAlternativeServiceBroken(
kAlternativeService2, NetworkIsolationKey()));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, NetworkIsolationKey()));
EXPECT_TRUE(properties->IsAlternativeServiceBroken(
kAlternativeService2, kNetworkIsolationKey2));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, kNetworkIsolationKey2));
// If NetworkIsolationKeys are enabled, there should be no
// cross-contamination of the NetworkIsolationKeys.
if (save_network_isolation_key_mode !=
NetworkIsolationKeyMode::kDisabled) {
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService2, kNetworkIsolationKey1));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, kNetworkIsolationKey1));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, NetworkIsolationKey()));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, NetworkIsolationKey()));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, kNetworkIsolationKey2));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, kNetworkIsolationKey2));
}
} else {
// Otherwise, only the values set with an empty NetworkIsolationKey
// should have been loaded successfully.
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, kNetworkIsolationKey1));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, kNetworkIsolationKey1));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService2, NetworkIsolationKey()));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, NetworkIsolationKey()));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService2, kNetworkIsolationKey2));
// If the load mode is NetworkIsolationKeyMode::kDisabled,
// kNetworkIsolationKey2 is NetworkIsolationKey().
EXPECT_EQ(load_network_isolation_key_mode ==
NetworkIsolationKeyMode::kDisabled,
properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, kNetworkIsolationKey2));
// There should be no cross-contamination of NetworkIsolationKeys, if
// NetworkIsolationKeys are enabled.
if (load_network_isolation_key_mode !=
NetworkIsolationKeyMode::kDisabled) {
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService2, kNetworkIsolationKey1));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, kNetworkIsolationKey1));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, NetworkIsolationKey()));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, NetworkIsolationKey()));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, kNetworkIsolationKey2));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, kNetworkIsolationKey2));
}
}
}
}
}
// Make sure broken alt services with opaque origins aren't saved.
TEST_F(HttpServerPropertiesManagerTest,
NetworkIsolationKeyBrokenAltServiceOpaqueOrigin) {
const url::Origin kOpaqueOrigin =
url::Origin::Create(GURL("data:text/plain,Hello World"));
const NetworkIsolationKey kNetworkIsolationKey(kOpaqueOrigin, kOpaqueOrigin);
const AlternativeService kAlternativeService(kProtoHTTP2, "alt.service1.test",
443);
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
// Create and initialize an HttpServerProperties, must be done after
// setting the feature.
std::unique_ptr<MockPrefDelegate> pref_delegate =
std::make_unique<MockPrefDelegate>();
MockPrefDelegate* unowned_pref_delegate = pref_delegate.get();
std::unique_ptr<HttpServerProperties> properties =
std::make_unique<HttpServerProperties>(std::move(pref_delegate),
/*net_log=*/nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(base::DictionaryValue());
properties->MarkAlternativeServiceBroken(kAlternativeService,
kNetworkIsolationKey);
// Verify values were set.
EXPECT_TRUE(properties->IsAlternativeServiceBroken(kAlternativeService,
kNetworkIsolationKey));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService, kNetworkIsolationKey));
// Wait until the data's been written to prefs, and then create a copy of
// the prefs data.
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
// No information should have been saved to prefs.
std::string preferences_json;
base::JSONWriter::Write(*unowned_pref_delegate->GetServerProperties(),
&preferences_json);
EXPECT_EQ("{\"servers\":[],\"version\":5}", preferences_json);
}
} // namespace net } // namespace net
...@@ -44,9 +44,10 @@ class HttpServerPropertiesPeer { ...@@ -44,9 +44,10 @@ class HttpServerPropertiesPeer {
static void AddBrokenAlternativeServiceWithExpirationTime( static void AddBrokenAlternativeServiceWithExpirationTime(
HttpServerProperties* impl, HttpServerProperties* impl,
const AlternativeService& alternative_service, const AlternativeService& alternative_service,
base::TimeTicks when) { base::TimeTicks when,
const NetworkIsolationKey network_isolation_key = NetworkIsolationKey()) {
BrokenAlternativeService broken_alternative_service( BrokenAlternativeService broken_alternative_service(
alternative_service, NetworkIsolationKey(), alternative_service, network_isolation_key,
true /* use_network_isolation_key */); true /* use_network_isolation_key */);
BrokenAlternativeServiceList::iterator unused_it; BrokenAlternativeServiceList::iterator unused_it;
impl->broken_alternative_services_.AddToBrokenListAndMap( impl->broken_alternative_services_.AddToBrokenListAndMap(
...@@ -91,6 +92,11 @@ class HttpServerPropertiesTest : public TestWithTaskEnvironment { ...@@ -91,6 +92,11 @@ class HttpServerPropertiesTest : public TestWithTaskEnvironment {
&test_clock_) { &test_clock_) {
// Set |test_clock_| to some random time. // Set |test_clock_| to some random time.
test_clock_.Advance(base::TimeDelta::FromSeconds(12345)); test_clock_.Advance(base::TimeDelta::FromSeconds(12345));
url::Origin origin1 = url::Origin::Create(GURL("https://foo.test/"));
network_isolation_key1_ = NetworkIsolationKey(origin1, origin1);
url::Origin origin2 = url::Origin::Create(GURL("https://bar.test/"));
network_isolation_key2_ = NetworkIsolationKey(origin2, origin2);
} }
bool HasAlternativeService(const url::SchemeHostPort& origin, bool HasAlternativeService(const url::SchemeHostPort& origin,
...@@ -121,6 +127,11 @@ class HttpServerPropertiesTest : public TestWithTaskEnvironment { ...@@ -121,6 +127,11 @@ class HttpServerPropertiesTest : public TestWithTaskEnvironment {
const base::TickClock* test_tick_clock_; const base::TickClock* test_tick_clock_;
base::SimpleTestClock test_clock_; base::SimpleTestClock test_clock_;
// Two different non-empty network isolation keys for use in tests that need
// them.
NetworkIsolationKey network_isolation_key1_;
NetworkIsolationKey network_isolation_key2_;
HttpServerProperties impl_; HttpServerProperties impl_;
}; };
...@@ -221,27 +232,27 @@ TEST_F(HttpServerPropertiesTest, SetSupportsSpdy) { ...@@ -221,27 +232,27 @@ TEST_F(HttpServerPropertiesTest, SetSupportsSpdy) {
TEST_F(HttpServerPropertiesTest, SetSupportsSpdyWithNetworkIsolationKey) { TEST_F(HttpServerPropertiesTest, SetSupportsSpdyWithNetworkIsolationKey) {
const url::SchemeHostPort kServer("https", "foo.test", 443); const url::SchemeHostPort kServer("https", "foo.test", 443);
const url::Origin kOrigin = url::Origin::Create(GURL("https://foo.test/"));
const NetworkIsolationKey kNetworkIsolationKey(kOrigin, kOrigin);
EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, kNetworkIsolationKey)); EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, network_isolation_key1_));
EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, kNetworkIsolationKey)); EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, network_isolation_key1_));
EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, NetworkIsolationKey())); EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, NetworkIsolationKey()));
EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, NetworkIsolationKey())); EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, NetworkIsolationKey()));
// Without network isolation keys enabled for HttpServerProperties, passing in // Without network isolation keys enabled for HttpServerProperties, passing in
// a NetworkIsolationKey should have no effect on behavior. // a NetworkIsolationKey should have no effect on behavior.
for (const auto network_isolation_key_to_set : for (const auto network_isolation_key_to_set :
{NetworkIsolationKey(), kNetworkIsolationKey}) { {NetworkIsolationKey(), network_isolation_key1_}) {
impl_.SetSupportsSpdy(kServer, network_isolation_key_to_set, true); impl_.SetSupportsSpdy(kServer, network_isolation_key_to_set, true);
EXPECT_TRUE(impl_.GetSupportsSpdy(kServer, kNetworkIsolationKey)); EXPECT_TRUE(impl_.GetSupportsSpdy(kServer, network_isolation_key1_));
EXPECT_TRUE(impl_.SupportsRequestPriority(kServer, kNetworkIsolationKey)); EXPECT_TRUE(
impl_.SupportsRequestPriority(kServer, network_isolation_key1_));
EXPECT_TRUE(impl_.GetSupportsSpdy(kServer, NetworkIsolationKey())); EXPECT_TRUE(impl_.GetSupportsSpdy(kServer, NetworkIsolationKey()));
EXPECT_TRUE(impl_.SupportsRequestPriority(kServer, NetworkIsolationKey())); EXPECT_TRUE(impl_.SupportsRequestPriority(kServer, NetworkIsolationKey()));
impl_.SetSupportsSpdy(kServer, network_isolation_key_to_set, false); impl_.SetSupportsSpdy(kServer, network_isolation_key_to_set, false);
EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, kNetworkIsolationKey)); EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, network_isolation_key1_));
EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, kNetworkIsolationKey)); EXPECT_FALSE(
impl_.SupportsRequestPriority(kServer, network_isolation_key1_));
EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, NetworkIsolationKey())); EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, NetworkIsolationKey()));
EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, NetworkIsolationKey())); EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, NetworkIsolationKey()));
} }
...@@ -258,41 +269,41 @@ TEST_F(HttpServerPropertiesTest, SetSupportsSpdyWithNetworkIsolationKey) { ...@@ -258,41 +269,41 @@ TEST_F(HttpServerPropertiesTest, SetSupportsSpdyWithNetworkIsolationKey) {
nullptr /* net_log */, test_tick_clock_, nullptr /* net_log */, test_tick_clock_,
&test_clock_); &test_clock_);
EXPECT_FALSE(properties.GetSupportsSpdy(kServer, kNetworkIsolationKey)); EXPECT_FALSE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
EXPECT_FALSE( EXPECT_FALSE(
properties.SupportsRequestPriority(kServer, kNetworkIsolationKey)); properties.SupportsRequestPriority(kServer, network_isolation_key1_));
EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey())); EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
EXPECT_FALSE( EXPECT_FALSE(
properties.SupportsRequestPriority(kServer, NetworkIsolationKey())); properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
properties.SetSupportsSpdy(kServer, kNetworkIsolationKey, true); properties.SetSupportsSpdy(kServer, network_isolation_key1_, true);
EXPECT_TRUE(properties.GetSupportsSpdy(kServer, kNetworkIsolationKey)); EXPECT_TRUE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
EXPECT_TRUE( EXPECT_TRUE(
properties.SupportsRequestPriority(kServer, kNetworkIsolationKey)); properties.SupportsRequestPriority(kServer, network_isolation_key1_));
EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey())); EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
EXPECT_FALSE( EXPECT_FALSE(
properties.SupportsRequestPriority(kServer, NetworkIsolationKey())); properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
properties.SetSupportsSpdy(kServer, NetworkIsolationKey(), true); properties.SetSupportsSpdy(kServer, NetworkIsolationKey(), true);
EXPECT_TRUE(properties.GetSupportsSpdy(kServer, kNetworkIsolationKey)); EXPECT_TRUE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
EXPECT_TRUE( EXPECT_TRUE(
properties.SupportsRequestPriority(kServer, kNetworkIsolationKey)); properties.SupportsRequestPriority(kServer, network_isolation_key1_));
EXPECT_TRUE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey())); EXPECT_TRUE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
EXPECT_TRUE( EXPECT_TRUE(
properties.SupportsRequestPriority(kServer, NetworkIsolationKey())); properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
properties.SetSupportsSpdy(kServer, kNetworkIsolationKey, false); properties.SetSupportsSpdy(kServer, network_isolation_key1_, false);
EXPECT_FALSE(properties.GetSupportsSpdy(kServer, kNetworkIsolationKey)); EXPECT_FALSE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
EXPECT_FALSE( EXPECT_FALSE(
properties.SupportsRequestPriority(kServer, kNetworkIsolationKey)); properties.SupportsRequestPriority(kServer, network_isolation_key1_));
EXPECT_TRUE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey())); EXPECT_TRUE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
EXPECT_TRUE( EXPECT_TRUE(
properties.SupportsRequestPriority(kServer, NetworkIsolationKey())); properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
properties.SetSupportsSpdy(kServer, NetworkIsolationKey(), false); properties.SetSupportsSpdy(kServer, NetworkIsolationKey(), false);
EXPECT_FALSE(properties.GetSupportsSpdy(kServer, kNetworkIsolationKey)); EXPECT_FALSE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
EXPECT_FALSE( EXPECT_FALSE(
properties.SupportsRequestPriority(kServer, kNetworkIsolationKey)); properties.SupportsRequestPriority(kServer, network_isolation_key1_));
EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey())); EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
EXPECT_FALSE( EXPECT_FALSE(
properties.SupportsRequestPriority(kServer, NetworkIsolationKey())); properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
...@@ -680,29 +691,28 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetWithNetworkIsolationKey) { ...@@ -680,29 +691,28 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetWithNetworkIsolationKey) {
{AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo( {AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
AlternativeService(kProtoHTTP2, "foo", 443), AlternativeService(kProtoHTTP2, "foo", 443),
base::Time::Now() + base::TimeDelta::FromDays(1) /* expiration */)}); base::Time::Now() + base::TimeDelta::FromDays(1) /* expiration */)});
const url::Origin kOrigin = url::Origin::Create(GURL("https://foo.test/"));
const NetworkIsolationKey kNetworkIsolationKey(kOrigin, kOrigin);
EXPECT_TRUE( EXPECT_TRUE(impl_.GetAlternativeServiceInfos(kServer, network_isolation_key1_)
impl_.GetAlternativeServiceInfos(kServer, kNetworkIsolationKey).empty()); .empty());
EXPECT_TRUE( EXPECT_TRUE(
impl_.GetAlternativeServiceInfos(kServer, NetworkIsolationKey()).empty()); impl_.GetAlternativeServiceInfos(kServer, NetworkIsolationKey()).empty());
// Without network isolation keys enabled for HttpServerProperties, passing in // Without network isolation keys enabled for HttpServerProperties, passing in
// a NetworkIsolationKey should have no effect on behavior. // a NetworkIsolationKey should have no effect on behavior.
for (const auto network_isolation_key_to_set : for (const auto network_isolation_key_to_set :
{NetworkIsolationKey(), kNetworkIsolationKey}) { {NetworkIsolationKey(), network_isolation_key1_}) {
impl_.SetAlternativeServices(kServer, network_isolation_key_to_set, impl_.SetAlternativeServices(kServer, network_isolation_key_to_set,
kAlternativeServices); kAlternativeServices);
EXPECT_EQ(kAlternativeServices, EXPECT_EQ(kAlternativeServices, impl_.GetAlternativeServiceInfos(
impl_.GetAlternativeServiceInfos(kServer, kNetworkIsolationKey)); kServer, network_isolation_key1_));
EXPECT_EQ(kAlternativeServices, EXPECT_EQ(kAlternativeServices,
impl_.GetAlternativeServiceInfos(kServer, NetworkIsolationKey())); impl_.GetAlternativeServiceInfos(kServer, NetworkIsolationKey()));
impl_.SetAlternativeServices(kServer, network_isolation_key_to_set, impl_.SetAlternativeServices(kServer, network_isolation_key_to_set,
AlternativeServiceInfoVector()); AlternativeServiceInfoVector());
EXPECT_TRUE(impl_.GetAlternativeServiceInfos(kServer, kNetworkIsolationKey) EXPECT_TRUE(
.empty()); impl_.GetAlternativeServiceInfos(kServer, network_isolation_key1_)
.empty());
EXPECT_TRUE(impl_.GetAlternativeServiceInfos(kServer, NetworkIsolationKey()) EXPECT_TRUE(impl_.GetAlternativeServiceInfos(kServer, NetworkIsolationKey())
.empty()); .empty());
} }
...@@ -719,10 +729,10 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetWithNetworkIsolationKey) { ...@@ -719,10 +729,10 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetWithNetworkIsolationKey) {
nullptr /* net_log */, test_tick_clock_, nullptr /* net_log */, test_tick_clock_,
&test_clock_); &test_clock_);
properties.SetAlternativeServices(kServer, kNetworkIsolationKey, properties.SetAlternativeServices(kServer, network_isolation_key1_,
kAlternativeServices); kAlternativeServices);
EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos( EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
kServer, kNetworkIsolationKey)); kServer, network_isolation_key1_));
EXPECT_TRUE( EXPECT_TRUE(
properties.GetAlternativeServiceInfos(kServer, NetworkIsolationKey()) properties.GetAlternativeServiceInfos(kServer, NetworkIsolationKey())
.empty()); .empty());
...@@ -730,14 +740,14 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetWithNetworkIsolationKey) { ...@@ -730,14 +740,14 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetWithNetworkIsolationKey) {
properties.SetAlternativeServices(kServer, NetworkIsolationKey(), properties.SetAlternativeServices(kServer, NetworkIsolationKey(),
kAlternativeServices); kAlternativeServices);
EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos( EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
kServer, kNetworkIsolationKey)); kServer, network_isolation_key1_));
EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos( EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
kServer, NetworkIsolationKey())); kServer, NetworkIsolationKey()));
properties.SetAlternativeServices(kServer, kNetworkIsolationKey, properties.SetAlternativeServices(kServer, network_isolation_key1_,
AlternativeServiceInfoVector()); AlternativeServiceInfoVector());
EXPECT_TRUE( EXPECT_TRUE(
properties.GetAlternativeServiceInfos(kServer, kNetworkIsolationKey) properties.GetAlternativeServiceInfos(kServer, network_isolation_key1_)
.empty()); .empty());
EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos( EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
kServer, NetworkIsolationKey())); kServer, NetworkIsolationKey()));
...@@ -745,7 +755,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetWithNetworkIsolationKey) { ...@@ -745,7 +755,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetWithNetworkIsolationKey) {
properties.SetAlternativeServices(kServer, NetworkIsolationKey(), properties.SetAlternativeServices(kServer, NetworkIsolationKey(),
AlternativeServiceInfoVector()); AlternativeServiceInfoVector());
EXPECT_TRUE( EXPECT_TRUE(
properties.GetAlternativeServiceInfos(kServer, kNetworkIsolationKey) properties.GetAlternativeServiceInfos(kServer, network_isolation_key1_)
.empty()); .empty());
EXPECT_TRUE( EXPECT_TRUE(
properties.GetAlternativeServiceInfos(kServer, NetworkIsolationKey()) properties.GetAlternativeServiceInfos(kServer, NetworkIsolationKey())
...@@ -1219,6 +1229,115 @@ TEST_F(AlternateProtocolServerPropertiesTest, ClearBroken) { ...@@ -1219,6 +1229,115 @@ TEST_F(AlternateProtocolServerPropertiesTest, ClearBroken) {
EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service)); EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service));
} }
TEST_F(AlternateProtocolServerPropertiesTest,
MarkBrokenWithNetworkIsolationKey) {
url::SchemeHostPort server("http", "foo", 80);
const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
const base::Time expiration =
test_clock_.Now() + base::TimeDelta::FromDays(1);
// Without NetworkIsolationKeys enabled, the NetworkIsolationKey parameter
// should be ignored.
impl_.SetHttp2AlternativeService(server, network_isolation_key1_,
alternative_service, expiration);
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
impl_.MarkAlternativeServiceBroken(alternative_service,
network_isolation_key1_);
EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
impl_.ConfirmAlternativeService(alternative_service, network_isolation_key2_);
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
// Since HttpServerProperties caches the feature value, have to create a new
// one.
HttpServerProperties properties(nullptr /* pref_delegate */,
nullptr /* net_log */, test_tick_clock_,
&test_clock_);
properties.SetHttp2AlternativeService(server, network_isolation_key1_,
alternative_service, expiration);
properties.SetHttp2AlternativeService(server, network_isolation_key2_,
alternative_service, expiration);
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.MarkAlternativeServiceBroken(alternative_service,
network_isolation_key1_);
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.MarkAlternativeServiceBroken(alternative_service,
network_isolation_key2_);
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.ConfirmAlternativeService(alternative_service,
network_isolation_key1_);
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.ConfirmAlternativeService(alternative_service,
network_isolation_key2_);
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
}
TEST_F(AlternateProtocolServerPropertiesTest, MarkRecentlyBroken) { TEST_F(AlternateProtocolServerPropertiesTest, MarkRecentlyBroken) {
url::SchemeHostPort server("http", "foo", 80); url::SchemeHostPort server("http", "foo", 80);
const AlternativeService alternative_service(kProtoHTTP2, "foo", 443); const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
...@@ -1236,6 +1355,114 @@ TEST_F(AlternateProtocolServerPropertiesTest, MarkRecentlyBroken) { ...@@ -1236,6 +1355,114 @@ TEST_F(AlternateProtocolServerPropertiesTest, MarkRecentlyBroken) {
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service)); EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
} }
TEST_F(AlternateProtocolServerPropertiesTest,
MarkRecentlyBrokenWithNetworkIsolationKey) {
url::SchemeHostPort server("http", "foo", 80);
const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
const base::Time expiration =
test_clock_.Now() + base::TimeDelta::FromDays(1);
// Without NetworkIsolationKeys enabled, the NetworkIsolationKey parameter
// should be ignored.
impl_.SetHttp2AlternativeService(server, network_isolation_key1_,
alternative_service, expiration);
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
impl_.MarkAlternativeServiceRecentlyBroken(alternative_service,
network_isolation_key1_);
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
impl_.ConfirmAlternativeService(alternative_service, network_isolation_key2_);
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
// Since HttpServerProperties caches the feature value, have to create a new
// one.
HttpServerProperties properties(nullptr /* pref_delegate */,
nullptr /* net_log */, test_tick_clock_,
&test_clock_);
properties.SetHttp2AlternativeService(server, network_isolation_key1_,
alternative_service, expiration);
properties.SetHttp2AlternativeService(server, network_isolation_key2_,
alternative_service, expiration);
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.MarkAlternativeServiceRecentlyBroken(alternative_service,
network_isolation_key1_);
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.MarkAlternativeServiceRecentlyBroken(alternative_service,
network_isolation_key2_);
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.ConfirmAlternativeService(alternative_service,
network_isolation_key1_);
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.ConfirmAlternativeService(alternative_service,
network_isolation_key2_);
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
}
TEST_F(AlternateProtocolServerPropertiesTest, TEST_F(AlternateProtocolServerPropertiesTest,
MarkBrokenUntilDefaultNetworkChanges) { MarkBrokenUntilDefaultNetworkChanges) {
url::SchemeHostPort server("http", "foo", 80); url::SchemeHostPort server("http", "foo", 80);
...@@ -1255,6 +1482,116 @@ TEST_F(AlternateProtocolServerPropertiesTest, ...@@ -1255,6 +1482,116 @@ TEST_F(AlternateProtocolServerPropertiesTest,
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service)); EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
} }
TEST_F(AlternateProtocolServerPropertiesTest,
MarkBrokenUntilDefaultNetworkChangesWithNetworkIsolationKey) {
url::SchemeHostPort server("http", "foo", 80);
const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
const base::Time expiration =
test_clock_.Now() + base::TimeDelta::FromDays(1);
// Without NetworkIsolationKeys enabled, the NetworkIsolationKey parameter
// should be ignored.
impl_.SetHttp2AlternativeService(server, network_isolation_key1_,
alternative_service, expiration);
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
alternative_service, network_isolation_key1_);
EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
impl_.ConfirmAlternativeService(alternative_service, network_isolation_key2_);
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
// Since HttpServerProperties caches the feature value, have to create a new
// one.
HttpServerProperties properties(nullptr /* pref_delegate */,
nullptr /* net_log */, test_tick_clock_,
&test_clock_);
properties.SetHttp2AlternativeService(server, network_isolation_key1_,
alternative_service, expiration);
properties.SetHttp2AlternativeService(server, network_isolation_key2_,
alternative_service, expiration);
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
alternative_service, network_isolation_key1_);
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
alternative_service, network_isolation_key2_);
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.ConfirmAlternativeService(alternative_service,
network_isolation_key1_);
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.ConfirmAlternativeService(alternative_service,
network_isolation_key2_);
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
}
TEST_F(AlternateProtocolServerPropertiesTest, OnDefaultNetworkChanged) { TEST_F(AlternateProtocolServerPropertiesTest, OnDefaultNetworkChanged) {
url::SchemeHostPort server("http", "foo", 80); url::SchemeHostPort server("http", "foo", 80);
const AlternativeService alternative_service(kProtoHTTP2, "foo", 443); const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
...@@ -1301,6 +1638,61 @@ TEST_F(AlternateProtocolServerPropertiesTest, OnDefaultNetworkChanged) { ...@@ -1301,6 +1638,61 @@ TEST_F(AlternateProtocolServerPropertiesTest, OnDefaultNetworkChanged) {
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service)); EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
} }
TEST_F(AlternateProtocolServerPropertiesTest,
OnDefaultNetworkChangedWithNetworkIsolationKey) {
url::SchemeHostPort server("http", "foo", 80);
const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
// Since HttpServerProperties caches the feature value, have to create a new
// one.
HttpServerProperties properties(nullptr /* pref_delegate */,
nullptr /* net_log */, test_tick_clock_,
&test_clock_);
const base::Time expiration =
test_clock_.Now() + base::TimeDelta::FromDays(1);
properties.SetHttp2AlternativeService(server, network_isolation_key1_,
alternative_service, expiration);
properties.SetHttp2AlternativeService(server, network_isolation_key2_,
alternative_service, expiration);
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
alternative_service, network_isolation_key1_);
properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
alternative_service, network_isolation_key2_);
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
// Default network change clears alt svc broken until default network changes.
properties.OnDefaultNetworkChanged();
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
}
TEST_F(AlternateProtocolServerPropertiesTest, Canonical) { TEST_F(AlternateProtocolServerPropertiesTest, Canonical) {
url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443); url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey())); EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
...@@ -1362,11 +1754,6 @@ TEST_F(AlternateProtocolServerPropertiesTest, ClearCanonical) { ...@@ -1362,11 +1754,6 @@ TEST_F(AlternateProtocolServerPropertiesTest, ClearCanonical) {
TEST_F(AlternateProtocolServerPropertiesTest, TEST_F(AlternateProtocolServerPropertiesTest,
CanonicalWithNetworkIsolationKey) { CanonicalWithNetworkIsolationKey) {
const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
const NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
const NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
base::test::ScopedFeatureList feature_list; base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature( feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey); features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
...@@ -1377,10 +1764,11 @@ TEST_F(AlternateProtocolServerPropertiesTest, ...@@ -1377,10 +1764,11 @@ TEST_F(AlternateProtocolServerPropertiesTest,
&test_clock_); &test_clock_);
url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443); url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
EXPECT_FALSE(HasAlternativeService(test_server, kNetworkIsolationKey1)); EXPECT_FALSE(HasAlternativeService(test_server, network_isolation_key1_));
url::SchemeHostPort canonical_server1("https", "bar.c.youtube.com", 443); url::SchemeHostPort canonical_server1("https", "bar.c.youtube.com", 443);
EXPECT_FALSE(HasAlternativeService(canonical_server1, kNetworkIsolationKey1)); EXPECT_FALSE(
HasAlternativeService(canonical_server1, network_isolation_key1_));
AlternativeServiceInfoVector alternative_service_info_vector; AlternativeServiceInfoVector alternative_service_info_vector;
const AlternativeService canonical_alternative_service1( const AlternativeService canonical_alternative_service1(
...@@ -1394,56 +1782,59 @@ TEST_F(AlternateProtocolServerPropertiesTest, ...@@ -1394,56 +1782,59 @@ TEST_F(AlternateProtocolServerPropertiesTest,
alternative_service_info_vector.push_back( alternative_service_info_vector.push_back(
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo( AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
canonical_alternative_service2, expiration)); canonical_alternative_service2, expiration));
properties.SetAlternativeServices(canonical_server1, kNetworkIsolationKey1, properties.SetAlternativeServices(canonical_server1, network_isolation_key1_,
alternative_service_info_vector); alternative_service_info_vector);
// Since |test_server| does not have an alternative service itself, // Since |test_server| does not have an alternative service itself,
// GetAlternativeServiceInfos should return those of |canonical_server|. // GetAlternativeServiceInfos should return those of |canonical_server|.
AlternativeServiceInfoVector alternative_service_info_vector2 = AlternativeServiceInfoVector alternative_service_info_vector2 =
properties.GetAlternativeServiceInfos(test_server, kNetworkIsolationKey1); properties.GetAlternativeServiceInfos(test_server,
network_isolation_key1_);
ASSERT_EQ(2u, alternative_service_info_vector2.size()); ASSERT_EQ(2u, alternative_service_info_vector2.size());
EXPECT_EQ(canonical_alternative_service1, EXPECT_EQ(canonical_alternative_service1,
alternative_service_info_vector2[0].alternative_service()); alternative_service_info_vector2[0].alternative_service());
// Canonical information should not be visible for other NetworkIsolationKeys. // Canonical information should not be visible for other NetworkIsolationKeys.
EXPECT_TRUE( EXPECT_TRUE(
properties.GetAlternativeServiceInfos(test_server, kNetworkIsolationKey2) properties
.GetAlternativeServiceInfos(test_server, network_isolation_key2_)
.empty()); .empty());
EXPECT_TRUE( EXPECT_TRUE(
properties.GetAlternativeServiceInfos(test_server, NetworkIsolationKey()) properties.GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
.empty()); .empty());
// Now add an alternative service entry for kNetworkIsolationKey2 for a // Now add an alternative service entry for network_isolation_key2_ for a
// different server and different NetworkIsolationKey, but with the same // different server and different NetworkIsolationKey, but with the same
// canonical suffix. // canonical suffix.
url::SchemeHostPort canonical_server2("https", "shrimp.c.youtube.com", 443); url::SchemeHostPort canonical_server2("https", "shrimp.c.youtube.com", 443);
properties.SetAlternativeServices(canonical_server2, kNetworkIsolationKey2, properties.SetAlternativeServices(canonical_server2, network_isolation_key2_,
{alternative_service_info_vector[0]}); {alternative_service_info_vector[0]});
// The canonical server information should reachable, and different, for both // The canonical server information should reachable, and different, for both
// NetworkIsolationKeys. // NetworkIsolationKeys.
EXPECT_EQ( EXPECT_EQ(
1u, 1u, properties
properties.GetAlternativeServiceInfos(test_server, kNetworkIsolationKey2) .GetAlternativeServiceInfos(test_server, network_isolation_key2_)
.size()); .size());
EXPECT_EQ( EXPECT_EQ(
2u, 2u, properties
properties.GetAlternativeServiceInfos(test_server, kNetworkIsolationKey1) .GetAlternativeServiceInfos(test_server, network_isolation_key1_)
.size()); .size());
EXPECT_TRUE( EXPECT_TRUE(
properties.GetAlternativeServiceInfos(test_server, NetworkIsolationKey()) properties.GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
.empty()); .empty());
// Clearing the alternate service state of kNetworkIsolationKey1's canonical // Clearing the alternate service state of network_isolation_key1_'s canonical
// server should only affect kNetworkIsolationKey1. // server should only affect network_isolation_key1_.
properties.SetAlternativeServices(canonical_server1, kNetworkIsolationKey1, properties.SetAlternativeServices(canonical_server1, network_isolation_key1_,
{}); {});
EXPECT_EQ( EXPECT_EQ(
1u, 1u, properties
properties.GetAlternativeServiceInfos(test_server, kNetworkIsolationKey2) .GetAlternativeServiceInfos(test_server, network_isolation_key2_)
.size()); .size());
EXPECT_TRUE( EXPECT_TRUE(
properties.GetAlternativeServiceInfos(test_server, kNetworkIsolationKey1) properties
.GetAlternativeServiceInfos(test_server, network_isolation_key1_)
.empty()); .empty());
EXPECT_TRUE( EXPECT_TRUE(
properties.GetAlternativeServiceInfos(test_server, NetworkIsolationKey()) properties.GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
...@@ -1528,10 +1919,97 @@ TEST_F(AlternateProtocolServerPropertiesTest, ...@@ -1528,10 +1919,97 @@ TEST_F(AlternateProtocolServerPropertiesTest,
EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service)); EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_); HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
EXPECT_FALSE(HasAlternativeService(server, NetworkIsolationKey()));
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service)); EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service)); EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
} }
TEST_F(AlternateProtocolServerPropertiesTest,
ExpireBrokenAlternateProtocolMappingsWithNetworkIsolationKey) {
url::SchemeHostPort server("https", "foo", 443);
AlternativeService alternative_service(kProtoHTTP2, "foo", 444);
base::TimeTicks past =
test_tick_clock_->NowTicks() - base::TimeDelta::FromSeconds(42);
base::TimeTicks future =
test_tick_clock_->NowTicks() + base::TimeDelta::FromSeconds(42);
const base::Time alt_service_expiration =
test_clock_.Now() + base::TimeDelta::FromDays(1);
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
// Since HttpServerProperties caches the feature value, have to create a new
// one.
HttpServerProperties properties(nullptr /* pref_delegate */,
nullptr /* net_log */, test_tick_clock_,
&test_clock_);
properties.SetHttp2AlternativeService(server, network_isolation_key1_,
alternative_service,
alt_service_expiration);
properties.SetHttp2AlternativeService(server, network_isolation_key2_,
alternative_service,
alt_service_expiration);
EXPECT_FALSE(
properties.GetAlternativeServiceInfos(server, network_isolation_key1_)
.empty());
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(
properties.GetAlternativeServiceInfos(server, network_isolation_key2_)
.empty());
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
// Set broken alternative service with expiration date in the past for
// |network_isolation_key1_|.
HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
&properties, alternative_service, past, network_isolation_key1_);
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
// Set broken alternative service with expiration date in the future for
// |network_isolation_key1_|.
HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
&properties, alternative_service, future, network_isolation_key2_);
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
// Only the broken entry for |network_isolation_key1_| should be expired.
HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&properties);
EXPECT_TRUE(
properties.GetAlternativeServiceInfos(server, network_isolation_key1_)
.empty());
EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key1_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key1_));
EXPECT_FALSE(
properties.GetAlternativeServiceInfos(server, network_isolation_key2_)
.empty());
EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
network_isolation_key2_));
EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
alternative_service, network_isolation_key2_));
}
// Regression test for https://crbug.com/505413. // Regression test for https://crbug.com/505413.
TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc) { TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc) {
url::SchemeHostPort foo_server("https", "foo", 443); url::SchemeHostPort foo_server("https", "foo", 443);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment