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