Index: chrome/browser/io_thread.cc |
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc |
index 33e2d451583a6fd3c7b9279e438b399cd9b31af9..b1eba837f2ec920a9546ca7e0037d0d0a81c3164 100644 |
--- a/chrome/browser/io_thread.cc |
+++ b/chrome/browser/io_thread.cc |
@@ -43,6 +43,7 @@ |
#include "components/data_reduction_proxy/browser/data_reduction_proxy_prefs.h" |
#include "components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.h" |
#include "components/policy/core/common/policy_service.h" |
+#include "components/variations/variations_associated_data.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/cookie_store_factory.h" |
#include "net/base/host_mapping_rules.h" |
@@ -286,6 +287,18 @@ int GetSwitchValueAsInt(const CommandLine& command_line, |
return value; |
} |
+// Returns the value associated with |key| in |params| or "" if the |
+// key is not present in the map. |
+const std::string& GetVariationParam( |
+ const std::map<std::string, std::string>& params, |
+ const std::string& key) { |
+ std::map<std::string, std::string>::const_iterator it = params.find(key); |
+ if (it == params.end()) |
+ return base::EmptyString(); |
+ |
+ return it->second; |
+} |
+ |
} // namespace |
class IOThread::LoggingNetworkChangeObserver |
@@ -934,58 +947,65 @@ void IOThread::ClearHostCache() { |
void IOThread::InitializeNetworkSessionParams( |
net::HttpNetworkSession::Params* params) { |
- params->host_resolver = globals_->host_resolver.get(); |
- params->cert_verifier = globals_->cert_verifier.get(); |
+ InitializeNetworkSessionParamsFromGlobals(*globals_, params); |
+} |
+ |
+// static |
+void IOThread::InitializeNetworkSessionParamsFromGlobals( |
+ const IOThread::Globals& globals, |
+ net::HttpNetworkSession::Params* params) { |
+ params->host_resolver = globals.host_resolver.get(); |
+ params->cert_verifier = globals.cert_verifier.get(); |
params->server_bound_cert_service = |
- globals_->system_server_bound_cert_service.get(); |
- params->transport_security_state = globals_->transport_security_state.get(); |
- params->ssl_config_service = globals_->ssl_config_service.get(); |
- params->http_auth_handler_factory = globals_->http_auth_handler_factory.get(); |
+ globals.system_server_bound_cert_service.get(); |
+ params->transport_security_state = globals.transport_security_state.get(); |
+ params->ssl_config_service = globals.ssl_config_service.get(); |
+ params->http_auth_handler_factory = globals.http_auth_handler_factory.get(); |
params->http_server_properties = |
- globals_->http_server_properties->GetWeakPtr(); |
- params->network_delegate = globals_->system_network_delegate.get(); |
- params->host_mapping_rules = globals_->host_mapping_rules.get(); |
- params->ignore_certificate_errors = globals_->ignore_certificate_errors; |
- params->testing_fixed_http_port = globals_->testing_fixed_http_port; |
- params->testing_fixed_https_port = globals_->testing_fixed_https_port; |
- |
- globals_->initial_max_spdy_concurrent_streams.CopyToIfSet( |
+ globals.http_server_properties->GetWeakPtr(); |
+ params->network_delegate = globals.system_network_delegate.get(); |
+ params->host_mapping_rules = globals.host_mapping_rules.get(); |
+ params->ignore_certificate_errors = globals.ignore_certificate_errors; |
+ params->testing_fixed_http_port = globals.testing_fixed_http_port; |
+ params->testing_fixed_https_port = globals.testing_fixed_https_port; |
+ |
+ globals.initial_max_spdy_concurrent_streams.CopyToIfSet( |
¶ms->spdy_initial_max_concurrent_streams); |
- globals_->force_spdy_single_domain.CopyToIfSet( |
+ globals.force_spdy_single_domain.CopyToIfSet( |
¶ms->force_spdy_single_domain); |
- globals_->enable_spdy_compression.CopyToIfSet( |
+ globals.enable_spdy_compression.CopyToIfSet( |
¶ms->enable_spdy_compression); |
- globals_->enable_spdy_ping_based_connection_checking.CopyToIfSet( |
+ globals.enable_spdy_ping_based_connection_checking.CopyToIfSet( |
¶ms->enable_spdy_ping_based_connection_checking); |
- globals_->spdy_default_protocol.CopyToIfSet( |
+ globals.spdy_default_protocol.CopyToIfSet( |
¶ms->spdy_default_protocol); |
- params->next_protos = globals_->next_protos; |
- globals_->trusted_spdy_proxy.CopyToIfSet(¶ms->trusted_spdy_proxy); |
- globals_->force_spdy_over_ssl.CopyToIfSet(¶ms->force_spdy_over_ssl); |
- globals_->force_spdy_always.CopyToIfSet(¶ms->force_spdy_always); |
- globals_->forced_spdy_exclusions = params->forced_spdy_exclusions; |
- globals_->use_alternate_protocols.CopyToIfSet( |
+ params->next_protos = globals.next_protos; |
+ globals.trusted_spdy_proxy.CopyToIfSet(¶ms->trusted_spdy_proxy); |
+ globals.force_spdy_over_ssl.CopyToIfSet(¶ms->force_spdy_over_ssl); |
+ globals.force_spdy_always.CopyToIfSet(¶ms->force_spdy_always); |
+ params->forced_spdy_exclusions = globals.forced_spdy_exclusions; |
+ globals.use_alternate_protocols.CopyToIfSet( |
¶ms->use_alternate_protocols); |
- globals_->enable_websocket_over_spdy.CopyToIfSet( |
+ globals.enable_websocket_over_spdy.CopyToIfSet( |
¶ms->enable_websocket_over_spdy); |
- globals_->enable_quic.CopyToIfSet(¶ms->enable_quic); |
- globals_->enable_quic_pacing.CopyToIfSet( |
+ globals.enable_quic.CopyToIfSet(¶ms->enable_quic); |
+ globals.enable_quic_pacing.CopyToIfSet( |
¶ms->enable_quic_pacing); |
- globals_->enable_quic_time_based_loss_detection.CopyToIfSet( |
+ globals.enable_quic_time_based_loss_detection.CopyToIfSet( |
¶ms->enable_quic_time_based_loss_detection); |
- globals_->enable_quic_persist_server_info.CopyToIfSet( |
- ¶ms->enable_quic_persist_server_info); |
- globals_->enable_quic_port_selection.CopyToIfSet( |
+ globals.enable_quic_port_selection.CopyToIfSet( |
¶ms->enable_quic_port_selection); |
- globals_->quic_max_packet_length.CopyToIfSet(¶ms->quic_max_packet_length); |
- globals_->quic_user_agent_id.CopyToIfSet(¶ms->quic_user_agent_id); |
- globals_->quic_supported_versions.CopyToIfSet( |
+ globals.quic_max_packet_length.CopyToIfSet(¶ms->quic_max_packet_length); |
+ globals.quic_user_agent_id.CopyToIfSet(¶ms->quic_user_agent_id); |
+ globals.quic_supported_versions.CopyToIfSet( |
¶ms->quic_supported_versions); |
- globals_->origin_to_force_quic_on.CopyToIfSet( |
+ params->quic_connection_options = globals.quic_connection_options; |
+ |
+ globals.origin_to_force_quic_on.CopyToIfSet( |
¶ms->origin_to_force_quic_on); |
params->enable_user_alternate_protocol_ports = |
- globals_->enable_user_alternate_protocol_ports; |
+ globals.enable_user_alternate_protocol_ports; |
} |
base::TimeTicks IOThread::creation_time() const { |
@@ -1061,26 +1081,42 @@ void IOThread::ConfigureQuic(const CommandLine& command_line) { |
// Always fetch the field trial group to ensure it is reported correctly. |
// The command line flags will be associated with a group that is reported |
// so long as trial is actually queried. |
- std::string quic_trial_group = |
+ std::string group = |
base::FieldTrialList::FindFullName(kQuicFieldTrialName); |
+ VariationParameters params; |
+ if (!chrome_variations::GetVariationParams(kQuicFieldTrialName, ¶ms)) { |
+ params.clear(); |
+ } |
+ |
+ ConfigureQuicGlobals(command_line, group, params, globals_); |
+} |
+// static |
+void IOThread::ConfigureQuicGlobals( |
+ const base::CommandLine& command_line, |
+ base::StringPiece quic_trial_group, |
+ const VariationParameters& quic_trial_params, |
+ IOThread::Globals* globals) { |
bool enable_quic = ShouldEnableQuic(command_line, quic_trial_group); |
- globals_->enable_quic.set(enable_quic); |
+ globals->enable_quic.set(enable_quic); |
if (enable_quic) { |
- globals_->enable_quic_pacing.set( |
- ShouldEnableQuicPacing(command_line, quic_trial_group)); |
- globals_->enable_quic_time_based_loss_detection.set( |
- ShouldEnableQuicTimeBasedLossDetection(command_line, quic_trial_group)); |
- globals_->enable_quic_persist_server_info.set( |
- ShouldEnableQuicPersistServerInfo(command_line)); |
- globals_->enable_quic_port_selection.set( |
+ globals->enable_quic_pacing.set( |
+ ShouldEnableQuicPacing(command_line, quic_trial_group, |
+ quic_trial_params)); |
+ globals->enable_quic_time_based_loss_detection.set( |
+ ShouldEnableQuicTimeBasedLossDetection(command_line, quic_trial_group, |
+ quic_trial_params)); |
+ globals->enable_quic_port_selection.set( |
ShouldEnableQuicPortSelection(command_line)); |
+ globals->quic_connection_options = |
+ GetQuicConnectionOptions(command_line, quic_trial_params); |
} |
size_t max_packet_length = GetQuicMaxPacketLength(command_line, |
- quic_trial_group); |
+ quic_trial_group, |
+ quic_trial_params); |
if (max_packet_length != 0) { |
- globals_->quic_max_packet_length.set(max_packet_length); |
+ globals->quic_max_packet_length.set(max_packet_length); |
} |
std::string quic_user_agent_id = |
@@ -1088,13 +1124,13 @@ void IOThread::ConfigureQuic(const CommandLine& command_line) { |
quic_user_agent_id.append(1, ' '); |
chrome::VersionInfo version_info; |
quic_user_agent_id.append(version_info.ProductNameAndVersionForUserAgent()); |
- globals_->quic_user_agent_id.set(quic_user_agent_id); |
+ globals->quic_user_agent_id.set(quic_user_agent_id); |
- net::QuicVersion version = GetQuicVersion(command_line); |
+ net::QuicVersion version = GetQuicVersion(command_line, quic_trial_params); |
if (version != net::QUIC_VERSION_UNSUPPORTED) { |
net::QuicVersionVector supported_versions; |
supported_versions.push_back(version); |
- globals_->quic_supported_versions.set(supported_versions); |
+ globals->quic_supported_versions.set(supported_versions); |
} |
if (command_line.HasSwitch(switches::kOriginToForceQuicOn)) { |
@@ -1102,7 +1138,7 @@ void IOThread::ConfigureQuic(const CommandLine& command_line) { |
net::HostPortPair::FromString( |
command_line.GetSwitchValueASCII(switches::kOriginToForceQuicOn)); |
if (!quic_origin.IsEmpty()) { |
- globals_->origin_to_force_quic_on.set(quic_origin); |
+ globals->origin_to_force_quic_on.set(quic_origin); |
} |
} |
} |
@@ -1130,38 +1166,82 @@ bool IOThread::ShouldEnableQuicPortSelection( |
return false; // Default to disabling port selection on all channels. |
} |
-bool IOThread::ShouldEnableQuicPacing(const CommandLine& command_line, |
- base::StringPiece quic_trial_group) { |
+bool IOThread::ShouldEnableQuicPacing( |
+ const CommandLine& command_line, |
+ base::StringPiece quic_trial_group, |
+ const VariationParameters& quic_trial_params) { |
if (command_line.HasSwitch(switches::kEnableQuicPacing)) |
return true; |
if (command_line.HasSwitch(switches::kDisableQuicPacing)) |
return false; |
+ if (LowerCaseEqualsASCII( |
+ GetVariationParam(quic_trial_params, "enable_pacing"), |
+ "true")) |
+ return true; |
+ |
return quic_trial_group.ends_with(kQuicFieldTrialPacingSuffix); |
} |
+net::QuicTagVector IOThread::GetQuicConnectionOptions( |
+ const CommandLine& command_line, |
+ const VariationParameters& quic_trial_params) { |
+ if (command_line.HasSwitch(switches::kQuicConnectionOptions)) { |
+ return ParseQuicConnectionOptions( |
+ command_line.GetSwitchValueASCII(switches::kQuicConnectionOptions)); |
+ } |
+ |
+ VariationParameters::const_iterator it = |
+ quic_trial_params.find("congestion_options"); |
+ if (it == quic_trial_params.end()) |
+ return net::QuicTagVector(); |
+ |
+ return ParseQuicConnectionOptions(it->second); |
+} |
+ |
+net::QuicTagVector IOThread::ParseQuicConnectionOptions( |
+ const std::string& connection_options) { |
+ net::QuicTagVector options; |
+ std::vector<std::string> tokens; |
+ base::SplitString(connection_options, ',', &tokens); |
+ // Tokens are expected to be no more than 4 characters long, but we |
+ // handle overflow gracefully. |
+ for (std::vector<std::string>::iterator token = tokens.begin(); |
+ token != tokens.end(); ++token) { |
+ uint32 option = 0; |
+ for (size_t i = token->length() ; i > 0; --i) { |
+ option <<= 8; |
+ option |= static_cast<unsigned char>((*token)[i - 1]); |
+ } |
+ options.push_back(static_cast<net::QuicTag>(option)); |
+ } |
+ return options; |
+} |
+ |
bool IOThread::ShouldEnableQuicTimeBasedLossDetection( |
const CommandLine& command_line, |
- base::StringPiece quic_trial_group) { |
+ base::StringPiece quic_trial_group, |
+ const VariationParameters& quic_trial_params) { |
if (command_line.HasSwitch(switches::kEnableQuicTimeBasedLossDetection)) |
return true; |
if (command_line.HasSwitch(switches::kDisableQuicTimeBasedLossDetection)) |
return false; |
+ if (LowerCaseEqualsASCII( |
+ GetVariationParam(quic_trial_params, "enable_time_based_loss_detection"), |
+ "true")) |
+ return true; |
+ |
return quic_trial_group.ends_with( |
kQuicFieldTrialTimeBasedLossDetectionSuffix); |
} |
-// TODO(rtenneti): Delete this method after the merge. |
-bool IOThread::ShouldEnableQuicPersistServerInfo( |
- const CommandLine& command_line) { |
- return true; |
-} |
- |
-size_t IOThread::GetQuicMaxPacketLength(const CommandLine& command_line, |
- base::StringPiece quic_trial_group) { |
+size_t IOThread::GetQuicMaxPacketLength( |
+ const CommandLine& command_line, |
+ base::StringPiece quic_trial_group, |
+ const VariationParameters& quic_trial_params) { |
if (command_line.HasSwitch(switches::kQuicMaxPacketLength)) { |
unsigned value; |
if (!base::StringToUint( |
@@ -1172,6 +1252,13 @@ size_t IOThread::GetQuicMaxPacketLength(const CommandLine& command_line, |
return value; |
} |
+ unsigned value; |
+ if (base::StringToUint(GetVariationParam(quic_trial_params, |
+ "max_packet_length"), |
+ &value)) { |
+ return value; |
+ } |
+ |
// Format of the packet length group names is: |
// (Https)?Enabled<length>BytePackets. |
base::StringPiece length_str(quic_trial_group); |
@@ -1186,25 +1273,31 @@ size_t IOThread::GetQuicMaxPacketLength(const CommandLine& command_line, |
return 0; |
} |
length_str.remove_suffix(strlen(kQuicFieldTrialPacketLengthSuffix)); |
- unsigned value; |
if (!base::StringToUint(length_str, &value)) { |
return 0; |
} |
return value; |
} |
-net::QuicVersion IOThread::GetQuicVersion(const CommandLine& command_line) { |
- if (!command_line.HasSwitch(switches::kQuicVersion)) { |
- return net::QUIC_VERSION_UNSUPPORTED; |
+net::QuicVersion IOThread::GetQuicVersion( |
+ const CommandLine& command_line, |
+ const VariationParameters& quic_trial_params) { |
+ if (command_line.HasSwitch(switches::kQuicVersion)) { |
+ return ParseQuicVersion( |
+ command_line.GetSwitchValueASCII(switches::kQuicVersion)); |
} |
+ |
+ return ParseQuicVersion(GetVariationParam(quic_trial_params, "quic_version")); |
+} |
+ |
+net::QuicVersion IOThread::ParseQuicVersion(const std::string& quic_version) { |
net::QuicVersionVector supported_versions = net::QuicSupportedVersions(); |
- std::string version_flag = |
- command_line.GetSwitchValueASCII(switches::kQuicVersion); |
for (size_t i = 0; i < supported_versions.size(); ++i) { |
net::QuicVersion version = supported_versions[i]; |
- if (net::QuicVersionToString(version) == version_flag) { |
+ if (net::QuicVersionToString(version) == quic_version) { |
return version; |
} |
} |
+ |
return net::QUIC_VERSION_UNSUPPORTED; |
} |