Skip to content

Commit

Permalink
Add protocolfilter setting to set overriding protocols for an origin. (
Browse files Browse the repository at this point in the history
…#4080)

b/205134049
  • Loading branch information
aee-google committed Sep 2, 2024
1 parent cb6d796 commit 9e61e55
Show file tree
Hide file tree
Showing 12 changed files with 297 additions and 5 deletions.
6 changes: 6 additions & 0 deletions cobalt/browser/browser_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,12 @@ BrowserModule::~BrowserModule() {
}

void BrowserModule::Navigate(const GURL& url_reference) {
if (network_module_) {
// If protocolfilter setting was updated, the setting does not take effect
// until the next page load.
network_module_->SetProtocolFilterFromPersistentSettings();
}

// The argument is sometimes |pending_navigate_url_|, and Navigate can modify
// |pending_navigate_url_|, so we want to keep a copy of the argument to
// preserve its original value.
Expand Down
33 changes: 33 additions & 0 deletions cobalt/h5vcc/h5vcc_settings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,32 @@ bool H5vccSettings::Set(const std::string& name, SetValueType value) const {
}
}

if (name.compare(network::kProtocolFilterKey) == 0 &&
value.IsType<std::string>() &&
value.AsType<std::string>().size() < 16384) {
std::string raw_json = value.AsType<std::string>();
base::Value old_config_json;
persistent_settings_->Get(network::kProtocolFilterKey, &old_config_json);

if (raw_json.empty() && (!old_config_json.is_string() ||
!old_config_json.GetString().empty())) {
persistent_settings_->Set(network::kProtocolFilterKey, base::Value());
network_module_->SetProtocolFilterUpdatePending();
return true;
}

absl::optional<base::Value> old_config =
base::JSONReader::Read(old_config_json.GetString());
absl::optional<base::Value> new_config = base::JSONReader::Read(raw_json);
if (!new_config) return false;
if (old_config && *old_config == *new_config) return false;

persistent_settings_->Set(network::kProtocolFilterKey,
base::Value(raw_json));
network_module_->SetProtocolFilterUpdatePending();
return true;
}

if (name.compare("cpu_usage_tracker_intervals") == 0 &&
value.IsType<std::string>() && value.AsType<std::string>().size() < 512) {
absl::optional<base::Value> config =
Expand Down Expand Up @@ -193,6 +219,13 @@ std::string H5vccSettings::GetPersistentSettingAsString(
absl::optional<std::string> json = base::WriteJson(value);
return json.value_or(std::string());
}

if (key.compare(network::kProtocolFilterKey) == 0) {
base::Value value;
persistent_settings_->Get(network::kProtocolFilterKey, &value);
if (!value.is_string()) return std::string();
return value.GetString();
}
return std::string();
}

Expand Down
71 changes: 71 additions & 0 deletions cobalt/network/network_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "base/bind.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
Expand Down Expand Up @@ -160,6 +161,74 @@ void NetworkModule::SetEnableHttp3FromPersistentSettings() {
}
}

void NetworkModule::SetProtocolFilterUpdatePending() {
protocol_filter_update_pending_ = true;
}

void NetworkModule::SetProtocolFilterFromPersistentSettings() {
if (!options_.persistent_settings) return;
if (!protocol_filter_update_pending_) return;
protocol_filter_update_pending_ = false;

base::Value value;
options_.persistent_settings->Get(kProtocolFilterKey, &value);
if (!value.is_string()) return;

if (value.GetString().empty()) {
task_runner()->PostTask(FROM_HERE,
base::Bind(
[](URLRequestContext* url_request_context) {
url_request_context->url_request_context()
->quic_context()
->params()
->protocol_filter = absl::nullopt;
},
base::Unretained(url_request_context_.get())));
return;
}

absl::optional<base::Value> config =
base::JSONReader::Read(value.GetString());
if (!config.has_value() || !config->is_list()) return;

net::ProtocolFilter protocol_filter;
for (auto& filter_value : config->GetList()) {
if (!filter_value.is_dict()) return;
const auto& dict = filter_value.GetDict();
const base::Value* origin = dict.Find("origin");
const base::Value* alt_svc = dict.Find("altSvc");
if (!origin || !alt_svc) continue;
if (!origin->is_string() || !alt_svc->is_string()) continue;
net::ProtocolFilterEntry entry;
entry.origin = origin->GetString();
if (base::StartsWith(alt_svc->GetString(), "h3")) {
entry.alt_svc.protocol = net::kProtoQUIC;
if (base::StartsWith(alt_svc->GetString(), "h3-Q046")) {
entry.alt_svc.quic_version =
net::ProtocolFilterEntry::QuicVersion::Q046;
} else {
entry.alt_svc.quic_version =
net::ProtocolFilterEntry::QuicVersion::RFC_V1;
}
} else {
entry.alt_svc.protocol = net::kProtoUnknown;
}
protocol_filter.push_back(std::move(entry));
}

task_runner()->PostTask(
FROM_HERE, base::Bind(
[](URLRequestContext* url_request_context,
net::ProtocolFilter protocol_filter) {
url_request_context->url_request_context()
->quic_context()
->params()
->protocol_filter = std::move(protocol_filter);
},
base::Unretained(url_request_context_.get()),
std::move(protocol_filter)));
}

void NetworkModule::EnsureStorageManagerStarted() {
DCHECK(storage_manager_);
storage_manager_->EnsureStarted();
Expand Down Expand Up @@ -249,6 +318,8 @@ void NetworkModule::Initialize(const std::string& user_agent_string,
SetEnableQuicFromPersistentSettings();
SetEnableHttp2FromPersistentSettings();
SetEnableHttp3FromPersistentSettings();
protocol_filter_update_pending_ = true;
SetProtocolFilterFromPersistentSettings();
}

void NetworkModule::OnCreate(
Expand Down
4 changes: 4 additions & 0 deletions cobalt/network/network_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ constexpr int32_t kEnabledClientHintHeaders = (kCallTypeLoader | kCallTypeXHR);
const char kQuicEnabledPersistentSettingsKey[] = "QUICEnabled";
const char kHttp2EnabledPersistentSettingsKey[] = "HTTP2Enabled";
const char kHttp3EnabledPersistentSettingsKey[] = "HTTP3Enabled";
const char kProtocolFilterKey[] = "protocolfilter";

class NetworkSystem;
// NetworkModule wraps various networking-related components such as
Expand Down Expand Up @@ -133,6 +134,8 @@ class NetworkModule : public base::CurrentThread::DestructionObserver {
void SetEnableQuicFromPersistentSettings();
void SetEnableHttp2FromPersistentSettings();
void SetEnableHttp3FromPersistentSettings();
void SetProtocolFilterUpdatePending();
void SetProtocolFilterFromPersistentSettings();

// Adds the Client Hint Headers to the provided URLFetcher if enabled.
void AddClientHintHeaders(net::URLFetcher& url_fetcher,
Expand Down Expand Up @@ -176,6 +179,7 @@ class NetworkModule : public base::CurrentThread::DestructionObserver {
std::unique_ptr<CobaltNetLog> net_log_{nullptr};
#endif
Options options_;
bool protocol_filter_update_pending_;

DISALLOW_COPY_AND_ASSIGN(NetworkModule);
};
Expand Down
17 changes: 17 additions & 0 deletions net/http/alternative_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,19 @@ AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
AlternativeServiceInfo AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
const AlternativeService& alternative_service,
base::Time expiration,
#if defined(STARBOARD)
const quic::ParsedQuicVersionVector& advertised_versions,
bool protocol_filter_override) {
#else
const quic::ParsedQuicVersionVector& advertised_versions) {
#endif // defined(STARBOARD)
DCHECK_EQ(alternative_service.protocol, kProtoQUIC);
return AlternativeServiceInfo(alternative_service, expiration,
#if defined(STARBOARD)
advertised_versions, protocol_filter_override);
#else
advertised_versions);
#endif // defined(STARBOARD)
}

AlternativeServiceInfo::AlternativeServiceInfo() : alternative_service_() {}
Expand All @@ -90,11 +99,19 @@ AlternativeServiceInfo::~AlternativeServiceInfo() = default;
AlternativeServiceInfo::AlternativeServiceInfo(
const AlternativeService& alternative_service,
base::Time expiration,
#if defined(STARBOARD)
const quic::ParsedQuicVersionVector& advertised_versions,
bool protocol_filter_override)
#else
const quic::ParsedQuicVersionVector& advertised_versions)
#endif // defined(STARBOARD)
: alternative_service_(alternative_service), expiration_(expiration) {
if (alternative_service_.protocol == kProtoQUIC) {
advertised_versions_ = advertised_versions;
}
#if defined(STARBOARD)
protocol_filter_override_ = protocol_filter_override;
#endif // defined(STARBOARD)
}

AlternativeServiceInfo::AlternativeServiceInfo(
Expand Down
35 changes: 35 additions & 0 deletions net/http/alternative_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,18 @@ class NET_EXPORT_PRIVATE AlternativeServiceInfo {
const AlternativeService& alternative_service,
base::Time expiration);

#if defined(STARBOARD)
static AlternativeServiceInfo CreateQuicAlternativeServiceInfo(
const AlternativeService& alternative_service,
base::Time expiration,
const quic::ParsedQuicVersionVector& advertised_versions,
bool protocol_filter_override = false);
#else
static AlternativeServiceInfo CreateQuicAlternativeServiceInfo(
const AlternativeService& alternative_service,
base::Time expiration,
const quic::ParsedQuicVersionVector& advertised_versions);
#endif // defined(STARBOARD)

AlternativeServiceInfo();
~AlternativeServiceInfo();
Expand All @@ -116,11 +124,20 @@ class NET_EXPORT_PRIVATE AlternativeServiceInfo {
AlternativeServiceInfo& operator=(
const AlternativeServiceInfo& alternative_service_info);

#if defined(STARBOARD)
bool operator==(const AlternativeServiceInfo& other) const {
return alternative_service_ == other.alternative_service() &&
expiration_ == other.expiration() &&
advertised_versions_ == other.advertised_versions() &&
protocol_filter_override_ == other.protocol_filter_override();
}
#else
bool operator==(const AlternativeServiceInfo& other) const {
return alternative_service_ == other.alternative_service() &&
expiration_ == other.expiration() &&
advertised_versions_ == other.advertised_versions();
}
#endif // defined(STARBOARD)

bool operator!=(const AlternativeServiceInfo& other) const {
return !this->operator==(other);
Expand Down Expand Up @@ -170,11 +187,25 @@ class NET_EXPORT_PRIVATE AlternativeServiceInfo {
return advertised_versions_;
}

#if defined(STARBOARD)
const bool protocol_filter_override() const {
return protocol_filter_override_;
}
#endif // defined(STARBOARD)

private:
#if defined(STARBOARD)
AlternativeServiceInfo(
const AlternativeService& alternative_service,
base::Time expiration,
const quic::ParsedQuicVersionVector& advertised_versions,
bool protocol_filter_override = false);
#else
AlternativeServiceInfo(
const AlternativeService& alternative_service,
base::Time expiration,
const quic::ParsedQuicVersionVector& advertised_versions);
#endif // defined(STARBOARD)

static bool TransportVersionLessThan(const quic::ParsedQuicVersion& lhs,
const quic::ParsedQuicVersion& rhs);
Expand All @@ -186,6 +217,10 @@ class NET_EXPORT_PRIVATE AlternativeServiceInfo {
// by Chrome. If empty, defaults to versions used by the current instance of
// the netstack. This list is sorted according to the server's preference.
quic::ParsedQuicVersionVector advertised_versions_;

#if defined(STARBOARD)
bool protocol_filter_override_;
#endif // defined(STARBOARD)
};

using AlternativeServiceInfoVector = std::vector<AlternativeServiceInfo>;
Expand Down
23 changes: 23 additions & 0 deletions net/http/http_stream_factory_job.cc
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,12 @@ HttpStreamFactory::Job::Job(Delegate* delegate,
quic::ParsedQuicVersion quic_version,
bool is_websocket,
bool enable_ip_based_pooling,
#if defined(STARBOARD)
NetLog* net_log,
bool protocol_filter_override)
#else
NetLog* net_log)
#endif // defined(STARBOARD)
: request_info_(request_info),
priority_(priority),
proxy_info_(proxy_info),
Expand Down Expand Up @@ -165,6 +170,9 @@ HttpStreamFactory::Job::Job(Delegate* delegate,
is_websocket_)) ||
job_type == DNS_ALPN_H3 ||
job_type == PRECONNECT_DNS_ALPN_H3),
#if defined(STARBOARD)
protocol_filter_override_(protocol_filter_override),
#endif //defined(STARBOARD)
quic_version_(quic_version),
expect_spdy_(alternative_protocol == kProtoHTTP2 && !using_quic_),
quic_request_(session_->quic_stream_factory()),
Expand Down Expand Up @@ -218,9 +226,15 @@ HttpStreamFactory::Job::Job(Delegate* delegate,
if (expect_spdy_) {
DCHECK(origin_url_.SchemeIs(url::kHttpsScheme));
}
#if defined(STARBOARD)
if (using_quic_ && !protocol_filter_override_) {
DCHECK(session_->IsQuicEnabled());
}
#else
if (using_quic_) {
DCHECK(session_->IsQuicEnabled());
}
#endif // defined(STARBOARD)
if (job_type_ == PRECONNECT || is_websocket_) {
DCHECK(request_info_.socket_tag == SocketTag());
}
Expand Down Expand Up @@ -1342,12 +1356,21 @@ HttpStreamFactory::JobFactory::CreateJob(
bool enable_ip_based_pooling,
NetLog* net_log,
NextProto alternative_protocol,
#if defined(STARBOARD)
quic::ParsedQuicVersion quic_version,
bool protocol_filter_override) {
#else
quic::ParsedQuicVersion quic_version) {
#endif // defined(STARBOARD)
return std::make_unique<HttpStreamFactory::Job>(
delegate, job_type, session, request_info, priority, proxy_info,
server_ssl_config, proxy_ssl_config, std::move(destination), origin_url,
alternative_protocol, quic_version, is_websocket, enable_ip_based_pooling,
#if defined(STARBOARD)
net_log, protocol_filter_override);
#else
net_log);
#endif // defined(STARBOARD)
}

bool HttpStreamFactory::Job::ShouldThrottleConnectForSpdy() const {
Expand Down
16 changes: 16 additions & 0 deletions net/http/http_stream_factory_job.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,12 @@ class HttpStreamFactory::Job
quic::ParsedQuicVersion quic_version,
bool is_websocket,
bool enable_ip_based_pooling,
#if defined(STARBOARD)
NetLog* net_log,
bool protocol_filter_override);
#else
NetLog* net_log);
#endif // defined(STARBOARD)

Job(const Job&) = delete;
Job& operator=(const Job&) = delete;
Expand Down Expand Up @@ -414,6 +419,11 @@ class HttpStreamFactory::Job
// proxy. This differs from `using_ssl_`, which only describes the origin.
const bool using_quic_;

#if defined(STARBOARD)
// True if |using_quic_| can be true when QUIC is not enabled by the session.
const bool protocol_filter_override_;
#endif //defined(STARBOARD)

// quic::ParsedQuicVersion that should be used to connect to the QUIC
// server if Job uses QUIC.
quic::ParsedQuicVersion quic_version_;
Expand Down Expand Up @@ -515,8 +525,14 @@ class HttpStreamFactory::JobFactory {
bool enable_ip_based_pooling,
NetLog* net_log,
NextProto alternative_protocol = kProtoUnknown,
#if defined(STARBOARD)
quic::ParsedQuicVersion quic_version =
quic::ParsedQuicVersion::Unsupported(),
bool protocol_filter_override = false);
#else
quic::ParsedQuicVersion quic_version =
quic::ParsedQuicVersion::Unsupported());
#endif // defined(STARBOARD)
};

} // namespace net
Expand Down
Loading

0 comments on commit 9e61e55

Please sign in to comment.