From 0b88c8dc98b6c3b88402344fb6f59fa88cb85e02 Mon Sep 17 00:00:00 2001 From: Jelle Foks Date: Fri, 9 Aug 2024 16:31:02 -0700 Subject: [PATCH] Add disable_h2 and matching h5vcc.settings This adds a command-line switch `disable_h2` that disables the HTTP/2 protocol (spdy), and a matching `h5vcc.settings` parameter 'HTTP2' (with backing by `PersistentSettings`) for run-time disabling of HTTP/2 and spdy. Similar to 'QUIC' and 'HTTP3', the setting takes effect immediately for new connections only. This also ensures that when the command-line parameter `disable_quic` or the new `disable_h2` is used, that that can not be overuled later with `5vcc.settings` or from the corresponding `PersistentSetting`. b/205134049 --- cobalt/h5vcc/h5vcc_settings.cc | 22 +++++++++++++++++----- cobalt/network/network_module.cc | 15 +++++++++++++++ cobalt/network/network_module.h | 2 ++ cobalt/network/switches.cc | 3 +++ cobalt/network/switches.h | 1 + cobalt/network/url_request_context.cc | 27 ++++++++++++++++++++------- cobalt/network/url_request_context.h | 1 + net/http/http_network_session.cc | 19 +++++++++++++++++++ net/http/http_network_session.h | 1 + 9 files changed, 79 insertions(+), 12 deletions(-) diff --git a/cobalt/h5vcc/h5vcc_settings.cc b/cobalt/h5vcc/h5vcc_settings.cc index b42ffc6e13b..0cb5ca7ef87 100644 --- a/cobalt/h5vcc/h5vcc_settings.cc +++ b/cobalt/h5vcc/h5vcc_settings.cc @@ -57,6 +57,7 @@ bool H5vccSettings::Set(const std::string& name, SetValueType value) const { const char kMediaCodecBlockList[] = "MediaCodecBlockList"; const char kNavigatorUAData[] = "NavigatorUAData"; const char kQUIC[] = "QUIC"; + const char kHTTP2[] = "HTTP2"; const char kHTTP3[] = "HTTP3"; const char kSkiaRasterizer[] = "SkiaRasterizer"; @@ -70,11 +71,6 @@ bool H5vccSettings::Set(const std::string& name, SetValueType value) const { return true; } - if (set_web_setting_func_ && value.IsType() && - set_web_setting_func_.Run(name, value.AsType())) { - return true; - } - if (name.rfind(kMediaPrefix, 0) == 0 && value.IsType()) { return media_module_ ? media_module_->SetConfiguration( @@ -100,6 +96,17 @@ bool H5vccSettings::Set(const std::string& name, SetValueType value) const { } } + if (name.compare(kHTTP2) == 0 && value.IsType()) { + if (!persistent_settings_ || !network_module_) { + return false; + } else { + persistent_settings_->Set(network::kHttp2EnabledPersistentSettingsKey, + base::Value(value.AsType() != 0)); + network_module_->SetEnableHttp2FromPersistentSettings(); + return true; + } + } + if (name.compare(kHTTP3) == 0 && value.IsType()) { if (!persistent_settings_ || !network_module_) { return false; @@ -153,6 +160,11 @@ bool H5vccSettings::Set(const std::string& name, SetValueType value) const { return true; } #endif + if (set_web_setting_func_ && value.IsType() && + set_web_setting_func_.Run(name, value.AsType())) { + return true; + } + return false; } diff --git a/cobalt/network/network_module.cc b/cobalt/network/network_module.cc index 3a0b02fc51b..8b2ec455800 100644 --- a/cobalt/network/network_module.cc +++ b/cobalt/network/network_module.cc @@ -120,6 +120,20 @@ void NetworkModule::SetEnableQuicFromPersistentSettings() { } } +void NetworkModule::SetEnableHttp2FromPersistentSettings() { + // Called on initialization and when the persistent setting is changed. + if (options_.persistent_settings != nullptr) { + base::Value value; + options_.persistent_settings->Get(kHttp2EnabledPersistentSettingsKey, + &value); + bool enable_http2 = value.GetIfBool().value_or(true); + task_runner()->PostTask( + FROM_HERE, + base::Bind(&URLRequestContext::SetEnableHttp2, + base::Unretained(url_request_context_.get()), enable_http2)); + } +} + void NetworkModule::SetEnableHttp3FromPersistentSettings() { // Called on initialization and when the persistent setting is changed. if (options_.persistent_settings != nullptr) { @@ -233,6 +247,7 @@ void NetworkModule::Initialize(const std::string& user_agent_string, url_request_context_.get(), thread_.get()); SetEnableQuicFromPersistentSettings(); + SetEnableHttp2FromPersistentSettings(); SetEnableHttp3FromPersistentSettings(); } diff --git a/cobalt/network/network_module.h b/cobalt/network/network_module.h index 01f13fe8a2a..e0151d69013 100644 --- a/cobalt/network/network_module.h +++ b/cobalt/network/network_module.h @@ -59,6 +59,7 @@ enum ClientHintHeadersCallType : int32_t { constexpr int32_t kEnabledClientHintHeaders = (kCallTypeLoader | kCallTypeXHR); const char kQuicEnabledPersistentSettingsKey[] = "QUICEnabled"; +const char kHttp2EnabledPersistentSettingsKey[] = "HTTP2Enabled"; const char kHttp3EnabledPersistentSettingsKey[] = "HTTP3Enabled"; class NetworkSystem; @@ -130,6 +131,7 @@ class NetworkModule : public base::CurrentThread::DestructionObserver { void SetProxy(const std::string& custom_proxy_rules); void SetEnableQuicFromPersistentSettings(); + void SetEnableHttp2FromPersistentSettings(); void SetEnableHttp3FromPersistentSettings(); // Adds the Client Hint Headers to the provided URLFetcher if enabled. diff --git a/cobalt/network/switches.cc b/cobalt/network/switches.cc index d7280d10c4f..c547ce07195 100644 --- a/cobalt/network/switches.cc +++ b/cobalt/network/switches.cc @@ -44,6 +44,9 @@ const char kDisableInAppDial[] = "disable_in_app_dial"; // Switch to disable use of the Quic network protocol. const char kDisableQuic[] = "disable_quic"; +// Switch to disable use of the HTTP/2 (SPDY) network protocol. +const char kDisableHttp2[] = "disable_h2"; + } // namespace switches } // namespace network diff --git a/cobalt/network/switches.h b/cobalt/network/switches.h index 6def908bdb6..83b842bc879 100644 --- a/cobalt/network/switches.h +++ b/cobalt/network/switches.h @@ -28,6 +28,7 @@ extern const char kMaxNetworkDelayHelp[]; extern const char kDisableInAppDial[]; #endif // ENABLE_DEBUG_COMMAND_LINE_SWITCHES extern const char kDisableQuic[]; +extern const char kDisableHttp2[]; } // namespace switches } // namespace network diff --git a/cobalt/network/url_request_context.cc b/cobalt/network/url_request_context.cc index 325d81b162e..666cf4fe8b0 100644 --- a/cobalt/network/url_request_context.cc +++ b/cobalt/network/url_request_context.cc @@ -209,17 +209,17 @@ URLRequestContext::URLRequestContext( quic::ParsedQuicVersionVector{quic::ParsedQuicVersion::Q046()}; url_request_context_builder->set_quic_context(std::move(quic_context)); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); bool quic_enabled = - configuration::Configuration::GetInstance()->CobaltEnableQuic(); - if (quic_enabled) { - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - quic_enabled = !command_line->HasSwitch(switches::kDisableQuic); - } + configuration::Configuration::GetInstance()->CobaltEnableQuic() && + !command_line->HasSwitch(switches::kDisableQuic); + bool spdy_enabled = !command_line->HasSwitch(switches::kDisableHttp2); - url_request_context_builder->SetSpdyAndQuicEnabled(/*spdy_enabled=*/true, + url_request_context_builder->SetSpdyAndQuicEnabled(spdy_enabled, quic_enabled); net::HttpNetworkSessionParams params; + params.enable_http2 = spdy_enabled; params.enable_quic = quic_enabled; params.use_quic_for_unknown_origins = quic_enabled; @@ -329,7 +329,20 @@ void URLRequestContext::SetProxy(const std::string& proxy_rules) { void URLRequestContext::SetEnableQuic(bool enable_quic) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - url_request_context_->http_network_session()->SetEnableQuic(enable_quic); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + bool quic_commandline_enabled = + !command_line->HasSwitch(switches::kDisableQuic); + url_request_context_->http_network_session()->SetEnableQuic( + enable_quic && quic_commandline_enabled); +} + +void URLRequestContext::SetEnableHttp2(bool enable_http2) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + bool http2_commandline_enabled = + !command_line->HasSwitch(switches::kDisableHttp2); + url_request_context_->http_network_session()->SetEnableHttp2( + enable_http2 && http2_commandline_enabled); } bool URLRequestContext::using_http_cache() { return using_http_cache_; } diff --git a/cobalt/network/url_request_context.h b/cobalt/network/url_request_context.h index dd987e472bf..4f93aface53 100644 --- a/cobalt/network/url_request_context.h +++ b/cobalt/network/url_request_context.h @@ -60,6 +60,7 @@ class URLRequestContext { void SetProxy(const std::string& custom_proxy_rules); void SetEnableQuic(bool enable_quic); + void SetEnableHttp2(bool enable_http2); bool using_http_cache(); diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 093e8a5486f..92b40b6fd8e 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc @@ -373,6 +373,25 @@ void HttpNetworkSession::DisableQuic() { void HttpNetworkSession::SetEnableQuic(bool enable_quic) { params_.enable_quic = enable_quic; } +void HttpNetworkSession::SetEnableHttp2(bool enable_http2) { + if (params_.enable_http2 == enable_http2) { + return; + } + params_.enable_http2 = enable_http2; + + if (params_.enable_http2) { + next_protos_.push_back(kProtoHTTP2); + if (base::FeatureList::IsEnabled(features::kAlpsForHttp2)) { + // Enable ALPS for HTTP/2 with empty data. + application_settings_[kProtoHTTP2] = {}; + } + } else { + if (next_protos_.back() == kProtoHTTP2) { + next_protos_.pop_back(); + } + application_settings_.erase(kProtoHTTP2); + } +} bool HttpNetworkSession::UseQuicForUnknownOrigin() const { return params_.use_quic_for_unknown_origins; diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index 7636bb3e85d..813d86cda42 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h @@ -315,6 +315,7 @@ class NET_EXPORT HttpNetworkSession { #if defined(STARBOARD) void SetEnableQuic(bool enable_quic); + void SetEnableHttp2(bool enable_http2); // Whether to try QUIC connection for origins without alt-svc on record. bool UseQuicForUnknownOrigin() const;