in netwerk/protocol/http/nsHttpHandler.cpp [1150:1940]
void nsHttpHandler::PrefsChanged(const char* pref) {
nsresult rv = NS_OK;
int32_t val;
LOG(("nsHttpHandler::PrefsChanged [pref=%s]\n", pref));
if (pref) {
gIOService->NotifySocketProcessPrefsChanged(pref);
}
#define PREF_CHANGED(p) ((pref == nullptr) || !strcmp(pref, p))
#define MULTI_PREF_CHANGED(p) \
((pref == nullptr) || !strncmp(pref, p, sizeof(p) - 1))
// If a security pref changed, lets clear our connection pool reuse
if (MULTI_PREF_CHANGED(SECURITY_PREFIX)) {
LOG(("nsHttpHandler::PrefsChanged Security Pref Changed %s\n", pref));
if (mConnMgr) {
rv = mConnMgr->DoShiftReloadConnectionCleanup();
if (NS_FAILED(rv)) {
LOG(
("nsHttpHandler::PrefsChanged "
"DoShiftReloadConnectionCleanup failed (%08x)\n",
static_cast<uint32_t>(rv)));
}
rv = mConnMgr->PruneDeadConnections();
if (NS_FAILED(rv)) {
LOG(
("nsHttpHandler::PrefsChanged "
"PruneDeadConnections failed (%08x)\n",
static_cast<uint32_t>(rv)));
}
}
}
//
// UA components
//
bool cVar = false;
if (PREF_CHANGED(UA_PREF("compatMode.firefox"))) {
rv = Preferences::GetBool(UA_PREF("compatMode.firefox"), &cVar);
mCompatFirefoxEnabled = (NS_SUCCEEDED(rv) && cVar);
mUserAgentIsDirty = true;
}
// general.useragent.override
if (PREF_CHANGED(UA_PREF("override"))) {
Preferences::GetCString(UA_PREF("override"), mUserAgentOverride);
mUserAgentIsDirty = true;
}
#ifdef ANDROID
// general.useragent.use_device
if (PREF_CHANGED(UA_PREF("use_device"))) {
if (Preferences::GetBool(UA_PREF("use_device"), false)) {
if (!XRE_IsSocketProcess()) {
mDeviceModelId = mozilla::net::GetDeviceModelId();
if (gIOService->SocketProcessReady()) {
RefPtr<SocketProcessParent> socketParent =
SocketProcessParent::GetSingleton();
Unused << socketParent->SendUpdateDeviceModelId(mDeviceModelId);
}
}
} else {
mDeviceModelId.Truncate();
}
mUserAgentIsDirty = true;
}
#endif
//
// HTTP options
//
if (PREF_CHANGED(HTTP_PREF("keep-alive.timeout"))) {
rv = Preferences::GetInt(HTTP_PREF("keep-alive.timeout"), &val);
if (NS_SUCCEEDED(rv)) {
mIdleTimeout = PR_SecondsToInterval(std::clamp(val, 1, 0xffff));
}
}
if (PREF_CHANGED(HTTP_PREF("request.max-attempts"))) {
rv = Preferences::GetInt(HTTP_PREF("request.max-attempts"), &val);
if (NS_SUCCEEDED(rv)) {
mMaxRequestAttempts = (uint16_t)std::clamp(val, 1, 0xffff);
}
}
if (PREF_CHANGED(HTTP_PREF("request.max-start-delay"))) {
rv = Preferences::GetInt(HTTP_PREF("request.max-start-delay"), &val);
if (NS_SUCCEEDED(rv)) {
mMaxRequestDelay = (uint16_t)std::clamp(val, 0, 0xffff);
if (mConnMgr) {
rv = mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_REQUEST_DELAY,
mMaxRequestDelay);
if (NS_FAILED(rv)) {
LOG(
("nsHttpHandler::PrefsChanged (request.max-start-delay)"
"UpdateParam failed (%08x)\n",
static_cast<uint32_t>(rv)));
}
}
}
}
if (PREF_CHANGED(HTTP_PREF("response.timeout"))) {
rv = Preferences::GetInt(HTTP_PREF("response.timeout"), &val);
if (NS_SUCCEEDED(rv)) {
mResponseTimeout = PR_SecondsToInterval(std::clamp(val, 0, 0xffff));
}
}
if (PREF_CHANGED(HTTP_PREF("network-changed.timeout"))) {
rv = Preferences::GetInt(HTTP_PREF("network-changed.timeout"), &val);
if (NS_SUCCEEDED(rv)) {
mNetworkChangedTimeout = std::clamp(val, 1, 600) * 1000;
}
}
if (PREF_CHANGED(HTTP_PREF("max-connections"))) {
rv = Preferences::GetInt(HTTP_PREF("max-connections"), &val);
if (NS_SUCCEEDED(rv)) {
mMaxConnections =
(uint16_t)std::clamp((uint32_t)val, (uint32_t)1, MaxSocketCount());
if (mConnMgr) {
rv = mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS,
mMaxConnections);
if (NS_FAILED(rv)) {
LOG(
("nsHttpHandler::PrefsChanged (max-connections)"
"UpdateParam failed (%08x)\n",
static_cast<uint32_t>(rv)));
}
}
}
}
if (PREF_CHANGED(
HTTP_PREF("max-urgent-start-excessive-connections-per-host"))) {
rv = Preferences::GetInt(
HTTP_PREF("max-urgent-start-excessive-connections-per-host"), &val);
if (NS_SUCCEEDED(rv)) {
mMaxUrgentExcessiveConns = (uint8_t)std::clamp(val, 1, 0xff);
if (mConnMgr) {
rv = mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_URGENT_START_Q,
mMaxUrgentExcessiveConns);
if (NS_FAILED(rv)) {
LOG(
("nsHttpHandler::PrefsChanged "
"(max-urgent-start-excessive-connections-per-host)"
"UpdateParam failed (%08x)\n",
static_cast<uint32_t>(rv)));
}
}
}
}
if (PREF_CHANGED(HTTP_PREF("max-persistent-connections-per-server"))) {
rv = Preferences::GetInt(HTTP_PREF("max-persistent-connections-per-server"),
&val);
if (NS_SUCCEEDED(rv)) {
mMaxPersistentConnectionsPerServer = (uint8_t)std::clamp(val, 1, 0xff);
if (mConnMgr) {
rv = mConnMgr->UpdateParam(
nsHttpConnectionMgr::MAX_PERSISTENT_CONNECTIONS_PER_HOST,
mMaxPersistentConnectionsPerServer);
if (NS_FAILED(rv)) {
LOG(
("nsHttpHandler::PrefsChanged "
"(max-persistent-connections-per-server)"
"UpdateParam failed (%08x)\n",
static_cast<uint32_t>(rv)));
}
}
}
}
if (PREF_CHANGED(HTTP_PREF("max-persistent-connections-per-proxy"))) {
rv = Preferences::GetInt(HTTP_PREF("max-persistent-connections-per-proxy"),
&val);
if (NS_SUCCEEDED(rv)) {
mMaxPersistentConnectionsPerProxy = (uint8_t)std::clamp(val, 1, 0xff);
if (mConnMgr) {
rv = mConnMgr->UpdateParam(
nsHttpConnectionMgr::MAX_PERSISTENT_CONNECTIONS_PER_PROXY,
mMaxPersistentConnectionsPerProxy);
if (NS_FAILED(rv)) {
LOG(
("nsHttpHandler::PrefsChanged "
"(max-persistent-connections-per-proxy)"
"UpdateParam failed (%08x)\n",
static_cast<uint32_t>(rv)));
}
}
}
}
if (PREF_CHANGED(HTTP_PREF("redirection-limit"))) {
rv = Preferences::GetInt(HTTP_PREF("redirection-limit"), &val);
if (NS_SUCCEEDED(rv)) mRedirectionLimit = (uint8_t)std::clamp(val, 0, 0xff);
}
if (PREF_CHANGED(HTTP_PREF("connection-retry-timeout"))) {
rv = Preferences::GetInt(HTTP_PREF("connection-retry-timeout"), &val);
if (NS_SUCCEEDED(rv)) mIdleSynTimeout = (uint16_t)std::clamp(val, 0, 3000);
}
if (PREF_CHANGED(HTTP_PREF("fast-fallback-to-IPv4"))) {
rv = Preferences::GetBool(HTTP_PREF("fast-fallback-to-IPv4"), &cVar);
if (NS_SUCCEEDED(rv)) mFastFallbackToIPv4 = cVar;
}
if (PREF_CHANGED(HTTP_PREF("fallback-connection-timeout"))) {
rv = Preferences::GetInt(HTTP_PREF("fallback-connection-timeout"), &val);
if (NS_SUCCEEDED(rv)) {
mFallbackSynTimeout = (uint16_t)std::clamp(val, 0, 10 * 60);
}
}
if (PREF_CHANGED(HTTP_PREF("version"))) {
nsAutoCString httpVersion;
Preferences::GetCString(HTTP_PREF("version"), httpVersion);
if (!httpVersion.IsVoid()) {
if (httpVersion.EqualsLiteral("1.1")) {
mHttpVersion = HttpVersion::v1_1;
} else if (httpVersion.EqualsLiteral("0.9")) {
mHttpVersion = HttpVersion::v0_9;
} else {
mHttpVersion = HttpVersion::v1_0;
}
}
}
if (PREF_CHANGED(HTTP_PREF("proxy.version"))) {
nsAutoCString httpVersion;
Preferences::GetCString(HTTP_PREF("proxy.version"), httpVersion);
if (!httpVersion.IsVoid()) {
if (httpVersion.EqualsLiteral("1.1")) {
mProxyHttpVersion = HttpVersion::v1_1;
} else {
mProxyHttpVersion = HttpVersion::v1_0;
}
// it does not make sense to issue a HTTP/0.9 request to a proxy server
}
}
if (PREF_CHANGED(HTTP_PREF("proxy.respect-be-conservative"))) {
rv =
Preferences::GetBool(HTTP_PREF("proxy.respect-be-conservative"), &cVar);
if (NS_SUCCEEDED(rv)) {
mBeConservativeForProxy = cVar;
if (mConnMgr) {
Unused << mConnMgr->UpdateParam(
nsHttpConnectionMgr::PROXY_BE_CONSERVATIVE,
static_cast<int32_t>(mBeConservativeForProxy));
}
}
}
if (PREF_CHANGED(HTTP_PREF("qos"))) {
rv = Preferences::GetInt(HTTP_PREF("qos"), &val);
if (NS_SUCCEEDED(rv)) mQoSBits = (uint8_t)std::clamp(val, 0, 0xff);
}
if (PREF_CHANGED(HTTP_PREF("accept-encoding"))) {
nsAutoCString acceptEncodings;
rv = Preferences::GetCString(HTTP_PREF("accept-encoding"), acceptEncodings);
if (NS_SUCCEEDED(rv)) {
rv = SetAcceptEncodings(acceptEncodings.get(), false);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
}
if (PREF_CHANGED(HTTP_PREF("accept-encoding.secure"))) {
nsAutoCString acceptEncodings;
rv = Preferences::GetCString(HTTP_PREF("accept-encoding.secure"),
acceptEncodings);
if (NS_SUCCEEDED(rv)) {
rv = SetAcceptEncodings(acceptEncodings.get(), true);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
}
if (PREF_CHANGED(HTTP_PREF("default-socket-type"))) {
nsAutoCString sval;
rv = Preferences::GetCString(HTTP_PREF("default-socket-type"), sval);
if (NS_SUCCEEDED(rv)) {
if (sval.IsEmpty()) {
mDefaultSocketType.SetIsVoid(true);
} else {
// verify that this socket type is actually valid
nsCOMPtr<nsISocketProviderService> sps =
nsSocketProviderService::GetOrCreate();
if (sps) {
nsCOMPtr<nsISocketProvider> sp;
rv = sps->GetSocketProvider(sval.get(), getter_AddRefs(sp));
if (NS_SUCCEEDED(rv)) {
// OK, this looks like a valid socket provider.
mDefaultSocketType.Assign(sval);
}
}
}
}
}
if (PREF_CHANGED(HTTP_PREF("prompt-temp-redirect"))) {
rv = Preferences::GetBool(HTTP_PREF("prompt-temp-redirect"), &cVar);
if (NS_SUCCEEDED(rv)) {
mPromptTempRedirect = cVar;
}
}
if (PREF_CHANGED(HTTP_PREF("assoc-req.enforce"))) {
cVar = false;
rv = Preferences::GetBool(HTTP_PREF("assoc-req.enforce"), &cVar);
if (NS_SUCCEEDED(rv)) mEnforceAssocReq = cVar;
}
// enable Persistent caching for HTTPS - bug#205921
if (PREF_CHANGED(BROWSER_PREF("disk_cache_ssl"))) {
cVar = false;
rv = Preferences::GetBool(BROWSER_PREF("disk_cache_ssl"), &cVar);
if (NS_SUCCEEDED(rv)) mEnablePersistentHttpsCaching = cVar;
}
if (PREF_CHANGED(HTTP_PREF("phishy-userpass-length"))) {
rv = Preferences::GetInt(HTTP_PREF("phishy-userpass-length"), &val);
if (NS_SUCCEEDED(rv)) {
mPhishyUserPassLength = (uint8_t)std::clamp(val, 0, 0xff);
}
}
if (PREF_CHANGED(HTTP_PREF("http2.timeout"))) {
mSpdyTimeout = PR_SecondsToInterval(
std::clamp(StaticPrefs::network_http_http2_timeout(), 1, 0xffff));
}
if (PREF_CHANGED(HTTP_PREF("http2.chunk-size"))) {
// keep this within http/2 ranges of 1 to 2^24-1
mSpdySendingChunkSize = (uint32_t)std::clamp(
StaticPrefs::network_http_http2_chunk_size(), 1, 0xffffff);
}
// The amount of idle seconds on a http2 connection before initiating a
// server ping. 0 will disable.
if (PREF_CHANGED(HTTP_PREF("http2.ping-threshold"))) {
mSpdyPingThreshold = PR_SecondsToInterval((uint16_t)std::clamp(
StaticPrefs::network_http_http2_ping_threshold(), 0, 0x7fffffff));
}
// The amount of seconds to wait for a http2 ping response before
// closing the session.
if (PREF_CHANGED(HTTP_PREF("http2.ping-timeout"))) {
mSpdyPingTimeout = PR_SecondsToInterval((uint16_t)std::clamp(
StaticPrefs::network_http_http2_ping_timeout(), 0, 0x7fffffff));
}
if (PREF_CHANGED(HTTP_PREF("altsvc.enabled"))) {
rv = Preferences::GetBool(HTTP_PREF("altsvc.enabled"), &cVar);
if (NS_SUCCEEDED(rv)) mEnableAltSvc = cVar;
}
if (PREF_CHANGED(HTTP_PREF("altsvc.oe"))) {
rv = Preferences::GetBool(HTTP_PREF("altsvc.oe"), &cVar);
if (NS_SUCCEEDED(rv)) mEnableAltSvcOE = cVar;
}
if (PREF_CHANGED(HTTP_PREF("http2.push-allowance"))) {
mSpdyPushAllowance = static_cast<uint32_t>(
std::clamp(StaticPrefs::network_http_http2_push_allowance(), 1024,
static_cast<int32_t>(ASpdySession::kInitialRwin)));
}
if (PREF_CHANGED(HTTP_PREF("http2.pull-allowance"))) {
mSpdyPullAllowance = static_cast<uint32_t>(std::clamp(
StaticPrefs::network_http_http2_pull_allowance(), 1024, 0x7fffffff));
}
if (PREF_CHANGED(HTTP_PREF("http2.default-concurrent"))) {
mDefaultSpdyConcurrent = static_cast<uint32_t>(std::max<int32_t>(
std::min<int32_t>(StaticPrefs::network_http_http2_default_concurrent(),
9999),
1));
}
// If http2.send-buffer-size is non-zero, the size to set the TCP
// sendbuffer to once the stream has surpassed this number of bytes uploaded
if (PREF_CHANGED(HTTP_PREF("http2.send-buffer-size"))) {
mSpdySendBufferSize = (uint32_t)std::clamp(
StaticPrefs::network_http_http2_send_buffer_size(), 1500, 0x7fffffff);
}
// The maximum amount of time to wait for socket transport to be
// established
if (PREF_CHANGED(HTTP_PREF("connection-timeout"))) {
rv = Preferences::GetInt(HTTP_PREF("connection-timeout"), &val);
if (NS_SUCCEEDED(rv)) {
// the pref is in seconds, but the variable is in milliseconds
mConnectTimeout = std::clamp(val, 1, 0xffff) * PR_MSEC_PER_SEC;
}
}
// The maximum amount of time to wait for a tls handshake to finish.
if (PREF_CHANGED(HTTP_PREF("tls-handshake-timeout"))) {
rv = Preferences::GetInt(HTTP_PREF("tls-handshake-timeout"), &val);
if (NS_SUCCEEDED(rv)) {
// the pref is in seconds, but the variable is in milliseconds
mTLSHandshakeTimeout = std::clamp(val, 1, 0xffff) * PR_MSEC_PER_SEC;
}
}
// The maximum number of current global half open sockets allowable
// for starting a new speculative connection.
if (PREF_CHANGED(HTTP_PREF("speculative-parallel-limit"))) {
rv = Preferences::GetInt(HTTP_PREF("speculative-parallel-limit"), &val);
if (NS_SUCCEEDED(rv)) {
mParallelSpeculativeConnectLimit = (uint32_t)std::clamp(val, 0, 1024);
}
}
// Whether or not to block requests for non head js/css items (e.g. media)
// while those elements load.
if (PREF_CHANGED(HTTP_PREF("rendering-critical-requests-prioritization"))) {
rv = Preferences::GetBool(
HTTP_PREF("rendering-critical-requests-prioritization"), &cVar);
if (NS_SUCCEEDED(rv)) mCriticalRequestPrioritization = cVar;
}
// on transition of network.http.diagnostics to true print
// a bunch of information to the console
if (pref && PREF_CHANGED(HTTP_PREF("diagnostics"))) {
rv = Preferences::GetBool(HTTP_PREF("diagnostics"), &cVar);
if (NS_SUCCEEDED(rv) && cVar) {
if (mConnMgr) mConnMgr->PrintDiagnostics();
}
}
if (PREF_CHANGED(HTTP_PREF("throttle.enable"))) {
rv = Preferences::GetBool(HTTP_PREF("throttle.enable"), &mThrottleEnabled);
if (NS_SUCCEEDED(rv) && mConnMgr) {
Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_ENABLED,
static_cast<int32_t>(mThrottleEnabled));
}
}
if (PREF_CHANGED(HTTP_PREF("throttle.suspend-for"))) {
rv = Preferences::GetInt(HTTP_PREF("throttle.suspend-for"), &val);
mThrottleSuspendFor = (uint32_t)std::clamp(val, 0, 120000);
if (NS_SUCCEEDED(rv) && mConnMgr) {
Unused << mConnMgr->UpdateParam(
nsHttpConnectionMgr::THROTTLING_SUSPEND_FOR, mThrottleSuspendFor);
}
}
if (PREF_CHANGED(HTTP_PREF("throttle.resume-for"))) {
rv = Preferences::GetInt(HTTP_PREF("throttle.resume-for"), &val);
mThrottleResumeFor = (uint32_t)std::clamp(val, 0, 120000);
if (NS_SUCCEEDED(rv) && mConnMgr) {
Unused << mConnMgr->UpdateParam(
nsHttpConnectionMgr::THROTTLING_RESUME_FOR, mThrottleResumeFor);
}
}
if (PREF_CHANGED(HTTP_PREF("throttle.hold-time-ms"))) {
rv = Preferences::GetInt(HTTP_PREF("throttle.hold-time-ms"), &val);
mThrottleHoldTime = (uint32_t)std::clamp(val, 0, 120000);
if (NS_SUCCEEDED(rv) && mConnMgr) {
Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_HOLD_TIME,
mThrottleHoldTime);
}
}
if (PREF_CHANGED(HTTP_PREF("throttle.max-time-ms"))) {
rv = Preferences::GetInt(HTTP_PREF("throttle.max-time-ms"), &val);
mThrottleMaxTime = (uint32_t)std::clamp(val, 0, 120000);
if (NS_SUCCEEDED(rv) && mConnMgr) {
Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_MAX_TIME,
mThrottleMaxTime);
}
}
if (PREF_CHANGED(HTTP_PREF("send_window_size"))) {
Unused << Preferences::GetInt(HTTP_PREF("send_window_size"), &val);
mSendWindowSize = val >= 0 ? val : 0;
}
if (PREF_CHANGED(HTTP_PREF("on_click_priority"))) {
Unused << Preferences::GetBool(HTTP_PREF("on_click_priority"),
&mUrgentStartEnabled);
}
if (PREF_CHANGED(HTTP_PREF("tailing.enabled"))) {
Unused << Preferences::GetBool(HTTP_PREF("tailing.enabled"),
&mTailBlockingEnabled);
}
if (PREF_CHANGED(HTTP_PREF("tailing.delay-quantum"))) {
val = StaticPrefs::network_http_tailing_delay_quantum();
mTailDelayQuantum = (uint32_t)std::clamp(val, 0, 60000);
}
if (PREF_CHANGED(HTTP_PREF("tailing.delay-quantum-after-domcontentloaded"))) {
val = StaticPrefs::
network_http_tailing_delay_quantum_after_domcontentloaded();
mTailDelayQuantumAfterDCL = (uint32_t)std::clamp(val, 0, 60000);
}
if (PREF_CHANGED(HTTP_PREF("tailing.delay-max"))) {
val = StaticPrefs::network_http_tailing_delay_max();
mTailDelayMax = (uint32_t)std::clamp(val, 0, 60000);
}
if (PREF_CHANGED(HTTP_PREF("tailing.total-max"))) {
val = StaticPrefs::network_http_tailing_total_max();
mTailTotalMax = (uint32_t)std::clamp(val, 0, 60000);
}
if (PREF_CHANGED(HTTP_PREF("focused_window_transaction_ratio"))) {
float ratio = 0;
rv = Preferences::GetFloat(HTTP_PREF("focused_window_transaction_ratio"),
&ratio);
if (NS_SUCCEEDED(rv)) {
if (ratio > 0 && ratio < 1) {
mFocusedWindowTransactionRatio = ratio;
} else {
NS_WARNING("Wrong value for focused_window_transaction_ratio");
}
}
}
//
// INTL options
//
if (PREF_CHANGED(INTL_ACCEPT_LANGUAGES)) {
// We don't want to set the new accept languages here since
// this pref is a complex type and it may be racy with flushing
// string resources.
mAcceptLanguagesIsDirty = true;
}
//
// Tracking options
//
// Hint option
if (PREF_CHANGED(SAFE_HINT_HEADER_VALUE)) {
cVar = false;
rv = Preferences::GetBool(SAFE_HINT_HEADER_VALUE, &cVar);
if (NS_SUCCEEDED(rv)) {
mSafeHintEnabled = cVar;
}
}
// toggle to true anytime a token bucket related pref is changed.. that
// includes telemetry and allow-experiments because of the abtest profile
bool requestTokenBucketUpdated = false;
// "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256" is the required h2 interop
// suite.
if (PREF_CHANGED(H2MANDATORY_SUITE)) {
cVar = false;
rv = Preferences::GetBool(H2MANDATORY_SUITE, &cVar);
if (NS_SUCCEEDED(rv)) {
mH2MandatorySuiteEnabled = cVar;
}
}
// network.http.debug-observations
if (PREF_CHANGED("network.http.debug-observations")) {
cVar = false;
rv = Preferences::GetBool("network.http.debug-observations", &cVar);
if (NS_SUCCEEDED(rv)) {
mDebugObservations = cVar;
}
}
if (PREF_CHANGED(HTTP_PREF("pacing.requests.enabled"))) {
rv = Preferences::GetBool(HTTP_PREF("pacing.requests.enabled"), &cVar);
if (NS_SUCCEEDED(rv)) {
mRequestTokenBucketEnabled = cVar;
requestTokenBucketUpdated = true;
}
}
if (PREF_CHANGED(HTTP_PREF("pacing.requests.min-parallelism"))) {
rv =
Preferences::GetInt(HTTP_PREF("pacing.requests.min-parallelism"), &val);
if (NS_SUCCEEDED(rv)) {
mRequestTokenBucketMinParallelism =
static_cast<uint16_t>(std::clamp(val, 1, 1024));
requestTokenBucketUpdated = true;
}
}
if (PREF_CHANGED(HTTP_PREF("pacing.requests.hz"))) {
rv = Preferences::GetInt(HTTP_PREF("pacing.requests.hz"), &val);
if (NS_SUCCEEDED(rv)) {
mRequestTokenBucketHz = static_cast<uint32_t>(std::clamp(val, 1, 10000));
requestTokenBucketUpdated = true;
}
}
if (PREF_CHANGED(HTTP_PREF("pacing.requests.burst"))) {
rv = Preferences::GetInt(HTTP_PREF("pacing.requests.burst"), &val);
if (NS_SUCCEEDED(rv)) {
mRequestTokenBucketBurst = val ? val : 1;
requestTokenBucketUpdated = true;
}
}
if (requestTokenBucketUpdated) {
MakeNewRequestTokenBucket();
}
// Keepalive values for initial and idle connections.
if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.short_lived_connections"))) {
rv = Preferences::GetBool(
HTTP_PREF("tcp_keepalive.short_lived_connections"), &cVar);
if (NS_SUCCEEDED(rv) && cVar != mTCPKeepaliveShortLivedEnabled) {
mTCPKeepaliveShortLivedEnabled = cVar;
}
}
if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.short_lived_time"))) {
rv = Preferences::GetInt(HTTP_PREF("tcp_keepalive.short_lived_time"), &val);
if (NS_SUCCEEDED(rv) && val > 0) {
mTCPKeepaliveShortLivedTimeS = std::clamp(val, 1, 300); // Max 5 mins.
}
}
if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.short_lived_idle_time"))) {
rv = Preferences::GetInt(HTTP_PREF("tcp_keepalive.short_lived_idle_time"),
&val);
if (NS_SUCCEEDED(rv) && val > 0) {
mTCPKeepaliveShortLivedIdleTimeS = std::clamp(val, 1, kMaxTCPKeepIdle);
}
}
// Keepalive values for Long-lived Connections.
if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.long_lived_connections"))) {
rv = Preferences::GetBool(HTTP_PREF("tcp_keepalive.long_lived_connections"),
&cVar);
if (NS_SUCCEEDED(rv) && cVar != mTCPKeepaliveLongLivedEnabled) {
mTCPKeepaliveLongLivedEnabled = cVar;
}
}
if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.long_lived_idle_time"))) {
rv = Preferences::GetInt(HTTP_PREF("tcp_keepalive.long_lived_idle_time"),
&val);
if (NS_SUCCEEDED(rv) && val > 0) {
mTCPKeepaliveLongLivedIdleTimeS = std::clamp(val, 1, kMaxTCPKeepIdle);
}
}
if (PREF_CHANGED(HTTP_PREF("enforce-framing.http1")) ||
PREF_CHANGED(HTTP_PREF("enforce-framing.soft")) ||
PREF_CHANGED(HTTP_PREF("enforce-framing.strict_chunked_encoding"))) {
rv = Preferences::GetBool(HTTP_PREF("enforce-framing.http1"), &cVar);
if (NS_SUCCEEDED(rv) && cVar) {
mEnforceH1Framing = FRAMECHECK_STRICT;
} else {
rv = Preferences::GetBool(
HTTP_PREF("enforce-framing.strict_chunked_encoding"), &cVar);
if (NS_SUCCEEDED(rv) && cVar) {
mEnforceH1Framing = FRAMECHECK_STRICT_CHUNKED;
} else {
rv = Preferences::GetBool(HTTP_PREF("enforce-framing.soft"), &cVar);
if (NS_SUCCEEDED(rv) && cVar) {
mEnforceH1Framing = FRAMECHECK_BARELY;
} else {
mEnforceH1Framing = FRAMECHECK_LAX;
}
}
}
}
if (PREF_CHANGED(HTTP_PREF("http2.default-hpack-buffer"))) {
mDefaultHpackBuffer =
StaticPrefs::network_http_http2_default_hpack_buffer();
}
if (PREF_CHANGED(HTTP_PREF("http3.default-qpack-table-size"))) {
rv = Preferences::GetInt(HTTP_PREF("http3.default-qpack-table-size"), &val);
if (NS_SUCCEEDED(rv)) {
mQpackTableSize = val;
}
}
if (PREF_CHANGED(HTTP_PREF("http3.default-max-stream-blocked"))) {
rv = Preferences::GetInt(HTTP_PREF("http3.default-max-stream-blocked"),
&val);
if (NS_SUCCEEDED(rv)) {
mHttp3MaxBlockedStreams = std::clamp(val, 0, 0xffff);
}
}
const bool imageAcceptPrefChanged = PREF_CHANGED("image.http.accept") ||
PREF_CHANGED("image.avif.enabled") ||
PREF_CHANGED("image.jxl.enabled");
if (imageAcceptPrefChanged) {
nsAutoCString userSetImageAcceptHeader;
if (Preferences::HasUserValue("image.http.accept")) {
rv = Preferences::GetCString("image.http.accept",
userSetImageAcceptHeader);
if (NS_FAILED(rv)) {
userSetImageAcceptHeader.Truncate();
}
}
if (userSetImageAcceptHeader.IsEmpty()) {
mImageAcceptHeader.Assign(ImageAcceptHeader());
} else {
mImageAcceptHeader.Assign(userSetImageAcceptHeader);
}
}
if (PREF_CHANGED("network.http.accept") || imageAcceptPrefChanged) {
nsAutoCString userSetDocumentAcceptHeader;
if (Preferences::HasUserValue("network.http.accept")) {
rv = Preferences::GetCString("network.http.accept",
userSetDocumentAcceptHeader);
if (NS_FAILED(rv)) {
userSetDocumentAcceptHeader.Truncate();
}
}
if (userSetDocumentAcceptHeader.IsEmpty()) {
mDocumentAcceptHeader.Assign(DocumentAcceptHeader());
} else {
mDocumentAcceptHeader.Assign(userSetDocumentAcceptHeader);
}
}
if (PREF_CHANGED(HTTP_PREF("http3.alt-svc-mapping-for-testing"))) {
nsAutoCString altSvcMappings;
rv = Preferences::GetCString(HTTP_PREF("http3.alt-svc-mapping-for-testing"),
altSvcMappings);
if (NS_SUCCEEDED(rv)) {
if (altSvcMappings.IsEmpty()) {
mAltSvcMappingTemptativeMap.Clear();
} else {
for (const nsACString& tokenSubstring :
nsCCharSeparatedTokenizer(altSvcMappings, ',').ToRange()) {
nsAutoCString token{tokenSubstring};
int32_t index = token.Find(";");
if (index != kNotFound) {
mAltSvcMappingTemptativeMap.InsertOrUpdate(
Substring(token, 0, index),
MakeUnique<nsCString>(Substring(token, index + 1)));
}
}
}
}
}
if (PREF_CHANGED(HTTP_PREF("http3.enable_qlog"))) {
// Initialize the directory.
nsCOMPtr<nsIFile> qlogDir;
if (Preferences::GetBool(HTTP_PREF("http3.enable_qlog")) &&
!mHttp3QlogDir.IsEmpty() &&
NS_SUCCEEDED(
NS_NewNativeLocalFile(mHttp3QlogDir, getter_AddRefs(qlogDir)))) {
// Here we do main thread IO, but since this only happens
// when enabling a developer feature it's not a problem for users.
rv = qlogDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
if (NS_FAILED(rv) && rv != NS_ERROR_FILE_ALREADY_EXISTS) {
NS_WARNING("Creating qlog dir failed");
}
}
}
#ifdef XP_MACOSX
if (XRE_IsParentProcess()) {
if (PREF_CHANGED(HTTP_PREF("microsoft-entra-sso.enabled"))) {
rv =
Preferences::GetBool(HTTP_PREF("microsoft-entra-sso.enabled"), &cVar);
if (NS_SUCCEEDED(rv) && cVar) {
InitMSAuthorities();
}
}
}
#endif
// Enable HTTP response timeout if TCP Keepalives are disabled.
mResponseTimeoutEnabled =
!mTCPKeepaliveShortLivedEnabled && !mTCPKeepaliveLongLivedEnabled;
#undef PREF_CHANGED
#undef MULTI_PREF_CHANGED
}