#include "net/http/http_server_properties_manager.h"
#include <utility>
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/values_test_util.h"
#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
#include "base/values.h"
#include "net/base/features.h"
#include "net/base/ip_address.h"
#include "net/base/schemeful_site.h"
#include "net/http/http_network_session.h"
#include "net/http/http_server_properties.h"
#include "net/quic/quic_context.h"
#include "net/test/test_with_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace net {
namespace {
using base::StringPrintf;
using ::testing::_;
using ::testing::AtLeast;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::StrictMock;
enum class NetworkAnonymizationKeyMode {
kDisabled,
kEnabled,
};
const NetworkAnonymizationKeyMode kNetworkAnonymizationKeyModes[] = {
NetworkAnonymizationKeyMode::kDisabled,
NetworkAnonymizationKeyMode::kEnabled,
};
std::unique_ptr<base::test::ScopedFeatureList> SetNetworkAnonymizationKeyMode(
NetworkAnonymizationKeyMode mode) {
auto feature_list = std::make_unique<base::test::ScopedFeatureList>();
switch (mode) {
case NetworkAnonymizationKeyMode::kDisabled:
feature_list->InitAndDisableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
break;
case NetworkAnonymizationKeyMode::kEnabled:
feature_list->InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
break;
}
return feature_list;
}
class MockPrefDelegate : public net::HttpServerProperties::PrefDelegate {
public:
MockPrefDelegate() = default;
MockPrefDelegate(const MockPrefDelegate&) = delete;
MockPrefDelegate& operator=(const MockPrefDelegate&) = delete;
~MockPrefDelegate() override = default;
const base::Value::Dict& GetServerProperties() const override {
return prefs_;
}
void SetServerProperties(base::Value::Dict dict,
base::OnceClosure callback) override {
prefs_.clear();
prefs_.Merge(std::move(dict));
++num_pref_updates_;
if (!prefs_changed_callback_.is_null())
std::move(prefs_changed_callback_).Run();
if (!extra_prefs_changed_callback_.is_null())
std::move(extra_prefs_changed_callback_).Run();
set_properties_callback_ = std::move(callback);
}
void WaitForPrefLoad(base::OnceClosure callback) override {
CHECK(prefs_changed_callback_.is_null());
prefs_changed_callback_ = std::move(callback);
}
void InitializePrefs(base::Value::Dict dict) {
ASSERT_FALSE(prefs_changed_callback_.is_null());
prefs_ = std::move(dict);
std::move(prefs_changed_callback_).Run();
}
int GetAndClearNumPrefUpdates() {
int out = num_pref_updates_;
num_pref_updates_ = 0;
return out;
}
void set_extra_update_prefs_callback(base::OnceClosure callback) {
extra_prefs_changed_callback_ = std::move(callback);
}
base::OnceClosure GetSetPropertiesCallback() {
return std::move(set_properties_callback_);
}
private:
base::Value::Dict prefs_;
base::OnceClosure prefs_changed_callback_;
base::OnceClosure extra_prefs_changed_callback_;
int num_pref_updates_ = 0;
base::OnceClosure set_properties_callback_;
};
base::Value::Dict ServerInfoMapToDict(
const HttpServerProperties::ServerInfoMap& server_info_map) {
std::unique_ptr<MockPrefDelegate> pref_delegate =
std::make_unique<MockPrefDelegate>();
MockPrefDelegate* unowned_pref_delegate = pref_delegate.get();
HttpServerPropertiesManager::OnPrefsLoadedCallback on_prefs_loaded_callback =
base::BindOnce(
[](std::unique_ptr<HttpServerProperties::ServerInfoMap>
server_info_map,
const IPAddress& last_quic_address,
std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
quic_server_info_map,
std::unique_ptr<BrokenAlternativeServiceList>
broken_alternative_service_list,
std::unique_ptr<RecentlyBrokenAlternativeServices>
recently_broken_alternative_services) { ADD_FAILURE(); });
HttpServerPropertiesManager manager(
std::move(pref_delegate), std::move(on_prefs_loaded_callback),
10 , nullptr ,
base::DefaultTickClock::GetInstance());
manager.WriteToPrefs(
server_info_map, HttpServerPropertiesManager::GetCannonicalSuffix(),
IPAddress() ,
HttpServerProperties::QuicServerInfoMap(10),
BrokenAlternativeServiceList(), RecentlyBrokenAlternativeServices(10),
base::OnceClosure());
return unowned_pref_delegate->GetServerProperties().Clone();
}
std::unique_ptr<HttpServerProperties::ServerInfoMap> DictToServerInfoMap(
base::Value::Dict dict) {
std::unique_ptr<MockPrefDelegate> pref_delegate =
std::make_unique<MockPrefDelegate>();
MockPrefDelegate* unowned_pref_delegate = pref_delegate.get();
std::unique_ptr<HttpServerProperties::ServerInfoMap> out;
bool callback_invoked = false;
HttpServerPropertiesManager::OnPrefsLoadedCallback on_prefs_loaded_callback =
base::BindLambdaForTesting(
[&](std::unique_ptr<HttpServerProperties::ServerInfoMap>
server_info_map,
const IPAddress& last_quic_address,
std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
quic_server_info_map,
std::unique_ptr<BrokenAlternativeServiceList>
broken_alternative_service_list,
std::unique_ptr<RecentlyBrokenAlternativeServices>
recently_broken_alternative_services) {
ASSERT_FALSE(callback_invoked);
callback_invoked = true;
out = std::move(server_info_map);
});
HttpServerPropertiesManager manager(
std::move(pref_delegate), std::move(on_prefs_loaded_callback),
10 , nullptr ,
base::DefaultTickClock::GetInstance());
unowned_pref_delegate->InitializePrefs(std::move(dict));
EXPECT_TRUE(callback_invoked);
return out;
}
}
class HttpServerPropertiesManagerTest : public testing::Test,
public WithTaskEnvironment {
public:
HttpServerPropertiesManagerTest(const HttpServerPropertiesManagerTest&) =
delete;
HttpServerPropertiesManagerTest& operator=(
const HttpServerPropertiesManagerTest&) = delete;
protected:
HttpServerPropertiesManagerTest()
: WithTaskEnvironment(
base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
void SetUp() override {
one_day_from_now_ = base::Time::Now() + base::Days(1);
advertised_versions_ = DefaultSupportedQuicVersions();
auto pref_delegate = std::make_unique<MockPrefDelegate>();
pref_delegate_ = pref_delegate.get();
http_server_props_ = std::make_unique<HttpServerProperties>(
std::move(pref_delegate), nullptr, GetMockTickClock());
EXPECT_FALSE(http_server_props_->IsInitialized());
EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
}
void InitializePrefs(base::Value::Dict dict = base::Value::Dict(),
bool expect_pref_update = false) {
EXPECT_FALSE(http_server_props_->IsInitialized());
pref_delegate_->InitializePrefs(std::move(dict));
EXPECT_TRUE(http_server_props_->IsInitialized());
if (!expect_pref_update) {
EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
} else {
EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
}
}
void TearDown() override {
base::RunLoop().RunUntilIdle();
http_server_props_.reset();
}
bool HasAlternativeService(
const url::SchemeHostPort& server,
const NetworkAnonymizationKey& network_anonymization_key) {
const AlternativeServiceInfoVector alternative_service_info_vector =
http_server_props_->GetAlternativeServiceInfos(
server, network_anonymization_key);
return !alternative_service_info_vector.empty();
}
static base::Value::Dict DictWithVersion() {
base::Value::Dict http_server_properties_dict;
http_server_properties_dict.Set("version", 5);
return http_server_properties_dict;
}
raw_ptr<MockPrefDelegate>
pref_delegate_;
std::unique_ptr<HttpServerProperties> http_server_props_;
base::Time one_day_from_now_;
quic::ParsedQuicVersionVector advertised_versions_;
};
TEST_F(HttpServerPropertiesManagerTest, BadCachedHostPortPair) {
base::Value::Dict server_pref_dict;
server_pref_dict.Set("supports_spdy", true);
base::Value::Dict alternative_service_dict;
alternative_service_dict.Set("protocol_str", "h2");
alternative_service_dict.Set("port", 80);
base::Value::List alternative_service_list;
alternative_service_list.Append(std::move(alternative_service_dict));
server_pref_dict.Set("alternative_service",
std::move(alternative_service_list));
base::Value::Dict stats;
stats.Set("srtt", 10);
server_pref_dict.Set("network_stats", std::move(stats));
base::Value::Dict servers_dict;
servers_dict.Set("www.google.com:65536", std::move(server_pref_dict));
base::Value::List servers_list;
servers_list.Append(std::move(servers_dict));
base::Value::Dict http_server_properties_dict = DictWithVersion();
http_server_properties_dict.Set("servers", std::move(servers_list));
base::Value::Dict quic_servers_dict;
base::Value::Dict quic_server_pref_dict1;
quic_server_pref_dict1.Set("server_info", "quic_server_info1");
quic_servers_dict.Set("http://mail.google.com:65536",
std::move(quic_server_pref_dict1));
http_server_properties_dict.Set("quic_servers", std::move(quic_servers_dict));
InitializePrefs(std::move(http_server_properties_dict));
HostPortPair google_host_port_pair =
HostPortPair::FromString("www.google.com:65536");
url::SchemeHostPort gooler_server("http", google_host_port_pair.host(),
google_host_port_pair.port());
EXPECT_FALSE(http_server_props_->SupportsRequestPriority(
gooler_server, NetworkAnonymizationKey()));
EXPECT_FALSE(HasAlternativeService(gooler_server, NetworkAnonymizationKey()));
const ServerNetworkStats* stats1 = http_server_props_->GetServerNetworkStats(
gooler_server, NetworkAnonymizationKey());
EXPECT_EQ(nullptr, stats1);
EXPECT_EQ(0u, http_server_props_->quic_server_info_map().size());
}
TEST_F(HttpServerPropertiesManagerTest, BadCachedAltProtocolPort) {
base::Value::Dict server_pref_dict;
server_pref_dict.Set("supports_spdy", true);
base::Value::Dict alternative_service_dict;
alternative_service_dict.Set("protocol_str", "h2");
alternative_service_dict.Set("port", 65536);
base::Value::List alternative_service_list;
alternative_service_list.Append(std::move(alternative_service_dict));
server_pref_dict.Set("alternative_service",
std::move(alternative_service_list));
base::Value::Dict servers_dict;
servers_dict.Set("www.google.com:80", std::move(server_pref_dict));
base::Value::List servers_list;
servers_list.Append(std::move(servers_dict));
base::Value::Dict http_server_properties_dict = DictWithVersion();
http_server_properties_dict.Set("servers", std::move(servers_list));
InitializePrefs(std::move(http_server_properties_dict));
EXPECT_FALSE(
HasAlternativeService(url::SchemeHostPort("http", "www.google.com", 80),
NetworkAnonymizationKey()));
}
TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) {
InitializePrefs();
url::SchemeHostPort spdy_server("https", "mail.google.com", 443);
EXPECT_FALSE(http_server_props_->SupportsRequestPriority(
spdy_server, NetworkAnonymizationKey()));
http_server_props_->SetSupportsSpdy(spdy_server, NetworkAnonymizationKey(),
true);
http_server_props_->SetSupportsSpdy(spdy_server, NetworkAnonymizationKey(),
true);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
http_server_props_->SetSupportsSpdy(spdy_server, NetworkAnonymizationKey(),
true);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
EXPECT_TRUE(http_server_props_->SupportsRequestPriority(
spdy_server, NetworkAnonymizationKey()));
}
TEST_F(HttpServerPropertiesManagerTest,
SinglePrefUpdateForTwoSpdyServerCacheChanges) {
InitializePrefs();
url::SchemeHostPort spdy_server("https", "mail.google.com", 443);
EXPECT_FALSE(http_server_props_->SupportsRequestPriority(
spdy_server, NetworkAnonymizationKey()));
http_server_props_->SetSupportsSpdy(spdy_server, NetworkAnonymizationKey(),
true);
EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting() -
base::Milliseconds(20));
url::SchemeHostPort spdy_server2("https", "drive.google.com", 443);
http_server_props_->SetSupportsSpdy(spdy_server2, NetworkAnonymizationKey(),
true);
EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
FastForwardBy(base::Milliseconds(20));
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
EXPECT_TRUE(http_server_props_->SupportsRequestPriority(
spdy_server, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->SupportsRequestPriority(
spdy_server2, NetworkAnonymizationKey()));
url::SchemeHostPort spdy_server3("https", "maps.google.com", 443);
http_server_props_->SetSupportsSpdy(spdy_server3, NetworkAnonymizationKey(),
true);
EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
}
TEST_F(HttpServerPropertiesManagerTest, GetAlternativeServiceInfos) {
InitializePrefs();
url::SchemeHostPort spdy_server_mail("http", "mail.google.com", 80);
EXPECT_FALSE(
HasAlternativeService(spdy_server_mail, NetworkAnonymizationKey()));
const AlternativeService alternative_service(kProtoHTTP2, "mail.google.com",
443);
http_server_props_->SetHttp2AlternativeService(
spdy_server_mail, NetworkAnonymizationKey(), alternative_service,
one_day_from_now_);
http_server_props_->SetHttp2AlternativeService(
spdy_server_mail, NetworkAnonymizationKey(), alternative_service,
one_day_from_now_);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
AlternativeServiceInfoVector alternative_service_info_vector =
http_server_props_->GetAlternativeServiceInfos(spdy_server_mail,
NetworkAnonymizationKey());
ASSERT_EQ(1u, alternative_service_info_vector.size());
EXPECT_EQ(alternative_service,
alternative_service_info_vector[0].alternative_service());
}
TEST_F(HttpServerPropertiesManagerTest, SetAlternativeServices) {
InitializePrefs();
url::SchemeHostPort spdy_server_mail("http", "mail.google.com", 80);
EXPECT_FALSE(
HasAlternativeService(spdy_server_mail, NetworkAnonymizationKey()));
AlternativeServiceInfoVector alternative_service_info_vector;
const AlternativeService alternative_service1(kProtoHTTP2, "mail.google.com",
443);
alternative_service_info_vector.push_back(
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
alternative_service1, one_day_from_now_));
const AlternativeService alternative_service2(kProtoQUIC, "mail.google.com",
1234);
alternative_service_info_vector.push_back(
AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
alternative_service2, one_day_from_now_, advertised_versions_));
http_server_props_->SetAlternativeServices(spdy_server_mail,
NetworkAnonymizationKey(),
alternative_service_info_vector);
http_server_props_->SetAlternativeServices(spdy_server_mail,
NetworkAnonymizationKey(),
alternative_service_info_vector);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
AlternativeServiceInfoVector alternative_service_info_vector2 =
http_server_props_->GetAlternativeServiceInfos(spdy_server_mail,
NetworkAnonymizationKey());
ASSERT_EQ(2u, alternative_service_info_vector2.size());
EXPECT_EQ(alternative_service1,
alternative_service_info_vector2[0].alternative_service());
EXPECT_EQ(alternative_service2,
alternative_service_info_vector2[1].alternative_service());
}
TEST_F(HttpServerPropertiesManagerTest, SetAlternativeServicesEmpty) {
InitializePrefs();
url::SchemeHostPort spdy_server_mail("http", "mail.google.com", 80);
EXPECT_FALSE(
HasAlternativeService(spdy_server_mail, NetworkAnonymizationKey()));
const AlternativeService alternative_service(kProtoHTTP2, "mail.google.com",
443);
http_server_props_->SetAlternativeServices(spdy_server_mail,
NetworkAnonymizationKey(),
AlternativeServiceInfoVector());
EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_FALSE(
HasAlternativeService(spdy_server_mail, NetworkAnonymizationKey()));
}
TEST_F(HttpServerPropertiesManagerTest, ConfirmAlternativeService) {
InitializePrefs();
url::SchemeHostPort spdy_server_mail;
AlternativeService alternative_service;
spdy_server_mail = url::SchemeHostPort("http", "mail.google.com", 80);
EXPECT_FALSE(
HasAlternativeService(spdy_server_mail, NetworkAnonymizationKey()));
alternative_service = AlternativeService(kProtoHTTP2, "mail.google.com", 443);
http_server_props_->SetHttp2AlternativeService(
spdy_server_mail, NetworkAnonymizationKey(), alternative_service,
one_day_from_now_);
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
http_server_props_->MarkAlternativeServiceBroken(alternative_service,
NetworkAnonymizationKey());
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
http_server_props_->ConfirmAlternativeService(alternative_service,
NetworkAnonymizationKey());
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
}
TEST_F(HttpServerPropertiesManagerTest, LateLoadAlternativeServiceInfo) {
url::SchemeHostPort spdy_server_mail("http", "mail.google.com", 80);
EXPECT_FALSE(
HasAlternativeService(spdy_server_mail, NetworkAnonymizationKey()));
const AlternativeService alternative_service(kProtoHTTP2, "mail.google.com",
443);
http_server_props_->SetHttp2AlternativeService(
spdy_server_mail, NetworkAnonymizationKey(), alternative_service,
one_day_from_now_);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
AlternativeServiceInfoVector alternative_service_info_vector =
http_server_props_->GetAlternativeServiceInfos(spdy_server_mail,
NetworkAnonymizationKey());
ASSERT_EQ(1u, alternative_service_info_vector.size());
EXPECT_EQ(alternative_service,
alternative_service_info_vector[0].alternative_service());
InitializePrefs(base::Value::Dict(),
true);
alternative_service_info_vector =
http_server_props_->GetAlternativeServiceInfos(spdy_server_mail,
NetworkAnonymizationKey());
EXPECT_EQ(1u, alternative_service_info_vector.size());
http_server_props_->SetHttp2AlternativeService(
spdy_server_mail, NetworkAnonymizationKey(), alternative_service,
one_day_from_now_ + base::Days(2));
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
alternative_service_info_vector =
http_server_props_->GetAlternativeServiceInfos(spdy_server_mail,
NetworkAnonymizationKey());
EXPECT_EQ(1u, alternative_service_info_vector.size());
}
TEST_F(HttpServerPropertiesManagerTest,
ClearPrefsBeforeLoadAlternativeServiceInfo) {
url::SchemeHostPort spdy_server_mail("http", "mail.google.com", 80);
EXPECT_FALSE(
HasAlternativeService(spdy_server_mail, NetworkAnonymizationKey()));
const AlternativeService alternative_service(kProtoHTTP2, "mail.google.com",
443);
http_server_props_->SetHttp2AlternativeService(
spdy_server_mail, NetworkAnonymizationKey(), alternative_service,
one_day_from_now_);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
AlternativeServiceInfoVector alternative_service_info_vector =
http_server_props_->GetAlternativeServiceInfos(spdy_server_mail,
NetworkAnonymizationKey());
ASSERT_EQ(1u, alternative_service_info_vector.size());
EXPECT_EQ(alternative_service,
alternative_service_info_vector[0].alternative_service());
bool callback_invoked_ = false;
http_server_props_->Clear(base::BindOnce(
[](bool* callback_invoked) {
EXPECT_FALSE(*callback_invoked);
*callback_invoked = true;
},
&callback_invoked_));
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_FALSE(callback_invoked_);
std::move(pref_delegate_->GetSetPropertiesCallback()).Run();
EXPECT_TRUE(callback_invoked_);
alternative_service_info_vector =
http_server_props_->GetAlternativeServiceInfos(spdy_server_mail,
NetworkAnonymizationKey());
EXPECT_EQ(0u, alternative_service_info_vector.size());
http_server_props_->SetHttp2AlternativeService(
spdy_server_mail, NetworkAnonymizationKey(), alternative_service,
one_day_from_now_);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
alternative_service_info_vector =
http_server_props_->GetAlternativeServiceInfos(spdy_server_mail,
NetworkAnonymizationKey());
EXPECT_EQ(1u, alternative_service_info_vector.size());
}
TEST_F(HttpServerPropertiesManagerTest,
ConfirmBrokenUntilDefaultNetworkChanges) {
InitializePrefs();
url::SchemeHostPort spdy_server_mail;
AlternativeService alternative_service;
spdy_server_mail = url::SchemeHostPort("http", "mail.google.com", 80);
EXPECT_FALSE(
HasAlternativeService(spdy_server_mail, NetworkAnonymizationKey()));
alternative_service = AlternativeService(kProtoHTTP2, "mail.google.com", 443);
http_server_props_->SetHttp2AlternativeService(
spdy_server_mail, NetworkAnonymizationKey(), alternative_service,
one_day_from_now_);
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
http_server_props_->MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
alternative_service, NetworkAnonymizationKey());
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
http_server_props_->ConfirmAlternativeService(alternative_service,
NetworkAnonymizationKey());
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
}
TEST_F(HttpServerPropertiesManagerTest,
OnDefaultNetworkChangedWithBrokenUntilDefaultNetworkChanges) {
InitializePrefs();
url::SchemeHostPort spdy_server_mail;
AlternativeService alternative_service;
spdy_server_mail = url::SchemeHostPort("http", "mail.google.com", 80);
EXPECT_FALSE(
HasAlternativeService(spdy_server_mail, NetworkAnonymizationKey()));
alternative_service = AlternativeService(kProtoHTTP2, "mail.google.com", 443);
http_server_props_->SetHttp2AlternativeService(
spdy_server_mail, NetworkAnonymizationKey(), alternative_service,
one_day_from_now_);
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
http_server_props_->MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
alternative_service, NetworkAnonymizationKey());
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
http_server_props_->OnDefaultNetworkChanged();
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
}
TEST_F(HttpServerPropertiesManagerTest, OnDefaultNetworkChangedWithBrokenOnly) {
InitializePrefs();
url::SchemeHostPort spdy_server_mail;
AlternativeService alternative_service;
spdy_server_mail = url::SchemeHostPort("http", "mail.google.com", 80);
EXPECT_FALSE(
HasAlternativeService(spdy_server_mail, NetworkAnonymizationKey()));
alternative_service = AlternativeService(kProtoHTTP2, "mail.google.com", 443);
http_server_props_->SetHttp2AlternativeService(
spdy_server_mail, NetworkAnonymizationKey(), alternative_service,
one_day_from_now_);
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
http_server_props_->MarkAlternativeServiceBroken(alternative_service,
NetworkAnonymizationKey());
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
http_server_props_->OnDefaultNetworkChanged();
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
alternative_service, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
alternative_service, NetworkAnonymizationKey()));
}
TEST_F(HttpServerPropertiesManagerTest, LastLocalAddressWhenQuicWorked) {
InitializePrefs();
IPAddress actual_address(127, 0, 0, 1);
EXPECT_FALSE(http_server_props_->HasLastLocalAddressWhenQuicWorked());
EXPECT_FALSE(
http_server_props_->WasLastLocalAddressWhenQuicWorked(actual_address));
http_server_props_->SetLastLocalAddressWhenQuicWorked(actual_address);
http_server_props_->SetLastLocalAddressWhenQuicWorked(actual_address);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_TRUE(
http_server_props_->WasLastLocalAddressWhenQuicWorked(actual_address));
http_server_props_->SetLastLocalAddressWhenQuicWorked(actual_address);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
}
TEST_F(HttpServerPropertiesManagerTest, ServerNetworkStats) {
InitializePrefs();
url::SchemeHostPort mail_server("http", "mail.google.com", 80);
const ServerNetworkStats* stats = http_server_props_->GetServerNetworkStats(
mail_server, NetworkAnonymizationKey());
EXPECT_EQ(nullptr, stats);
ServerNetworkStats stats1;
stats1.srtt = base::Microseconds(10);
http_server_props_->SetServerNetworkStats(mail_server,
NetworkAnonymizationKey(), stats1);
http_server_props_->SetServerNetworkStats(mail_server,
NetworkAnonymizationKey(), stats1);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
http_server_props_->SetServerNetworkStats(mail_server,
NetworkAnonymizationKey(), stats1);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_EQ(GetPendingMainThreadTaskCount(), 0u);
const ServerNetworkStats* stats2 = http_server_props_->GetServerNetworkStats(
mail_server, NetworkAnonymizationKey());
EXPECT_EQ(10, stats2->srtt.ToInternalValue());
http_server_props_->ClearServerNetworkStats(mail_server,
NetworkAnonymizationKey());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_EQ(nullptr, http_server_props_->GetServerNetworkStats(
mail_server, NetworkAnonymizationKey()));
}
TEST_F(HttpServerPropertiesManagerTest, QuicServerInfo) {
InitializePrefs();
quic::QuicServerId mail_quic_server_id("mail.google.com", 80, false);
EXPECT_EQ(nullptr, http_server_props_->GetQuicServerInfo(
mail_quic_server_id, NetworkAnonymizationKey()));
std::string quic_server_info1("quic_server_info1");
http_server_props_->SetQuicServerInfo(
mail_quic_server_id, NetworkAnonymizationKey(), quic_server_info1);
http_server_props_->SetQuicServerInfo(
mail_quic_server_id, NetworkAnonymizationKey(), quic_server_info1);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_EQ(quic_server_info1,
*http_server_props_->GetQuicServerInfo(mail_quic_server_id,
NetworkAnonymizationKey()));
http_server_props_->SetQuicServerInfo(
mail_quic_server_id, NetworkAnonymizationKey(), quic_server_info1);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
}
TEST_F(HttpServerPropertiesManagerTest, Clear) {
InitializePrefs();
const url::SchemeHostPort spdy_server("https", "mail.google.com", 443);
const IPAddress actual_address(127, 0, 0, 1);
const quic::QuicServerId mail_quic_server_id("mail.google.com", 80, false);
const std::string quic_server_info1("quic_server_info1");
const AlternativeService alternative_service(kProtoHTTP2, "mail.google.com",
1234);
const AlternativeService broken_alternative_service(
kProtoHTTP2, "broken.google.com", 1234);
AlternativeServiceInfoVector alt_svc_info_vector;
alt_svc_info_vector.push_back(
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
alternative_service, one_day_from_now_));
alt_svc_info_vector.push_back(
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
broken_alternative_service, one_day_from_now_));
http_server_props_->SetAlternativeServices(
spdy_server, NetworkAnonymizationKey(), alt_svc_info_vector);
http_server_props_->MarkAlternativeServiceBroken(broken_alternative_service,
NetworkAnonymizationKey());
http_server_props_->SetSupportsSpdy(spdy_server, NetworkAnonymizationKey(),
true);
http_server_props_->SetLastLocalAddressWhenQuicWorked(actual_address);
ServerNetworkStats stats;
stats.srtt = base::Microseconds(10);
http_server_props_->SetServerNetworkStats(spdy_server,
NetworkAnonymizationKey(), stats);
http_server_props_->SetQuicServerInfo(
mail_quic_server_id, NetworkAnonymizationKey(), quic_server_info1);
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
broken_alternative_service, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->SupportsRequestPriority(
spdy_server, NetworkAnonymizationKey()));
EXPECT_TRUE(HasAlternativeService(spdy_server, NetworkAnonymizationKey()));
EXPECT_TRUE(
http_server_props_->WasLastLocalAddressWhenQuicWorked(actual_address));
const ServerNetworkStats* stats1 = http_server_props_->GetServerNetworkStats(
spdy_server, NetworkAnonymizationKey());
EXPECT_EQ(10, stats1->srtt.ToInternalValue());
EXPECT_EQ(quic_server_info1,
*http_server_props_->GetQuicServerInfo(mail_quic_server_id,
NetworkAnonymizationKey()));
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
bool callback_invoked_ = false;
http_server_props_->Clear(base::BindOnce(
[](bool* callback_invoked) {
EXPECT_FALSE(*callback_invoked);
*callback_invoked = true;
},
&callback_invoked_));
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_FALSE(callback_invoked_);
std::move(pref_delegate_->GetSetPropertiesCallback()).Run();
EXPECT_TRUE(callback_invoked_);
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
broken_alternative_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->SupportsRequestPriority(
spdy_server, NetworkAnonymizationKey()));
EXPECT_FALSE(HasAlternativeService(spdy_server, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->HasLastLocalAddressWhenQuicWorked());
const ServerNetworkStats* stats2 = http_server_props_->GetServerNetworkStats(
spdy_server, NetworkAnonymizationKey());
EXPECT_EQ(nullptr, stats2);
EXPECT_EQ(nullptr, http_server_props_->GetQuicServerInfo(
mail_quic_server_id, NetworkAnonymizationKey()));
}
TEST_F(HttpServerPropertiesManagerTest, BadLastLocalAddressWhenQuicWorked) {
base::Value::List servers_list;
for (int i = 1; i <= 200; ++i) {
base::Value::Dict server_dict;
base::Value::Dict alternative_service_dict;
alternative_service_dict.Set("protocol_str", "quic");
alternative_service_dict.Set("port", i);
base::Value::List alternative_service_list;
alternative_service_list.Append(std::move(alternative_service_dict));
server_dict.Set("alternative_service", std::move(alternative_service_list));
server_dict.Set("server", StringPrintf("https://www.google.com:%d", i));
server_dict.Set("anonymization", base::Value(base::Value::Type::LIST));
servers_list.Append(std::move(server_dict));
}
base::Value::Dict server_dict2;
server_dict2.Set("server", "https://mail.google.com");
server_dict2.Set("anonymization", base::Value(base::Value::Type::LIST));
servers_list.Append(std::move(server_dict2));
base::Value::Dict http_server_properties_dict = DictWithVersion();
http_server_properties_dict.Set("servers", std::move(servers_list));
base::Value::Dict supports_quic;
supports_quic.Set("used_quic", true);
supports_quic.Set("address", "127.0.0.1");
http_server_properties_dict.Set("supports_quic", std::move(supports_quic));
InitializePrefs(std::move(http_server_properties_dict));
for (int i = 1; i <= 200; ++i) {
GURL server_gurl;
server_gurl = GURL(StringPrintf("https://www.google.com:%d", i));
url::SchemeHostPort server(server_gurl);
AlternativeServiceInfoVector alternative_service_info_vector =
http_server_props_->GetAlternativeServiceInfos(
server, NetworkAnonymizationKey());
ASSERT_EQ(1u, alternative_service_info_vector.size());
EXPECT_EQ(
kProtoQUIC,
alternative_service_info_vector[0].alternative_service().protocol);
EXPECT_EQ(i, alternative_service_info_vector[0].alternative_service().port);
}
ASSERT_TRUE(http_server_props_->WasLastLocalAddressWhenQuicWorked(
IPAddress::IPv4Localhost()));
}
TEST_F(HttpServerPropertiesManagerTest, UpdatePrefsWithCache) {
InitializePrefs();
const url::SchemeHostPort server_www("https", "www.google.com", 80);
const url::SchemeHostPort server_mail("https", "mail.google.com", 80);
AlternativeServiceInfoVector alternative_service_info_vector;
AlternativeService www_alternative_service1(kProtoHTTP2, "", 443);
base::Time expiration1;
ASSERT_TRUE(base::Time::FromUTCString("2036-12-01 10:00:00", &expiration1));
alternative_service_info_vector.push_back(
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
www_alternative_service1, expiration1));
AlternativeService www_alternative_service2(kProtoHTTP2, "www.google.com",
1234);
base::Time expiration2;
ASSERT_TRUE(base::Time::FromUTCString("2036-12-31 10:00:00", &expiration2));
alternative_service_info_vector.push_back(
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
www_alternative_service2, expiration2));
http_server_props_->SetAlternativeServices(
server_www, NetworkAnonymizationKey(), alternative_service_info_vector);
AlternativeService mail_alternative_service(kProtoHTTP2, "foo.google.com",
444);
base::Time expiration3 = base::Time::Max();
http_server_props_->SetHttp2AlternativeService(
server_mail, NetworkAnonymizationKey(), mail_alternative_service,
expiration3);
http_server_props_->MarkAlternativeServiceBroken(www_alternative_service2,
NetworkAnonymizationKey());
http_server_props_->MarkAlternativeServiceRecentlyBroken(
mail_alternative_service, NetworkAnonymizationKey());
http_server_props_->SetSupportsSpdy(server_www, NetworkAnonymizationKey(),
false);
http_server_props_->SetSupportsSpdy(server_mail, NetworkAnonymizationKey(),
true);
http_server_props_->SetSupportsSpdy(
url::SchemeHostPort("http", "not_persisted.com", 80),
NetworkAnonymizationKey(), false);
ServerNetworkStats stats;
stats.srtt = base::TimeDelta::FromInternalValue(42);
http_server_props_->SetServerNetworkStats(server_mail,
NetworkAnonymizationKey(), stats);
quic::QuicServerId mail_quic_server_id("mail.google.com", 80, false);
std::string quic_server_info1("quic_server_info1");
http_server_props_->SetQuicServerInfo(
mail_quic_server_id, NetworkAnonymizationKey(), quic_server_info1);
IPAddress actual_address(127, 0, 0, 1);
http_server_props_->SetLastLocalAddressWhenQuicWorked(actual_address);
base::Time time_before_prefs_update = base::Time::Now();
EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
base::Time time_after_prefs_update = base::Time::Now();
base::Value::Dict server_dict = pref_delegate_->GetServerProperties().Clone();
base::Value::List* broken_alt_svc_list =
server_dict.FindList("broken_alternative_services");
ASSERT_TRUE(broken_alt_svc_list);
ASSERT_EQ(2u, broken_alt_svc_list->size());
base::Value& broken_alt_svcs_list_entry = (*broken_alt_svc_list)[0];
const std::string* broken_until_str =
broken_alt_svcs_list_entry.GetDict().FindString("broken_until");
ASSERT_TRUE(broken_until_str);
const std::string expiration_string = *broken_until_str;
broken_alt_svcs_list_entry.GetDict().Remove("broken_until");
int64_t expiration_int64;
ASSERT_TRUE(base::StringToInt64(expiration_string, &expiration_int64));
base::TimeDelta expiration_delta =
base::Minutes(5) - HttpServerProperties::GetUpdatePrefsDelayForTesting();
time_t time_t_of_prefs_update = static_cast<time_t>(expiration_int64);
EXPECT_LE((time_before_prefs_update + expiration_delta).ToTimeT(),
time_t_of_prefs_update);
EXPECT_GE((time_after_prefs_update + expiration_delta).ToTimeT(),
time_t_of_prefs_update);
const char expected_json[] =
"{"
"\"broken_alternative_services\":"
"[{\"anonymization\":[],\"broken_count\":1,\"host\":\"www.google.com\","
"\"port\":1234,\"protocol_str\":\"h2\"},"
"{\"anonymization\":[],\"broken_count\":1,\"host\":\"foo.google.com\","
"\"port\":444,\"protocol_str\":\"h2\"}],"
"\"quic_servers\":"
"[{\"anonymization\":[],"
"\"server_id\":\"https://mail.google.com:80\","
"\"server_info\":\"quic_server_info1\"}],"
"\"servers\":["
"{\"alternative_service\":[{\"advertised_alpns\":[],"
"\"expiration\":\"13756212000000000\",\"port\":443,"
"\"protocol_str\":\"h2\"},"
"{\"advertised_alpns\":[],\"expiration\":\"13758804000000000\","
"\"host\":\"www.google.com\",\"port\":1234,\"protocol_str\":\"h2\"}],"
"\"anonymization\":[],"
"\"server\":\"https://www.google.com:80\"},"
"{\"alternative_service\":[{\"advertised_alpns\":[],"
"\"expiration\":\"9223372036854775807\",\"host\":\"foo.google.com\","
"\"port\":444,\"protocol_str\":\"h2\"}],"
"\"anonymization\":[],"
"\"network_stats\":{\"srtt\":42},"
"\"server\":\"https://mail.google.com:80\","
"\"supports_spdy\":true}],"
"\"supports_quic\":{\"address\":\"127.0.0.1\",\"used_quic\":true},"
"\"version\":5}";
std::string preferences_json;
EXPECT_TRUE(base::JSONWriter::Write(server_dict, &preferences_json));
EXPECT_EQ(expected_json, preferences_json);
}
TEST_F(HttpServerPropertiesManagerTest, ParseAlternativeServiceInfo) {
InitializePrefs();
base::Value::Dict server_dict = base::test::ParseJsonDict(
"{\"alternative_service\":[{\"port\":443,\"protocol_str\":\"h2\"},"
"{\"port\":123,\"protocol_str\":\"quic\","
"\"expiration\":\"9223372036854775807\"},{\"host\":\"example.org\","
"\"port\":1234,\"protocol_str\":\"h2\","
"\"expiration\":\"13758804000000000\"}]}");
const url::SchemeHostPort server("https", "example.com", 443);
HttpServerProperties::ServerInfo server_info;
EXPECT_TRUE(HttpServerPropertiesManager::ParseAlternativeServiceInfo(
server, server_dict, &server_info));
ASSERT_TRUE(server_info.alternative_services.has_value());
AlternativeServiceInfoVector alternative_service_info_vector =
server_info.alternative_services.value();
ASSERT_EQ(3u, alternative_service_info_vector.size());
EXPECT_EQ(kProtoHTTP2,
alternative_service_info_vector[0].alternative_service().protocol);
EXPECT_EQ("", alternative_service_info_vector[0].alternative_service().host);
EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port);
const base::Time now = base::Time::Now();
const base::Time expiration = alternative_service_info_vector[0].expiration();
EXPECT_LE(now + base::Hours(23), expiration);
EXPECT_GE(now + base::Days(1), expiration);
EXPECT_EQ(kProtoQUIC,
alternative_service_info_vector[1].alternative_service().protocol);
EXPECT_EQ("", alternative_service_info_vector[1].alternative_service().host);
EXPECT_EQ(123, alternative_service_info_vector[1].alternative_service().port);
EXPECT_EQ(base::Time::Max(), alternative_service_info_vector[1].expiration());
EXPECT_EQ(kProtoHTTP2,
alternative_service_info_vector[2].alternative_service().protocol);
EXPECT_EQ("example.org",
alternative_service_info_vector[2].alternative_service().host);
EXPECT_EQ(1234,
alternative_service_info_vector[2].alternative_service().port);
base::Time expected_expiration;
ASSERT_TRUE(
base::Time::FromUTCString("2036-12-31 10:00:00", &expected_expiration));
EXPECT_EQ(expected_expiration,
alternative_service_info_vector[2].expiration());
server_info.alternative_services.reset();
EXPECT_TRUE(server_info.empty());
}
TEST_F(HttpServerPropertiesManagerTest, DoNotLoadAltSvcForInsecureOrigins) {
InitializePrefs();
base::Value::Dict server_dict = base::test::ParseJsonDict(
"{\"alternative_service\":[{\"port\":443,\"protocol_str\":\"h2\","
"\"expiration\":\"9223372036854775807\"}]}");
const url::SchemeHostPort server("http", "example.com", 80);
HttpServerProperties::ServerInfo server_info;
EXPECT_FALSE(HttpServerPropertiesManager::ParseAlternativeServiceInfo(
server, server_dict, &server_info));
EXPECT_TRUE(server_info.empty());
}
TEST_F(HttpServerPropertiesManagerTest, DoNotPersistExpiredAlternativeService) {
InitializePrefs();
AlternativeServiceInfoVector alternative_service_info_vector;
const AlternativeService broken_alternative_service(
kProtoHTTP2, "broken.example.com", 443);
const base::Time time_one_day_later = base::Time::Now() + base::Days(1);
alternative_service_info_vector.push_back(
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
broken_alternative_service, time_one_day_later));
http_server_props_->MarkAlternativeServiceBroken(broken_alternative_service,
NetworkAnonymizationKey());
const AlternativeService expired_alternative_service(
kProtoHTTP2, "expired.example.com", 443);
const base::Time time_one_day_ago = base::Time::Now() - base::Days(1);
alternative_service_info_vector.push_back(
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
expired_alternative_service, time_one_day_ago));
const AlternativeService valid_alternative_service(kProtoHTTP2,
"valid.example.com", 443);
alternative_service_info_vector.push_back(
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
valid_alternative_service, time_one_day_later));
const url::SchemeHostPort server("https", "www.example.com", 443);
http_server_props_->SetAlternativeServices(server, NetworkAnonymizationKey(),
alternative_service_info_vector);
EXPECT_EQ(2U, GetPendingMainThreadTaskCount());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
EXPECT_EQ(1U, GetPendingMainThreadTaskCount());
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
const base::Value::Dict& pref_dict = pref_delegate_->GetServerProperties();
const base::Value::List* servers_list = pref_dict.FindList("servers");
ASSERT_TRUE(servers_list);
auto it = servers_list->begin();
const base::Value& server_pref_dict = *it;
ASSERT_TRUE(server_pref_dict.is_dict());
const std::string* server_str =
server_pref_dict.GetDict().FindString("server");
ASSERT_TRUE(server_str);
EXPECT_EQ("https://www.example.com", *server_str);
const base::Value* network_anonymization_key_value =
server_pref_dict.GetDict().Find("anonymization");
ASSERT_TRUE(network_anonymization_key_value);
ASSERT_EQ(base::Value::Type::LIST, network_anonymization_key_value->type());
EXPECT_TRUE(network_anonymization_key_value->GetList().empty());
const base::Value::List* altsvc_list =
server_pref_dict.GetDict().FindList("alternative_service");
ASSERT_TRUE(altsvc_list);
ASSERT_EQ(2u, altsvc_list->size());
const base::Value& altsvc_entry = (*altsvc_list)[0];
ASSERT_TRUE(altsvc_entry.is_dict());
const std::string* hostname = altsvc_entry.GetDict().FindString("host");
ASSERT_TRUE(hostname);
EXPECT_EQ("broken.example.com", *hostname);
const base::Value& altsvc_entry2 = (*altsvc_list)[1];
ASSERT_TRUE(altsvc_entry.is_dict());
hostname = altsvc_entry2.GetDict().FindString("host");
ASSERT_TRUE(hostname);
EXPECT_EQ("valid.example.com", *hostname);
}
TEST_F(HttpServerPropertiesManagerTest, DoNotLoadExpiredAlternativeService) {
InitializePrefs();
base::Value::List alternative_service_list;
base::Value::Dict expired_dict;
expired_dict.Set("protocol_str", "h2");
expired_dict.Set("host", "expired.example.com");
expired_dict.Set("port", 443);
base::Time time_one_day_ago = base::Time::Now() - base::Days(1);
expired_dict.Set("expiration",
base::NumberToString(time_one_day_ago.ToInternalValue()));
alternative_service_list.Append(std::move(expired_dict));
base::Value::Dict valid_dict;
valid_dict.Set("protocol_str", "h2");
valid_dict.Set("host", "valid.example.com");
valid_dict.Set("port", 443);
valid_dict.Set("expiration",
base::NumberToString(one_day_from_now_.ToInternalValue()));
alternative_service_list.Append(std::move(valid_dict));
base::Value::Dict server_pref_dict;
server_pref_dict.Set("alternative_service",
std::move(alternative_service_list));
const url::SchemeHostPort server("https", "example.com", 443);
HttpServerProperties::ServerInfo server_info;
ASSERT_TRUE(HttpServerPropertiesManager::ParseAlternativeServiceInfo(
server, server_pref_dict, &server_info));
ASSERT_TRUE(server_info.alternative_services.has_value());
AlternativeServiceInfoVector alternative_service_info_vector =
server_info.alternative_services.value();
ASSERT_EQ(1u, alternative_service_info_vector.size());
EXPECT_EQ(kProtoHTTP2,
alternative_service_info_vector[0].alternative_service().protocol);
EXPECT_EQ("valid.example.com",
alternative_service_info_vector[0].alternative_service().host);
EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port);
EXPECT_EQ(one_day_from_now_, alternative_service_info_vector[0].expiration());
server_info.alternative_services.reset();
EXPECT_TRUE(server_info.empty());
}
TEST_F(HttpServerPropertiesManagerTest, UpdatePrefsOnShutdown) {
InitializePrefs();
int pref_updates = 0;
pref_delegate_->set_extra_update_prefs_callback(
base::BindRepeating([](int* updates) { (*updates)++; }, &pref_updates));
http_server_props_.reset();
EXPECT_EQ(1, pref_updates);
}
TEST_F(HttpServerPropertiesManagerTest, PersistAdvertisedVersionsToPref) {
InitializePrefs();
const url::SchemeHostPort server_www("https", "www.google.com", 80);
const url::SchemeHostPort server_mail("https", "mail.google.com", 80);
AlternativeServiceInfoVector alternative_service_info_vector;
AlternativeService quic_alternative_service1(kProtoQUIC, "", 443);
base::Time expiration1;
ASSERT_TRUE(base::Time::FromUTCString("2036-12-01 10:00:00", &expiration1));
quic::ParsedQuicVersionVector advertised_versions = {
quic::ParsedQuicVersion::Q046(), quic::ParsedQuicVersion::Q043()};
alternative_service_info_vector.push_back(
AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
quic_alternative_service1, expiration1, advertised_versions));
AlternativeService h2_alternative_service(kProtoHTTP2, "www.google.com",
1234);
base::Time expiration2;
ASSERT_TRUE(base::Time::FromUTCString("2036-12-31 10:00:00", &expiration2));
alternative_service_info_vector.push_back(
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
h2_alternative_service, expiration2));
http_server_props_->SetAlternativeServices(
server_www, NetworkAnonymizationKey(), alternative_service_info_vector);
AlternativeService mail_alternative_service(kProtoQUIC, "foo.google.com",
444);
base::Time expiration3 = base::Time::Max();
http_server_props_->SetQuicAlternativeService(
server_mail, NetworkAnonymizationKey(), mail_alternative_service,
expiration3, advertised_versions_);
ServerNetworkStats stats;
stats.srtt = base::TimeDelta::FromInternalValue(42);
http_server_props_->SetServerNetworkStats(server_mail,
NetworkAnonymizationKey(), stats);
quic::QuicServerId mail_quic_server_id("mail.google.com", 80, false);
std::string quic_server_info1("quic_server_info1");
http_server_props_->SetQuicServerInfo(
mail_quic_server_id, NetworkAnonymizationKey(), quic_server_info1);
IPAddress actual_address(127, 0, 0, 1);
http_server_props_->SetLastLocalAddressWhenQuicWorked(actual_address);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
const char expected_json[] =
"{\"quic_servers\":["
"{\"anonymization\":[],"
"\"server_id\":\"https://mail.google.com:80\","
"\"server_info\":\"quic_server_info1\"}],"
"\"servers\":["
"{\"alternative_service\":[{"
"\"advertised_alpns\":[\"h3-Q046\",\"h3-Q043\"],\"expiration\":"
"\"13756212000000000\","
"\"port\":443,\"protocol_str\":\"quic\"},{\"advertised_alpns\":[],"
"\"expiration\":\"13758804000000000\",\"host\":\"www.google.com\","
"\"port\":1234,\"protocol_str\":\"h2\"}],"
"\"anonymization\":[],"
"\"server\":\"https://www.google.com:80\"},"
"{\"alternative_service\":[{"
"\"advertised_alpns\":[\"h3\"],"
"\"expiration\":\"9223372036854775807\","
"\"host\":\"foo.google.com\",\"port\":444,\"protocol_str\":\"quic\"}],"
"\"anonymization\":[],"
"\"network_stats\":{\"srtt\":42},"
"\"server\":\"https://mail.google.com:80\"}],"
"\"supports_quic\":{"
"\"address\":\"127.0.0.1\",\"used_quic\":true},\"version\":5}";
const base::Value::Dict& http_server_properties =
pref_delegate_->GetServerProperties();
std::string preferences_json;
EXPECT_TRUE(
base::JSONWriter::Write(http_server_properties, &preferences_json));
EXPECT_EQ(expected_json, preferences_json);
}
TEST_F(HttpServerPropertiesManagerTest, ReadAdvertisedVersionsFromPref) {
InitializePrefs();
base::Value::Dict server_dict = base::test::ParseJsonDict(
"{\"alternative_service\":["
"{\"port\":443,\"protocol_str\":\"quic\"},"
"{\"port\":123,\"protocol_str\":\"quic\","
"\"expiration\":\"9223372036854775807\","
"\"advertised_alpns\":[\"h3-Q033\",\"h3-Q046\",\"h3-Q043\"]}]}");
const url::SchemeHostPort server("https", "example.com", 443);
HttpServerProperties::ServerInfo server_info;
EXPECT_TRUE(HttpServerPropertiesManager::ParseAlternativeServiceInfo(
server, server_dict, &server_info));
ASSERT_TRUE(server_info.alternative_services.has_value());
AlternativeServiceInfoVector alternative_service_info_vector =
server_info.alternative_services.value();
ASSERT_EQ(2u, alternative_service_info_vector.size());
EXPECT_EQ(kProtoQUIC,
alternative_service_info_vector[0].alternative_service().protocol);
EXPECT_EQ("", alternative_service_info_vector[0].alternative_service().host);
EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port);
const base::Time now = base::Time::Now();
const base::Time expiration = alternative_service_info_vector[0].expiration();
EXPECT_LE(now + base::Hours(23), expiration);
EXPECT_GE(now + base::Days(1), expiration);
EXPECT_TRUE(alternative_service_info_vector[0].advertised_versions().empty());
EXPECT_EQ(kProtoQUIC,
alternative_service_info_vector[1].alternative_service().protocol);
EXPECT_EQ("", alternative_service_info_vector[1].alternative_service().host);
EXPECT_EQ(123, alternative_service_info_vector[1].alternative_service().port);
EXPECT_EQ(base::Time::Max(), alternative_service_info_vector[1].expiration());
const quic::ParsedQuicVersionVector loaded_advertised_versions =
alternative_service_info_vector[1].advertised_versions();
ASSERT_EQ(2u, loaded_advertised_versions.size());
EXPECT_EQ(quic::ParsedQuicVersion::Q043(), loaded_advertised_versions[0]);
EXPECT_EQ(quic::ParsedQuicVersion::Q046(), loaded_advertised_versions[1]);
server_info.alternative_services.reset();
EXPECT_TRUE(server_info.empty());
}
TEST_F(HttpServerPropertiesManagerTest,
UpdatePrefWhenAdvertisedVersionsChange) {
InitializePrefs();
const url::SchemeHostPort server_www("https", "www.google.com", 80);
AlternativeServiceInfoVector alternative_service_info_vector;
AlternativeService quic_alternative_service1(kProtoQUIC, "", 443);
base::Time expiration1;
ASSERT_TRUE(base::Time::FromUTCString("2036-12-01 10:00:00", &expiration1));
alternative_service_info_vector.push_back(
AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
quic_alternative_service1, expiration1, advertised_versions_));
http_server_props_->SetAlternativeServices(
server_www, NetworkAnonymizationKey(), alternative_service_info_vector);
quic::QuicServerId mail_quic_server_id("mail.google.com", 80, false);
std::string quic_server_info1("quic_server_info1");
http_server_props_->SetQuicServerInfo(
mail_quic_server_id, NetworkAnonymizationKey(), quic_server_info1);
IPAddress actual_address(127, 0, 0, 1);
http_server_props_->SetLastLocalAddressWhenQuicWorked(actual_address);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
const char expected_json[] =
"{\"quic_servers\":"
"[{\"anonymization\":[],"
"\"server_id\":\"https://mail.google.com:80\","
"\"server_info\":\"quic_server_info1\"}],"
"\"servers\":["
"{\"alternative_service\":[{"
"\"advertised_alpns\":[\"h3\"],"
"\"expiration\":\"13756212000000000\",\"port\":443,"
"\"protocol_str\":\"quic\"}],"
"\"anonymization\":[],"
"\"server\":\"https://www.google.com:80\"}],"
"\"supports_quic\":"
"{\"address\":\"127.0.0.1\",\"used_quic\":true},\"version\":5}";
const base::Value::Dict& http_server_properties =
pref_delegate_->GetServerProperties();
std::string preferences_json;
EXPECT_TRUE(
base::JSONWriter::Write(http_server_properties, &preferences_json));
EXPECT_EQ(expected_json, preferences_json);
AlternativeServiceInfoVector alternative_service_info_vector_2;
quic::ParsedQuicVersionVector advertised_versions = {
quic::ParsedQuicVersion::Q046(), quic::ParsedQuicVersion::Q043()};
alternative_service_info_vector_2.push_back(
AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
quic_alternative_service1, expiration1, advertised_versions));
http_server_props_->SetAlternativeServices(
server_www, NetworkAnonymizationKey(), alternative_service_info_vector_2);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
const char expected_json_updated[] =
"{\"quic_servers\":"
"[{\"anonymization\":[],"
"\"server_id\":\"https://mail.google.com:80\","
"\"server_info\":\"quic_server_info1\"}],"
"\"servers\":["
"{\"alternative_service\":"
"[{\"advertised_alpns\":[\"h3-Q046\",\"h3-Q043\"],"
"\"expiration\":\"13756212000000000\",\"port\":443,"
"\"protocol_str\":\"quic\"}],"
"\"anonymization\":[],"
"\"server\":\"https://www.google.com:80\"}],"
"\"supports_quic\":"
"{\"address\":\"127.0.0.1\",\"used_quic\":true},\"version\":5}";
EXPECT_TRUE(
base::JSONWriter::Write(http_server_properties, &preferences_json));
EXPECT_EQ(expected_json_updated, preferences_json);
AlternativeServiceInfoVector alternative_service_info_vector_3;
quic::ParsedQuicVersionVector advertised_versions_2 = {
quic::ParsedQuicVersion::Q043(), quic::ParsedQuicVersion::Q046()};
alternative_service_info_vector_3.push_back(
AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
quic_alternative_service1, expiration1, advertised_versions_2));
http_server_props_->SetAlternativeServices(
server_www, NetworkAnonymizationKey(), alternative_service_info_vector_3);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
const char expected_json_updated2[] =
"{\"quic_servers\":"
"[{\"anonymization\":[],"
"\"server_id\":\"https://mail.google.com:80\","
"\"server_info\":\"quic_server_info1\"}],"
"\"servers\":["
"{\"alternative_service\":"
"[{\"advertised_alpns\":[\"h3-Q043\",\"h3-Q046\"],"
"\"expiration\":\"13756212000000000\",\"port\":443,"
"\"protocol_str\":\"quic\"}],"
"\"anonymization\":[],"
"\"server\":\"https://www.google.com:80\"}],"
"\"supports_quic\":"
"{\"address\":\"127.0.0.1\",\"used_quic\":true},\"version\":5}";
EXPECT_TRUE(
base::JSONWriter::Write(http_server_properties, &preferences_json));
EXPECT_EQ(expected_json_updated2, preferences_json);
}
TEST_F(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) {
AlternativeService cached_broken_service(kProtoQUIC, "cached_broken", 443);
AlternativeService cached_broken_service2(kProtoQUIC, "cached_broken2", 443);
AlternativeService cached_recently_broken_service(kProtoQUIC,
"cached_rbroken", 443);
http_server_props_->MarkAlternativeServiceBroken(cached_broken_service,
NetworkAnonymizationKey());
http_server_props_->MarkAlternativeServiceBroken(cached_broken_service2,
NetworkAnonymizationKey());
http_server_props_->MarkAlternativeServiceRecentlyBroken(
cached_recently_broken_service, NetworkAnonymizationKey());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
std::string expiration_str =
base::NumberToString(static_cast<int64_t>(one_day_from_now_.ToTimeT()));
base::Value::Dict server_dict = base::test::ParseJsonDict(
"{"
"\"broken_alternative_services\":["
"{\"broken_until\":\"" +
expiration_str +
"\","
"\"host\":\"www.google.com\",\"anonymization\":[],"
"\"port\":1234,\"protocol_str\":\"h2\"},"
"{\"broken_count\":2,\"broken_until\":\"" +
expiration_str +
"\","
"\"host\":\"cached_broken\",\"anonymization\":[],"
"\"port\":443,\"protocol_str\":\"quic\"},"
"{\"broken_count\":3,"
"\"host\":\"cached_rbroken\",\"anonymization\":[],"
"\"port\":443,\"protocol_str\":\"quic\"}],"
"\"quic_servers\":["
"{\"anonymization\":[],"
"\"server_id\":\"https://mail.google.com:80\","
"\"server_info\":\"quic_server_info1\"}"
"],"
"\"servers\":["
"{\"server\":\"https://www.google.com:80\","
"\"anonymization\":[],"
"\"alternative_service\":["
"{\"expiration\":\"13756212000000000\",\"port\":443,"
"\"protocol_str\":\"h2\"},"
"{\"expiration\":\"13758804000000000\",\"host\":\"www.google.com\","
"\"port\":1234,\"protocol_str\":\"h2\"}"
"]"
"},"
"{\"server\":\"https://mail.google.com:80\","
"\"anonymization\":[],"
"\"alternative_service\":["
"{\"expiration\":\"9223372036854775807\",\"host\":\"foo.google.com\","
"\"port\":444,\"protocol_str\":\"h2\"}"
"],"
"\"network_stats\":{\"srtt\":42}"
"}"
"],"
"\"supports_quic\":"
"{\"address\":\"127.0.0.1\",\"used_quic\":true},"
"\"version\":5"
"}");
pref_delegate_->InitializePrefs(std::move(server_dict));
EXPECT_TRUE(http_server_props_->IsInitialized());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
AlternativeServiceInfoVector alternative_service_info_vector =
http_server_props_->GetAlternativeServiceInfos(
url::SchemeHostPort("https", "www.google.com", 80),
NetworkAnonymizationKey());
ASSERT_EQ(2u, alternative_service_info_vector.size());
EXPECT_EQ(kProtoHTTP2,
alternative_service_info_vector[0].alternative_service().protocol);
EXPECT_EQ("www.google.com",
alternative_service_info_vector[0].alternative_service().host);
EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port);
EXPECT_EQ(
"13756212000000000",
base::NumberToString(
alternative_service_info_vector[0].expiration().ToInternalValue()));
EXPECT_EQ(kProtoHTTP2,
alternative_service_info_vector[1].alternative_service().protocol);
EXPECT_EQ("www.google.com",
alternative_service_info_vector[1].alternative_service().host);
EXPECT_EQ(1234,
alternative_service_info_vector[1].alternative_service().port);
EXPECT_EQ(
"13758804000000000",
base::NumberToString(
alternative_service_info_vector[1].expiration().ToInternalValue()));
alternative_service_info_vector =
http_server_props_->GetAlternativeServiceInfos(
url::SchemeHostPort("https", "mail.google.com", 80),
NetworkAnonymizationKey());
ASSERT_EQ(1u, alternative_service_info_vector.size());
EXPECT_EQ(kProtoHTTP2,
alternative_service_info_vector[0].alternative_service().protocol);
EXPECT_EQ("foo.google.com",
alternative_service_info_vector[0].alternative_service().host);
EXPECT_EQ(444, alternative_service_info_vector[0].alternative_service().port);
EXPECT_EQ(
"9223372036854775807",
base::NumberToString(
alternative_service_info_vector[0].expiration().ToInternalValue()));
AlternativeService prefs_broken_service(kProtoHTTP2, "www.google.com", 1234);
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
cached_broken_service, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
cached_broken_service2, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
prefs_broken_service, NetworkAnonymizationKey()));
FastForwardBy(base::Minutes(5) -
HttpServerProperties::GetUpdatePrefsDelayForTesting());
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
cached_broken_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
cached_broken_service2, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
prefs_broken_service, NetworkAnonymizationKey()));
FastForwardBy(base::Days(1));
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
cached_broken_service, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
cached_broken_service2, NetworkAnonymizationKey()));
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
prefs_broken_service, NetworkAnonymizationKey()));
alternative_service_info_vector =
http_server_props_->GetAlternativeServiceInfos(
url::SchemeHostPort("https", "www.google.com", 80),
NetworkAnonymizationKey());
ASSERT_EQ(1u, alternative_service_info_vector.size());
EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
prefs_broken_service, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
cached_recently_broken_service, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
cached_broken_service, NetworkAnonymizationKey()));
EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
cached_broken_service2, NetworkAnonymizationKey()));
http_server_props_->MarkAlternativeServiceBroken(prefs_broken_service,
NetworkAnonymizationKey());
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardBy(base::Minutes(10) - base::TimeDelta::FromInternalValue(1));
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
prefs_broken_service, NetworkAnonymizationKey()));
FastForwardBy(base::TimeDelta::FromInternalValue(1));
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
prefs_broken_service, NetworkAnonymizationKey()));
http_server_props_->MarkAlternativeServiceBroken(
cached_recently_broken_service, NetworkAnonymizationKey());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardBy(base::Minutes(40) - base::TimeDelta::FromInternalValue(1));
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
cached_recently_broken_service, NetworkAnonymizationKey()));
FastForwardBy(base::TimeDelta::FromInternalValue(1));
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
cached_recently_broken_service, NetworkAnonymizationKey()));
http_server_props_->MarkAlternativeServiceBroken(cached_broken_service,
NetworkAnonymizationKey());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardBy(base::Minutes(20) - base::TimeDelta::FromInternalValue(1));
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
cached_broken_service, NetworkAnonymizationKey()));
FastForwardBy(base::TimeDelta::FromInternalValue(1));
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
cached_broken_service, NetworkAnonymizationKey()));
http_server_props_->MarkAlternativeServiceBroken(cached_broken_service2,
NetworkAnonymizationKey());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardBy(base::Minutes(10) - base::TimeDelta::FromInternalValue(1));
EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
cached_broken_service2, NetworkAnonymizationKey()));
FastForwardBy(base::TimeDelta::FromInternalValue(1));
EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
cached_broken_service2, NetworkAnonymizationKey()));
const ServerNetworkStats* server_network_stats =
http_server_props_->GetServerNetworkStats(
url::SchemeHostPort("https", "mail.google.com", 80),
NetworkAnonymizationKey());
EXPECT_TRUE(server_network_stats);
EXPECT_EQ(server_network_stats->srtt, base::TimeDelta::FromInternalValue(42));
const std::string* quic_server_info = http_server_props_->GetQuicServerInfo(
quic::QuicServerId("mail.google.com", 80, false),
NetworkAnonymizationKey());
EXPECT_EQ("quic_server_info1", *quic_server_info);
IPAddress actual_address(127, 0, 0, 1);
EXPECT_TRUE(
http_server_props_->WasLastLocalAddressWhenQuicWorked(actual_address));
EXPECT_EQ(4, pref_delegate_->GetAndClearNumPrefUpdates());
}
TEST_F(HttpServerPropertiesManagerTest, ForceHTTP11) {
const url::SchemeHostPort kServer1("https", "foo.test", 443);
const url::SchemeHostPort kServer2("https", "bar.test", 443);
const url::SchemeHostPort kServer3("https", "baz.test", 443);
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),
nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(base::Value::Dict());
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer1, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->RequiresHTTP11(kServer1, NetworkAnonymizationKey()));
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer2, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->RequiresHTTP11(kServer2, NetworkAnonymizationKey()));
properties->SetSupportsSpdy(kServer1, NetworkAnonymizationKey(), true);
properties->SetHTTP11Required(kServer1, NetworkAnonymizationKey());
properties->SetHTTP11Required(kServer2, NetworkAnonymizationKey());
EXPECT_TRUE(properties->GetSupportsSpdy(kServer1, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->RequiresHTTP11(kServer1, NetworkAnonymizationKey()));
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer2, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->RequiresHTTP11(kServer2, NetworkAnonymizationKey()));
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
base::Value::Dict saved_value =
unowned_pref_delegate->GetServerProperties().Clone();
properties.reset();
std::string preferences_json;
base::JSONWriter::Write(saved_value, &preferences_json);
EXPECT_EQ(
"{\"servers\":["
"{\"anonymization\":[],"
"\"server\":\"https://foo.test\","
"\"supports_spdy\":true}],"
"\"version\":5}",
preferences_json);
pref_delegate = std::make_unique<MockPrefDelegate>();
unowned_pref_delegate = pref_delegate.get();
properties = std::make_unique<HttpServerProperties>(
std::move(pref_delegate), nullptr, GetMockTickClock());
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer1, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->RequiresHTTP11(kServer1, NetworkAnonymizationKey()));
properties->SetHTTP11Required(kServer1, NetworkAnonymizationKey());
properties->SetHTTP11Required(kServer3, NetworkAnonymizationKey());
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer1, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->RequiresHTTP11(kServer1, NetworkAnonymizationKey()));
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer2, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->RequiresHTTP11(kServer2, NetworkAnonymizationKey()));
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer3, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->RequiresHTTP11(kServer3, NetworkAnonymizationKey()));
unowned_pref_delegate->InitializePrefs(std::move(saved_value));
EXPECT_TRUE(properties->GetSupportsSpdy(kServer1, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->RequiresHTTP11(kServer1, NetworkAnonymizationKey()));
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer2, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->RequiresHTTP11(kServer2, NetworkAnonymizationKey()));
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer3, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->RequiresHTTP11(kServer3, NetworkAnonymizationKey()));
}
TEST_F(HttpServerPropertiesManagerTest, NetworkAnonymizationKeyServerInfo) {
const SchemefulSite kSite1(GURL("https://foo.test/"));
const SchemefulSite kSite2(GURL("https://bar.test/"));
const SchemefulSite kOpaqueSite(GURL("data:text/plain,Hello World"));
const url::SchemeHostPort kServer("https", "baz.test", 443);
const url::SchemeHostPort kServer2("https", "zab.test", 443);
HttpServerProperties::ServerInfo server_info;
server_info.supports_spdy = true;
for (auto save_network_anonymization_key_mode :
kNetworkAnonymizationKeyModes) {
SCOPED_TRACE(static_cast<int>(save_network_anonymization_key_mode));
base::Value::Dict saved_value;
{
std::unique_ptr<base::test::ScopedFeatureList> feature_list =
SetNetworkAnonymizationKeyMode(save_network_anonymization_key_mode);
bool use_network_anonymization_key =
save_network_anonymization_key_mode !=
NetworkAnonymizationKeyMode::kDisabled;
HttpServerProperties::ServerInfoMap server_info_map;
HttpServerProperties::ServerInfoMapKey server_info_key(
kServer, NetworkAnonymizationKey::CreateCrossSite(kSite1),
use_network_anonymization_key);
server_info_map.Put(server_info_key, server_info);
if (use_network_anonymization_key) {
HttpServerProperties::ServerInfoMapKey server_info_key2(
kServer2, NetworkAnonymizationKey::CreateSameSite(kOpaqueSite),
use_network_anonymization_key);
server_info_map.Put(server_info_key2, server_info);
}
saved_value = ServerInfoMapToDict(server_info_map);
}
for (auto load_network_anonymization_key_mode :
kNetworkAnonymizationKeyModes) {
SCOPED_TRACE(static_cast<int>(load_network_anonymization_key_mode));
std::unique_ptr<base::test::ScopedFeatureList> feature_list =
SetNetworkAnonymizationKeyMode(load_network_anonymization_key_mode);
std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map2 =
DictToServerInfoMap(saved_value.Clone());
ASSERT_TRUE(server_info_map2);
if (save_network_anonymization_key_mode ==
NetworkAnonymizationKeyMode::kDisabled) {
ASSERT_EQ(1u, server_info_map2->size());
const HttpServerProperties::ServerInfoMapKey& server_info_key2 =
server_info_map2->begin()->first;
const HttpServerProperties::ServerInfo& server_info2 =
server_info_map2->begin()->second;
EXPECT_EQ(kServer, server_info_key2.server);
EXPECT_EQ(NetworkAnonymizationKey(),
server_info_key2.network_anonymization_key);
EXPECT_EQ(server_info, server_info2);
} else if (save_network_anonymization_key_mode ==
load_network_anonymization_key_mode) {
ASSERT_EQ(1u, server_info_map2->size());
const HttpServerProperties::ServerInfoMapKey& server_info_key2 =
server_info_map2->begin()->first;
const HttpServerProperties::ServerInfo& server_info2 =
server_info_map2->begin()->second;
EXPECT_EQ(kServer, server_info_key2.server);
EXPECT_EQ(NetworkAnonymizationKey::CreateCrossSite(kSite1),
server_info_key2.network_anonymization_key);
EXPECT_EQ(server_info, server_info2);
} else {
EXPECT_EQ(0u, server_info_map2->size());
}
}
}
}
TEST_F(HttpServerPropertiesManagerTest, NetworkAnonymizationKeyIntegration) {
const SchemefulSite kSite(GURL("https://foo.test/"));
const auto kNetworkAnonymizationKey =
NetworkAnonymizationKey::CreateSameSite(kSite);
const url::SchemeHostPort kServer("https", "baz.test", 443);
const SchemefulSite kOpaqueSite(GURL("data:text/plain,Hello World"));
const auto kOpaqueSiteNetworkAnonymizationKey =
NetworkAnonymizationKey::CreateSameSite(kOpaqueSite);
const url::SchemeHostPort kServer2("https", "zab.test", 443);
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
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),
nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(base::Value::Dict());
properties->SetSupportsSpdy(kServer, kNetworkAnonymizationKey, true);
EXPECT_TRUE(properties->GetSupportsSpdy(kServer, kNetworkAnonymizationKey));
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer, kOpaqueSiteNetworkAnonymizationKey));
EXPECT_FALSE(properties->GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
properties->SetSupportsSpdy(kServer2, kOpaqueSiteNetworkAnonymizationKey,
true);
EXPECT_FALSE(properties->GetSupportsSpdy(kServer2, kNetworkAnonymizationKey));
EXPECT_TRUE(properties->GetSupportsSpdy(kServer2,
kOpaqueSiteNetworkAnonymizationKey));
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer2, NetworkAnonymizationKey()));
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
base::Value::Dict saved_value =
unowned_pref_delegate->GetServerProperties().Clone();
properties.reset();
pref_delegate = std::make_unique<MockPrefDelegate>();
unowned_pref_delegate = pref_delegate.get();
properties = std::make_unique<HttpServerProperties>(
std::move(pref_delegate), nullptr, GetMockTickClock());
unowned_pref_delegate->InitializePrefs(std::move(saved_value));
EXPECT_TRUE(properties->GetSupportsSpdy(kServer, kNetworkAnonymizationKey));
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer, kOpaqueSiteNetworkAnonymizationKey));
EXPECT_FALSE(properties->GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->GetSupportsSpdy(kServer2, kNetworkAnonymizationKey));
EXPECT_FALSE(properties->GetSupportsSpdy(kServer2,
kOpaqueSiteNetworkAnonymizationKey));
EXPECT_FALSE(
properties->GetSupportsSpdy(kServer2, NetworkAnonymizationKey()));
}
TEST_F(HttpServerPropertiesManagerTest,
CanonicalSuffixRoundTripWithNetworkAnonymizationKey) {
const SchemefulSite kSite1(GURL("https://foo.test/"));
const SchemefulSite kSite2(GURL("https://bar.test/"));
const auto kNetworkAnonymizationKey1 =
NetworkAnonymizationKey::CreateSameSite(kSite1);
const auto kNetworkAnonymizationKey2 =
NetworkAnonymizationKey::CreateSameSite(kSite2);
const url::SchemeHostPort kServer1("https", "foo.c.youtube.com", 443);
const url::SchemeHostPort kServer2("https", "bar.c.youtube.com", 443);
const url::SchemeHostPort kServer3("https", "baz.c.youtube.com", 443);
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
base::Time expiration = base::Time::Now() + base::Days(1);
AlternativeServiceInfo alt_service1 =
AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
AlternativeService(kProtoQUIC, "foopy.c.youtube.com", 1234),
expiration, DefaultSupportedQuicVersions());
AlternativeServiceInfo alt_service2 =
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
AlternativeService(kProtoHTTP2, "foopy.c.youtube.com", 443),
expiration);
AlternativeServiceInfo alt_service3 =
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
AlternativeService(kProtoHTTP2, "foopy2.c.youtube.com", 443),
expiration);
AlternativeServiceInfoVector alt_service_vector1 = {alt_service1};
AlternativeServiceInfoVector alt_service_vector2 = {alt_service1,
alt_service2};
AlternativeServiceInfoVector alt_service_vector3 = {
alt_service1, alt_service2, alt_service3};
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),
nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(base::Value::Dict());
properties->SetAlternativeServices(kServer1, kNetworkAnonymizationKey1,
alt_service_vector1);
EXPECT_EQ(
1u, properties
->GetAlternativeServiceInfos(kServer1, kNetworkAnonymizationKey1)
.size());
EXPECT_EQ(
1u, properties
->GetAlternativeServiceInfos(kServer2, kNetworkAnonymizationKey1)
.size());
EXPECT_EQ(
1u, properties
->GetAlternativeServiceInfos(kServer3, kNetworkAnonymizationKey1)
.size());
EXPECT_EQ(
0u, properties
->GetAlternativeServiceInfos(kServer1, kNetworkAnonymizationKey2)
.size());
properties->SetAlternativeServices(kServer2, kNetworkAnonymizationKey1,
alt_service_vector2);
EXPECT_EQ(
1u, properties
->GetAlternativeServiceInfos(kServer1, kNetworkAnonymizationKey1)
.size());
EXPECT_EQ(
2u, properties
->GetAlternativeServiceInfos(kServer2, kNetworkAnonymizationKey1)
.size());
EXPECT_EQ(
2u, properties
->GetAlternativeServiceInfos(kServer3, kNetworkAnonymizationKey1)
.size());
EXPECT_EQ(
0u, properties
->GetAlternativeServiceInfos(kServer1, kNetworkAnonymizationKey2)
.size());
properties->SetAlternativeServices(kServer1, kNetworkAnonymizationKey2,
alt_service_vector3);
EXPECT_EQ(
1u, properties
->GetAlternativeServiceInfos(kServer1, kNetworkAnonymizationKey1)
.size());
EXPECT_EQ(
2u, properties
->GetAlternativeServiceInfos(kServer2, kNetworkAnonymizationKey1)
.size());
EXPECT_EQ(
2u, properties
->GetAlternativeServiceInfos(kServer3, kNetworkAnonymizationKey1)
.size());
EXPECT_EQ(
3u, properties
->GetAlternativeServiceInfos(kServer1, kNetworkAnonymizationKey2)
.size());
EXPECT_EQ(
3u, properties
->GetAlternativeServiceInfos(kServer2, kNetworkAnonymizationKey2)
.size());
EXPECT_EQ(
3u, properties
->GetAlternativeServiceInfos(kServer3, kNetworkAnonymizationKey2)
.size());
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
base::Value::Dict saved_value =
unowned_pref_delegate->GetServerProperties().Clone();
properties.reset();
pref_delegate = std::make_unique<MockPrefDelegate>();
unowned_pref_delegate = pref_delegate.get();
properties = std::make_unique<HttpServerProperties>(
std::move(pref_delegate), nullptr, GetMockTickClock());
unowned_pref_delegate->InitializePrefs(std::move(saved_value));
EXPECT_EQ(
2u, properties
->GetAlternativeServiceInfos(kServer1, kNetworkAnonymizationKey1)
.size());
EXPECT_EQ(
2u, properties
->GetAlternativeServiceInfos(kServer2, kNetworkAnonymizationKey1)
.size());
EXPECT_EQ(
2u, properties
->GetAlternativeServiceInfos(kServer3, kNetworkAnonymizationKey1)
.size());
EXPECT_EQ(
3u, properties
->GetAlternativeServiceInfos(kServer1, kNetworkAnonymizationKey2)
.size());
EXPECT_EQ(
3u, properties
->GetAlternativeServiceInfos(kServer2, kNetworkAnonymizationKey2)
.size());
EXPECT_EQ(
3u, properties
->GetAlternativeServiceInfos(kServer3, kNetworkAnonymizationKey2)
.size());
}
TEST_F(HttpServerPropertiesManagerTest,
NetworkAnonymizationKeyBrokenAltServiceRoundTrip) {
const SchemefulSite kSite1(GURL("https://foo1.test/"));
const SchemefulSite kSite2(GURL("https://foo2.test/"));
const auto kNetworkAnonymizationKey1 =
NetworkAnonymizationKey::CreateSameSite(kSite1);
const auto kNetworkAnonymizationKey2 =
NetworkAnonymizationKey::CreateSameSite(kSite2);
const AlternativeService kAlternativeService1(kProtoHTTP2,
"alt.service1.test", 443);
const AlternativeService kAlternativeService2(kProtoHTTP2,
"alt.service2.test", 443);
for (auto save_network_anonymization_key_mode :
kNetworkAnonymizationKeyModes) {
SCOPED_TRACE(static_cast<int>(save_network_anonymization_key_mode));
base::Value::Dict saved_value;
{
std::unique_ptr<base::test::ScopedFeatureList> feature_list =
SetNetworkAnonymizationKeyMode(save_network_anonymization_key_mode);
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),
nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(base::Value::Dict());
properties->MarkAlternativeServiceBroken(kAlternativeService1,
kNetworkAnonymizationKey1);
properties->MarkAlternativeServiceRecentlyBroken(
kAlternativeService2, NetworkAnonymizationKey());
properties->MarkAlternativeServiceBroken(kAlternativeService2,
kNetworkAnonymizationKey2);
EXPECT_TRUE(properties->IsAlternativeServiceBroken(
kAlternativeService1, kNetworkAnonymizationKey1));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, kNetworkAnonymizationKey1));
EXPECT_EQ(save_network_anonymization_key_mode ==
NetworkAnonymizationKeyMode::kDisabled,
properties->IsAlternativeServiceBroken(
kAlternativeService2, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->IsAlternativeServiceBroken(
kAlternativeService2, kNetworkAnonymizationKey2));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, kNetworkAnonymizationKey2));
if (save_network_anonymization_key_mode !=
NetworkAnonymizationKeyMode::kDisabled) {
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService2, kNetworkAnonymizationKey1));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, kNetworkAnonymizationKey1));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, kNetworkAnonymizationKey2));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, kNetworkAnonymizationKey2));
}
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
saved_value = unowned_pref_delegate->GetServerProperties().Clone();
}
for (auto load_network_anonymization_key_mode :
kNetworkAnonymizationKeyModes) {
SCOPED_TRACE(static_cast<int>(load_network_anonymization_key_mode));
std::unique_ptr<base::test::ScopedFeatureList> feature_list =
SetNetworkAnonymizationKeyMode(load_network_anonymization_key_mode);
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),
nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(saved_value.Clone());
if (save_network_anonymization_key_mode ==
NetworkAnonymizationKeyMode::kDisabled) {
EXPECT_TRUE(properties->IsAlternativeServiceBroken(
kAlternativeService1, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->IsAlternativeServiceBroken(
kAlternativeService2, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, NetworkAnonymizationKey()));
} else if (save_network_anonymization_key_mode ==
load_network_anonymization_key_mode) {
EXPECT_TRUE(properties->IsAlternativeServiceBroken(
kAlternativeService1, kNetworkAnonymizationKey1));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, kNetworkAnonymizationKey1));
EXPECT_EQ(save_network_anonymization_key_mode ==
NetworkAnonymizationKeyMode::kDisabled,
properties->IsAlternativeServiceBroken(
kAlternativeService2, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->IsAlternativeServiceBroken(
kAlternativeService2, kNetworkAnonymizationKey2));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, kNetworkAnonymizationKey2));
if (save_network_anonymization_key_mode !=
NetworkAnonymizationKeyMode::kDisabled) {
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService2, kNetworkAnonymizationKey1));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, kNetworkAnonymizationKey1));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, kNetworkAnonymizationKey2));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, kNetworkAnonymizationKey2));
}
} else {
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, kNetworkAnonymizationKey1));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, kNetworkAnonymizationKey1));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService2, NetworkAnonymizationKey()));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService2, kNetworkAnonymizationKey2));
EXPECT_EQ(load_network_anonymization_key_mode ==
NetworkAnonymizationKeyMode::kDisabled,
properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, kNetworkAnonymizationKey2));
if (load_network_anonymization_key_mode !=
NetworkAnonymizationKeyMode::kDisabled) {
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService2, kNetworkAnonymizationKey1));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService2, kNetworkAnonymizationKey1));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, NetworkAnonymizationKey()));
EXPECT_FALSE(properties->IsAlternativeServiceBroken(
kAlternativeService1, kNetworkAnonymizationKey2));
EXPECT_FALSE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService1, kNetworkAnonymizationKey2));
}
}
}
}
}
TEST_F(HttpServerPropertiesManagerTest,
NetworkAnonymizationKeyBrokenAltServiceOpaqueOrigin) {
const SchemefulSite kOpaqueSite(GURL("data:text/plain,Hello World"));
const auto kNetworkAnonymizationKey =
NetworkAnonymizationKey::CreateSameSite(kOpaqueSite);
const AlternativeService kAlternativeService(kProtoHTTP2, "alt.service1.test",
443);
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
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),
nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(base::Value::Dict());
properties->MarkAlternativeServiceBroken(kAlternativeService,
kNetworkAnonymizationKey);
EXPECT_TRUE(properties->IsAlternativeServiceBroken(kAlternativeService,
kNetworkAnonymizationKey));
EXPECT_TRUE(properties->WasAlternativeServiceRecentlyBroken(
kAlternativeService, kNetworkAnonymizationKey));
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
std::string preferences_json;
base::JSONWriter::Write(unowned_pref_delegate->GetServerProperties(),
&preferences_json);
EXPECT_EQ("{\"servers\":[],\"version\":5}", preferences_json);
}
TEST_F(HttpServerPropertiesManagerTest,
NetworkAnonymizationKeyQuicServerInfoRoundTrip) {
const SchemefulSite kSite1(GURL("https://foo1.test/"));
const SchemefulSite kSite2(GURL("https://foo2.test/"));
const auto kNetworkAnonymizationKey1 =
NetworkAnonymizationKey::CreateSameSite(kSite1);
const auto kNetworkAnonymizationKey2 =
NetworkAnonymizationKey::CreateSameSite(kSite2);
const quic::QuicServerId kServer1("foo", 443,
false );
const quic::QuicServerId kServer2("foo", 443,
true );
const char kQuicServerInfo1[] = "info1";
const char kQuicServerInfo2[] = "info2";
const char kQuicServerInfo3[] = "info3";
for (auto save_network_anonymization_key_mode :
kNetworkAnonymizationKeyModes) {
SCOPED_TRACE(static_cast<int>(save_network_anonymization_key_mode));
base::Value::Dict saved_value;
{
std::unique_ptr<base::test::ScopedFeatureList> feature_list =
SetNetworkAnonymizationKeyMode(save_network_anonymization_key_mode);
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),
nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(base::Value::Dict());
properties->SetQuicServerInfo(kServer1, kNetworkAnonymizationKey1,
kQuicServerInfo1);
properties->SetQuicServerInfo(kServer2, kNetworkAnonymizationKey2,
kQuicServerInfo2);
properties->SetQuicServerInfo(kServer1, NetworkAnonymizationKey(),
kQuicServerInfo3);
if (save_network_anonymization_key_mode !=
NetworkAnonymizationKeyMode::kDisabled) {
EXPECT_EQ(kQuicServerInfo1, *properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey1));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey2));
EXPECT_EQ(kQuicServerInfo3, *properties->GetQuicServerInfo(
kServer1, NetworkAnonymizationKey()));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey1));
EXPECT_EQ(kQuicServerInfo2, *properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey2));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer2, NetworkAnonymizationKey()));
} else {
EXPECT_EQ(kQuicServerInfo3, *properties->GetQuicServerInfo(
kServer1, NetworkAnonymizationKey()));
EXPECT_EQ(kQuicServerInfo2, *properties->GetQuicServerInfo(
kServer2, NetworkAnonymizationKey()));
}
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
saved_value = unowned_pref_delegate->GetServerProperties().Clone();
}
for (auto load_network_anonymization_key_mode :
kNetworkAnonymizationKeyModes) {
SCOPED_TRACE(static_cast<int>(load_network_anonymization_key_mode));
std::unique_ptr<base::test::ScopedFeatureList> feature_list =
SetNetworkAnonymizationKeyMode(load_network_anonymization_key_mode);
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),
nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(saved_value.Clone());
if (save_network_anonymization_key_mode ==
NetworkAnonymizationKeyMode::kDisabled) {
EXPECT_EQ(kQuicServerInfo3, *properties->GetQuicServerInfo(
kServer1, NetworkAnonymizationKey()));
EXPECT_EQ(kQuicServerInfo2, *properties->GetQuicServerInfo(
kServer2, NetworkAnonymizationKey()));
if (load_network_anonymization_key_mode !=
NetworkAnonymizationKeyMode::kDisabled) {
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey1));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey2));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey1));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey2));
}
} else if (save_network_anonymization_key_mode ==
load_network_anonymization_key_mode) {
EXPECT_EQ(kQuicServerInfo1, *properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey1));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey2));
EXPECT_EQ(kQuicServerInfo3, *properties->GetQuicServerInfo(
kServer1, NetworkAnonymizationKey()));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey1));
EXPECT_EQ(kQuicServerInfo2, *properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey2));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer2, NetworkAnonymizationKey()));
} else {
EXPECT_EQ(kQuicServerInfo3, *properties->GetQuicServerInfo(
kServer1, NetworkAnonymizationKey()));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey1));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey2));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer2, NetworkAnonymizationKey()));
if (load_network_anonymization_key_mode !=
NetworkAnonymizationKeyMode::kDisabled) {
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey1));
EXPECT_EQ(nullptr, properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey2));
}
}
}
}
}
TEST_F(HttpServerPropertiesManagerTest,
NetworkAnonymizationKeyQuicServerInfoCanonicalSuffixRoundTrip) {
const SchemefulSite kSite1(GURL("https://foo.test/"));
const SchemefulSite kSite2(GURL("https://bar.test/"));
const auto kNetworkAnonymizationKey1 =
NetworkAnonymizationKey::CreateSameSite(kSite1);
const auto kNetworkAnonymizationKey2 =
NetworkAnonymizationKey::CreateSameSite(kSite2);
const quic::QuicServerId kServer1("foo.c.youtube.com", 443,
false );
const quic::QuicServerId kServer2("bar.c.youtube.com", 443,
false );
const quic::QuicServerId kServer3("baz.c.youtube.com", 443,
false );
const char kQuicServerInfo1[] = "info1";
const char kQuicServerInfo2[] = "info2";
const char kQuicServerInfo3[] = "info3";
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
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),
nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(base::Value::Dict());
properties->SetQuicServerInfo(kServer1, kNetworkAnonymizationKey1,
kQuicServerInfo1);
EXPECT_EQ(kQuicServerInfo1, *properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey1));
EXPECT_EQ(kQuicServerInfo1, *properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey1));
EXPECT_EQ(kQuicServerInfo1, *properties->GetQuicServerInfo(
kServer3, kNetworkAnonymizationKey1));
EXPECT_FALSE(
properties->GetQuicServerInfo(kServer1, kNetworkAnonymizationKey2));
properties->SetQuicServerInfo(kServer2, kNetworkAnonymizationKey1,
kQuicServerInfo2);
EXPECT_EQ(kQuicServerInfo1, *properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey1));
EXPECT_EQ(kQuicServerInfo2, *properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey1));
EXPECT_EQ(kQuicServerInfo2, *properties->GetQuicServerInfo(
kServer3, kNetworkAnonymizationKey1));
EXPECT_FALSE(
properties->GetQuicServerInfo(kServer1, kNetworkAnonymizationKey2));
properties->SetQuicServerInfo(kServer1, kNetworkAnonymizationKey2,
kQuicServerInfo3);
EXPECT_EQ(kQuicServerInfo1, *properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey1));
EXPECT_EQ(kQuicServerInfo2, *properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey1));
EXPECT_EQ(kQuicServerInfo2, *properties->GetQuicServerInfo(
kServer3, kNetworkAnonymizationKey1));
EXPECT_EQ(kQuicServerInfo3, *properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey2));
EXPECT_EQ(kQuicServerInfo3, *properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey2));
EXPECT_EQ(kQuicServerInfo3, *properties->GetQuicServerInfo(
kServer3, kNetworkAnonymizationKey2));
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
base::Value::Dict saved_value =
unowned_pref_delegate->GetServerProperties().Clone();
properties.reset();
pref_delegate = std::make_unique<MockPrefDelegate>();
unowned_pref_delegate = pref_delegate.get();
properties = std::make_unique<HttpServerProperties>(
std::move(pref_delegate), nullptr, GetMockTickClock());
unowned_pref_delegate->InitializePrefs(std::move(saved_value));
EXPECT_EQ(kQuicServerInfo1, *properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey1));
EXPECT_EQ(kQuicServerInfo2, *properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey1));
EXPECT_EQ(kQuicServerInfo2, *properties->GetQuicServerInfo(
kServer3, kNetworkAnonymizationKey1));
EXPECT_EQ(kQuicServerInfo3, *properties->GetQuicServerInfo(
kServer1, kNetworkAnonymizationKey2));
EXPECT_EQ(kQuicServerInfo3, *properties->GetQuicServerInfo(
kServer2, kNetworkAnonymizationKey2));
EXPECT_EQ(kQuicServerInfo3, *properties->GetQuicServerInfo(
kServer3, kNetworkAnonymizationKey2));
}
TEST_F(HttpServerPropertiesManagerTest,
NetworkAnonymizationKeyQuicServerInfoOpaqueOrigin) {
const SchemefulSite kOpaqueSite(GURL("data:text/plain,Hello World"));
const auto kNetworkAnonymizationKey =
NetworkAnonymizationKey::CreateSameSite(kOpaqueSite);
const quic::QuicServerId kServer("foo", 443,
false );
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
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),
nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(base::Value::Dict());
properties->SetQuicServerInfo(kServer, kNetworkAnonymizationKey,
"QuicServerInfo");
EXPECT_TRUE(properties->GetQuicServerInfo(kServer, kNetworkAnonymizationKey));
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
std::string preferences_json;
base::JSONWriter::Write(unowned_pref_delegate->GetServerProperties(),
&preferences_json);
EXPECT_EQ("{\"quic_servers\":[],\"servers\":[],\"version\":5}",
preferences_json);
}
TEST_F(HttpServerPropertiesManagerTest, AdvertisedVersionsRoundTrip) {
for (const quic::ParsedQuicVersion& version : AllSupportedQuicVersions()) {
if (version.AlpnDeferToRFCv1()) {
continue;
}
TearDown();
SetUp();
InitializePrefs();
const url::SchemeHostPort server("https", "quic.example.org", 443);
AlternativeServiceInfoVector alternative_service_info_vector_in;
AlternativeService quic_alternative_service(kProtoQUIC, "", 443);
base::Time expiration;
ASSERT_TRUE(base::Time::FromUTCString("2036-12-01 10:00:00", &expiration));
quic::ParsedQuicVersionVector advertised_versions = {version};
alternative_service_info_vector_in.push_back(
AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
quic_alternative_service, expiration, advertised_versions));
http_server_props_->SetAlternativeServices(
server, NetworkAnonymizationKey(), alternative_service_info_vector_in);
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
EXPECT_NE(0u, GetPendingMainThreadTaskCount());
FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
const base::Value::Dict& http_server_properties =
pref_delegate_->GetServerProperties();
std::string preferences_json;
EXPECT_TRUE(
base::JSONWriter::Write(http_server_properties, &preferences_json));
TearDown();
SetUp();
InitializePrefs();
base::Value::Dict preferences_dict =
base::test::ParseJsonDict(preferences_json);
ASSERT_FALSE(preferences_dict.empty());
const base::Value::List* servers_list =
preferences_dict.FindList("servers");
ASSERT_TRUE(servers_list);
ASSERT_EQ(servers_list->size(), 1u);
const base::Value& server_dict = (*servers_list)[0];
HttpServerProperties::ServerInfo server_info;
EXPECT_TRUE(HttpServerPropertiesManager::ParseAlternativeServiceInfo(
server, server_dict.GetDict(), &server_info));
ASSERT_TRUE(server_info.alternative_services.has_value());
AlternativeServiceInfoVector alternative_service_info_vector_out =
server_info.alternative_services.value();
ASSERT_EQ(1u, alternative_service_info_vector_out.size());
EXPECT_EQ(
kProtoQUIC,
alternative_service_info_vector_out[0].alternative_service().protocol);
EXPECT_EQ(advertised_versions,
alternative_service_info_vector_out[0].advertised_versions());
}
}
TEST_F(HttpServerPropertiesManagerTest, SameOrderAfterReload) {
const SchemefulSite kSite1(GURL("https://foo.test/"));
const SchemefulSite kSite2(GURL("https://bar.test/"));
const auto kNetworkAnonymizationKey1 =
NetworkAnonymizationKey::CreateSameSite(kSite1);
const auto kNetworkAnonymizationKey2 =
NetworkAnonymizationKey::CreateSameSite(kSite2);
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
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),
nullptr,
GetMockTickClock());
unowned_pref_delegate->InitializePrefs(base::Value::Dict());
base::Time expiration = base::Time::Now() + base::Days(1);
AlternativeServiceInfo alt_service1 =
AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
AlternativeService(kProtoQUIC, "1.example", 1234), expiration,
DefaultSupportedQuicVersions());
AlternativeServiceInfo alt_service2 =
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
AlternativeService(kProtoHTTP2, "2.example", 443), expiration);
AlternativeServiceInfo alt_service3 =
AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
AlternativeService(kProtoHTTP2, "3.example", 443), expiration);
const url::SchemeHostPort kServer1("https", "1.example", 443);
const url::SchemeHostPort kServer2("https", "2.example", 443);
const url::SchemeHostPort kServer3("https", "3.example", 443);
properties->SetAlternativeServices(kServer1, kNetworkAnonymizationKey1,
{alt_service1});
properties->SetAlternativeServices(kServer2, kNetworkAnonymizationKey1,
{alt_service2});
properties->SetAlternativeServices(kServer3, kNetworkAnonymizationKey2,
{alt_service3});
quic::QuicServerId quic_server_id1("quic1.example", 80, false);
quic::QuicServerId quic_server_id2("quic2.example", 80, false);
quic::QuicServerId quic_server_id3("quic3.example", 80, false);
properties->SetQuicServerInfo(quic_server_id1, kNetworkAnonymizationKey1,
"quic_server_info1");
properties->SetQuicServerInfo(quic_server_id2, kNetworkAnonymizationKey1,
"quic_server_info2");
properties->SetQuicServerInfo(quic_server_id3, kNetworkAnonymizationKey2,
"quic_server_info3");
AlternativeService broken_service1(kProtoQUIC, "broken1.example", 443);
AlternativeService broken_service2(kProtoQUIC, "broken2.example", 443);
AlternativeService broken_service3(kProtoQUIC, "broken3.example", 443);
properties->MarkAlternativeServiceBroken(broken_service1,
kNetworkAnonymizationKey1);
FastForwardBy(base::Milliseconds(1));
properties->MarkAlternativeServiceBroken(broken_service2,
kNetworkAnonymizationKey1);
FastForwardBy(base::Milliseconds(1));
properties->MarkAlternativeServiceBroken(broken_service3,
kNetworkAnonymizationKey2);
EXPECT_EQ(3u, properties->server_info_map_for_testing().size());
EXPECT_EQ(
properties->server_info_map_for_testing().begin()->first.server.host(),
"3.example");
EXPECT_EQ(3u, properties->broken_alternative_services_for_testing()
.recently_broken_alternative_services()
.size());
EXPECT_EQ("broken3.example",
properties->broken_alternative_services_for_testing()
.recently_broken_alternative_services()
.begin()
->first.alternative_service.host);
EXPECT_EQ(3u, properties->quic_server_info_map_for_testing().size());
EXPECT_EQ("quic3.example", properties->quic_server_info_map_for_testing()
.begin()
->first.server_id.host());
EXPECT_EQ(3u, properties->broken_alternative_services_for_testing()
.broken_alternative_service_list()
.size());
EXPECT_EQ("broken1.example",
properties->broken_alternative_services_for_testing()
.broken_alternative_service_list()
.begin()
->first.alternative_service.host);
FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting());
base::Value::Dict saved_value =
unowned_pref_delegate->GetServerProperties().Clone();
pref_delegate = std::make_unique<MockPrefDelegate>();
unowned_pref_delegate = pref_delegate.get();
properties = std::make_unique<HttpServerProperties>(
std::move(pref_delegate), nullptr, GetMockTickClock());
unowned_pref_delegate->InitializePrefs(std::move(saved_value));
EXPECT_EQ(3u, properties->server_info_map_for_testing().size());
EXPECT_EQ(
properties->server_info_map_for_testing().begin()->first.server.host(),
"3.example");
EXPECT_EQ(3u, properties->broken_alternative_services_for_testing()
.recently_broken_alternative_services()
.size());
EXPECT_EQ("broken3.example",
properties->broken_alternative_services_for_testing()
.recently_broken_alternative_services()
.begin()
->first.alternative_service.host);
EXPECT_EQ(3u, properties->quic_server_info_map_for_testing().size());
EXPECT_EQ("quic3.example", properties->quic_server_info_map_for_testing()
.begin()
->first.server_id.host());
EXPECT_EQ(3u, properties->broken_alternative_services_for_testing()
.broken_alternative_service_list()
.size());
EXPECT_EQ("broken1.example",
properties->broken_alternative_services_for_testing()
.broken_alternative_service_list()
.begin()
->first.alternative_service.host);
}
}