Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim:set ts=4 sw=2 sts=2 et cin: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
* License, v. 2.0. If a copy of the MPL was not distributed with this
5
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
// HttpLog.h should generally be included first
8
#include "HttpLog.h"
9
10
#include "prsystem.h"
11
12
#include "nsError.h"
13
#include "nsHttp.h"
14
#include "nsHttpHandler.h"
15
#include "nsHttpChannel.h"
16
#include "nsHttpAuthCache.h"
17
#include "nsStandardURL.h"
18
#include "nsIDOMWindow.h"
19
#include "nsIHttpChannel.h"
20
#include "nsIStandardURL.h"
21
#include "LoadContextInfo.h"
22
#include "nsCategoryManagerUtils.h"
23
#include "nsIPrefService.h"
24
#include "nsIPrefBranch.h"
25
#include "nsIPrefLocalizedString.h"
26
#include "nsSocketProviderService.h"
27
#include "nsISocketProvider.h"
28
#include "nsPrintfCString.h"
29
#include "nsCOMPtr.h"
30
#include "nsNetCID.h"
31
#include "mozilla/ClearOnShutdown.h"
32
#include "mozilla/Printf.h"
33
#include "mozilla/Sprintf.h"
34
#include "mozilla/StaticPrefs_network.h"
35
#include "mozilla/StaticPrefs_privacy.h"
36
#include "nsAsyncRedirectVerifyHelper.h"
37
#include "nsSocketTransportService2.h"
38
#include "nsAlgorithm.h"
39
#include "ASpdySession.h"
40
#include "EventTokenBucket.h"
41
#include "Tickler.h"
42
#include "nsIXULAppInfo.h"
43
#include "nsICookieService.h"
44
#include "nsIObserverService.h"
45
#include "nsISiteSecurityService.h"
46
#include "nsIStreamConverterService.h"
47
#include "nsCRT.h"
48
#include "nsIMemoryReporter.h"
49
#include "nsIParentalControlsService.h"
50
#include "nsPIDOMWindow.h"
51
#include "nsINetworkLinkService.h"
52
#include "nsHttpChannelAuthProvider.h"
53
#include "nsNetUtil.h"
54
#include "nsServiceManagerUtils.h"
55
#include "nsComponentManagerUtils.h"
56
#include "nsSocketTransportService2.h"
57
#include "nsIOService.h"
58
#include "nsISupportsPrimitives.h"
59
#include "nsIXULRuntime.h"
60
#include "nsCharSeparatedTokenizer.h"
61
#include "nsRFPService.h"
62
#include "rust-helper/src/helper.h"
63
64
#include "mozilla/net/NeckoChild.h"
65
#include "mozilla/net/NeckoParent.h"
66
#include "mozilla/net/RequestContextService.h"
67
#include "mozilla/ipc/URIUtils.h"
68
#include "mozilla/Telemetry.h"
69
#include "mozilla/Unused.h"
70
#include "mozilla/BasePrincipal.h"
71
#include "mozilla/LazyIdleThread.h"
72
73
#include "mozilla/dom/ContentParent.h"
74
#include "mozilla/dom/Navigator.h"
75
#include "mozilla/dom/Promise.h"
76
#include "mozilla/dom/network/Connection.h"
77
78
#include "nsNSSComponent.h"
79
80
#if defined(XP_UNIX)
81
# include <sys/utsname.h>
82
#endif
83
84
#if defined(XP_WIN)
85
# include <windows.h>
86
# include "mozilla/WindowsVersion.h"
87
#endif
88
89
#if defined(XP_MACOSX)
90
# include <CoreServices/CoreServices.h>
91
# include "nsCocoaFeatures.h"
92
#endif
93
94
#ifdef MOZ_TASK_TRACER
95
# include "GeckoTaskTracer.h"
96
#endif
97
98
//-----------------------------------------------------------------------------
99
#include "mozilla/net/HttpChannelChild.h"
100
101
#define UA_PREF_PREFIX "general.useragent."
102
#ifdef XP_WIN
103
# define UA_SPARE_PLATFORM
104
#endif
105
106
#define HTTP_PREF_PREFIX "network.http."
107
#define INTL_ACCEPT_LANGUAGES "intl.accept_languages"
108
#define BROWSER_PREF_PREFIX "browser.cache."
109
#define H2MANDATORY_SUITE "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256"
110
#define SAFE_HINT_HEADER_VALUE "safeHint.enabled"
111
#define SECURITY_PREFIX "security."
112
#define DOM_SECURITY_PREFIX "dom.security"
113
#define TCP_FAST_OPEN_ENABLE "network.tcp.tcp_fastopen_enable"
114
#define TCP_FAST_OPEN_FAILURE_LIMIT \
115
"network.tcp.tcp_fastopen_consecutive_failure_limit"
116
#define TCP_FAST_OPEN_STALLS_LIMIT "network.tcp.tcp_fastopen_http_stalls_limit"
117
#define TCP_FAST_OPEN_STALLS_IDLE \
118
"network.tcp.tcp_fastopen_http_check_for_stalls_only_if_idle_for"
119
#define TCP_FAST_OPEN_STALLS_TIMEOUT \
120
"network.tcp.tcp_fastopen_http_stalls_timeout"
121
122
#define ACCEPT_HEADER_NAVIGATION \
123
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
124
#define ACCEPT_HEADER_IMAGE "image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5"
125
#define ACCEPT_HEADER_STYLE "text/css,*/*;q=0.1"
126
#define ACCEPT_HEADER_ALL "*/*"
127
128
#define UA_PREF(_pref) UA_PREF_PREFIX _pref
129
#define HTTP_PREF(_pref) HTTP_PREF_PREFIX _pref
130
#define BROWSER_PREF(_pref) BROWSER_PREF_PREFIX _pref
131
132
#define NS_HTTP_PROTOCOL_FLAGS \
133
(URI_STD | ALLOWS_PROXY | ALLOWS_PROXY_HTTP | URI_LOADABLE_BY_ANYONE)
134
135
//-----------------------------------------------------------------------------
136
137
using mozilla::dom::Promise;
138
using mozilla::Telemetry::LABELS_NETWORK_HTTP_REDIRECT_TO_SCHEME;
139
140
namespace mozilla {
141
namespace net {
142
143
LazyLogModule gHttpLog("nsHttp");
144
145
#ifdef ANDROID
146
static nsCString GetDeviceModelId() {
147
// Assumed to be running on the main thread
148
// We need the device property in either case
149
nsAutoCString deviceModelId;
150
nsCOMPtr<nsIPropertyBag2> infoService =
151
do_GetService("@mozilla.org/system-info;1");
152
MOZ_ASSERT(infoService, "Could not find a system info service");
153
nsAutoString androidDevice;
154
nsresult rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("device"),
155
androidDevice);
156
if (NS_SUCCEEDED(rv)) {
157
deviceModelId = NS_LossyConvertUTF16toASCII(androidDevice);
158
}
159
nsAutoCString deviceString;
160
rv = Preferences::GetCString(UA_PREF("device_string"), deviceString);
161
if (NS_SUCCEEDED(rv)) {
162
deviceString.Trim(" ", true, true);
163
deviceString.ReplaceSubstring(NS_LITERAL_CSTRING("%DEVICEID%"),
164
deviceModelId);
165
return std::move(deviceString);
166
}
167
return std::move(deviceModelId);
168
}
169
#endif
170
171
//-----------------------------------------------------------------------------
172
// nsHttpHandler <public>
173
//-----------------------------------------------------------------------------
174
175
StaticRefPtr<nsHttpHandler> gHttpHandler;
176
177
/* static */
178
already_AddRefed<nsHttpHandler> nsHttpHandler::GetInstance() {
179
if (!gHttpHandler) {
180
gHttpHandler = new nsHttpHandler();
181
DebugOnly<nsresult> rv = gHttpHandler->Init();
182
MOZ_ASSERT(NS_SUCCEEDED(rv));
183
// There is code that may be executed during the final cycle collection
184
// shutdown and still referencing gHttpHandler.
185
ClearOnShutdown(&gHttpHandler,
186
ShutdownPhase::ShutdownPostLastCycleCollection);
187
}
188
RefPtr<nsHttpHandler> httpHandler = gHttpHandler;
189
return httpHandler.forget();
190
}
191
192
nsHttpHandler::nsHttpHandler()
193
: mHttpVersion(HttpVersion::v1_1),
194
mProxyHttpVersion(HttpVersion::v1_1),
195
mCapabilities(NS_HTTP_ALLOW_KEEPALIVE),
196
mFastFallbackToIPv4(false),
197
mIdleTimeout(PR_SecondsToInterval(10)),
198
mSpdyTimeout(PR_SecondsToInterval(180)),
199
mResponseTimeout(PR_SecondsToInterval(300)),
200
mResponseTimeoutEnabled(false),
201
mNetworkChangedTimeout(5000),
202
mMaxRequestAttempts(6),
203
mMaxRequestDelay(10),
204
mIdleSynTimeout(250),
205
mFallbackSynTimeout(5),
206
mH2MandatorySuiteEnabled(false),
207
mMaxUrgentExcessiveConns(3),
208
mMaxConnections(24),
209
mMaxPersistentConnectionsPerServer(2),
210
mMaxPersistentConnectionsPerProxy(4),
211
mThrottleEnabled(true),
212
mThrottleVersion(2),
213
mThrottleSuspendFor(3000),
214
mThrottleResumeFor(200),
215
mThrottleReadLimit(8000),
216
mThrottleReadInterval(500),
217
mThrottleHoldTime(600),
218
mThrottleMaxTime(3000),
219
mSendWindowSize(1024),
220
mUrgentStartEnabled(true),
221
mTailBlockingEnabled(true),
222
mTailDelayQuantum(600),
223
mTailDelayQuantumAfterDCL(100),
224
mTailDelayMax(6000),
225
mTailTotalMax(0),
226
mRedirectionLimit(10),
227
mPhishyUserPassLength(1),
228
mQoSBits(0x00),
229
mEnforceAssocReq(false),
230
mLastUniqueID(NowInSeconds()),
231
mSessionStartTime(0),
232
mLegacyAppName("Mozilla"),
233
mLegacyAppVersion("5.0"),
234
mProduct("Gecko"),
235
mCompatFirefoxEnabled(false),
236
mUserAgentIsDirty(true),
237
mAcceptLanguagesIsDirty(true),
238
mPromptTempRedirect(true),
239
mEnablePersistentHttpsCaching(false),
240
mSafeHintEnabled(false),
241
mParentalControlEnabled(false),
242
mHandlerActive(false),
243
mDebugObservations(false),
244
mEnableSpdy(false),
245
mHttp2Enabled(true),
246
mUseH2Deps(true),
247
mEnforceHttp2TlsProfile(true),
248
mCoalesceSpdy(true),
249
mSpdyPersistentSettings(false),
250
mAllowPush(true),
251
mEnableAltSvc(false),
252
mEnableAltSvcOE(false),
253
mEnableOriginExtension(false),
254
mEnableH2Websockets(true),
255
mDumpHpackTables(false),
256
mSpdySendingChunkSize(ASpdySession::kSendingChunkSize),
257
mSpdySendBufferSize(ASpdySession::kTCPSendBufferSize),
258
mSpdyPushAllowance(131072) // match default pref
259
,
260
mSpdyPullAllowance(ASpdySession::kInitialRwin),
261
mDefaultSpdyConcurrent(ASpdySession::kDefaultMaxConcurrent),
262
mSpdyPingThreshold(PR_SecondsToInterval(58)),
263
mSpdyPingTimeout(PR_SecondsToInterval(8)),
264
mConnectTimeout(90000),
265
mTLSHandshakeTimeout(30000),
266
mParallelSpeculativeConnectLimit(6),
267
mRequestTokenBucketEnabled(true),
268
mRequestTokenBucketMinParallelism(6),
269
mRequestTokenBucketHz(100),
270
mRequestTokenBucketBurst(32),
271
mCriticalRequestPrioritization(true),
272
mRespectDocumentNoSniff(true),
273
mTCPKeepaliveShortLivedEnabled(false),
274
mTCPKeepaliveShortLivedTimeS(60),
275
mTCPKeepaliveShortLivedIdleTimeS(10),
276
mTCPKeepaliveLongLivedEnabled(false),
277
mTCPKeepaliveLongLivedIdleTimeS(600),
278
mEnforceH1Framing(FRAMECHECK_BARELY),
279
mDefaultHpackBuffer(4096),
280
mBug1563538(true),
281
mBug1563695(true),
282
mBug1556491(true),
283
mMaxHttpResponseHeaderSize(393216),
284
mFocusedWindowTransactionRatio(0.9f),
285
mSpeculativeConnectEnabled(false),
286
mUseFastOpen(true),
287
mFastOpenConsecutiveFailureLimit(5),
288
mFastOpenConsecutiveFailureCounter(0),
289
mFastOpenStallsLimit(3),
290
mFastOpenStallsCounter(0),
291
mFastOpenStallsIdleTime(10),
292
mFastOpenStallsTimeout(20),
293
mActiveTabPriority(true),
294
mProcessId(0),
295
mNextChannelId(1),
296
mLastActiveTabLoadOptimizationLock(
297
"nsHttpConnectionMgr::LastActiveTabLoadOptimization"),
298
mThroughCaptivePortal(false) {
299
LOG(("Creating nsHttpHandler [this=%p].\n", this));
300
301
mUserAgentOverride.SetIsVoid(true);
302
303
MOZ_ASSERT(!gHttpHandler, "HTTP handler already created!");
304
305
nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/runtime;1");
306
if (runtime) {
307
runtime->GetProcessID(&mProcessId);
308
}
309
SetFastOpenOSSupport();
310
}
311
312
void nsHttpHandler::SetFastOpenOSSupport() {
313
mFastOpenSupported = false;
314
#if !defined(XP_WIN) && !defined(XP_LINUX) && !defined(ANDROID) && \
315
!defined(HAS_CONNECTX)
316
return;
317
#elif defined(XP_WIN)
318
mFastOpenSupported = IsWindows10BuildOrLater(16299);
319
320
if (mFastOpenSupported) {
321
// We have some problems with lavasoft software and tcp fast open.
322
if (GetModuleHandleW(L"pmls64.dll") || GetModuleHandleW(L"rlls64.dll")) {
323
mFastOpenSupported = false;
324
}
325
}
326
#else
327
328
nsAutoCString version;
329
nsresult rv;
330
# ifdef ANDROID
331
nsCOMPtr<nsIPropertyBag2> infoService =
332
do_GetService("@mozilla.org/system-info;1");
333
MOZ_ASSERT(infoService, "Could not find a system info service");
334
rv = infoService->GetPropertyAsACString(NS_LITERAL_STRING("sdk_version"),
335
version);
336
# else
337
char buf[SYS_INFO_BUFFER_LENGTH];
338
if (PR_GetSystemInfo(PR_SI_RELEASE, buf, sizeof(buf)) == PR_SUCCESS) {
339
version = buf;
340
rv = NS_OK;
341
} else {
342
rv = NS_ERROR_FAILURE;
343
}
344
# endif
345
346
LOG(("nsHttpHandler::SetFastOpenOSSupport version %s", version.get()));
347
348
if (NS_SUCCEEDED(rv)) {
349
// set min version minus 1.
350
# if XP_MACOSX
351
int min_version[] = {17, 5}; // High Sierra 10.13.4
352
# elif ANDROID
353
int min_version[] = {4, 4};
354
# elif XP_LINUX
355
int min_version[] = {3, 6};
356
# endif
357
int inx = 0;
358
nsCCharSeparatedTokenizer tokenizer(version, '.');
359
while ((inx < 2) && tokenizer.hasMoreTokens()) {
360
nsAutoCString token(tokenizer.nextToken());
361
const char* nondigit = NS_strspnp("0123456789", token.get());
362
if (nondigit && *nondigit) {
363
break;
364
}
365
nsresult rv;
366
int32_t ver = token.ToInteger(&rv);
367
if (NS_FAILED(rv)) {
368
break;
369
}
370
if (ver > min_version[inx]) {
371
mFastOpenSupported = true;
372
break;
373
} else if (ver == min_version[inx] && inx == 1) {
374
mFastOpenSupported = true;
375
} else if (ver < min_version[inx]) {
376
break;
377
}
378
inx++;
379
}
380
}
381
#endif
382
LOG(("nsHttpHandler::SetFastOpenOSSupport %s supported.\n",
383
mFastOpenSupported ? "" : "not"));
384
}
385
386
void nsHttpHandler::EnsureUAOverridesInit() {
387
MOZ_ASSERT(XRE_IsParentProcess());
388
MOZ_ASSERT(NS_IsMainThread());
389
390
static bool initDone = false;
391
392
if (initDone) {
393
return;
394
}
395
396
nsresult rv;
397
nsCOMPtr<nsISupports> bootstrapper =
398
do_GetService("@mozilla.org/network/ua-overrides-bootstrapper;1", &rv);
399
MOZ_ASSERT(bootstrapper);
400
MOZ_ASSERT(NS_SUCCEEDED(rv));
401
initDone = true;
402
}
403
404
nsHttpHandler::~nsHttpHandler() {
405
LOG(("Deleting nsHttpHandler [this=%p]\n", this));
406
407
// make sure the connection manager is shutdown
408
if (mConnMgr) {
409
nsresult rv = mConnMgr->Shutdown();
410
if (NS_FAILED(rv)) {
411
LOG(
412
("nsHttpHandler [this=%p] "
413
"failed to shutdown connection manager (%08x)\n",
414
this, static_cast<uint32_t>(rv)));
415
}
416
mConnMgr = nullptr;
417
}
418
419
// Note: don't call NeckoChild::DestroyNeckoChild() here, as it's too late
420
// and it'll segfault. NeckoChild will get cleaned up by process exit.
421
422
nsHttp::DestroyAtomTable();
423
}
424
425
static const char* gCallbackPrefs[] = {
426
HTTP_PREF_PREFIX,
427
UA_PREF_PREFIX,
428
INTL_ACCEPT_LANGUAGES,
429
BROWSER_PREF("disk_cache_ssl"),
430
H2MANDATORY_SUITE,
431
HTTP_PREF("tcp_keepalive.short_lived_connections"),
432
HTTP_PREF("tcp_keepalive.long_lived_connections"),
433
SAFE_HINT_HEADER_VALUE,
434
SECURITY_PREFIX,
435
DOM_SECURITY_PREFIX,
436
TCP_FAST_OPEN_ENABLE,
437
TCP_FAST_OPEN_FAILURE_LIMIT,
438
TCP_FAST_OPEN_STALLS_LIMIT,
439
TCP_FAST_OPEN_STALLS_IDLE,
440
TCP_FAST_OPEN_STALLS_TIMEOUT,
441
nullptr,
442
};
443
444
nsresult nsHttpHandler::Init() {
445
nsresult rv;
446
447
LOG(("nsHttpHandler::Init\n"));
448
MOZ_ASSERT(NS_IsMainThread());
449
450
rv = nsHttp::CreateAtomTable();
451
if (NS_FAILED(rv)) return rv;
452
453
nsCOMPtr<nsIIOService> service = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
454
if (NS_FAILED(rv)) {
455
NS_WARNING("unable to continue without io service");
456
return rv;
457
}
458
mIOService = new nsMainThreadPtrHolder<nsIIOService>(
459
"nsHttpHandler::mIOService", service);
460
461
mBackgroundThread = new mozilla::LazyIdleThread(
462
10000, NS_LITERAL_CSTRING("HTTP Handler Background"));
463
464
if (IsNeckoChild()) NeckoChild::InitNeckoChild();
465
466
InitUserAgentComponents();
467
468
// This perference is only used in parent process.
469
if (!IsNeckoChild()) {
470
mActiveTabPriority =
471
Preferences::GetBool(HTTP_PREF("active_tab_priority"), true);
472
}
473
474
// monitor some preference changes
475
Preferences::RegisterPrefixCallbacks(
476
PREF_CHANGE_METHOD(nsHttpHandler::PrefsChanged), gCallbackPrefs, this);
477
PrefsChanged(nullptr);
478
479
mMisc.AssignLiteral("rv:" MOZILLA_UAVERSION);
480
481
mCompatFirefox.AssignLiteral("Firefox/" MOZILLA_UAVERSION);
482
483
nsCOMPtr<nsIXULAppInfo> appInfo =
484
do_GetService("@mozilla.org/xre/app-info;1");
485
486
mAppName.AssignLiteral(MOZ_APP_UA_NAME);
487
if (mAppName.Length() == 0 && appInfo) {
488
// Try to get the UA name from appInfo, falling back to the name
489
appInfo->GetUAName(mAppName);
490
if (mAppName.Length() == 0) {
491
appInfo->GetName(mAppName);
492
}
493
appInfo->GetVersion(mAppVersion);
494
mAppName.StripChars(R"( ()<>@,;:\"/[]?={})");
495
} else {
496
mAppVersion.AssignLiteral(MOZ_APP_UA_VERSION);
497
}
498
499
// Generate the spoofed User Agent for fingerprinting resistance.
500
nsRFPService::GetSpoofedUserAgent(mSpoofedUserAgent, true);
501
502
mSessionStartTime = NowInSeconds();
503
mHandlerActive = true;
504
505
rv = InitConnectionMgr();
506
if (NS_FAILED(rv)) return rv;
507
508
mRequestContextService = RequestContextService::GetOrCreate();
509
510
#if defined(ANDROID)
511
mProductSub.AssignLiteral(MOZILLA_UAVERSION);
512
#else
513
mProductSub.AssignLiteral(LEGACY_UA_GECKO_TRAIL);
514
#endif
515
516
#if DEBUG
517
// dump user agent prefs
518
LOG(("> legacy-app-name = %s\n", mLegacyAppName.get()));
519
LOG(("> legacy-app-version = %s\n", mLegacyAppVersion.get()));
520
LOG(("> platform = %s\n", mPlatform.get()));
521
LOG(("> oscpu = %s\n", mOscpu.get()));
522
LOG(("> misc = %s\n", mMisc.get()));
523
LOG(("> product = %s\n", mProduct.get()));
524
LOG(("> product-sub = %s\n", mProductSub.get()));
525
LOG(("> app-name = %s\n", mAppName.get()));
526
LOG(("> app-version = %s\n", mAppVersion.get()));
527
LOG(("> compat-firefox = %s\n", mCompatFirefox.get()));
528
LOG(("> user-agent = %s\n", UserAgent().get()));
529
#endif
530
531
// Startup the http category
532
// Bring alive the objects in the http-protocol-startup category
533
NS_CreateServicesFromCategory(
534
NS_HTTP_STARTUP_CATEGORY,
535
static_cast<nsISupports*>(static_cast<void*>(this)),
536
NS_HTTP_STARTUP_TOPIC);
537
538
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
539
if (obsService) {
540
// register the handler object as a weak callback as we don't need to worry
541
// about shutdown ordering.
542
obsService->AddObserver(this, "profile-change-net-teardown", true);
543
obsService->AddObserver(this, "profile-change-net-restore", true);
544
obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true);
545
obsService->AddObserver(this, "net:clear-active-logins", true);
546
obsService->AddObserver(this, "net:prune-dead-connections", true);
547
// Sent by the TorButton add-on in the Tor Browser
548
obsService->AddObserver(this, "net:prune-all-connections", true);
549
obsService->AddObserver(this, "net:cancel-all-connections", true);
550
obsService->AddObserver(this, "last-pb-context-exited", true);
551
obsService->AddObserver(this, "browser:purge-session-history", true);
552
obsService->AddObserver(this, NS_NETWORK_LINK_TOPIC, true);
553
obsService->AddObserver(this, "application-background", true);
554
obsService->AddObserver(this, "psm:user-certificate-added", true);
555
obsService->AddObserver(this, "psm:user-certificate-deleted", true);
556
obsService->AddObserver(this, "intl:app-locales-changed", true);
557
obsService->AddObserver(this, "browser-delayed-startup-finished", true);
558
obsService->AddObserver(this, "network:captive-portal-connectivity", true);
559
560
if (!IsNeckoChild()) {
561
obsService->AddObserver(
562
this, "net:current-toplevel-outer-content-windowid", true);
563
}
564
565
if (mFastOpenSupported) {
566
obsService->AddObserver(this, "captive-portal-login", true);
567
obsService->AddObserver(this, "captive-portal-login-success", true);
568
}
569
570
// disabled as its a nop right now
571
// obsService->AddObserver(this, "net:failed-to-process-uri-content", true);
572
}
573
574
MakeNewRequestTokenBucket();
575
mWifiTickler = new Tickler();
576
if (NS_FAILED(mWifiTickler->Init())) mWifiTickler = nullptr;
577
578
nsCOMPtr<nsIParentalControlsService> pc =
579
do_CreateInstance("@mozilla.org/parental-controls-service;1");
580
if (pc) {
581
pc->GetParentalControlsEnabled(&mParentalControlEnabled);
582
}
583
return NS_OK;
584
}
585
586
void nsHttpHandler::MakeNewRequestTokenBucket() {
587
LOG(("nsHttpHandler::MakeNewRequestTokenBucket this=%p child=%d\n", this,
588
IsNeckoChild()));
589
if (!mConnMgr || IsNeckoChild()) {
590
return;
591
}
592
RefPtr<EventTokenBucket> tokenBucket =
593
new EventTokenBucket(RequestTokenBucketHz(), RequestTokenBucketBurst());
594
// NOTE The thread or socket may be gone already.
595
nsresult rv = mConnMgr->UpdateRequestTokenBucket(tokenBucket);
596
if (NS_FAILED(rv)) {
597
LOG((" failed to update request token bucket\n"));
598
}
599
}
600
601
nsresult nsHttpHandler::InitConnectionMgr() {
602
// Init ConnectionManager only on parent!
603
if (IsNeckoChild()) {
604
return NS_OK;
605
}
606
607
nsresult rv;
608
609
if (!mConnMgr) {
610
mConnMgr = new nsHttpConnectionMgr();
611
}
612
613
rv = mConnMgr->Init(
614
mMaxUrgentExcessiveConns, mMaxConnections,
615
mMaxPersistentConnectionsPerServer, mMaxPersistentConnectionsPerProxy,
616
mMaxRequestDelay, mThrottleEnabled, mThrottleVersion, mThrottleSuspendFor,
617
mThrottleResumeFor, mThrottleReadLimit, mThrottleReadInterval,
618
mThrottleHoldTime, mThrottleMaxTime);
619
return rv;
620
}
621
622
nsresult nsHttpHandler::AddStandardRequestHeaders(
623
nsHttpRequestHead* request, bool isSecure,
624
nsContentPolicyType aContentPolicyType) {
625
nsresult rv;
626
627
// Add the "User-Agent" header
628
rv = request->SetHeader(nsHttp::User_Agent, UserAgent(), false,
629
nsHttpHeaderArray::eVarietyRequestDefault);
630
if (NS_FAILED(rv)) return rv;
631
632
// MIME based content negotiation lives!
633
// Add the "Accept" header. Note, this is set as an override because the
634
// service worker expects to see it. The other "default" headers are
635
// hidden from service worker interception.
636
nsAutoCString accept;
637
if (aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
638
aContentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) {
639
accept.Assign(ACCEPT_HEADER_NAVIGATION);
640
} else if (aContentPolicyType == nsIContentPolicy::TYPE_IMAGE ||
641
aContentPolicyType == nsIContentPolicy::TYPE_IMAGESET) {
642
accept.Assign(ACCEPT_HEADER_IMAGE);
643
} else if (aContentPolicyType == nsIContentPolicy::TYPE_STYLESHEET) {
644
accept.Assign(ACCEPT_HEADER_STYLE);
645
} else {
646
accept.Assign(ACCEPT_HEADER_ALL);
647
}
648
649
rv = request->SetHeader(nsHttp::Accept, accept, false,
650
nsHttpHeaderArray::eVarietyRequestOverride);
651
if (NS_FAILED(rv)) return rv;
652
653
// Add the "Accept-Language" header. This header is also exposed to the
654
// service worker.
655
if (mAcceptLanguagesIsDirty) {
656
rv = SetAcceptLanguages();
657
MOZ_ASSERT(NS_SUCCEEDED(rv));
658
}
659
660
// Add the "Accept-Language" header
661
if (!mAcceptLanguages.IsEmpty()) {
662
rv = request->SetHeader(nsHttp::Accept_Language, mAcceptLanguages, false,
663
nsHttpHeaderArray::eVarietyRequestOverride);
664
if (NS_FAILED(rv)) return rv;
665
}
666
667
// Add the "Accept-Encoding" header
668
if (isSecure) {
669
rv = request->SetHeader(nsHttp::Accept_Encoding, mHttpsAcceptEncodings,
670
false, nsHttpHeaderArray::eVarietyRequestDefault);
671
} else {
672
rv = request->SetHeader(nsHttp::Accept_Encoding, mHttpAcceptEncodings,
673
false, nsHttpHeaderArray::eVarietyRequestDefault);
674
}
675
if (NS_FAILED(rv)) return rv;
676
677
// add the "Send Hint" header
678
if (mSafeHintEnabled || mParentalControlEnabled) {
679
rv = request->SetHeader(nsHttp::Prefer, NS_LITERAL_CSTRING("safe"), false,
680
nsHttpHeaderArray::eVarietyRequestDefault);
681
if (NS_FAILED(rv)) return rv;
682
}
683
return NS_OK;
684
}
685
686
nsresult nsHttpHandler::AddConnectionHeader(nsHttpRequestHead* request,
687
uint32_t caps) {
688
// RFC2616 section 19.6.2 states that the "Connection: keep-alive"
689
// and "Keep-alive" request headers should not be sent by HTTP/1.1
690
// user-agents. But this is not a problem in practice, and the
691
// alternative proxy-connection is worse. see 570283
692
693
NS_NAMED_LITERAL_CSTRING(close, "close");
694
NS_NAMED_LITERAL_CSTRING(keepAlive, "keep-alive");
695
696
const nsLiteralCString* connectionType = &close;
697
if (caps & NS_HTTP_ALLOW_KEEPALIVE) {
698
connectionType = &keepAlive;
699
}
700
701
return request->SetHeader(nsHttp::Connection, *connectionType);
702
}
703
704
bool nsHttpHandler::IsAcceptableEncoding(const char* enc, bool isSecure) {
705
if (!enc) return false;
706
707
// we used to accept x-foo anytime foo was acceptable, but that's just
708
// continuing bad behavior.. so limit it to known x-* patterns
709
bool rv;
710
if (isSecure) {
711
rv = nsHttp::FindToken(mHttpsAcceptEncodings.get(), enc, HTTP_LWS ",") !=
712
nullptr;
713
} else {
714
rv = nsHttp::FindToken(mHttpAcceptEncodings.get(), enc, HTTP_LWS ",") !=
715
nullptr;
716
}
717
// gzip and deflate are inherently acceptable in modern HTTP - always
718
// process them if a stream converter can also be found.
719
if (!rv &&
720
(!PL_strcasecmp(enc, "gzip") || !PL_strcasecmp(enc, "deflate") ||
721
!PL_strcasecmp(enc, "x-gzip") || !PL_strcasecmp(enc, "x-deflate"))) {
722
rv = true;
723
}
724
LOG(("nsHttpHandler::IsAceptableEncoding %s https=%d %d\n", enc, isSecure,
725
rv));
726
return rv;
727
}
728
729
void nsHttpHandler::IncrementFastOpenConsecutiveFailureCounter() {
730
LOG(
731
("nsHttpHandler::IncrementFastOpenConsecutiveFailureCounter - "
732
"failed=%d failure_limit=%d",
733
mFastOpenConsecutiveFailureCounter, mFastOpenConsecutiveFailureLimit));
734
if (mFastOpenConsecutiveFailureCounter < mFastOpenConsecutiveFailureLimit) {
735
mFastOpenConsecutiveFailureCounter++;
736
if (mFastOpenConsecutiveFailureCounter ==
737
mFastOpenConsecutiveFailureLimit) {
738
LOG(
739
("nsHttpHandler::IncrementFastOpenConsecutiveFailureCounter - "
740
"Fast open failed too many times"));
741
}
742
}
743
}
744
745
void nsHttpHandler::IncrementFastOpenStallsCounter() {
746
LOG(
747
("nsHttpHandler::IncrementFastOpenStallsCounter - failed=%d "
748
"failure_limit=%d",
749
mFastOpenStallsCounter, mFastOpenStallsLimit));
750
if (mFastOpenStallsCounter < mFastOpenStallsLimit) {
751
mFastOpenStallsCounter++;
752
if (mFastOpenStallsCounter == mFastOpenStallsLimit) {
753
LOG(
754
("nsHttpHandler::IncrementFastOpenStallsCounter - "
755
"There are too many stalls involving TFO and TLS."));
756
}
757
}
758
}
759
760
nsresult nsHttpHandler::GetStreamConverterService(
761
nsIStreamConverterService** result) {
762
if (!mStreamConvSvc) {
763
nsresult rv;
764
nsCOMPtr<nsIStreamConverterService> service =
765
do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv);
766
if (NS_FAILED(rv)) return rv;
767
mStreamConvSvc = new nsMainThreadPtrHolder<nsIStreamConverterService>(
768
"nsHttpHandler::mStreamConvSvc", service);
769
}
770
*result = mStreamConvSvc;
771
NS_ADDREF(*result);
772
return NS_OK;
773
}
774
775
nsISiteSecurityService* nsHttpHandler::GetSSService() {
776
if (!mSSService) {
777
nsCOMPtr<nsISiteSecurityService> service =
778
do_GetService(NS_SSSERVICE_CONTRACTID);
779
mSSService = new nsMainThreadPtrHolder<nsISiteSecurityService>(
780
"nsHttpHandler::mSSService", service);
781
}
782
return mSSService;
783
}
784
785
nsICookieService* nsHttpHandler::GetCookieService() {
786
if (!mCookieService) {
787
nsCOMPtr<nsICookieService> service =
788
do_GetService(NS_COOKIESERVICE_CONTRACTID);
789
mCookieService = new nsMainThreadPtrHolder<nsICookieService>(
790
"nsHttpHandler::mCookieService", service);
791
}
792
return mCookieService;
793
}
794
795
nsresult nsHttpHandler::GetIOService(nsIIOService** result) {
796
NS_ENSURE_ARG_POINTER(result);
797
798
NS_ADDREF(*result = mIOService);
799
return NS_OK;
800
}
801
802
uint32_t nsHttpHandler::Get32BitsOfPseudoRandom() {
803
// only confirm rand seeding on socket thread
804
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
805
806
// rand() provides different amounts of PRNG on different platforms.
807
// 15 or 31 bits are common amounts.
808
809
static_assert(RAND_MAX >= 0xfff, "RAND_MAX should be >= 12 bits");
810
811
#if RAND_MAX < 0xffffU
812
return ((uint16_t)rand() << 20) | (((uint16_t)rand() & 0xfff) << 8) |
813
((uint16_t)rand() & 0xff);
814
#elif RAND_MAX < 0xffffffffU
815
return ((uint16_t)rand() << 16) | ((uint16_t)rand() & 0xffff);
816
#else
817
return (uint32_t)rand();
818
#endif
819
}
820
821
void nsHttpHandler::NotifyObservers(nsIHttpChannel* chan, const char* event) {
822
LOG(("nsHttpHandler::NotifyObservers [chan=%p event=\"%s\"]\n", chan, event));
823
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
824
if (obsService) obsService->NotifyObservers(chan, event, nullptr);
825
}
826
827
nsresult nsHttpHandler::AsyncOnChannelRedirect(
828
nsIChannel* oldChan, nsIChannel* newChan, uint32_t flags,
829
nsIEventTarget* mainThreadEventTarget) {
830
MOZ_ASSERT(NS_IsMainThread() && (oldChan && newChan));
831
832
nsCOMPtr<nsIURI> newURI;
833
newChan->GetURI(getter_AddRefs(newURI));
834
MOZ_ASSERT(newURI);
835
836
nsAutoCString scheme;
837
newURI->GetScheme(scheme);
838
MOZ_ASSERT(!scheme.IsEmpty());
839
840
Telemetry::AccumulateCategoricalKeyed(
841
scheme, oldChan->IsDocument()
842
? LABELS_NETWORK_HTTP_REDIRECT_TO_SCHEME::topLevel
843
: LABELS_NETWORK_HTTP_REDIRECT_TO_SCHEME::subresource);
844
845
// TODO E10S This helper has to be initialized on the other process
846
RefPtr<nsAsyncRedirectVerifyHelper> redirectCallbackHelper =
847
new nsAsyncRedirectVerifyHelper();
848
849
return redirectCallbackHelper->Init(oldChan, newChan, flags,
850
mainThreadEventTarget);
851
}
852
853
/* static */
854
nsresult nsHttpHandler::GenerateHostPort(const nsCString& host, int32_t port,
855
nsACString& hostLine) {
856
return NS_GenerateHostPort(host, port, hostLine);
857
}
858
859
//-----------------------------------------------------------------------------
860
// nsHttpHandler <private>
861
//-----------------------------------------------------------------------------
862
863
const nsCString& nsHttpHandler::UserAgent() {
864
if (nsContentUtils::ShouldResistFingerprinting() &&
865
!mSpoofedUserAgent.IsEmpty()) {
866
LOG(("using spoofed userAgent : %s\n", mSpoofedUserAgent.get()));
867
return mSpoofedUserAgent;
868
}
869
870
if (!mUserAgentOverride.IsVoid()) {
871
LOG(("using general.useragent.override : %s\n", mUserAgentOverride.get()));
872
return mUserAgentOverride;
873
}
874
875
if (mUserAgentIsDirty) {
876
BuildUserAgent();
877
mUserAgentIsDirty = false;
878
}
879
880
return mUserAgent;
881
}
882
883
void nsHttpHandler::BuildUserAgent() {
884
LOG(("nsHttpHandler::BuildUserAgent\n"));
885
886
MOZ_ASSERT(!mLegacyAppName.IsEmpty() && !mLegacyAppVersion.IsEmpty(),
887
"HTTP cannot send practical requests without this much");
888
889
// preallocate to worst-case size, which should always be better
890
// than if we didn't preallocate at all.
891
mUserAgent.SetCapacity(mLegacyAppName.Length() + mLegacyAppVersion.Length() +
892
#ifndef UA_SPARE_PLATFORM
893
mPlatform.Length() +
894
#endif
895
mOscpu.Length() + mMisc.Length() + mProduct.Length() +
896
mProductSub.Length() + mAppName.Length() +
897
mAppVersion.Length() + mCompatFirefox.Length() +
898
mCompatDevice.Length() + mDeviceModelId.Length() + 13);
899
900
// Application portion
901
mUserAgent.Assign(mLegacyAppName);
902
mUserAgent += '/';
903
mUserAgent += mLegacyAppVersion;
904
mUserAgent += ' ';
905
906
// Application comment
907
mUserAgent += '(';
908
#ifndef UA_SPARE_PLATFORM
909
if (!mPlatform.IsEmpty()) {
910
mUserAgent += mPlatform;
911
mUserAgent.AppendLiteral("; ");
912
}
913
#endif
914
if (!mCompatDevice.IsEmpty()) {
915
mUserAgent += mCompatDevice;
916
mUserAgent.AppendLiteral("; ");
917
} else if (!mOscpu.IsEmpty()) {
918
mUserAgent += mOscpu;
919
mUserAgent.AppendLiteral("; ");
920
}
921
if (!mDeviceModelId.IsEmpty()) {
922
mUserAgent += mDeviceModelId;
923
mUserAgent.AppendLiteral("; ");
924
}
925
mUserAgent += mMisc;
926
mUserAgent += ')';
927
928
// Product portion
929
mUserAgent += ' ';
930
mUserAgent += mProduct;
931
mUserAgent += '/';
932
mUserAgent += mProductSub;
933
934
bool isFirefox = mAppName.EqualsLiteral("Firefox");
935
if (isFirefox || mCompatFirefoxEnabled) {
936
// "Firefox/x.y" (compatibility) app token
937
mUserAgent += ' ';
938
mUserAgent += mCompatFirefox;
939
}
940
if (!isFirefox) {
941
// App portion
942
mUserAgent += ' ';
943
mUserAgent += mAppName;
944
mUserAgent += '/';
945
mUserAgent += mAppVersion;
946
}
947
}
948
949
#ifdef XP_WIN
950
# define OSCPU_WINDOWS "Windows NT %ld.%ld"
951
# define OSCPU_WIN64 OSCPU_WINDOWS "; Win64; x64"
952
#endif
953
954
void nsHttpHandler::InitUserAgentComponents() {
955
#ifndef MOZ_UA_OS_AGNOSTIC
956
// Gather platform.
957
mPlatform.AssignLiteral(
958
# if defined(ANDROID)
959
"Android"
960
# elif defined(XP_WIN)
961
"Windows"
962
# elif defined(XP_MACOSX)
963
"Macintosh"
964
# elif defined(XP_UNIX)
965
// We historically have always had X11 here,
966
// and there seems little a webpage can sensibly do
967
// based on it being something else, so use X11 for
968
// backwards compatibility in all cases.
969
"X11"
970
# endif
971
);
972
#endif
973
974
#ifdef ANDROID
975
nsCOMPtr<nsIPropertyBag2> infoService =
976
do_GetService("@mozilla.org/system-info;1");
977
MOZ_ASSERT(infoService, "Could not find a system info service");
978
nsresult rv;
979
// Add the Android version number to the Fennec platform identifier.
980
# if defined MOZ_WIDGET_ANDROID
981
# ifndef MOZ_UA_OS_AGNOSTIC // Don't add anything to mPlatform since it's
982
// empty.
983
nsAutoString androidVersion;
984
rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("release_version"),
985
androidVersion);
986
if (NS_SUCCEEDED(rv)) {
987
mPlatform += " ";
988
// If the 2nd character is a ".", we know the major version is a single
989
// digit. If we're running on a version below 4 we pretend to be on
990
// Android KitKat (4.4) to work around scripts sniffing for low versions.
991
if (androidVersion[1] == 46 && androidVersion[0] < 52) {
992
mPlatform += "4.4";
993
} else {
994
mPlatform += NS_LossyConvertUTF16toASCII(androidVersion);
995
}
996
}
997
# endif
998
# endif
999
// Add the `Mobile` or `Tablet` or `TV` token when running on device.
1000
bool isTablet;
1001
rv = infoService->GetPropertyAsBool(NS_LITERAL_STRING("tablet"), &isTablet);
1002
if (NS_SUCCEEDED(rv) && isTablet) {
1003
mCompatDevice.AssignLiteral("Tablet");
1004
} else {
1005
bool isTV;
1006
rv = infoService->GetPropertyAsBool(NS_LITERAL_STRING("tv"), &isTV);
1007
if (NS_SUCCEEDED(rv) && isTV) {
1008
mCompatDevice.AssignLiteral("TV");
1009
} else {
1010
mCompatDevice.AssignLiteral("Mobile");
1011
}
1012
}
1013
1014
if (Preferences::GetBool(UA_PREF("use_device"), false)) {
1015
mDeviceModelId = mozilla::net::GetDeviceModelId();
1016
}
1017
#endif // ANDROID
1018
1019
#ifndef MOZ_UA_OS_AGNOSTIC
1020
// Gather OS/CPU.
1021
# if defined(XP_WIN)
1022
OSVERSIONINFO info = {sizeof(OSVERSIONINFO)};
1023
# pragma warning(push)
1024
# pragma warning(disable : 4996)
1025
if (GetVersionEx(&info)) {
1026
# pragma warning(pop)
1027
1028
const char* format;
1029
# if defined _M_X64 || defined _M_AMD64
1030
format = OSCPU_WIN64;
1031
# else
1032
BOOL isWow64 = FALSE;
1033
if (!IsWow64Process(GetCurrentProcess(), &isWow64)) {
1034
isWow64 = FALSE;
1035
}
1036
format = isWow64 ? OSCPU_WIN64 : OSCPU_WINDOWS;
1037
# endif
1038
1039
SmprintfPointer buf =
1040
mozilla::Smprintf(format, info.dwMajorVersion, info.dwMinorVersion);
1041
if (buf) {
1042
mOscpu = buf.get();
1043
}
1044
}
1045
# elif defined(XP_MACOSX)
1046
# if defined(__ppc__)
1047
mOscpu.AssignLiteral("PPC Mac OS X");
1048
# elif defined(__i386__) || defined(__x86_64__)
1049
mOscpu.AssignLiteral("Intel Mac OS X");
1050
# endif
1051
SInt32 majorVersion = nsCocoaFeatures::OSXVersionMajor();
1052
SInt32 minorVersion = nsCocoaFeatures::OSXVersionMinor();
1053
mOscpu += nsPrintfCString(" %d.%d", static_cast<int>(majorVersion),
1054
static_cast<int>(minorVersion));
1055
# elif defined(XP_UNIX)
1056
struct utsname name;
1057
int ret = uname(&name);
1058
if (ret >= 0) {
1059
nsAutoCString buf;
1060
buf = (char*)name.sysname;
1061
buf += ' ';
1062
1063
# ifdef AIX
1064
// AIX uname returns machine specific info in the uname.machine
1065
// field and does not return the cpu type like other platforms.
1066
// We use the AIX version and release numbers instead.
1067
buf += (char*)name.version;
1068
buf += '.';
1069
buf += (char*)name.release;
1070
# else
1071
buf += (char*)name.machine;
1072
# endif
1073
1074
mOscpu.Assign(buf);
1075
}
1076
# endif
1077
#endif
1078
1079
mUserAgentIsDirty = true;
1080
}
1081
1082
uint32_t nsHttpHandler::MaxSocketCount() {
1083
PR_CallOnce(&nsSocketTransportService::gMaxCountInitOnce,
1084
nsSocketTransportService::DiscoverMaxCount);
1085
// Don't use the full max count because sockets can be held in
1086
// the persistent connection pool for a long time and that could
1087
// starve other users.
1088
1089
uint32_t maxCount = nsSocketTransportService::gMaxCount;
1090
if (maxCount <= 8)
1091
maxCount = 1;
1092
else
1093
maxCount -= 8;
1094
1095
return maxCount;
1096
}
1097
1098
void nsHttpHandler::PrefsChanged(const char* pref) {
1099
nsresult rv = NS_OK;
1100
int32_t val;
1101
1102
LOG(("nsHttpHandler::PrefsChanged [pref=%s]\n", pref));
1103
1104
if (pref) {
1105
gIOService->NotifySocketProcessPrefsChanged(pref);
1106
}
1107
1108
#define PREF_CHANGED(p) ((pref == nullptr) || !PL_strcmp(pref, p))
1109
#define MULTI_PREF_CHANGED(p) \
1110
((pref == nullptr) || !PL_strncmp(pref, p, sizeof(p) - 1))
1111
1112
// If a security pref changed, lets clear our connection pool reuse
1113
if (MULTI_PREF_CHANGED(SECURITY_PREFIX)) {
1114
LOG(("nsHttpHandler::PrefsChanged Security Pref Changed %s\n", pref));
1115
if (mConnMgr) {
1116
rv = mConnMgr->DoShiftReloadConnectionCleanup(nullptr);
1117
if (NS_FAILED(rv)) {
1118
LOG(
1119
("nsHttpHandler::PrefsChanged "
1120
"DoShiftReloadConnectionCleanup failed (%08x)\n",
1121
static_cast<uint32_t>(rv)));
1122
}
1123
rv = mConnMgr->PruneDeadConnections();
1124
if (NS_FAILED(rv)) {
1125
LOG(
1126
("nsHttpHandler::PrefsChanged "
1127
"PruneDeadConnections failed (%08x)\n",
1128
static_cast<uint32_t>(rv)));
1129
}
1130
}
1131
}
1132
1133
//
1134
// UA components
1135
//
1136
1137
bool cVar = false;
1138
1139
if (PREF_CHANGED(UA_PREF("compatMode.firefox"))) {
1140
rv = Preferences::GetBool(UA_PREF("compatMode.firefox"), &cVar);
1141
mCompatFirefoxEnabled = (NS_SUCCEEDED(rv) && cVar);
1142
mUserAgentIsDirty = true;
1143
}
1144
1145
// general.useragent.override
1146
if (PREF_CHANGED(UA_PREF("override"))) {
1147
Preferences::GetCString(UA_PREF("override"), mUserAgentOverride);
1148
mUserAgentIsDirty = true;
1149
}
1150
1151
#ifdef ANDROID
1152
// general.useragent.use_device
1153
if (PREF_CHANGED(UA_PREF("use_device"))) {
1154
if (Preferences::GetBool(UA_PREF("use_device"), false)) {
1155
mDeviceModelId = mozilla::net::GetDeviceModelId();
1156
} else {
1157
mDeviceModelId = EmptyCString();
1158
}
1159
mUserAgentIsDirty = true;
1160
}
1161
#endif
1162
1163
//
1164
// HTTP options
1165
//
1166
1167
if (PREF_CHANGED(HTTP_PREF("keep-alive.timeout"))) {
1168
rv = Preferences::GetInt(HTTP_PREF("keep-alive.timeout"), &val);
1169
if (NS_SUCCEEDED(rv))
1170
mIdleTimeout = PR_SecondsToInterval(clamped(val, 1, 0xffff));
1171
}
1172
1173
if (PREF_CHANGED(HTTP_PREF("request.max-attempts"))) {
1174
rv = Preferences::GetInt(HTTP_PREF("request.max-attempts"), &val);
1175
if (NS_SUCCEEDED(rv))
1176
mMaxRequestAttempts = (uint16_t)clamped(val, 1, 0xffff);
1177
}
1178
1179
if (PREF_CHANGED(HTTP_PREF("request.max-start-delay"))) {
1180
rv = Preferences::GetInt(HTTP_PREF("request.max-start-delay"), &val);
1181
if (NS_SUCCEEDED(rv)) {
1182
mMaxRequestDelay = (uint16_t)clamped(val, 0, 0xffff);
1183
if (mConnMgr) {
1184
rv = mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_REQUEST_DELAY,
1185
mMaxRequestDelay);
1186
if (NS_FAILED(rv)) {
1187
LOG(
1188
("nsHttpHandler::PrefsChanged (request.max-start-delay)"
1189
"UpdateParam failed (%08x)\n",
1190
static_cast<uint32_t>(rv)));
1191
}
1192
}
1193
}
1194
}
1195
1196
if (PREF_CHANGED(HTTP_PREF("response.timeout"))) {
1197
rv = Preferences::GetInt(HTTP_PREF("response.timeout"), &val);
1198
if (NS_SUCCEEDED(rv))
1199
mResponseTimeout = PR_SecondsToInterval(clamped(val, 0, 0xffff));
1200
}
1201
1202
if (PREF_CHANGED(HTTP_PREF("network-changed.timeout"))) {
1203
rv = Preferences::GetInt(HTTP_PREF("network-changed.timeout"), &val);
1204
if (NS_SUCCEEDED(rv)) mNetworkChangedTimeout = clamped(val, 1, 600) * 1000;
1205
}
1206
1207
if (PREF_CHANGED(HTTP_PREF("max-connections"))) {
1208
rv = Preferences::GetInt(HTTP_PREF("max-connections"), &val);
1209
if (NS_SUCCEEDED(rv)) {
1210
mMaxConnections =
1211
(uint16_t)clamped((uint32_t)val, (uint32_t)1, MaxSocketCount());
1212
1213
if (mConnMgr) {
1214
rv = mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS,
1215
mMaxConnections);
1216
if (NS_FAILED(rv)) {
1217
LOG(
1218
("nsHttpHandler::PrefsChanged (max-connections)"
1219
"UpdateParam failed (%08x)\n",
1220
static_cast<uint32_t>(rv)));
1221
}
1222
}
1223
}
1224
}
1225
1226
if (PREF_CHANGED(
1227
HTTP_PREF("max-urgent-start-excessive-connections-per-host"))) {
1228
rv = Preferences::GetInt(
1229
HTTP_PREF("max-urgent-start-excessive-connections-per-host"), &val);
1230
if (NS_SUCCEEDED(rv)) {
1231
mMaxUrgentExcessiveConns = (uint8_t)clamped(val, 1, 0xff);
1232
if (mConnMgr) {
1233
rv = mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_URGENT_START_Q,
1234
mMaxUrgentExcessiveConns);
1235
if (NS_FAILED(rv)) {
1236
LOG(
1237
("nsHttpHandler::PrefsChanged "
1238
"(max-urgent-start-excessive-connections-per-host)"
1239
"UpdateParam failed (%08x)\n",
1240
static_cast<uint32_t>(rv)));
1241
}
1242
}
1243
}
1244
}
1245
1246
if (PREF_CHANGED(HTTP_PREF("max-persistent-connections-per-server"))) {
1247
rv = Preferences::GetInt(HTTP_PREF("max-persistent-connections-per-server"),
1248
&val);
1249
if (NS_SUCCEEDED(rv)) {
1250
mMaxPersistentConnectionsPerServer = (uint8_t)clamped(val, 1, 0xff);
1251
if (mConnMgr) {
1252
rv = mConnMgr->UpdateParam(
1253
nsHttpConnectionMgr::MAX_PERSISTENT_CONNECTIONS_PER_HOST,
1254
mMaxPersistentConnectionsPerServer);
1255
if (NS_FAILED(rv)) {
1256
LOG(
1257
("nsHttpHandler::PrefsChanged "
1258
"(max-persistent-connections-per-server)"
1259
"UpdateParam failed (%08x)\n",
1260
static_cast<uint32_t>(rv)));
1261
}
1262
}
1263
}
1264
}
1265
1266
if (PREF_CHANGED(HTTP_PREF("max-persistent-connections-per-proxy"))) {
1267
rv = Preferences::GetInt(HTTP_PREF("max-persistent-connections-per-proxy"),
1268
&val);
1269
if (NS_SUCCEEDED(rv)) {
1270
mMaxPersistentConnectionsPerProxy = (uint8_t)clamped(val, 1, 0xff);
1271
if (mConnMgr) {
1272
rv = mConnMgr->UpdateParam(
1273
nsHttpConnectionMgr::MAX_PERSISTENT_CONNECTIONS_PER_PROXY,
1274
mMaxPersistentConnectionsPerProxy);
1275
if (NS_FAILED(rv)) {
1276
LOG(
1277
("nsHttpHandler::PrefsChanged "
1278
"(max-persistent-connections-per-proxy)"
1279
"UpdateParam failed (%08x)\n",
1280
static_cast<uint32_t>(rv)));
1281
}
1282
}
1283
}
1284
}
1285
1286
if (PREF_CHANGED(HTTP_PREF("redirection-limit"))) {
1287
rv = Preferences::GetInt(HTTP_PREF("redirection-limit"), &val);
1288
if (NS_SUCCEEDED(rv)) mRedirectionLimit = (uint8_t)clamped(val, 0, 0xff);
1289
}
1290
1291
if (PREF_CHANGED(HTTP_PREF("connection-retry-timeout"))) {
1292
rv = Preferences::GetInt(HTTP_PREF("connection-retry-timeout"), &val);
1293
if (NS_SUCCEEDED(rv)) mIdleSynTimeout = (uint16_t)clamped(val, 0, 3000);
1294
}
1295
1296
if (PREF_CHANGED(HTTP_PREF("fast-fallback-to-IPv4"))) {
1297
rv = Preferences::GetBool(HTTP_PREF("fast-fallback-to-IPv4"), &cVar);
1298
if (NS_SUCCEEDED(rv)) mFastFallbackToIPv4 = cVar;
1299
}
1300
1301
if (PREF_CHANGED(HTTP_PREF("fallback-connection-timeout"))) {
1302
rv = Preferences::GetInt(HTTP_PREF("fallback-connection-timeout"), &val);
1303
if (NS_SUCCEEDED(rv))
1304
mFallbackSynTimeout = (uint16_t)clamped(val, 0, 10 * 60);
1305
}
1306
1307
if (PREF_CHANGED(HTTP_PREF("version"))) {
1308
nsAutoCString httpVersion;
1309
Preferences::GetCString(HTTP_PREF("version"), httpVersion);
1310
if (!httpVersion.IsVoid()) {
1311
if (httpVersion.EqualsLiteral("1.1"))
1312
mHttpVersion = HttpVersion::v1_1;
1313
else if (httpVersion.EqualsLiteral("0.9"))
1314
mHttpVersion = HttpVersion::v0_9;
1315
else
1316
mHttpVersion = HttpVersion::v1_0;
1317
}
1318
}
1319
1320
if (PREF_CHANGED(HTTP_PREF("proxy.version"))) {
1321
nsAutoCString httpVersion;
1322
Preferences::GetCString(HTTP_PREF("proxy.version"), httpVersion);
1323
if (!httpVersion.IsVoid()) {
1324
if (httpVersion.EqualsLiteral("1.1"))
1325
mProxyHttpVersion = HttpVersion::v1_1;
1326
else
1327
mProxyHttpVersion = HttpVersion::v1_0;
1328
// it does not make sense to issue a HTTP/0.9 request to a proxy server
1329
}
1330
}
1331
1332
if (PREF_CHANGED(HTTP_PREF("qos"))) {
1333
rv = Preferences::GetInt(HTTP_PREF("qos"), &val);
1334
if (NS_SUCCEEDED(rv)) mQoSBits = (uint8_t)clamped(val, 0, 0xff);
1335
}
1336
1337
if (PREF_CHANGED(HTTP_PREF("accept-encoding"))) {
1338
nsAutoCString acceptEncodings;
1339
rv = Preferences::GetCString(HTTP_PREF("accept-encoding"), acceptEncodings);
1340
if (NS_SUCCEEDED(rv)) {
1341
rv = SetAcceptEncodings(acceptEncodings.get(), false);
1342
MOZ_ASSERT(NS_SUCCEEDED(rv));
1343
}
1344
}
1345
1346
if (PREF_CHANGED(HTTP_PREF("accept-encoding.secure"))) {
1347
nsAutoCString acceptEncodings;
1348
rv = Preferences::GetCString(HTTP_PREF("accept-encoding.secure"),
1349
acceptEncodings);
1350
if (NS_SUCCEEDED(rv)) {
1351
rv = SetAcceptEncodings(acceptEncodings.get(), true);
1352
MOZ_ASSERT(NS_SUCCEEDED(rv));
1353
}
1354
}
1355
1356
if (PREF_CHANGED(HTTP_PREF("default-socket-type"))) {
1357
nsAutoCString sval;
1358
rv = Preferences::GetCString(HTTP_PREF("default-socket-type"), sval);
1359
if (NS_SUCCEEDED(rv)) {
1360
if (sval.IsEmpty())
1361
mDefaultSocketType.SetIsVoid(true);
1362
else {
1363
// verify that this socket type is actually valid
1364
nsCOMPtr<nsISocketProviderService> sps =
1365
nsSocketProviderService::GetOrCreate();
1366
if (sps) {
1367
nsCOMPtr<nsISocketProvider> sp;
1368
rv = sps->GetSocketProvider(sval.get(), getter_AddRefs(sp));
1369
if (NS_SUCCEEDED(rv)) {
1370
// OK, this looks like a valid socket provider.
1371
mDefaultSocketType.Assign(sval);
1372
}
1373
}
1374
}
1375
}
1376
}
1377
1378
if (PREF_CHANGED(HTTP_PREF("prompt-temp-redirect"))) {
1379
rv = Preferences::GetBool(HTTP_PREF("prompt-temp-redirect"), &cVar);
1380
if (NS_SUCCEEDED(rv)) {
1381
mPromptTempRedirect = cVar;
1382
}
1383
}
1384
1385
if (PREF_CHANGED(HTTP_PREF("assoc-req.enforce"))) {
1386
cVar = false;
1387
rv = Preferences::GetBool(HTTP_PREF("assoc-req.enforce"), &cVar);
1388
if (NS_SUCCEEDED(rv)) mEnforceAssocReq = cVar;
1389
}
1390
1391
// enable Persistent caching for HTTPS - bug#205921
1392
if (PREF_CHANGED(BROWSER_PREF("disk_cache_ssl"))) {
1393
cVar = false;
1394
rv = Preferences::GetBool(BROWSER_PREF("disk_cache_ssl"), &cVar);
1395
if (NS_SUCCEEDED(rv)) mEnablePersistentHttpsCaching = cVar;
1396
}
1397
1398
if (PREF_CHANGED(HTTP_PREF("phishy-userpass-length"))) {
1399
rv = Preferences::GetInt(HTTP_PREF("phishy-userpass-length"), &val);
1400
if (NS_SUCCEEDED(rv))
1401
mPhishyUserPassLength = (uint8_t)clamped(val, 0, 0xff);
1402
}
1403
1404
if (PREF_CHANGED(HTTP_PREF("spdy.enabled"))) {
1405
rv = Preferences::GetBool(HTTP_PREF("spdy.enabled"), &cVar);
1406
if (NS_SUCCEEDED(rv)) mEnableSpdy = cVar;
1407
}
1408
1409
if (PREF_CHANGED(HTTP_PREF("spdy.enabled.http2"))) {
1410
rv = Preferences::GetBool(HTTP_PREF("spdy.enabled.http2"), &cVar);
1411
if (NS_SUCCEEDED(rv)) mHttp2Enabled = cVar;
1412
}
1413
1414
if (PREF_CHANGED(HTTP_PREF("spdy.enabled.deps"))) {
1415
rv = Preferences::GetBool(HTTP_PREF("spdy.enabled.deps"), &cVar);
1416
if (NS_SUCCEEDED(rv)) mUseH2Deps = cVar;
1417
}
1418
1419
if (PREF_CHANGED(HTTP_PREF("spdy.enforce-tls-profile"))) {
1420
rv = Preferences::GetBool(HTTP_PREF("spdy.enforce-tls-profile"), &cVar);
1421
if (NS_SUCCEEDED(rv)) mEnforceHttp2TlsProfile = cVar;
1422
}
1423
1424
if (PREF_CHANGED(HTTP_PREF("spdy.coalesce-hostnames"))) {
1425
rv = Preferences::GetBool(HTTP_PREF("spdy.coalesce-hostnames"), &cVar);
1426
if (NS_SUCCEEDED(rv)) mCoalesceSpdy = cVar;
1427
}
1428
1429
if (PREF_CHANGED(HTTP_PREF("spdy.persistent-settings"))) {
1430
rv = Preferences::GetBool(HTTP_PREF("spdy.persistent-settings"), &cVar);
1431
if (NS_SUCCEEDED(rv)) mSpdyPersistentSettings = cVar;
1432
}
1433
1434
if (PREF_CHANGED(HTTP_PREF("spdy.timeout"))) {
1435
rv = Preferences::GetInt(HTTP_PREF("spdy.timeout"), &val);
1436
if (NS_SUCCEEDED(rv))
1437
mSpdyTimeout = PR_SecondsToInterval(clamped(val, 1, 0xffff));
1438
}
1439
1440
if (PREF_CHANGED(HTTP_PREF("spdy.chunk-size"))) {
1441
// keep this within http/2 ranges of 1 to 2^14-1
1442
rv = Preferences::GetInt(HTTP_PREF("spdy.chunk-size"), &val);
1443
if (NS_SUCCEEDED(rv))
1444
mSpdySendingChunkSize = (uint32_t)clamped(val, 1, 0x3fff);
1445
}
1446
1447
// The amount of idle seconds on a spdy connection before initiating a
1448
// server ping. 0 will disable.
1449
if (PREF_CHANGED(HTTP_PREF("spdy.ping-threshold"))) {
1450
rv = Preferences::GetInt(HTTP_PREF("spdy.ping-threshold"), &val);
1451
if (NS_SUCCEEDED(rv))
1452
mSpdyPingThreshold =
1453
PR_SecondsToInterval((uint16_t)clamped(val, 0, 0x7fffffff));
1454
}
1455
1456
// The amount of seconds to wait for a spdy ping response before
1457
// closing the session.
1458
if (PREF_CHANGED(HTTP_PREF("spdy.ping-timeout"))) {
1459
rv = Preferences::GetInt(HTTP_PREF("spdy.ping-timeout"), &val);
1460
if (NS_SUCCEEDED(rv))
1461
mSpdyPingTimeout =
1462
PR_SecondsToInterval((uint16_t)clamped(val, 0, 0x7fffffff));
1463
}
1464
1465
if (PREF_CHANGED(HTTP_PREF("spdy.allow-push"))) {
1466
rv = Preferences::GetBool(HTTP_PREF("spdy.allow-push"), &cVar);
1467
if (NS_SUCCEEDED(rv)) mAllowPush = cVar;
1468
}
1469
1470
if (PREF_CHANGED(HTTP_PREF("altsvc.enabled"))) {
1471
rv = Preferences::GetBool(HTTP_PREF("altsvc.enabled"), &cVar);
1472
if (NS_SUCCEEDED(rv)) mEnableAltSvc = cVar;
1473
}
1474
1475
if (PREF_CHANGED(HTTP_PREF("altsvc.oe"))) {
1476
rv = Preferences::GetBool(HTTP_PREF("altsvc.oe"), &cVar);
1477
if (NS_SUCCEEDED(rv)) mEnableAltSvcOE = cVar;
1478
}
1479
1480
if (PREF_CHANGED(HTTP_PREF("originextension"))) {
1481
rv = Preferences::GetBool(HTTP_PREF("originextension"), &cVar);
1482
if (NS_SUCCEEDED(rv)) mEnableOriginExtension = cVar;
1483
}
1484
1485
if (PREF_CHANGED(HTTP_PREF("spdy.websockets"))) {
1486
rv = Preferences::GetBool(HTTP_PREF("spdy.websockets"), &cVar);
1487
if (NS_SUCCEEDED(rv)) {
1488
mEnableH2Websockets = cVar;
1489
}
1490
}
1491
1492
if (PREF_CHANGED(HTTP_PREF("spdy.push-allowance"))) {
1493
rv = Preferences::GetInt(HTTP_PREF("spdy.push-allowance"), &val);
1494
if (NS_SUCCEEDED(rv)) {
1495
mSpdyPushAllowance = static_cast<uint32_t>(
1496
clamped(val, 1024, static_cast<int32_t>(ASpdySession::kInitialRwin)));
1497
}
1498
}
1499
1500
if (PREF_CHANGED(HTTP_PREF("spdy.pull-allowance"))) {
1501
rv = Preferences::GetInt(HTTP_PREF("spdy.pull-allowance"), &val);
1502
if (NS_SUCCEEDED(rv)) {
1503
mSpdyPullAllowance =
1504
static_cast<uint32_t>(clamped(val, 1024, 0x7fffffff));
1505
}
1506
}
1507
1508
if (PREF_CHANGED(HTTP_PREF("spdy.default-concurrent"))) {
1509
rv = Preferences::GetInt(HTTP_PREF("spdy.default-concurrent"), &val);
1510
if (NS_SUCCEEDED(rv)) {
1511
mDefaultSpdyConcurrent = static_cast<uint32_t>(
1512
std::max<int32_t>(std::min<int32_t>(val, 9999), 1));
1513
}
1514
}
1515
1516
// The amount of seconds to wait for a spdy ping response before
1517
// closing the session.
1518
if (PREF_CHANGED(HTTP_PREF("spdy.send-buffer-size"))) {
1519
rv = Preferences::GetInt(HTTP_PREF("spdy.send-buffer-size"), &val);
1520
if (NS_SUCCEEDED(rv))
1521
mSpdySendBufferSize = (uint32_t)clamped(val, 1500, 0x7fffffff);
1522
}
1523
1524
if (PREF_CHANGED(HTTP_PREF("spdy.enable-hpack-dump"))) {
1525
rv = Preferences::GetBool(HTTP_PREF("spdy.enable-hpack-dump"), &cVar);
1526
if (NS_SUCCEEDED(rv)) {
1527
mDumpHpackTables = cVar;
1528
}
1529
}
1530
1531
// The maximum amount of time to wait for socket transport to be
1532
// established
1533
if (PREF_CHANGED(HTTP_PREF("connection-timeout"))) {
1534
rv = Preferences::GetInt(HTTP_PREF("connection-timeout"), &val);
1535
if (NS_SUCCEEDED(rv))
1536
// the pref is in seconds, but the variable is in milliseconds
1537
mConnectTimeout = clamped(val, 1, 0xffff) * PR_MSEC_PER_SEC;
1538
}
1539
1540
// The maximum amount of time to wait for a tls handshake to finish.
1541
if (PREF_CHANGED(HTTP_PREF("tls-handshake-timeout"))) {
1542
rv = Preferences::GetInt(HTTP_PREF("tls-handshake-timeout"), &val);
1543
if (NS_SUCCEEDED(rv))
1544
// the pref is in seconds, but the variable is in milliseconds
1545
mTLSHandshakeTimeout = clamped(val, 1, 0xffff) * PR_MSEC_PER_SEC;
1546
}
1547
1548
// The maximum number of current global half open sockets allowable
1549
// for starting a new speculative connection.
1550
if (PREF_CHANGED(HTTP_PREF("speculative-parallel-limit"))) {
1551
rv = Preferences::GetInt(HTTP_PREF("speculative-parallel-limit"), &val);
1552
if (NS_SUCCEEDED(rv))
1553
mParallelSpeculativeConnectLimit = (uint32_t)clamped(val, 0, 1024);
1554
}
1555
1556
// Whether or not to block requests for non head js/css items (e.g. media)
1557
// while those elements load.
1558
if (PREF_CHANGED(HTTP_PREF("rendering-critical-requests-prioritization"))) {
1559
rv = Preferences::GetBool(
1560
HTTP_PREF("rendering-critical-requests-prioritization"), &cVar);
1561
if (NS_SUCCEEDED(rv)) mCriticalRequestPrioritization = cVar;
1562
}
1563
1564
// Whether to respect X-Content-Type nosniff on Page loads
1565
if (PREF_CHANGED("dom.security.respect_document_nosniff")) {
1566
rv = Preferences::GetBool("dom.security.respect_document_nosniff", &cVar);
1567
if (NS_SUCCEEDED(rv)) {
1568
mRespectDocumentNoSniff = cVar;
1569
}
1570
}
1571
1572
// on transition of network.http.diagnostics to true print
1573
// a bunch of information to the console
1574
if (pref && PREF_CHANGED(HTTP_PREF("diagnostics"))) {
1575
rv = Preferences::GetBool(HTTP_PREF("diagnostics"), &cVar);
1576
if (NS_SUCCEEDED(rv) && cVar) {
1577
if (mConnMgr) mConnMgr->PrintDiagnostics();
1578
}
1579
}
1580
1581
if (PREF_CHANGED(HTTP_PREF("max_response_header_size"))) {
1582
rv = Preferences::GetInt(HTTP_PREF("max_response_header_size"), &val);
1583
if (NS_SUCCEEDED(rv)) {
1584
mMaxHttpResponseHeaderSize = val;
1585
}
1586
}
1587
1588
if (PREF_CHANGED(HTTP_PREF("throttle.enable"))) {
1589
rv = Preferences::GetBool(HTTP_PREF("throttle.enable"), &mThrottleEnabled);
1590
if (NS_SUCCEEDED(rv) && mConnMgr) {
1591
Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_ENABLED,
1592
static_cast<int32_t>(mThrottleEnabled));
1593
}
1594
}
1595
1596
if (PREF_CHANGED(HTTP_PREF("throttle.version"))) {
1597
Unused << Preferences::GetInt(HTTP_PREF("throttle.version"), &val);
1598
mThrottleVersion = (uint32_t)clamped(val, 1, 2);
1599
}
1600
1601
if (PREF_CHANGED(HTTP_PREF("throttle.suspend-for"))) {
1602
rv = Preferences::GetInt(HTTP_PREF("throttle.suspend-for"), &val);
1603
mThrottleSuspendFor = (uint32_t)clamped(val, 0, 120000);
1604
if (NS_SUCCEEDED(rv) && mConnMgr) {
1605
Unused << mConnMgr->UpdateParam(
1606
nsHttpConnectionMgr::THROTTLING_SUSPEND_FOR, mThrottleSuspendFor);
1607
}
1608
}
1609
1610
if (PREF_CHANGED(HTTP_PREF("throttle.resume-for"))) {
1611
rv = Preferences::GetInt(HTTP_PREF("throttle.resume-for"), &val);
1612
mThrottleResumeFor = (uint32_t)clamped(val, 0, 120000);
1613
if (NS_SUCCEEDED(rv) && mConnMgr) {
1614
Unused << mConnMgr->UpdateParam(
1615
nsHttpConnectionMgr::THROTTLING_RESUME_FOR, mThrottleResumeFor);
1616
}
1617
}
1618
1619
if (PREF_CHANGED(HTTP_PREF("throttle.read-limit-bytes"))) {
1620
rv = Preferences::GetInt(HTTP_PREF("throttle.read-limit-bytes"), &val);
1621
mThrottleReadLimit = (uint32_t)clamped(val, 0, 500000);
1622
if (NS_SUCCEEDED(rv) && mConnMgr) {
1623
Unused << mConnMgr->UpdateParam(
1624
nsHttpConnectionMgr::THROTTLING_READ_LIMIT, mThrottleReadLimit);
1625
}
1626
}
1627
1628
if (PREF_CHANGED(HTTP_PREF("throttle.read-interval-ms"))) {
1629
rv = Preferences::GetInt(HTTP_PREF("throttle.read-interval-ms"), &val);
1630
mThrottleReadInterval = (uint32_t)clamped(val, 0, 120000);
1631
if (NS_SUCCEEDED(rv) && mConnMgr) {
1632
Unused << mConnMgr->UpdateParam(
1633
nsHttpConnectionMgr::THROTTLING_READ_INTERVAL, mThrottleReadInterval);
1634
}
1635
}
1636
1637
if (PREF_CHANGED(HTTP_PREF("throttle.hold-time-ms"))) {
1638
rv = Preferences::GetInt(HTTP_PREF("throttle.hold-time-ms"), &val);
1639
mThrottleHoldTime = (uint32_t)clamped(val, 0, 120000);
1640
if (NS_SUCCEEDED(rv) && mConnMgr) {
1641
Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_HOLD_TIME,
1642
mThrottleHoldTime);
1643
}
1644
}
1645
1646
if (PREF_CHANGED(HTTP_PREF("throttle.max-time-ms"))) {
1647
rv = Preferences::GetInt(HTTP_PREF("throttle.max-time-ms"), &val);
1648
mThrottleMaxTime = (uint32_t)clamped(val, 0, 120000);
1649
if (NS_SUCCEEDED(rv) && mConnMgr) {
1650
Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_MAX_TIME,
1651
mThrottleMaxTime);
1652
}
1653
}
1654
1655
if (PREF_CHANGED(HTTP_PREF("send_window_size"))) {
1656
Unused << Preferences::GetInt(HTTP_PREF("send_window_size"), &val);
1657
mSendWindowSize = val >= 0 ? val : 0;
1658
}
1659
1660
if (PREF_CHANGED(HTTP_PREF("on_click_priority"))) {
1661
Unused << Preferences::GetBool(HTTP_PREF("on_click_priority"),
1662
&mUrgentStartEnabled);
1663
}
1664
1665
if (PREF_CHANGED(HTTP_PREF("tailing.enabled"))) {
1666
Unused << Preferences::GetBool(HTTP_PREF("tailing.enabled"),
1667
&mTailBlockingEnabled);
1668
}
1669
if (PREF_CHANGED(HTTP_PREF("tailing.delay-quantum"))) {
1670
Unused << Preferences::GetInt(HTTP_PREF("tailing.delay-quantum"), &val);
1671
mTailDelayQuantum = (uint32_t)clamped(val, 0, 60000);
1672
}
1673
if (PREF_CHANGED(HTTP_PREF("tailing.delay-quantum-after-domcontentloaded"))) {
1674
Unused << Preferences::GetInt(
1675
HTTP_PREF("tailing.delay-quantum-after-domcontentloaded"), &val);
1676
mTailDelayQuantumAfterDCL = (uint32_t)clamped(val, 0, 60000);
1677
}
1678
if (PREF_CHANGED(HTTP_PREF("tailing.delay-max"))) {
1679
Unused << Preferences::GetInt(HTTP_PREF("tailing.delay-max"), &val);
1680
mTailDelayMax = (uint32_t)clamped(val, 0, 60000);
1681
}
1682
if (PREF_CHANGED(HTTP_PREF("tailing.total-max"))) {
1683
Unused << Preferences::GetInt(HTTP_PREF("tailing.total-max"), &val);
1684
mTailTotalMax = (uint32_t)clamped(val, 0, 60000);
1685
}
1686
1687
if (PREF_CHANGED(HTTP_PREF("focused_window_transaction_ratio"))) {
1688
float ratio = 0;
1689
rv = Preferences::GetFloat(HTTP_PREF("focused_window_transaction_ratio"),
1690
&ratio);
1691
if (NS_SUCCEEDED(rv)) {
1692
if (ratio > 0 && ratio < 1) {
1693
mFocusedWindowTransactionRatio = ratio;
1694
} else {
1695
NS_WARNING("Wrong value for focused_window_transaction_ratio");
1696
}
1697
}
1698
}
1699
1700
//
1701
// INTL options
1702
//
1703
1704
if (PREF_CHANGED(INTL_ACCEPT_LANGUAGES)) {
1705
// We don't want to set the new accept languages here since
1706
// this pref is a complex type and it may be racy with flushing
1707
// string resources.
1708
mAcceptLanguagesIsDirty = true;
1709
}
1710
1711
//
1712
// Tracking options
1713
//
1714
1715
// Hint option
1716
if (PREF_CHANGED(SAFE_HINT_HEADER_VALUE)) {
1717
cVar = false;
1718
rv = Preferences::GetBool(SAFE_HINT_HEADER_VALUE, &cVar);
1719
if (NS_SUCCEEDED(rv)) {
1720
mSafeHintEnabled = cVar;
1721
}
1722
}
1723
1724
// toggle to true anytime a token bucket related pref is changed.. that
1725
// includes telemetry and allow-experiments because of the abtest profile
1726
bool requestTokenBucketUpdated = false;
1727
1728
// "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256" is the required h2 interop
1729
// suite.
1730
1731
if (PREF_CHANGED(H2MANDATORY_SUITE)) {
1732
cVar = false;
1733
rv = Preferences::GetBool(H2MANDATORY_SUITE, &cVar);
1734
if (NS_SUCCEEDED(rv)) {
1735
mH2MandatorySuiteEnabled = cVar;
1736
}
1737
}
1738
1739
// network.http.debug-observations
1740
if (PREF_CHANGED("network.http.debug-observations")) {
1741
cVar = false;
1742
rv = Preferences::GetBool("network.http.debug-observations", &cVar);
1743
if (NS_SUCCEEDED(rv)) {
1744
mDebugObservations = cVar;
1745
}
1746
}
1747
1748
if (PREF_CHANGED(HTTP_PREF("pacing.requests.enabled"))) {
1749
rv = Preferences::GetBool(HTTP_PREF("pacing.requests.enabled"), &cVar);
1750
if (NS_SUCCEEDED(rv)) {
1751
mRequestTokenBucketEnabled = cVar;
1752
requestTokenBucketUpdated = true;
1753
}
1754
}
1755
if (PREF_CHANGED(HTTP_PREF("pacing.requests.min-parallelism"))) {
1756
rv =
1757
Preferences::GetInt(HTTP_PREF("pacing.requests.min-parallelism"), &val);
1758
if (NS_SUCCEEDED(rv)) {
1759
mRequestTokenBucketMinParallelism =
1760
static_cast<uint16_t>(clamped(val, 1, 1024));
1761
requestTokenBucketUpdated = true;
1762
}
1763
}