|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* vim:set ts=4 sw=4 sts=4 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 "nsHttp.h" |
|
11 #include "nsHttpHandler.h" |
|
12 #include "nsHttpChannel.h" |
|
13 #include "nsHttpAuthCache.h" |
|
14 #include "nsStandardURL.h" |
|
15 #include "nsIDOMWindow.h" |
|
16 #include "nsIDOMNavigator.h" |
|
17 #include "nsIMozNavigatorNetwork.h" |
|
18 #include "nsINetworkProperties.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 "nsISocketProviderService.h" |
|
27 #include "nsISocketProvider.h" |
|
28 #include "nsPrintfCString.h" |
|
29 #include "nsCOMPtr.h" |
|
30 #include "nsNetCID.h" |
|
31 #include "prprf.h" |
|
32 #include "nsNetUtil.h" |
|
33 #include "nsAsyncRedirectVerifyHelper.h" |
|
34 #include "nsSocketTransportService2.h" |
|
35 #include "nsAlgorithm.h" |
|
36 #include "ASpdySession.h" |
|
37 #include "mozIApplicationClearPrivateDataParams.h" |
|
38 #include "EventTokenBucket.h" |
|
39 #include "Tickler.h" |
|
40 #include "nsIXULAppInfo.h" |
|
41 #include "nsICacheSession.h" |
|
42 #include "nsICookieService.h" |
|
43 #include "nsIObserverService.h" |
|
44 #include "nsISiteSecurityService.h" |
|
45 #include "nsIStreamConverterService.h" |
|
46 #include "nsITimer.h" |
|
47 #include "nsCRT.h" |
|
48 #include "SpdyZlibReporter.h" |
|
49 #include "nsIMemoryReporter.h" |
|
50 #include "nsIParentalControlsService.h" |
|
51 |
|
52 #include "mozilla/net/NeckoChild.h" |
|
53 #include "mozilla/Telemetry.h" |
|
54 |
|
55 #if defined(XP_UNIX) |
|
56 #include <sys/utsname.h> |
|
57 #endif |
|
58 |
|
59 #if defined(XP_WIN) |
|
60 #include <windows.h> |
|
61 #endif |
|
62 |
|
63 #if defined(XP_MACOSX) |
|
64 #include <CoreServices/CoreServices.h> |
|
65 #include "nsCocoaFeatures.h" |
|
66 #endif |
|
67 |
|
68 //----------------------------------------------------------------------------- |
|
69 #include "mozilla/net/HttpChannelChild.h" |
|
70 |
|
71 |
|
72 #ifdef DEBUG |
|
73 // defined by the socket transport service while active |
|
74 extern PRThread *gSocketThread; |
|
75 #endif |
|
76 |
|
77 #define UA_PREF_PREFIX "general.useragent." |
|
78 #ifdef XP_WIN |
|
79 #define UA_SPARE_PLATFORM |
|
80 #endif |
|
81 |
|
82 #define HTTP_PREF_PREFIX "network.http." |
|
83 #define INTL_ACCEPT_LANGUAGES "intl.accept_languages" |
|
84 #define BROWSER_PREF_PREFIX "browser.cache." |
|
85 #define DONOTTRACK_HEADER_ENABLED "privacy.donottrackheader.enabled" |
|
86 #define DONOTTRACK_HEADER_VALUE "privacy.donottrackheader.value" |
|
87 #define DONOTTRACK_VALUE_UNSET 2 |
|
88 #define TELEMETRY_ENABLED "toolkit.telemetry.enabled" |
|
89 #define ALLOW_EXPERIMENTS "network.allow-experiments" |
|
90 #define SAFE_HINT_HEADER_VALUE "safeHint.enabled" |
|
91 |
|
92 #define UA_PREF(_pref) UA_PREF_PREFIX _pref |
|
93 #define HTTP_PREF(_pref) HTTP_PREF_PREFIX _pref |
|
94 #define BROWSER_PREF(_pref) BROWSER_PREF_PREFIX _pref |
|
95 |
|
96 #define NS_HTTP_PROTOCOL_FLAGS (URI_STD | ALLOWS_PROXY | ALLOWS_PROXY_HTTP | URI_LOADABLE_BY_ANYONE) |
|
97 |
|
98 //----------------------------------------------------------------------------- |
|
99 |
|
100 namespace mozilla { |
|
101 namespace net { |
|
102 |
|
103 static nsresult |
|
104 NewURI(const nsACString &aSpec, |
|
105 const char *aCharset, |
|
106 nsIURI *aBaseURI, |
|
107 int32_t aDefaultPort, |
|
108 nsIURI **aURI) |
|
109 { |
|
110 nsStandardURL *url = new nsStandardURL(); |
|
111 if (!url) |
|
112 return NS_ERROR_OUT_OF_MEMORY; |
|
113 NS_ADDREF(url); |
|
114 |
|
115 nsresult rv = url->Init(nsIStandardURL::URLTYPE_AUTHORITY, |
|
116 aDefaultPort, aSpec, aCharset, aBaseURI); |
|
117 if (NS_FAILED(rv)) { |
|
118 NS_RELEASE(url); |
|
119 return rv; |
|
120 } |
|
121 |
|
122 *aURI = url; // no QI needed |
|
123 return NS_OK; |
|
124 } |
|
125 |
|
126 //----------------------------------------------------------------------------- |
|
127 // nsHttpHandler <public> |
|
128 //----------------------------------------------------------------------------- |
|
129 |
|
130 nsHttpHandler *gHttpHandler = nullptr; |
|
131 |
|
132 nsHttpHandler::nsHttpHandler() |
|
133 : mConnMgr(nullptr) |
|
134 , mHttpVersion(NS_HTTP_VERSION_1_1) |
|
135 , mProxyHttpVersion(NS_HTTP_VERSION_1_1) |
|
136 , mCapabilities(NS_HTTP_ALLOW_KEEPALIVE) |
|
137 , mReferrerLevel(0xff) // by default we always send a referrer |
|
138 , mSpoofReferrerSource(false) |
|
139 , mReferrerTrimmingPolicy(0) |
|
140 , mReferrerXOriginPolicy(0) |
|
141 , mFastFallbackToIPv4(false) |
|
142 , mProxyPipelining(true) |
|
143 , mIdleTimeout(PR_SecondsToInterval(10)) |
|
144 , mSpdyTimeout(PR_SecondsToInterval(180)) |
|
145 , mResponseTimeout(300) |
|
146 , mResponseTimeoutEnabled(false) |
|
147 , mMaxRequestAttempts(10) |
|
148 , mMaxRequestDelay(10) |
|
149 , mIdleSynTimeout(250) |
|
150 , mPipeliningEnabled(false) |
|
151 , mMaxConnections(24) |
|
152 , mMaxPersistentConnectionsPerServer(2) |
|
153 , mMaxPersistentConnectionsPerProxy(4) |
|
154 , mMaxPipelinedRequests(32) |
|
155 , mMaxOptimisticPipelinedRequests(4) |
|
156 , mPipelineAggressive(false) |
|
157 , mMaxPipelineObjectSize(300000) |
|
158 , mPipelineRescheduleOnTimeout(true) |
|
159 , mPipelineRescheduleTimeout(PR_MillisecondsToInterval(1500)) |
|
160 , mPipelineReadTimeout(PR_MillisecondsToInterval(30000)) |
|
161 , mRedirectionLimit(10) |
|
162 , mPhishyUserPassLength(1) |
|
163 , mQoSBits(0x00) |
|
164 , mPipeliningOverSSL(false) |
|
165 , mEnforceAssocReq(false) |
|
166 , mLastUniqueID(NowInSeconds()) |
|
167 , mSessionStartTime(0) |
|
168 , mLegacyAppName("Mozilla") |
|
169 , mLegacyAppVersion("5.0") |
|
170 , mProduct("Gecko") |
|
171 , mUserAgentIsDirty(true) |
|
172 , mUseCache(true) |
|
173 , mPromptTempRedirect(true) |
|
174 , mSendSecureXSiteReferrer(true) |
|
175 , mEnablePersistentHttpsCaching(false) |
|
176 , mDoNotTrackEnabled(false) |
|
177 , mDoNotTrackValue(1) |
|
178 , mSafeHintEnabled(false) |
|
179 , mParentalControlEnabled(false) |
|
180 , mTelemetryEnabled(false) |
|
181 , mAllowExperiments(true) |
|
182 , mHandlerActive(false) |
|
183 , mEnableSpdy(false) |
|
184 , mSpdyV3(true) |
|
185 , mSpdyV31(true) |
|
186 , mHttp2DraftEnabled(true) |
|
187 , mEnforceHttp2TlsProfile(true) |
|
188 , mCoalesceSpdy(true) |
|
189 , mSpdyPersistentSettings(false) |
|
190 , mAllowPush(true) |
|
191 , mSpdySendingChunkSize(ASpdySession::kSendingChunkSize) |
|
192 , mSpdySendBufferSize(ASpdySession::kTCPSendBufferSize) |
|
193 , mSpdyPushAllowance(32768) |
|
194 , mSpdyPingThreshold(PR_SecondsToInterval(58)) |
|
195 , mSpdyPingTimeout(PR_SecondsToInterval(8)) |
|
196 , mConnectTimeout(90000) |
|
197 , mBypassCacheLockThreshold(250.0) |
|
198 , mParallelSpeculativeConnectLimit(6) |
|
199 , mRequestTokenBucketEnabled(true) |
|
200 , mRequestTokenBucketMinParallelism(6) |
|
201 , mRequestTokenBucketHz(100) |
|
202 , mRequestTokenBucketBurst(32) |
|
203 , mTCPKeepaliveShortLivedEnabled(false) |
|
204 , mTCPKeepaliveShortLivedTimeS(60) |
|
205 , mTCPKeepaliveShortLivedIdleTimeS(10) |
|
206 , mTCPKeepaliveLongLivedEnabled(false) |
|
207 , mTCPKeepaliveLongLivedIdleTimeS(600) |
|
208 { |
|
209 #if defined(PR_LOGGING) |
|
210 gHttpLog = PR_NewLogModule("nsHttp"); |
|
211 #endif |
|
212 |
|
213 LOG(("Creating nsHttpHandler [this=%p].\n", this)); |
|
214 |
|
215 RegisterStrongMemoryReporter(new SpdyZlibReporter()); |
|
216 |
|
217 MOZ_ASSERT(!gHttpHandler, "HTTP handler already created!"); |
|
218 gHttpHandler = this; |
|
219 } |
|
220 |
|
221 nsHttpHandler::~nsHttpHandler() |
|
222 { |
|
223 LOG(("Deleting nsHttpHandler [this=%p]\n", this)); |
|
224 |
|
225 // make sure the connection manager is shutdown |
|
226 if (mConnMgr) { |
|
227 mConnMgr->Shutdown(); |
|
228 NS_RELEASE(mConnMgr); |
|
229 } |
|
230 |
|
231 // Note: don't call NeckoChild::DestroyNeckoChild() here, as it's too late |
|
232 // and it'll segfault. NeckoChild will get cleaned up by process exit. |
|
233 |
|
234 nsHttp::DestroyAtomTable(); |
|
235 if (mPipelineTestTimer) { |
|
236 mPipelineTestTimer->Cancel(); |
|
237 mPipelineTestTimer = nullptr; |
|
238 } |
|
239 |
|
240 gHttpHandler = nullptr; |
|
241 } |
|
242 |
|
243 nsresult |
|
244 nsHttpHandler::Init() |
|
245 { |
|
246 nsresult rv; |
|
247 |
|
248 LOG(("nsHttpHandler::Init\n")); |
|
249 |
|
250 rv = nsHttp::CreateAtomTable(); |
|
251 if (NS_FAILED(rv)) |
|
252 return rv; |
|
253 |
|
254 nsCOMPtr<nsIIOService> service = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); |
|
255 if (NS_FAILED(rv)) { |
|
256 NS_WARNING("unable to continue without io service"); |
|
257 return rv; |
|
258 } |
|
259 mIOService = new nsMainThreadPtrHolder<nsIIOService>(service); |
|
260 |
|
261 if (IsNeckoChild()) |
|
262 NeckoChild::InitNeckoChild(); |
|
263 |
|
264 InitUserAgentComponents(); |
|
265 |
|
266 // monitor some preference changes |
|
267 nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID); |
|
268 if (prefBranch) { |
|
269 prefBranch->AddObserver(HTTP_PREF_PREFIX, this, true); |
|
270 prefBranch->AddObserver(UA_PREF_PREFIX, this, true); |
|
271 prefBranch->AddObserver(INTL_ACCEPT_LANGUAGES, this, true); |
|
272 prefBranch->AddObserver(BROWSER_PREF("disk_cache_ssl"), this, true); |
|
273 prefBranch->AddObserver(DONOTTRACK_HEADER_ENABLED, this, true); |
|
274 prefBranch->AddObserver(DONOTTRACK_HEADER_VALUE, this, true); |
|
275 prefBranch->AddObserver(TELEMETRY_ENABLED, this, true); |
|
276 prefBranch->AddObserver(HTTP_PREF("tcp_keepalive.short_lived_connections"), this, true); |
|
277 prefBranch->AddObserver(HTTP_PREF("tcp_keepalive.long_lived_connections"), this, true); |
|
278 prefBranch->AddObserver(SAFE_HINT_HEADER_VALUE, this, true); |
|
279 PrefsChanged(prefBranch, nullptr); |
|
280 } |
|
281 |
|
282 mMisc.AssignLiteral("rv:" MOZILLA_UAVERSION); |
|
283 |
|
284 mCompatFirefox.AssignLiteral("Firefox/" MOZILLA_UAVERSION); |
|
285 |
|
286 nsCOMPtr<nsIXULAppInfo> appInfo = |
|
287 do_GetService("@mozilla.org/xre/app-info;1"); |
|
288 |
|
289 mAppName.AssignLiteral(MOZ_APP_UA_NAME); |
|
290 if (mAppName.Length() == 0 && appInfo) { |
|
291 // Try to get the UA name from appInfo, falling back to the name |
|
292 appInfo->GetUAName(mAppName); |
|
293 if (mAppName.Length() == 0) { |
|
294 appInfo->GetName(mAppName); |
|
295 } |
|
296 appInfo->GetVersion(mAppVersion); |
|
297 mAppName.StripChars(" ()<>@,;:\\\"/[]?={}"); |
|
298 } else { |
|
299 mAppVersion.AssignLiteral(MOZ_APP_UA_VERSION); |
|
300 } |
|
301 |
|
302 mSessionStartTime = NowInSeconds(); |
|
303 mHandlerActive = true; |
|
304 |
|
305 rv = mAuthCache.Init(); |
|
306 if (NS_FAILED(rv)) return rv; |
|
307 |
|
308 rv = mPrivateAuthCache.Init(); |
|
309 if (NS_FAILED(rv)) return rv; |
|
310 |
|
311 rv = InitConnectionMgr(); |
|
312 if (NS_FAILED(rv)) return rv; |
|
313 |
|
314 #ifdef ANDROID |
|
315 mProductSub.AssignLiteral(MOZILLA_UAVERSION); |
|
316 #else |
|
317 mProductSub.AssignLiteral("20100101"); |
|
318 #endif |
|
319 |
|
320 #if DEBUG |
|
321 // dump user agent prefs |
|
322 LOG(("> legacy-app-name = %s\n", mLegacyAppName.get())); |
|
323 LOG(("> legacy-app-version = %s\n", mLegacyAppVersion.get())); |
|
324 LOG(("> platform = %s\n", mPlatform.get())); |
|
325 LOG(("> oscpu = %s\n", mOscpu.get())); |
|
326 LOG(("> misc = %s\n", mMisc.get())); |
|
327 LOG(("> product = %s\n", mProduct.get())); |
|
328 LOG(("> product-sub = %s\n", mProductSub.get())); |
|
329 LOG(("> app-name = %s\n", mAppName.get())); |
|
330 LOG(("> app-version = %s\n", mAppVersion.get())); |
|
331 LOG(("> compat-firefox = %s\n", mCompatFirefox.get())); |
|
332 LOG(("> user-agent = %s\n", UserAgent().get())); |
|
333 #endif |
|
334 |
|
335 // Startup the http category |
|
336 // Bring alive the objects in the http-protocol-startup category |
|
337 NS_CreateServicesFromCategory(NS_HTTP_STARTUP_CATEGORY, |
|
338 static_cast<nsISupports*>(static_cast<void*>(this)), |
|
339 NS_HTTP_STARTUP_TOPIC); |
|
340 |
|
341 nsCOMPtr<nsIObserverService> obsService = services::GetObserverService(); |
|
342 mObserverService = new nsMainThreadPtrHolder<nsIObserverService>(obsService); |
|
343 if (mObserverService) { |
|
344 mObserverService->AddObserver(this, "profile-change-net-teardown", true); |
|
345 mObserverService->AddObserver(this, "profile-change-net-restore", true); |
|
346 mObserverService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true); |
|
347 mObserverService->AddObserver(this, "net:clear-active-logins", true); |
|
348 mObserverService->AddObserver(this, "net:prune-dead-connections", true); |
|
349 mObserverService->AddObserver(this, "net:prune-all-connections", true); |
|
350 mObserverService->AddObserver(this, "net:failed-to-process-uri-content", true); |
|
351 mObserverService->AddObserver(this, "last-pb-context-exited", true); |
|
352 } |
|
353 |
|
354 MakeNewRequestTokenBucket(); |
|
355 mWifiTickler = new Tickler(); |
|
356 if (NS_FAILED(mWifiTickler->Init())) |
|
357 mWifiTickler = nullptr; |
|
358 |
|
359 nsCOMPtr<nsIParentalControlsService> pc = do_CreateInstance("@mozilla.org/parental-controls-service;1"); |
|
360 if (pc) { |
|
361 pc->GetParentalControlsEnabled(&mParentalControlEnabled); |
|
362 } |
|
363 return NS_OK; |
|
364 } |
|
365 |
|
366 void |
|
367 nsHttpHandler::MakeNewRequestTokenBucket() |
|
368 { |
|
369 if (!mConnMgr) |
|
370 return; |
|
371 |
|
372 nsRefPtr<EventTokenBucket> tokenBucket = |
|
373 new EventTokenBucket(RequestTokenBucketHz(), |
|
374 RequestTokenBucketBurst()); |
|
375 mConnMgr->UpdateRequestTokenBucket(tokenBucket); |
|
376 } |
|
377 |
|
378 nsresult |
|
379 nsHttpHandler::InitConnectionMgr() |
|
380 { |
|
381 nsresult rv; |
|
382 |
|
383 if (!mConnMgr) { |
|
384 mConnMgr = new nsHttpConnectionMgr(); |
|
385 if (!mConnMgr) |
|
386 return NS_ERROR_OUT_OF_MEMORY; |
|
387 NS_ADDREF(mConnMgr); |
|
388 } |
|
389 |
|
390 rv = mConnMgr->Init(mMaxConnections, |
|
391 mMaxPersistentConnectionsPerServer, |
|
392 mMaxPersistentConnectionsPerProxy, |
|
393 mMaxRequestDelay, |
|
394 mMaxPipelinedRequests, |
|
395 mMaxOptimisticPipelinedRequests); |
|
396 return rv; |
|
397 } |
|
398 |
|
399 nsresult |
|
400 nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request) |
|
401 { |
|
402 nsresult rv; |
|
403 |
|
404 // Add the "User-Agent" header |
|
405 rv = request->SetHeader(nsHttp::User_Agent, UserAgent()); |
|
406 if (NS_FAILED(rv)) return rv; |
|
407 |
|
408 // MIME based content negotiation lives! |
|
409 // Add the "Accept" header |
|
410 rv = request->SetHeader(nsHttp::Accept, mAccept); |
|
411 if (NS_FAILED(rv)) return rv; |
|
412 |
|
413 // Add the "Accept-Language" header |
|
414 if (!mAcceptLanguages.IsEmpty()) { |
|
415 // Add the "Accept-Language" header |
|
416 rv = request->SetHeader(nsHttp::Accept_Language, mAcceptLanguages); |
|
417 if (NS_FAILED(rv)) return rv; |
|
418 } |
|
419 |
|
420 // Add the "Accept-Encoding" header |
|
421 rv = request->SetHeader(nsHttp::Accept_Encoding, mAcceptEncodings); |
|
422 if (NS_FAILED(rv)) return rv; |
|
423 |
|
424 // Add the "Do-Not-Track" header |
|
425 if (mDoNotTrackEnabled) { |
|
426 rv = request->SetHeader(nsHttp::DoNotTrack, |
|
427 nsPrintfCString("%d", mDoNotTrackValue)); |
|
428 if (NS_FAILED(rv)) return rv; |
|
429 } |
|
430 |
|
431 // add the "Send Hint" header |
|
432 if (mSafeHintEnabled || mParentalControlEnabled) { |
|
433 rv = request->SetHeader(nsHttp::Prefer, NS_LITERAL_CSTRING("safe")); |
|
434 if (NS_FAILED(rv)) return rv; |
|
435 } |
|
436 return NS_OK; |
|
437 } |
|
438 |
|
439 nsresult |
|
440 nsHttpHandler::AddConnectionHeader(nsHttpHeaderArray *request, |
|
441 uint32_t caps) |
|
442 { |
|
443 // RFC2616 section 19.6.2 states that the "Connection: keep-alive" |
|
444 // and "Keep-alive" request headers should not be sent by HTTP/1.1 |
|
445 // user-agents. But this is not a problem in practice, and the |
|
446 // alternative proxy-connection is worse. see 570283 |
|
447 |
|
448 NS_NAMED_LITERAL_CSTRING(close, "close"); |
|
449 NS_NAMED_LITERAL_CSTRING(keepAlive, "keep-alive"); |
|
450 |
|
451 const nsACString *connectionType = &close; |
|
452 if (caps & NS_HTTP_ALLOW_KEEPALIVE) { |
|
453 connectionType = &keepAlive; |
|
454 } |
|
455 |
|
456 return request->SetHeader(nsHttp::Connection, *connectionType); |
|
457 } |
|
458 |
|
459 bool |
|
460 nsHttpHandler::IsAcceptableEncoding(const char *enc) |
|
461 { |
|
462 if (!enc) |
|
463 return false; |
|
464 |
|
465 // HTTP 1.1 allows servers to send x-gzip and x-compress instead |
|
466 // of gzip and compress, for example. So, we'll always strip off |
|
467 // an "x-" prefix before matching the encoding to one we claim |
|
468 // to accept. |
|
469 if (!PL_strncasecmp(enc, "x-", 2)) |
|
470 enc += 2; |
|
471 |
|
472 // gzip and deflate are inherently acceptable in modern HTTP - always |
|
473 // process them if a stream converter can also be found. |
|
474 if (!PL_strcasecmp(enc, "gzip") || !PL_strcasecmp(enc, "deflate")) |
|
475 return true; |
|
476 |
|
477 return nsHttp::FindToken(mAcceptEncodings.get(), enc, HTTP_LWS ",") != nullptr; |
|
478 } |
|
479 |
|
480 nsresult |
|
481 nsHttpHandler::GetStreamConverterService(nsIStreamConverterService **result) |
|
482 { |
|
483 if (!mStreamConvSvc) { |
|
484 nsresult rv; |
|
485 nsCOMPtr<nsIStreamConverterService> service = |
|
486 do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv); |
|
487 if (NS_FAILED(rv)) |
|
488 return rv; |
|
489 mStreamConvSvc = new nsMainThreadPtrHolder<nsIStreamConverterService>(service); |
|
490 } |
|
491 *result = mStreamConvSvc; |
|
492 NS_ADDREF(*result); |
|
493 return NS_OK; |
|
494 } |
|
495 |
|
496 nsISiteSecurityService* |
|
497 nsHttpHandler::GetSSService() |
|
498 { |
|
499 if (!mSSService) { |
|
500 nsCOMPtr<nsISiteSecurityService> service = do_GetService(NS_SSSERVICE_CONTRACTID); |
|
501 mSSService = new nsMainThreadPtrHolder<nsISiteSecurityService>(service); |
|
502 } |
|
503 return mSSService; |
|
504 } |
|
505 |
|
506 nsICookieService * |
|
507 nsHttpHandler::GetCookieService() |
|
508 { |
|
509 if (!mCookieService) { |
|
510 nsCOMPtr<nsICookieService> service = do_GetService(NS_COOKIESERVICE_CONTRACTID); |
|
511 mCookieService = new nsMainThreadPtrHolder<nsICookieService>(service); |
|
512 } |
|
513 return mCookieService; |
|
514 } |
|
515 |
|
516 nsresult |
|
517 nsHttpHandler::GetIOService(nsIIOService** result) |
|
518 { |
|
519 NS_ADDREF(*result = mIOService); |
|
520 return NS_OK; |
|
521 } |
|
522 |
|
523 uint32_t |
|
524 nsHttpHandler::Get32BitsOfPseudoRandom() |
|
525 { |
|
526 // only confirm rand seeding on socket thread |
|
527 MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); |
|
528 |
|
529 // rand() provides different amounts of PRNG on different platforms. |
|
530 // 15 or 31 bits are common amounts. |
|
531 |
|
532 PR_STATIC_ASSERT(RAND_MAX >= 0xfff); |
|
533 |
|
534 #if RAND_MAX < 0xffffU |
|
535 return ((uint16_t) rand() << 20) | |
|
536 (((uint16_t) rand() & 0xfff) << 8) | |
|
537 ((uint16_t) rand() & 0xff); |
|
538 #elif RAND_MAX < 0xffffffffU |
|
539 return ((uint16_t) rand() << 16) | ((uint16_t) rand() & 0xffff); |
|
540 #else |
|
541 return (uint32_t) rand(); |
|
542 #endif |
|
543 } |
|
544 |
|
545 void |
|
546 nsHttpHandler::NotifyObservers(nsIHttpChannel *chan, const char *event) |
|
547 { |
|
548 LOG(("nsHttpHandler::NotifyObservers [chan=%x event=\"%s\"]\n", chan, event)); |
|
549 if (mObserverService) |
|
550 mObserverService->NotifyObservers(chan, event, nullptr); |
|
551 } |
|
552 |
|
553 nsresult |
|
554 nsHttpHandler::AsyncOnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan, |
|
555 uint32_t flags) |
|
556 { |
|
557 // TODO E10S This helper has to be initialized on the other process |
|
558 nsRefPtr<nsAsyncRedirectVerifyHelper> redirectCallbackHelper = |
|
559 new nsAsyncRedirectVerifyHelper(); |
|
560 |
|
561 return redirectCallbackHelper->Init(oldChan, newChan, flags); |
|
562 } |
|
563 |
|
564 /* static */ nsresult |
|
565 nsHttpHandler::GenerateHostPort(const nsCString& host, int32_t port, |
|
566 nsCString& hostLine) |
|
567 { |
|
568 return NS_GenerateHostPort(host, port, hostLine); |
|
569 } |
|
570 |
|
571 //----------------------------------------------------------------------------- |
|
572 // nsHttpHandler <private> |
|
573 //----------------------------------------------------------------------------- |
|
574 |
|
575 const nsAFlatCString & |
|
576 nsHttpHandler::UserAgent() |
|
577 { |
|
578 if (mUserAgentOverride) { |
|
579 LOG(("using general.useragent.override : %s\n", mUserAgentOverride.get())); |
|
580 return mUserAgentOverride; |
|
581 } |
|
582 |
|
583 if (mUserAgentIsDirty) { |
|
584 BuildUserAgent(); |
|
585 mUserAgentIsDirty = false; |
|
586 } |
|
587 |
|
588 return mUserAgent; |
|
589 } |
|
590 |
|
591 void |
|
592 nsHttpHandler::BuildUserAgent() |
|
593 { |
|
594 LOG(("nsHttpHandler::BuildUserAgent\n")); |
|
595 |
|
596 MOZ_ASSERT(!mLegacyAppName.IsEmpty() && |
|
597 !mLegacyAppVersion.IsEmpty(), |
|
598 "HTTP cannot send practical requests without this much"); |
|
599 |
|
600 // preallocate to worst-case size, which should always be better |
|
601 // than if we didn't preallocate at all. |
|
602 mUserAgent.SetCapacity(mLegacyAppName.Length() + |
|
603 mLegacyAppVersion.Length() + |
|
604 #ifndef UA_SPARE_PLATFORM |
|
605 mPlatform.Length() + |
|
606 #endif |
|
607 mOscpu.Length() + |
|
608 mMisc.Length() + |
|
609 mProduct.Length() + |
|
610 mProductSub.Length() + |
|
611 mAppName.Length() + |
|
612 mAppVersion.Length() + |
|
613 mCompatFirefox.Length() + |
|
614 mCompatDevice.Length() + |
|
615 13); |
|
616 |
|
617 // Application portion |
|
618 mUserAgent.Assign(mLegacyAppName); |
|
619 mUserAgent += '/'; |
|
620 mUserAgent += mLegacyAppVersion; |
|
621 mUserAgent += ' '; |
|
622 |
|
623 // Application comment |
|
624 mUserAgent += '('; |
|
625 #ifndef UA_SPARE_PLATFORM |
|
626 if (!mPlatform.IsEmpty()) { |
|
627 mUserAgent += mPlatform; |
|
628 mUserAgent.AppendLiteral("; "); |
|
629 } |
|
630 #endif |
|
631 if (!mCompatDevice.IsEmpty()) { |
|
632 mUserAgent += mCompatDevice; |
|
633 mUserAgent.AppendLiteral("; "); |
|
634 } |
|
635 else if (!mOscpu.IsEmpty()) { |
|
636 mUserAgent += mOscpu; |
|
637 mUserAgent.AppendLiteral("; "); |
|
638 } |
|
639 mUserAgent += mMisc; |
|
640 mUserAgent += ')'; |
|
641 |
|
642 // Product portion |
|
643 mUserAgent += ' '; |
|
644 mUserAgent += mProduct; |
|
645 mUserAgent += '/'; |
|
646 mUserAgent += mProductSub; |
|
647 |
|
648 bool isFirefox = mAppName.EqualsLiteral("Firefox"); |
|
649 if (isFirefox || mCompatFirefoxEnabled) { |
|
650 // "Firefox/x.y" (compatibility) app token |
|
651 mUserAgent += ' '; |
|
652 mUserAgent += mCompatFirefox; |
|
653 } |
|
654 if (!isFirefox) { |
|
655 // App portion |
|
656 mUserAgent += ' '; |
|
657 mUserAgent += mAppName; |
|
658 mUserAgent += '/'; |
|
659 mUserAgent += mAppVersion; |
|
660 } |
|
661 } |
|
662 |
|
663 #ifdef XP_WIN |
|
664 #define WNT_BASE "Windows NT %ld.%ld" |
|
665 #define W64_PREFIX "; Win64" |
|
666 #endif |
|
667 |
|
668 void |
|
669 nsHttpHandler::InitUserAgentComponents() |
|
670 { |
|
671 #ifndef MOZ_UA_OS_AGNOSTIC |
|
672 // Gather platform. |
|
673 mPlatform.AssignLiteral( |
|
674 #if defined(ANDROID) |
|
675 "Android" |
|
676 #elif defined(XP_WIN) |
|
677 "Windows" |
|
678 #elif defined(XP_MACOSX) |
|
679 "Macintosh" |
|
680 #elif defined(MOZ_X11) |
|
681 "X11" |
|
682 #endif |
|
683 ); |
|
684 #endif |
|
685 |
|
686 #if defined(ANDROID) || defined(MOZ_B2G) |
|
687 nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1"); |
|
688 MOZ_ASSERT(infoService, "Could not find a system info service"); |
|
689 |
|
690 bool isTablet; |
|
691 nsresult rv = infoService->GetPropertyAsBool(NS_LITERAL_STRING("tablet"), &isTablet); |
|
692 if (NS_SUCCEEDED(rv) && isTablet) |
|
693 mCompatDevice.AssignLiteral("Tablet"); |
|
694 else |
|
695 mCompatDevice.AssignLiteral("Mobile"); |
|
696 #endif |
|
697 |
|
698 #ifndef MOZ_UA_OS_AGNOSTIC |
|
699 // Gather OS/CPU. |
|
700 #if defined(XP_WIN) |
|
701 OSVERSIONINFO info = { sizeof(OSVERSIONINFO) }; |
|
702 #pragma warning(push) |
|
703 #pragma warning(disable:4996) |
|
704 if (GetVersionEx(&info)) { |
|
705 #pragma warning(pop) |
|
706 const char *format; |
|
707 #if defined _M_IA64 |
|
708 format = WNT_BASE W64_PREFIX "; IA64"; |
|
709 #elif defined _M_X64 || defined _M_AMD64 |
|
710 format = WNT_BASE W64_PREFIX "; x64"; |
|
711 #else |
|
712 BOOL isWow64 = FALSE; |
|
713 if (!IsWow64Process(GetCurrentProcess(), &isWow64)) { |
|
714 isWow64 = FALSE; |
|
715 } |
|
716 format = isWow64 |
|
717 ? WNT_BASE "; WOW64" |
|
718 : WNT_BASE; |
|
719 #endif |
|
720 char *buf = PR_smprintf(format, |
|
721 info.dwMajorVersion, |
|
722 info.dwMinorVersion); |
|
723 if (buf) { |
|
724 mOscpu = buf; |
|
725 PR_smprintf_free(buf); |
|
726 } |
|
727 } |
|
728 #elif defined (XP_MACOSX) |
|
729 #if defined(__ppc__) |
|
730 mOscpu.AssignLiteral("PPC Mac OS X"); |
|
731 #elif defined(__i386__) || defined(__x86_64__) |
|
732 mOscpu.AssignLiteral("Intel Mac OS X"); |
|
733 #endif |
|
734 SInt32 majorVersion = nsCocoaFeatures::OSXVersionMajor(); |
|
735 SInt32 minorVersion = nsCocoaFeatures::OSXVersionMinor(); |
|
736 mOscpu += nsPrintfCString(" %d.%d", majorVersion, minorVersion); |
|
737 #elif defined (XP_UNIX) |
|
738 struct utsname name; |
|
739 |
|
740 int ret = uname(&name); |
|
741 if (ret >= 0) { |
|
742 nsAutoCString buf; |
|
743 buf = (char*)name.sysname; |
|
744 |
|
745 if (strcmp(name.machine, "x86_64") == 0 && |
|
746 sizeof(void *) == sizeof(int32_t)) { |
|
747 // We're running 32-bit code on x86_64. Make this browser |
|
748 // look like it's running on i686 hardware, but append " |
|
749 // (x86_64)" to the end of the oscpu identifier to be able |
|
750 // to differentiate this from someone running 64-bit code |
|
751 // on x86_64.. |
|
752 |
|
753 buf += " i686 on x86_64"; |
|
754 } else { |
|
755 buf += ' '; |
|
756 |
|
757 #ifdef AIX |
|
758 // AIX uname returns machine specific info in the uname.machine |
|
759 // field and does not return the cpu type like other platforms. |
|
760 // We use the AIX version and release numbers instead. |
|
761 buf += (char*)name.version; |
|
762 buf += '.'; |
|
763 buf += (char*)name.release; |
|
764 #else |
|
765 buf += (char*)name.machine; |
|
766 #endif |
|
767 } |
|
768 |
|
769 mOscpu.Assign(buf); |
|
770 } |
|
771 #endif |
|
772 #endif |
|
773 |
|
774 mUserAgentIsDirty = true; |
|
775 } |
|
776 |
|
777 uint32_t |
|
778 nsHttpHandler::MaxSocketCount() |
|
779 { |
|
780 PR_CallOnce(&nsSocketTransportService::gMaxCountInitOnce, |
|
781 nsSocketTransportService::DiscoverMaxCount); |
|
782 // Don't use the full max count because sockets can be held in |
|
783 // the persistent connection pool for a long time and that could |
|
784 // starve other users. |
|
785 |
|
786 uint32_t maxCount = nsSocketTransportService::gMaxCount; |
|
787 if (maxCount <= 8) |
|
788 maxCount = 1; |
|
789 else |
|
790 maxCount -= 8; |
|
791 |
|
792 return maxCount; |
|
793 } |
|
794 |
|
795 void |
|
796 nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref) |
|
797 { |
|
798 nsresult rv = NS_OK; |
|
799 int32_t val; |
|
800 |
|
801 LOG(("nsHttpHandler::PrefsChanged [pref=%s]\n", pref)); |
|
802 |
|
803 #define PREF_CHANGED(p) ((pref == nullptr) || !PL_strcmp(pref, p)) |
|
804 #define MULTI_PREF_CHANGED(p) \ |
|
805 ((pref == nullptr) || !PL_strncmp(pref, p, sizeof(p) - 1)) |
|
806 |
|
807 // |
|
808 // UA components |
|
809 // |
|
810 |
|
811 bool cVar = false; |
|
812 |
|
813 if (PREF_CHANGED(UA_PREF("compatMode.firefox"))) { |
|
814 rv = prefs->GetBoolPref(UA_PREF("compatMode.firefox"), &cVar); |
|
815 mCompatFirefoxEnabled = (NS_SUCCEEDED(rv) && cVar); |
|
816 mUserAgentIsDirty = true; |
|
817 } |
|
818 |
|
819 // general.useragent.override |
|
820 if (PREF_CHANGED(UA_PREF("override"))) { |
|
821 prefs->GetCharPref(UA_PREF("override"), |
|
822 getter_Copies(mUserAgentOverride)); |
|
823 mUserAgentIsDirty = true; |
|
824 } |
|
825 |
|
826 // |
|
827 // HTTP options |
|
828 // |
|
829 |
|
830 if (PREF_CHANGED(HTTP_PREF("keep-alive.timeout"))) { |
|
831 rv = prefs->GetIntPref(HTTP_PREF("keep-alive.timeout"), &val); |
|
832 if (NS_SUCCEEDED(rv)) |
|
833 mIdleTimeout = PR_SecondsToInterval(clamped(val, 1, 0xffff)); |
|
834 } |
|
835 |
|
836 if (PREF_CHANGED(HTTP_PREF("request.max-attempts"))) { |
|
837 rv = prefs->GetIntPref(HTTP_PREF("request.max-attempts"), &val); |
|
838 if (NS_SUCCEEDED(rv)) |
|
839 mMaxRequestAttempts = (uint16_t) clamped(val, 1, 0xffff); |
|
840 } |
|
841 |
|
842 if (PREF_CHANGED(HTTP_PREF("request.max-start-delay"))) { |
|
843 rv = prefs->GetIntPref(HTTP_PREF("request.max-start-delay"), &val); |
|
844 if (NS_SUCCEEDED(rv)) { |
|
845 mMaxRequestDelay = (uint16_t) clamped(val, 0, 0xffff); |
|
846 if (mConnMgr) |
|
847 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_REQUEST_DELAY, |
|
848 mMaxRequestDelay); |
|
849 } |
|
850 } |
|
851 |
|
852 if (PREF_CHANGED(HTTP_PREF("response.timeout"))) { |
|
853 rv = prefs->GetIntPref(HTTP_PREF("response.timeout"), &val); |
|
854 if (NS_SUCCEEDED(rv)) |
|
855 mResponseTimeout = PR_SecondsToInterval(clamped(val, 0, 0xffff)); |
|
856 } |
|
857 |
|
858 if (PREF_CHANGED(HTTP_PREF("max-connections"))) { |
|
859 rv = prefs->GetIntPref(HTTP_PREF("max-connections"), &val); |
|
860 if (NS_SUCCEEDED(rv)) { |
|
861 |
|
862 mMaxConnections = (uint16_t) clamped((uint32_t)val, |
|
863 (uint32_t)1, MaxSocketCount()); |
|
864 |
|
865 if (mConnMgr) |
|
866 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS, |
|
867 mMaxConnections); |
|
868 } |
|
869 } |
|
870 |
|
871 if (PREF_CHANGED(HTTP_PREF("max-persistent-connections-per-server"))) { |
|
872 rv = prefs->GetIntPref(HTTP_PREF("max-persistent-connections-per-server"), &val); |
|
873 if (NS_SUCCEEDED(rv)) { |
|
874 mMaxPersistentConnectionsPerServer = (uint8_t) clamped(val, 1, 0xff); |
|
875 if (mConnMgr) |
|
876 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_PERSISTENT_CONNECTIONS_PER_HOST, |
|
877 mMaxPersistentConnectionsPerServer); |
|
878 } |
|
879 } |
|
880 |
|
881 if (PREF_CHANGED(HTTP_PREF("max-persistent-connections-per-proxy"))) { |
|
882 rv = prefs->GetIntPref(HTTP_PREF("max-persistent-connections-per-proxy"), &val); |
|
883 if (NS_SUCCEEDED(rv)) { |
|
884 mMaxPersistentConnectionsPerProxy = (uint8_t) clamped(val, 1, 0xff); |
|
885 if (mConnMgr) |
|
886 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_PERSISTENT_CONNECTIONS_PER_PROXY, |
|
887 mMaxPersistentConnectionsPerProxy); |
|
888 } |
|
889 } |
|
890 |
|
891 if (PREF_CHANGED(HTTP_PREF("sendRefererHeader"))) { |
|
892 rv = prefs->GetIntPref(HTTP_PREF("sendRefererHeader"), &val); |
|
893 if (NS_SUCCEEDED(rv)) |
|
894 mReferrerLevel = (uint8_t) clamped(val, 0, 0xff); |
|
895 } |
|
896 |
|
897 if (PREF_CHANGED(HTTP_PREF("referer.spoofSource"))) { |
|
898 rv = prefs->GetBoolPref(HTTP_PREF("referer.spoofSource"), &cVar); |
|
899 if (NS_SUCCEEDED(rv)) |
|
900 mSpoofReferrerSource = cVar; |
|
901 } |
|
902 |
|
903 if (PREF_CHANGED(HTTP_PREF("referer.trimmingPolicy"))) { |
|
904 rv = prefs->GetIntPref(HTTP_PREF("referer.trimmingPolicy"), &val); |
|
905 if (NS_SUCCEEDED(rv)) |
|
906 mReferrerTrimmingPolicy = (uint8_t) clamped(val, 0, 0xff); |
|
907 } |
|
908 |
|
909 if (PREF_CHANGED(HTTP_PREF("referer.XOriginPolicy"))) { |
|
910 rv = prefs->GetIntPref(HTTP_PREF("referer.XOriginPolicy"), &val); |
|
911 if (NS_SUCCEEDED(rv)) |
|
912 mReferrerXOriginPolicy = (uint8_t) clamped(val, 0, 0xff); |
|
913 } |
|
914 |
|
915 if (PREF_CHANGED(HTTP_PREF("redirection-limit"))) { |
|
916 rv = prefs->GetIntPref(HTTP_PREF("redirection-limit"), &val); |
|
917 if (NS_SUCCEEDED(rv)) |
|
918 mRedirectionLimit = (uint8_t) clamped(val, 0, 0xff); |
|
919 } |
|
920 |
|
921 if (PREF_CHANGED(HTTP_PREF("connection-retry-timeout"))) { |
|
922 rv = prefs->GetIntPref(HTTP_PREF("connection-retry-timeout"), &val); |
|
923 if (NS_SUCCEEDED(rv)) |
|
924 mIdleSynTimeout = (uint16_t) clamped(val, 0, 3000); |
|
925 } |
|
926 |
|
927 if (PREF_CHANGED(HTTP_PREF("fast-fallback-to-IPv4"))) { |
|
928 rv = prefs->GetBoolPref(HTTP_PREF("fast-fallback-to-IPv4"), &cVar); |
|
929 if (NS_SUCCEEDED(rv)) |
|
930 mFastFallbackToIPv4 = cVar; |
|
931 } |
|
932 |
|
933 if (PREF_CHANGED(HTTP_PREF("version"))) { |
|
934 nsXPIDLCString httpVersion; |
|
935 prefs->GetCharPref(HTTP_PREF("version"), getter_Copies(httpVersion)); |
|
936 if (httpVersion) { |
|
937 if (!PL_strcmp(httpVersion, "1.1")) |
|
938 mHttpVersion = NS_HTTP_VERSION_1_1; |
|
939 else if (!PL_strcmp(httpVersion, "0.9")) |
|
940 mHttpVersion = NS_HTTP_VERSION_0_9; |
|
941 else |
|
942 mHttpVersion = NS_HTTP_VERSION_1_0; |
|
943 } |
|
944 } |
|
945 |
|
946 if (PREF_CHANGED(HTTP_PREF("proxy.version"))) { |
|
947 nsXPIDLCString httpVersion; |
|
948 prefs->GetCharPref(HTTP_PREF("proxy.version"), getter_Copies(httpVersion)); |
|
949 if (httpVersion) { |
|
950 if (!PL_strcmp(httpVersion, "1.1")) |
|
951 mProxyHttpVersion = NS_HTTP_VERSION_1_1; |
|
952 else |
|
953 mProxyHttpVersion = NS_HTTP_VERSION_1_0; |
|
954 // it does not make sense to issue a HTTP/0.9 request to a proxy server |
|
955 } |
|
956 } |
|
957 |
|
958 if (PREF_CHANGED(HTTP_PREF("pipelining"))) { |
|
959 rv = prefs->GetBoolPref(HTTP_PREF("pipelining"), &cVar); |
|
960 if (NS_SUCCEEDED(rv)) { |
|
961 if (cVar) |
|
962 mCapabilities |= NS_HTTP_ALLOW_PIPELINING; |
|
963 else |
|
964 mCapabilities &= ~NS_HTTP_ALLOW_PIPELINING; |
|
965 mPipeliningEnabled = cVar; |
|
966 } |
|
967 } |
|
968 |
|
969 if (PREF_CHANGED(HTTP_PREF("pipelining.maxrequests"))) { |
|
970 rv = prefs->GetIntPref(HTTP_PREF("pipelining.maxrequests"), &val); |
|
971 if (NS_SUCCEEDED(rv)) { |
|
972 mMaxPipelinedRequests = clamped(val, 1, 0xffff); |
|
973 if (mConnMgr) |
|
974 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_PIPELINED_REQUESTS, |
|
975 mMaxPipelinedRequests); |
|
976 } |
|
977 } |
|
978 |
|
979 if (PREF_CHANGED(HTTP_PREF("pipelining.max-optimistic-requests"))) { |
|
980 rv = prefs-> |
|
981 GetIntPref(HTTP_PREF("pipelining.max-optimistic-requests"), &val); |
|
982 if (NS_SUCCEEDED(rv)) { |
|
983 mMaxOptimisticPipelinedRequests = clamped(val, 1, 0xffff); |
|
984 if (mConnMgr) |
|
985 mConnMgr->UpdateParam |
|
986 (nsHttpConnectionMgr::MAX_OPTIMISTIC_PIPELINED_REQUESTS, |
|
987 mMaxOptimisticPipelinedRequests); |
|
988 } |
|
989 } |
|
990 |
|
991 if (PREF_CHANGED(HTTP_PREF("pipelining.aggressive"))) { |
|
992 rv = prefs->GetBoolPref(HTTP_PREF("pipelining.aggressive"), &cVar); |
|
993 if (NS_SUCCEEDED(rv)) |
|
994 mPipelineAggressive = cVar; |
|
995 } |
|
996 |
|
997 if (PREF_CHANGED(HTTP_PREF("pipelining.maxsize"))) { |
|
998 rv = prefs->GetIntPref(HTTP_PREF("pipelining.maxsize"), &val); |
|
999 if (NS_SUCCEEDED(rv)) { |
|
1000 mMaxPipelineObjectSize = |
|
1001 static_cast<int64_t>(clamped(val, 1000, 100000000)); |
|
1002 } |
|
1003 } |
|
1004 |
|
1005 // Determines whether or not to actually reschedule after the |
|
1006 // reschedule-timeout has expired |
|
1007 if (PREF_CHANGED(HTTP_PREF("pipelining.reschedule-on-timeout"))) { |
|
1008 rv = prefs->GetBoolPref(HTTP_PREF("pipelining.reschedule-on-timeout"), |
|
1009 &cVar); |
|
1010 if (NS_SUCCEEDED(rv)) |
|
1011 mPipelineRescheduleOnTimeout = cVar; |
|
1012 } |
|
1013 |
|
1014 // The amount of time head of line blocking is allowed (in ms) |
|
1015 // before the blocked transactions are moved to another pipeline |
|
1016 if (PREF_CHANGED(HTTP_PREF("pipelining.reschedule-timeout"))) { |
|
1017 rv = prefs->GetIntPref(HTTP_PREF("pipelining.reschedule-timeout"), |
|
1018 &val); |
|
1019 if (NS_SUCCEEDED(rv)) { |
|
1020 mPipelineRescheduleTimeout = |
|
1021 PR_MillisecondsToInterval((uint16_t) clamped(val, 500, 0xffff)); |
|
1022 } |
|
1023 } |
|
1024 |
|
1025 // The amount of time a pipelined transaction is allowed to wait before |
|
1026 // being canceled and retried in a non-pipeline connection |
|
1027 if (PREF_CHANGED(HTTP_PREF("pipelining.read-timeout"))) { |
|
1028 rv = prefs->GetIntPref(HTTP_PREF("pipelining.read-timeout"), &val); |
|
1029 if (NS_SUCCEEDED(rv)) { |
|
1030 mPipelineReadTimeout = |
|
1031 PR_MillisecondsToInterval((uint16_t) clamped(val, 5000, |
|
1032 0xffff)); |
|
1033 } |
|
1034 } |
|
1035 |
|
1036 if (PREF_CHANGED(HTTP_PREF("pipelining.ssl"))) { |
|
1037 rv = prefs->GetBoolPref(HTTP_PREF("pipelining.ssl"), &cVar); |
|
1038 if (NS_SUCCEEDED(rv)) |
|
1039 mPipeliningOverSSL = cVar; |
|
1040 } |
|
1041 |
|
1042 if (PREF_CHANGED(HTTP_PREF("proxy.pipelining"))) { |
|
1043 rv = prefs->GetBoolPref(HTTP_PREF("proxy.pipelining"), &cVar); |
|
1044 if (NS_SUCCEEDED(rv)) |
|
1045 mProxyPipelining = cVar; |
|
1046 } |
|
1047 |
|
1048 if (PREF_CHANGED(HTTP_PREF("qos"))) { |
|
1049 rv = prefs->GetIntPref(HTTP_PREF("qos"), &val); |
|
1050 if (NS_SUCCEEDED(rv)) |
|
1051 mQoSBits = (uint8_t) clamped(val, 0, 0xff); |
|
1052 } |
|
1053 |
|
1054 if (PREF_CHANGED(HTTP_PREF("sendSecureXSiteReferrer"))) { |
|
1055 rv = prefs->GetBoolPref(HTTP_PREF("sendSecureXSiteReferrer"), &cVar); |
|
1056 if (NS_SUCCEEDED(rv)) |
|
1057 mSendSecureXSiteReferrer = cVar; |
|
1058 } |
|
1059 |
|
1060 if (PREF_CHANGED(HTTP_PREF("accept.default"))) { |
|
1061 nsXPIDLCString accept; |
|
1062 rv = prefs->GetCharPref(HTTP_PREF("accept.default"), |
|
1063 getter_Copies(accept)); |
|
1064 if (NS_SUCCEEDED(rv)) |
|
1065 SetAccept(accept); |
|
1066 } |
|
1067 |
|
1068 if (PREF_CHANGED(HTTP_PREF("accept-encoding"))) { |
|
1069 nsXPIDLCString acceptEncodings; |
|
1070 rv = prefs->GetCharPref(HTTP_PREF("accept-encoding"), |
|
1071 getter_Copies(acceptEncodings)); |
|
1072 if (NS_SUCCEEDED(rv)) |
|
1073 SetAcceptEncodings(acceptEncodings); |
|
1074 } |
|
1075 |
|
1076 if (PREF_CHANGED(HTTP_PREF("use-cache"))) { |
|
1077 rv = prefs->GetBoolPref(HTTP_PREF("use-cache"), &cVar); |
|
1078 if (NS_SUCCEEDED(rv)) { |
|
1079 mUseCache = cVar; |
|
1080 } |
|
1081 } |
|
1082 |
|
1083 if (PREF_CHANGED(HTTP_PREF("default-socket-type"))) { |
|
1084 nsXPIDLCString sval; |
|
1085 rv = prefs->GetCharPref(HTTP_PREF("default-socket-type"), |
|
1086 getter_Copies(sval)); |
|
1087 if (NS_SUCCEEDED(rv)) { |
|
1088 if (sval.IsEmpty()) |
|
1089 mDefaultSocketType.Adopt(0); |
|
1090 else { |
|
1091 // verify that this socket type is actually valid |
|
1092 nsCOMPtr<nsISocketProviderService> sps( |
|
1093 do_GetService(NS_SOCKETPROVIDERSERVICE_CONTRACTID)); |
|
1094 if (sps) { |
|
1095 nsCOMPtr<nsISocketProvider> sp; |
|
1096 rv = sps->GetSocketProvider(sval, getter_AddRefs(sp)); |
|
1097 if (NS_SUCCEEDED(rv)) { |
|
1098 // OK, this looks like a valid socket provider. |
|
1099 mDefaultSocketType.Assign(sval); |
|
1100 } |
|
1101 } |
|
1102 } |
|
1103 } |
|
1104 } |
|
1105 |
|
1106 if (PREF_CHANGED(HTTP_PREF("prompt-temp-redirect"))) { |
|
1107 rv = prefs->GetBoolPref(HTTP_PREF("prompt-temp-redirect"), &cVar); |
|
1108 if (NS_SUCCEEDED(rv)) { |
|
1109 mPromptTempRedirect = cVar; |
|
1110 } |
|
1111 } |
|
1112 |
|
1113 if (PREF_CHANGED(HTTP_PREF("assoc-req.enforce"))) { |
|
1114 cVar = false; |
|
1115 rv = prefs->GetBoolPref(HTTP_PREF("assoc-req.enforce"), &cVar); |
|
1116 if (NS_SUCCEEDED(rv)) |
|
1117 mEnforceAssocReq = cVar; |
|
1118 } |
|
1119 |
|
1120 // enable Persistent caching for HTTPS - bug#205921 |
|
1121 if (PREF_CHANGED(BROWSER_PREF("disk_cache_ssl"))) { |
|
1122 cVar = false; |
|
1123 rv = prefs->GetBoolPref(BROWSER_PREF("disk_cache_ssl"), &cVar); |
|
1124 if (NS_SUCCEEDED(rv)) |
|
1125 mEnablePersistentHttpsCaching = cVar; |
|
1126 } |
|
1127 |
|
1128 if (PREF_CHANGED(HTTP_PREF("phishy-userpass-length"))) { |
|
1129 rv = prefs->GetIntPref(HTTP_PREF("phishy-userpass-length"), &val); |
|
1130 if (NS_SUCCEEDED(rv)) |
|
1131 mPhishyUserPassLength = (uint8_t) clamped(val, 0, 0xff); |
|
1132 } |
|
1133 |
|
1134 if (PREF_CHANGED(HTTP_PREF("spdy.enabled"))) { |
|
1135 rv = prefs->GetBoolPref(HTTP_PREF("spdy.enabled"), &cVar); |
|
1136 if (NS_SUCCEEDED(rv)) |
|
1137 mEnableSpdy = cVar; |
|
1138 } |
|
1139 |
|
1140 if (PREF_CHANGED(HTTP_PREF("spdy.enabled.v3"))) { |
|
1141 rv = prefs->GetBoolPref(HTTP_PREF("spdy.enabled.v3"), &cVar); |
|
1142 if (NS_SUCCEEDED(rv)) |
|
1143 mSpdyV3 = cVar; |
|
1144 } |
|
1145 |
|
1146 if (PREF_CHANGED(HTTP_PREF("spdy.enabled.v3-1"))) { |
|
1147 rv = prefs->GetBoolPref(HTTP_PREF("spdy.enabled.v3-1"), &cVar); |
|
1148 if (NS_SUCCEEDED(rv)) |
|
1149 mSpdyV31 = cVar; |
|
1150 } |
|
1151 |
|
1152 if (PREF_CHANGED(HTTP_PREF("spdy.enabled.http2draft"))) { |
|
1153 rv = prefs->GetBoolPref(HTTP_PREF("spdy.enabled.http2draft"), &cVar); |
|
1154 if (NS_SUCCEEDED(rv)) |
|
1155 mHttp2DraftEnabled = cVar; |
|
1156 } |
|
1157 |
|
1158 if (PREF_CHANGED(HTTP_PREF("spdy.enforce-tls-profile"))) { |
|
1159 rv = prefs->GetBoolPref(HTTP_PREF("spdy.enforce-tls-profile"), &cVar); |
|
1160 if (NS_SUCCEEDED(rv)) |
|
1161 mEnforceHttp2TlsProfile = cVar; |
|
1162 } |
|
1163 |
|
1164 if (PREF_CHANGED(HTTP_PREF("spdy.coalesce-hostnames"))) { |
|
1165 rv = prefs->GetBoolPref(HTTP_PREF("spdy.coalesce-hostnames"), &cVar); |
|
1166 if (NS_SUCCEEDED(rv)) |
|
1167 mCoalesceSpdy = cVar; |
|
1168 } |
|
1169 |
|
1170 if (PREF_CHANGED(HTTP_PREF("spdy.persistent-settings"))) { |
|
1171 rv = prefs->GetBoolPref(HTTP_PREF("spdy.persistent-settings"), |
|
1172 &cVar); |
|
1173 if (NS_SUCCEEDED(rv)) |
|
1174 mSpdyPersistentSettings = cVar; |
|
1175 } |
|
1176 |
|
1177 if (PREF_CHANGED(HTTP_PREF("spdy.timeout"))) { |
|
1178 rv = prefs->GetIntPref(HTTP_PREF("spdy.timeout"), &val); |
|
1179 if (NS_SUCCEEDED(rv)) |
|
1180 mSpdyTimeout = PR_SecondsToInterval(clamped(val, 1, 0xffff)); |
|
1181 } |
|
1182 |
|
1183 if (PREF_CHANGED(HTTP_PREF("spdy.chunk-size"))) { |
|
1184 // keep this within http/2 ranges of 1 to 2^14-1 |
|
1185 rv = prefs->GetIntPref(HTTP_PREF("spdy.chunk-size"), &val); |
|
1186 if (NS_SUCCEEDED(rv)) |
|
1187 mSpdySendingChunkSize = (uint32_t) clamped(val, 1, 0x3fff); |
|
1188 } |
|
1189 |
|
1190 // The amount of idle seconds on a spdy connection before initiating a |
|
1191 // server ping. 0 will disable. |
|
1192 if (PREF_CHANGED(HTTP_PREF("spdy.ping-threshold"))) { |
|
1193 rv = prefs->GetIntPref(HTTP_PREF("spdy.ping-threshold"), &val); |
|
1194 if (NS_SUCCEEDED(rv)) |
|
1195 mSpdyPingThreshold = |
|
1196 PR_SecondsToInterval((uint16_t) clamped(val, 0, 0x7fffffff)); |
|
1197 } |
|
1198 |
|
1199 // The amount of seconds to wait for a spdy ping response before |
|
1200 // closing the session. |
|
1201 if (PREF_CHANGED(HTTP_PREF("spdy.ping-timeout"))) { |
|
1202 rv = prefs->GetIntPref(HTTP_PREF("spdy.ping-timeout"), &val); |
|
1203 if (NS_SUCCEEDED(rv)) |
|
1204 mSpdyPingTimeout = |
|
1205 PR_SecondsToInterval((uint16_t) clamped(val, 0, 0x7fffffff)); |
|
1206 } |
|
1207 |
|
1208 if (PREF_CHANGED(HTTP_PREF("spdy.allow-push"))) { |
|
1209 rv = prefs->GetBoolPref(HTTP_PREF("spdy.allow-push"), |
|
1210 &cVar); |
|
1211 if (NS_SUCCEEDED(rv)) |
|
1212 mAllowPush = cVar; |
|
1213 } |
|
1214 |
|
1215 if (PREF_CHANGED(HTTP_PREF("spdy.push-allowance"))) { |
|
1216 rv = prefs->GetIntPref(HTTP_PREF("spdy.push-allowance"), &val); |
|
1217 if (NS_SUCCEEDED(rv)) { |
|
1218 mSpdyPushAllowance = |
|
1219 static_cast<uint32_t> |
|
1220 (clamped(val, 1024, static_cast<int32_t>(ASpdySession::kInitialRwin))); |
|
1221 } |
|
1222 } |
|
1223 |
|
1224 // The amount of seconds to wait for a spdy ping response before |
|
1225 // closing the session. |
|
1226 if (PREF_CHANGED(HTTP_PREF("spdy.send-buffer-size"))) { |
|
1227 rv = prefs->GetIntPref(HTTP_PREF("spdy.send-buffer-size"), &val); |
|
1228 if (NS_SUCCEEDED(rv)) |
|
1229 mSpdySendBufferSize = (uint32_t) clamped(val, 1500, 0x7fffffff); |
|
1230 } |
|
1231 |
|
1232 // The maximum amount of time to wait for socket transport to be |
|
1233 // established |
|
1234 if (PREF_CHANGED(HTTP_PREF("connection-timeout"))) { |
|
1235 rv = prefs->GetIntPref(HTTP_PREF("connection-timeout"), &val); |
|
1236 if (NS_SUCCEEDED(rv)) |
|
1237 // the pref is in seconds, but the variable is in milliseconds |
|
1238 mConnectTimeout = clamped(val, 1, 0xffff) * PR_MSEC_PER_SEC; |
|
1239 } |
|
1240 |
|
1241 // The maximum amount of time the cache session lock can be held |
|
1242 // before a new transaction bypasses the cache. In milliseconds. |
|
1243 if (PREF_CHANGED(HTTP_PREF("bypass-cachelock-threshold"))) { |
|
1244 rv = prefs->GetIntPref(HTTP_PREF("bypass-cachelock-threshold"), &val); |
|
1245 if (NS_SUCCEEDED(rv)) |
|
1246 // the pref and variable are both in milliseconds |
|
1247 mBypassCacheLockThreshold = |
|
1248 static_cast<double>(clamped(val, 0, 0x7ffffff)); |
|
1249 } |
|
1250 |
|
1251 // The maximum number of current global half open sockets allowable |
|
1252 // for starting a new speculative connection. |
|
1253 if (PREF_CHANGED(HTTP_PREF("speculative-parallel-limit"))) { |
|
1254 rv = prefs->GetIntPref(HTTP_PREF("speculative-parallel-limit"), &val); |
|
1255 if (NS_SUCCEEDED(rv)) |
|
1256 mParallelSpeculativeConnectLimit = (uint32_t) clamped(val, 0, 1024); |
|
1257 } |
|
1258 |
|
1259 // Whether or not to block requests for non head js/css items (e.g. media) |
|
1260 // while those elements load. |
|
1261 if (PREF_CHANGED(HTTP_PREF("rendering-critical-requests-prioritization"))) { |
|
1262 rv = prefs->GetBoolPref(HTTP_PREF("rendering-critical-requests-prioritization"), &cVar); |
|
1263 if (NS_SUCCEEDED(rv)) |
|
1264 mCriticalRequestPrioritization = cVar; |
|
1265 } |
|
1266 |
|
1267 // on transition of network.http.diagnostics to true print |
|
1268 // a bunch of information to the console |
|
1269 if (pref && PREF_CHANGED(HTTP_PREF("diagnostics"))) { |
|
1270 rv = prefs->GetBoolPref(HTTP_PREF("diagnostics"), &cVar); |
|
1271 if (NS_SUCCEEDED(rv) && cVar) { |
|
1272 if (mConnMgr) |
|
1273 mConnMgr->PrintDiagnostics(); |
|
1274 } |
|
1275 } |
|
1276 // |
|
1277 // INTL options |
|
1278 // |
|
1279 |
|
1280 if (PREF_CHANGED(INTL_ACCEPT_LANGUAGES)) { |
|
1281 nsCOMPtr<nsIPrefLocalizedString> pls; |
|
1282 prefs->GetComplexValue(INTL_ACCEPT_LANGUAGES, |
|
1283 NS_GET_IID(nsIPrefLocalizedString), |
|
1284 getter_AddRefs(pls)); |
|
1285 if (pls) { |
|
1286 nsXPIDLString uval; |
|
1287 pls->ToString(getter_Copies(uval)); |
|
1288 if (uval) |
|
1289 SetAcceptLanguages(NS_ConvertUTF16toUTF8(uval).get()); |
|
1290 } |
|
1291 } |
|
1292 |
|
1293 // |
|
1294 // Tracking options |
|
1295 // |
|
1296 |
|
1297 if (PREF_CHANGED(DONOTTRACK_HEADER_ENABLED)) { |
|
1298 cVar = false; |
|
1299 rv = prefs->GetBoolPref(DONOTTRACK_HEADER_ENABLED, &cVar); |
|
1300 if (NS_SUCCEEDED(rv)) { |
|
1301 mDoNotTrackEnabled = cVar; |
|
1302 } |
|
1303 } |
|
1304 if (PREF_CHANGED(DONOTTRACK_HEADER_VALUE)) { |
|
1305 val = 1; |
|
1306 rv = prefs->GetIntPref(DONOTTRACK_HEADER_VALUE, &val); |
|
1307 if (NS_SUCCEEDED(rv)) { |
|
1308 mDoNotTrackValue = val; |
|
1309 } |
|
1310 } |
|
1311 |
|
1312 // Hint option |
|
1313 if (PREF_CHANGED(SAFE_HINT_HEADER_VALUE)) { |
|
1314 cVar = false; |
|
1315 rv = prefs->GetBoolPref(SAFE_HINT_HEADER_VALUE, &cVar); |
|
1316 if (NS_SUCCEEDED(rv)) { |
|
1317 mSafeHintEnabled = cVar; |
|
1318 } |
|
1319 } |
|
1320 |
|
1321 // toggle to true anytime a token bucket related pref is changed.. that |
|
1322 // includes telemetry and allow-experiments because of the abtest profile |
|
1323 bool requestTokenBucketUpdated = false; |
|
1324 |
|
1325 // |
|
1326 // Telemetry |
|
1327 // |
|
1328 |
|
1329 if (PREF_CHANGED(TELEMETRY_ENABLED)) { |
|
1330 cVar = false; |
|
1331 requestTokenBucketUpdated = true; |
|
1332 rv = prefs->GetBoolPref(TELEMETRY_ENABLED, &cVar); |
|
1333 if (NS_SUCCEEDED(rv)) { |
|
1334 mTelemetryEnabled = cVar; |
|
1335 } |
|
1336 } |
|
1337 |
|
1338 // |
|
1339 // network.allow-experiments |
|
1340 // |
|
1341 if (PREF_CHANGED(ALLOW_EXPERIMENTS)) { |
|
1342 cVar = true; |
|
1343 requestTokenBucketUpdated = true; |
|
1344 rv = prefs->GetBoolPref(ALLOW_EXPERIMENTS, &cVar); |
|
1345 if (NS_SUCCEEDED(rv)) { |
|
1346 mAllowExperiments = cVar; |
|
1347 } |
|
1348 } |
|
1349 |
|
1350 // |
|
1351 // Test HTTP Pipelining (bug796192) |
|
1352 // If experiments are allowed and pipelining is Off, |
|
1353 // turn it On for just 10 minutes |
|
1354 // |
|
1355 if (mAllowExperiments && !mPipeliningEnabled && |
|
1356 PREF_CHANGED(HTTP_PREF("pipelining.abtest"))) { |
|
1357 rv = prefs->GetBoolPref(HTTP_PREF("pipelining.abtest"), &cVar); |
|
1358 if (NS_SUCCEEDED(rv)) { |
|
1359 // If option is enabled, only test for ~1% of sessions |
|
1360 if (cVar && !(rand() % 128)) { |
|
1361 mCapabilities |= NS_HTTP_ALLOW_PIPELINING; |
|
1362 if (mPipelineTestTimer) |
|
1363 mPipelineTestTimer->Cancel(); |
|
1364 mPipelineTestTimer = |
|
1365 do_CreateInstance("@mozilla.org/timer;1", &rv); |
|
1366 if (NS_SUCCEEDED(rv)) { |
|
1367 rv = mPipelineTestTimer->InitWithFuncCallback( |
|
1368 TimerCallback, this, 10*60*1000, // 10 minutes |
|
1369 nsITimer::TYPE_ONE_SHOT); |
|
1370 } |
|
1371 } else { |
|
1372 mCapabilities &= ~NS_HTTP_ALLOW_PIPELINING; |
|
1373 if (mPipelineTestTimer) { |
|
1374 mPipelineTestTimer->Cancel(); |
|
1375 mPipelineTestTimer = nullptr; |
|
1376 } |
|
1377 } |
|
1378 } |
|
1379 } |
|
1380 if (requestTokenBucketUpdated) { |
|
1381 MakeNewRequestTokenBucket(); |
|
1382 } |
|
1383 |
|
1384 if (PREF_CHANGED(HTTP_PREF("pacing.requests.enabled"))) { |
|
1385 rv = prefs->GetBoolPref(HTTP_PREF("pacing.requests.enabled"), |
|
1386 &cVar); |
|
1387 if (NS_SUCCEEDED(rv)){ |
|
1388 requestTokenBucketUpdated = true; |
|
1389 mRequestTokenBucketEnabled = cVar; |
|
1390 } |
|
1391 } |
|
1392 |
|
1393 if (PREF_CHANGED(HTTP_PREF("pacing.requests.min-parallelism"))) { |
|
1394 rv = prefs->GetIntPref(HTTP_PREF("pacing.requests.min-parallelism"), &val); |
|
1395 if (NS_SUCCEEDED(rv)) |
|
1396 mRequestTokenBucketMinParallelism = static_cast<uint16_t>(clamped(val, 1, 1024)); |
|
1397 } |
|
1398 if (PREF_CHANGED(HTTP_PREF("pacing.requests.hz"))) { |
|
1399 rv = prefs->GetIntPref(HTTP_PREF("pacing.requests.hz"), &val); |
|
1400 if (NS_SUCCEEDED(rv)) { |
|
1401 mRequestTokenBucketHz = static_cast<uint32_t>(clamped(val, 1, 10000)); |
|
1402 requestTokenBucketUpdated = true; |
|
1403 } |
|
1404 } |
|
1405 if (PREF_CHANGED(HTTP_PREF("pacing.requests.burst"))) { |
|
1406 rv = prefs->GetIntPref(HTTP_PREF("pacing.requests.burst"), &val); |
|
1407 if (NS_SUCCEEDED(rv)) { |
|
1408 mRequestTokenBucketBurst = val ? val : 1; |
|
1409 requestTokenBucketUpdated = true; |
|
1410 } |
|
1411 } |
|
1412 if (requestTokenBucketUpdated) { |
|
1413 mRequestTokenBucket = |
|
1414 new EventTokenBucket(RequestTokenBucketHz(), |
|
1415 RequestTokenBucketBurst()); |
|
1416 } |
|
1417 |
|
1418 // Keepalive values for initial and idle connections. |
|
1419 if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.short_lived_connections"))) { |
|
1420 rv = prefs->GetBoolPref( |
|
1421 HTTP_PREF("tcp_keepalive.short_lived_connections"), &cVar); |
|
1422 if (NS_SUCCEEDED(rv) && cVar != mTCPKeepaliveShortLivedEnabled) { |
|
1423 mTCPKeepaliveShortLivedEnabled = cVar; |
|
1424 } |
|
1425 } |
|
1426 |
|
1427 if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.short_lived_time"))) { |
|
1428 rv = prefs->GetIntPref( |
|
1429 HTTP_PREF("tcp_keepalive.short_lived_time"), &val); |
|
1430 if (NS_SUCCEEDED(rv) && val > 0) |
|
1431 mTCPKeepaliveShortLivedTimeS = clamped(val, 1, 300); // Max 5 mins. |
|
1432 } |
|
1433 |
|
1434 if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.short_lived_idle_time"))) { |
|
1435 rv = prefs->GetIntPref( |
|
1436 HTTP_PREF("tcp_keepalive.short_lived_idle_time"), &val); |
|
1437 if (NS_SUCCEEDED(rv) && val > 0) |
|
1438 mTCPKeepaliveShortLivedIdleTimeS = clamped(val, |
|
1439 1, kMaxTCPKeepIdle); |
|
1440 } |
|
1441 |
|
1442 // Keepalive values for Long-lived Connections. |
|
1443 if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.long_lived_connections"))) { |
|
1444 rv = prefs->GetBoolPref( |
|
1445 HTTP_PREF("tcp_keepalive.long_lived_connections"), &cVar); |
|
1446 if (NS_SUCCEEDED(rv) && cVar != mTCPKeepaliveLongLivedEnabled) { |
|
1447 mTCPKeepaliveLongLivedEnabled = cVar; |
|
1448 } |
|
1449 } |
|
1450 |
|
1451 if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.long_lived_idle_time"))) { |
|
1452 rv = prefs->GetIntPref( |
|
1453 HTTP_PREF("tcp_keepalive.long_lived_idle_time"), &val); |
|
1454 if (NS_SUCCEEDED(rv) && val > 0) |
|
1455 mTCPKeepaliveLongLivedIdleTimeS = clamped(val, |
|
1456 1, kMaxTCPKeepIdle); |
|
1457 } |
|
1458 |
|
1459 // Enable HTTP response timeout if TCP Keepalives are disabled. |
|
1460 mResponseTimeoutEnabled = !mTCPKeepaliveShortLivedEnabled && |
|
1461 !mTCPKeepaliveLongLivedEnabled; |
|
1462 |
|
1463 #undef PREF_CHANGED |
|
1464 #undef MULTI_PREF_CHANGED |
|
1465 } |
|
1466 |
|
1467 |
|
1468 /** |
|
1469 * Static method called by mPipelineTestTimer when it expires. |
|
1470 */ |
|
1471 void |
|
1472 nsHttpHandler::TimerCallback(nsITimer * aTimer, void * aClosure) |
|
1473 { |
|
1474 nsRefPtr<nsHttpHandler> thisObject = static_cast<nsHttpHandler*>(aClosure); |
|
1475 if (!thisObject->mPipeliningEnabled) |
|
1476 thisObject->mCapabilities &= ~NS_HTTP_ALLOW_PIPELINING; |
|
1477 } |
|
1478 |
|
1479 /** |
|
1480 * Allocates a C string into that contains a ISO 639 language list |
|
1481 * notated with HTTP "q" values for output with a HTTP Accept-Language |
|
1482 * header. Previous q values will be stripped because the order of |
|
1483 * the langs imply the q value. The q values are calculated by dividing |
|
1484 * 1.0 amongst the number of languages present. |
|
1485 * |
|
1486 * Ex: passing: "en, ja" |
|
1487 * returns: "en,ja;q=0.5" |
|
1488 * |
|
1489 * passing: "en, ja, fr_CA" |
|
1490 * returns: "en,ja;q=0.7,fr_CA;q=0.3" |
|
1491 */ |
|
1492 static nsresult |
|
1493 PrepareAcceptLanguages(const char *i_AcceptLanguages, nsACString &o_AcceptLanguages) |
|
1494 { |
|
1495 if (!i_AcceptLanguages) |
|
1496 return NS_OK; |
|
1497 |
|
1498 uint32_t n, count_n, size, wrote; |
|
1499 double q, dec; |
|
1500 char *p, *p2, *token, *q_Accept, *o_Accept; |
|
1501 const char *comma; |
|
1502 int32_t available; |
|
1503 |
|
1504 o_Accept = strdup(i_AcceptLanguages); |
|
1505 if (!o_Accept) |
|
1506 return NS_ERROR_OUT_OF_MEMORY; |
|
1507 for (p = o_Accept, n = size = 0; '\0' != *p; p++) { |
|
1508 if (*p == ',') n++; |
|
1509 size++; |
|
1510 } |
|
1511 |
|
1512 available = size + ++n * 11 + 1; |
|
1513 q_Accept = new char[available]; |
|
1514 if (!q_Accept) { |
|
1515 free(o_Accept); |
|
1516 return NS_ERROR_OUT_OF_MEMORY; |
|
1517 } |
|
1518 *q_Accept = '\0'; |
|
1519 q = 1.0; |
|
1520 dec = q / (double) n; |
|
1521 count_n = 0; |
|
1522 p2 = q_Accept; |
|
1523 for (token = nsCRT::strtok(o_Accept, ",", &p); |
|
1524 token != (char *) 0; |
|
1525 token = nsCRT::strtok(p, ",", &p)) |
|
1526 { |
|
1527 token = net_FindCharNotInSet(token, HTTP_LWS); |
|
1528 char* trim; |
|
1529 trim = net_FindCharInSet(token, ";" HTTP_LWS); |
|
1530 if (trim != (char*)0) // remove "; q=..." if present |
|
1531 *trim = '\0'; |
|
1532 |
|
1533 if (*token != '\0') { |
|
1534 comma = count_n++ != 0 ? "," : ""; // delimiter if not first item |
|
1535 uint32_t u = QVAL_TO_UINT(q); |
|
1536 |
|
1537 // Only display q-value if less than 1.00. |
|
1538 if (u < 100) { |
|
1539 const char *qval_str; |
|
1540 |
|
1541 // With a small number of languages, one decimal place is enough to prevent duplicate q-values. |
|
1542 // Also, trailing zeroes do not add any information, so they can be removed. |
|
1543 if ((n < 10) || ((u % 10) == 0)) { |
|
1544 u = (u + 5) / 10; |
|
1545 qval_str = "%s%s;q=0.%u"; |
|
1546 } else { |
|
1547 // Values below 10 require zero padding. |
|
1548 qval_str = "%s%s;q=0.%02u"; |
|
1549 } |
|
1550 |
|
1551 wrote = PR_snprintf(p2, available, qval_str, comma, token, u); |
|
1552 } else { |
|
1553 wrote = PR_snprintf(p2, available, "%s%s", comma, token); |
|
1554 } |
|
1555 |
|
1556 q -= dec; |
|
1557 p2 += wrote; |
|
1558 available -= wrote; |
|
1559 MOZ_ASSERT(available > 0, "allocated string not long enough"); |
|
1560 } |
|
1561 } |
|
1562 free(o_Accept); |
|
1563 |
|
1564 o_AcceptLanguages.Assign((const char *) q_Accept); |
|
1565 delete [] q_Accept; |
|
1566 |
|
1567 return NS_OK; |
|
1568 } |
|
1569 |
|
1570 nsresult |
|
1571 nsHttpHandler::SetAcceptLanguages(const char *aAcceptLanguages) |
|
1572 { |
|
1573 nsAutoCString buf; |
|
1574 nsresult rv = PrepareAcceptLanguages(aAcceptLanguages, buf); |
|
1575 if (NS_SUCCEEDED(rv)) |
|
1576 mAcceptLanguages.Assign(buf); |
|
1577 return rv; |
|
1578 } |
|
1579 |
|
1580 nsresult |
|
1581 nsHttpHandler::SetAccept(const char *aAccept) |
|
1582 { |
|
1583 mAccept = aAccept; |
|
1584 return NS_OK; |
|
1585 } |
|
1586 |
|
1587 nsresult |
|
1588 nsHttpHandler::SetAcceptEncodings(const char *aAcceptEncodings) |
|
1589 { |
|
1590 mAcceptEncodings = aAcceptEncodings; |
|
1591 return NS_OK; |
|
1592 } |
|
1593 |
|
1594 //----------------------------------------------------------------------------- |
|
1595 // nsHttpHandler::nsISupports |
|
1596 //----------------------------------------------------------------------------- |
|
1597 |
|
1598 NS_IMPL_ISUPPORTS(nsHttpHandler, |
|
1599 nsIHttpProtocolHandler, |
|
1600 nsIProxiedProtocolHandler, |
|
1601 nsIProtocolHandler, |
|
1602 nsIObserver, |
|
1603 nsISupportsWeakReference, |
|
1604 nsISpeculativeConnect) |
|
1605 |
|
1606 //----------------------------------------------------------------------------- |
|
1607 // nsHttpHandler::nsIProtocolHandler |
|
1608 //----------------------------------------------------------------------------- |
|
1609 |
|
1610 NS_IMETHODIMP |
|
1611 nsHttpHandler::GetScheme(nsACString &aScheme) |
|
1612 { |
|
1613 aScheme.AssignLiteral("http"); |
|
1614 return NS_OK; |
|
1615 } |
|
1616 |
|
1617 NS_IMETHODIMP |
|
1618 nsHttpHandler::GetDefaultPort(int32_t *result) |
|
1619 { |
|
1620 *result = NS_HTTP_DEFAULT_PORT; |
|
1621 return NS_OK; |
|
1622 } |
|
1623 |
|
1624 NS_IMETHODIMP |
|
1625 nsHttpHandler::GetProtocolFlags(uint32_t *result) |
|
1626 { |
|
1627 *result = NS_HTTP_PROTOCOL_FLAGS; |
|
1628 return NS_OK; |
|
1629 } |
|
1630 |
|
1631 NS_IMETHODIMP |
|
1632 nsHttpHandler::NewURI(const nsACString &aSpec, |
|
1633 const char *aCharset, |
|
1634 nsIURI *aBaseURI, |
|
1635 nsIURI **aURI) |
|
1636 { |
|
1637 return mozilla::net::NewURI(aSpec, aCharset, aBaseURI, NS_HTTP_DEFAULT_PORT, aURI); |
|
1638 } |
|
1639 |
|
1640 NS_IMETHODIMP |
|
1641 nsHttpHandler::NewChannel(nsIURI *uri, nsIChannel **result) |
|
1642 { |
|
1643 LOG(("nsHttpHandler::NewChannel\n")); |
|
1644 |
|
1645 NS_ENSURE_ARG_POINTER(uri); |
|
1646 NS_ENSURE_ARG_POINTER(result); |
|
1647 |
|
1648 bool isHttp = false, isHttps = false; |
|
1649 |
|
1650 // Verify that we have been given a valid scheme |
|
1651 nsresult rv = uri->SchemeIs("http", &isHttp); |
|
1652 if (NS_FAILED(rv)) return rv; |
|
1653 if (!isHttp) { |
|
1654 rv = uri->SchemeIs("https", &isHttps); |
|
1655 if (NS_FAILED(rv)) return rv; |
|
1656 if (!isHttps) { |
|
1657 NS_WARNING("Invalid URI scheme"); |
|
1658 return NS_ERROR_UNEXPECTED; |
|
1659 } |
|
1660 } |
|
1661 |
|
1662 return NewProxiedChannel(uri, nullptr, 0, nullptr, result); |
|
1663 } |
|
1664 |
|
1665 NS_IMETHODIMP |
|
1666 nsHttpHandler::AllowPort(int32_t port, const char *scheme, bool *_retval) |
|
1667 { |
|
1668 // don't override anything. |
|
1669 *_retval = false; |
|
1670 return NS_OK; |
|
1671 } |
|
1672 |
|
1673 //----------------------------------------------------------------------------- |
|
1674 // nsHttpHandler::nsIProxiedProtocolHandler |
|
1675 //----------------------------------------------------------------------------- |
|
1676 |
|
1677 NS_IMETHODIMP |
|
1678 nsHttpHandler::NewProxiedChannel(nsIURI *uri, |
|
1679 nsIProxyInfo* givenProxyInfo, |
|
1680 uint32_t proxyResolveFlags, |
|
1681 nsIURI *proxyURI, |
|
1682 nsIChannel **result) |
|
1683 { |
|
1684 nsRefPtr<HttpBaseChannel> httpChannel; |
|
1685 |
|
1686 LOG(("nsHttpHandler::NewProxiedChannel [proxyInfo=%p]\n", |
|
1687 givenProxyInfo)); |
|
1688 |
|
1689 nsCOMPtr<nsProxyInfo> proxyInfo; |
|
1690 if (givenProxyInfo) { |
|
1691 proxyInfo = do_QueryInterface(givenProxyInfo); |
|
1692 NS_ENSURE_ARG(proxyInfo); |
|
1693 } |
|
1694 |
|
1695 bool https; |
|
1696 nsresult rv = uri->SchemeIs("https", &https); |
|
1697 if (NS_FAILED(rv)) |
|
1698 return rv; |
|
1699 |
|
1700 if (IsNeckoChild()) { |
|
1701 httpChannel = new HttpChannelChild(); |
|
1702 } else { |
|
1703 httpChannel = new nsHttpChannel(); |
|
1704 } |
|
1705 |
|
1706 uint32_t caps = mCapabilities; |
|
1707 |
|
1708 if (https) { |
|
1709 // enable pipelining over SSL if requested |
|
1710 if (mPipeliningOverSSL) |
|
1711 caps |= NS_HTTP_ALLOW_PIPELINING; |
|
1712 } |
|
1713 |
|
1714 if (!IsNeckoChild()) { |
|
1715 // HACK: make sure PSM gets initialized on the main thread. |
|
1716 net_EnsurePSMInit(); |
|
1717 } |
|
1718 |
|
1719 rv = httpChannel->Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI); |
|
1720 if (NS_FAILED(rv)) |
|
1721 return rv; |
|
1722 |
|
1723 httpChannel.forget(result); |
|
1724 return NS_OK; |
|
1725 } |
|
1726 |
|
1727 //----------------------------------------------------------------------------- |
|
1728 // nsHttpHandler::nsIHttpProtocolHandler |
|
1729 //----------------------------------------------------------------------------- |
|
1730 |
|
1731 NS_IMETHODIMP |
|
1732 nsHttpHandler::GetUserAgent(nsACString &value) |
|
1733 { |
|
1734 value = UserAgent(); |
|
1735 return NS_OK; |
|
1736 } |
|
1737 |
|
1738 NS_IMETHODIMP |
|
1739 nsHttpHandler::GetAppName(nsACString &value) |
|
1740 { |
|
1741 value = mLegacyAppName; |
|
1742 return NS_OK; |
|
1743 } |
|
1744 |
|
1745 NS_IMETHODIMP |
|
1746 nsHttpHandler::GetAppVersion(nsACString &value) |
|
1747 { |
|
1748 value = mLegacyAppVersion; |
|
1749 return NS_OK; |
|
1750 } |
|
1751 |
|
1752 NS_IMETHODIMP |
|
1753 nsHttpHandler::GetPlatform(nsACString &value) |
|
1754 { |
|
1755 value = mPlatform; |
|
1756 return NS_OK; |
|
1757 } |
|
1758 |
|
1759 NS_IMETHODIMP |
|
1760 nsHttpHandler::GetOscpu(nsACString &value) |
|
1761 { |
|
1762 value = mOscpu; |
|
1763 return NS_OK; |
|
1764 } |
|
1765 |
|
1766 NS_IMETHODIMP |
|
1767 nsHttpHandler::GetMisc(nsACString &value) |
|
1768 { |
|
1769 value = mMisc; |
|
1770 return NS_OK; |
|
1771 } |
|
1772 |
|
1773 /*static*/ void |
|
1774 nsHttpHandler::GetCacheSessionNameForStoragePolicy( |
|
1775 nsCacheStoragePolicy storagePolicy, |
|
1776 bool isPrivate, |
|
1777 uint32_t appId, |
|
1778 bool inBrowser, |
|
1779 nsACString& sessionName) |
|
1780 { |
|
1781 MOZ_ASSERT(!isPrivate || storagePolicy == nsICache::STORE_IN_MEMORY); |
|
1782 |
|
1783 switch (storagePolicy) { |
|
1784 case nsICache::STORE_IN_MEMORY: |
|
1785 sessionName.AssignASCII(isPrivate ? "HTTP-memory-only-PB" : "HTTP-memory-only"); |
|
1786 break; |
|
1787 case nsICache::STORE_OFFLINE: |
|
1788 sessionName.AssignLiteral("HTTP-offline"); |
|
1789 break; |
|
1790 default: |
|
1791 sessionName.AssignLiteral("HTTP"); |
|
1792 break; |
|
1793 } |
|
1794 if (appId != NECKO_NO_APP_ID || inBrowser) { |
|
1795 sessionName.Append('~'); |
|
1796 sessionName.AppendInt(appId); |
|
1797 sessionName.Append('~'); |
|
1798 sessionName.AppendInt(inBrowser); |
|
1799 } |
|
1800 } |
|
1801 |
|
1802 //----------------------------------------------------------------------------- |
|
1803 // nsHttpHandler::nsIObserver |
|
1804 //----------------------------------------------------------------------------- |
|
1805 |
|
1806 NS_IMETHODIMP |
|
1807 nsHttpHandler::Observe(nsISupports *subject, |
|
1808 const char *topic, |
|
1809 const char16_t *data) |
|
1810 { |
|
1811 LOG(("nsHttpHandler::Observe [topic=\"%s\"]\n", topic)); |
|
1812 |
|
1813 if (strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) { |
|
1814 nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(subject); |
|
1815 if (prefBranch) |
|
1816 PrefsChanged(prefBranch, NS_ConvertUTF16toUTF8(data).get()); |
|
1817 } |
|
1818 else if (strcmp(topic, "profile-change-net-teardown") == 0 || |
|
1819 strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { |
|
1820 |
|
1821 mHandlerActive = false; |
|
1822 |
|
1823 // clear cache of all authentication credentials. |
|
1824 mAuthCache.ClearAll(); |
|
1825 mPrivateAuthCache.ClearAll(); |
|
1826 if (mWifiTickler) |
|
1827 mWifiTickler->Cancel(); |
|
1828 |
|
1829 // ensure connection manager is shutdown |
|
1830 if (mConnMgr) |
|
1831 mConnMgr->Shutdown(); |
|
1832 |
|
1833 // need to reset the session start time since cache validation may |
|
1834 // depend on this value. |
|
1835 mSessionStartTime = NowInSeconds(); |
|
1836 |
|
1837 if (!mDoNotTrackEnabled) { |
|
1838 Telemetry::Accumulate(Telemetry::DNT_USAGE, DONOTTRACK_VALUE_UNSET); |
|
1839 } |
|
1840 else { |
|
1841 Telemetry::Accumulate(Telemetry::DNT_USAGE, mDoNotTrackValue); |
|
1842 } |
|
1843 } |
|
1844 else if (strcmp(topic, "profile-change-net-restore") == 0) { |
|
1845 // initialize connection manager |
|
1846 InitConnectionMgr(); |
|
1847 } |
|
1848 else if (strcmp(topic, "net:clear-active-logins") == 0) { |
|
1849 mAuthCache.ClearAll(); |
|
1850 mPrivateAuthCache.ClearAll(); |
|
1851 } |
|
1852 else if (strcmp(topic, "net:prune-dead-connections") == 0) { |
|
1853 if (mConnMgr) { |
|
1854 mConnMgr->PruneDeadConnections(); |
|
1855 } |
|
1856 } |
|
1857 else if (strcmp(topic, "net:prune-all-connections") == 0) { |
|
1858 if (mConnMgr) { |
|
1859 mConnMgr->DoShiftReloadConnectionCleanup(nullptr); |
|
1860 mConnMgr->PruneDeadConnections(); |
|
1861 } |
|
1862 } |
|
1863 else if (strcmp(topic, "net:failed-to-process-uri-content") == 0) { |
|
1864 nsCOMPtr<nsIURI> uri = do_QueryInterface(subject); |
|
1865 if (uri && mConnMgr) |
|
1866 mConnMgr->ReportFailedToProcess(uri); |
|
1867 } |
|
1868 else if (strcmp(topic, "last-pb-context-exited") == 0) { |
|
1869 mPrivateAuthCache.ClearAll(); |
|
1870 } |
|
1871 |
|
1872 return NS_OK; |
|
1873 } |
|
1874 |
|
1875 // nsISpeculativeConnect |
|
1876 |
|
1877 NS_IMETHODIMP |
|
1878 nsHttpHandler::SpeculativeConnect(nsIURI *aURI, |
|
1879 nsIInterfaceRequestor *aCallbacks) |
|
1880 { |
|
1881 if (!mHandlerActive) |
|
1882 return NS_OK; |
|
1883 |
|
1884 nsISiteSecurityService* sss = gHttpHandler->GetSSService(); |
|
1885 bool isStsHost = false; |
|
1886 if (!sss) |
|
1887 return NS_OK; |
|
1888 |
|
1889 nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(aCallbacks); |
|
1890 uint32_t flags = 0; |
|
1891 if (loadContext && loadContext->UsePrivateBrowsing()) |
|
1892 flags |= nsISocketProvider::NO_PERMANENT_STORAGE; |
|
1893 nsCOMPtr<nsIURI> clone; |
|
1894 if (NS_SUCCEEDED(sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, |
|
1895 aURI, flags, &isStsHost)) && isStsHost) { |
|
1896 if (NS_SUCCEEDED(aURI->Clone(getter_AddRefs(clone)))) { |
|
1897 clone->SetScheme(NS_LITERAL_CSTRING("https")); |
|
1898 aURI = clone.get(); |
|
1899 } |
|
1900 } |
|
1901 |
|
1902 nsAutoCString scheme; |
|
1903 nsresult rv = aURI->GetScheme(scheme); |
|
1904 if (NS_FAILED(rv)) |
|
1905 return rv; |
|
1906 |
|
1907 // If this is HTTPS, make sure PSM is initialized as the channel |
|
1908 // creation path may have been bypassed |
|
1909 if (scheme.EqualsLiteral("https")) { |
|
1910 if (!IsNeckoChild()) { |
|
1911 // make sure PSM gets initialized on the main thread. |
|
1912 net_EnsurePSMInit(); |
|
1913 } |
|
1914 } |
|
1915 // Ensure that this is HTTP or HTTPS, otherwise we don't do preconnect here |
|
1916 else if (!scheme.EqualsLiteral("http")) |
|
1917 return NS_ERROR_UNEXPECTED; |
|
1918 |
|
1919 // Construct connection info object |
|
1920 bool usingSSL = false; |
|
1921 rv = aURI->SchemeIs("https", &usingSSL); |
|
1922 if (NS_FAILED(rv)) |
|
1923 return rv; |
|
1924 |
|
1925 nsAutoCString host; |
|
1926 rv = aURI->GetAsciiHost(host); |
|
1927 if (NS_FAILED(rv)) |
|
1928 return rv; |
|
1929 |
|
1930 int32_t port = -1; |
|
1931 rv = aURI->GetPort(&port); |
|
1932 if (NS_FAILED(rv)) |
|
1933 return rv; |
|
1934 |
|
1935 nsAutoCString username; |
|
1936 aURI->GetUsername(username); |
|
1937 |
|
1938 nsHttpConnectionInfo *ci = |
|
1939 new nsHttpConnectionInfo(host, port, username, nullptr, usingSSL); |
|
1940 |
|
1941 return SpeculativeConnect(ci, aCallbacks); |
|
1942 } |
|
1943 |
|
1944 void |
|
1945 nsHttpHandler::TickleWifi(nsIInterfaceRequestor *cb) |
|
1946 { |
|
1947 if (!cb || !mWifiTickler) |
|
1948 return; |
|
1949 |
|
1950 // If B2G requires a similar mechanism nsINetworkManager, currently only avail |
|
1951 // on B2G, contains the necessary information on wifi and gateway |
|
1952 |
|
1953 nsCOMPtr<nsIDOMWindow> domWindow; |
|
1954 cb->GetInterface(NS_GET_IID(nsIDOMWindow), getter_AddRefs(domWindow)); |
|
1955 if (!domWindow) |
|
1956 return; |
|
1957 |
|
1958 nsCOMPtr<nsIDOMNavigator> domNavigator; |
|
1959 domWindow->GetNavigator(getter_AddRefs(domNavigator)); |
|
1960 nsCOMPtr<nsIMozNavigatorNetwork> networkNavigator = |
|
1961 do_QueryInterface(domNavigator); |
|
1962 if (!networkNavigator) |
|
1963 return; |
|
1964 |
|
1965 nsCOMPtr<nsINetworkProperties> networkProperties; |
|
1966 networkNavigator->GetProperties(getter_AddRefs(networkProperties)); |
|
1967 if (!networkProperties) |
|
1968 return; |
|
1969 |
|
1970 uint32_t gwAddress; |
|
1971 bool isWifi; |
|
1972 nsresult rv; |
|
1973 |
|
1974 rv = networkProperties->GetDhcpGateway(&gwAddress); |
|
1975 if (NS_SUCCEEDED(rv)) |
|
1976 rv = networkProperties->GetIsWifi(&isWifi); |
|
1977 if (NS_FAILED(rv)) |
|
1978 return; |
|
1979 |
|
1980 if (!gwAddress || !isWifi) |
|
1981 return; |
|
1982 |
|
1983 mWifiTickler->SetIPV4Address(gwAddress); |
|
1984 mWifiTickler->Tickle(); |
|
1985 } |
|
1986 |
|
1987 //----------------------------------------------------------------------------- |
|
1988 // nsHttpsHandler implementation |
|
1989 //----------------------------------------------------------------------------- |
|
1990 |
|
1991 NS_IMPL_ISUPPORTS(nsHttpsHandler, |
|
1992 nsIHttpProtocolHandler, |
|
1993 nsIProxiedProtocolHandler, |
|
1994 nsIProtocolHandler, |
|
1995 nsISupportsWeakReference, |
|
1996 nsISpeculativeConnect) |
|
1997 |
|
1998 nsresult |
|
1999 nsHttpsHandler::Init() |
|
2000 { |
|
2001 nsCOMPtr<nsIProtocolHandler> httpHandler( |
|
2002 do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http")); |
|
2003 MOZ_ASSERT(httpHandler.get() != nullptr); |
|
2004 return NS_OK; |
|
2005 } |
|
2006 |
|
2007 NS_IMETHODIMP |
|
2008 nsHttpsHandler::GetScheme(nsACString &aScheme) |
|
2009 { |
|
2010 aScheme.AssignLiteral("https"); |
|
2011 return NS_OK; |
|
2012 } |
|
2013 |
|
2014 NS_IMETHODIMP |
|
2015 nsHttpsHandler::GetDefaultPort(int32_t *aPort) |
|
2016 { |
|
2017 *aPort = NS_HTTPS_DEFAULT_PORT; |
|
2018 return NS_OK; |
|
2019 } |
|
2020 |
|
2021 NS_IMETHODIMP |
|
2022 nsHttpsHandler::GetProtocolFlags(uint32_t *aProtocolFlags) |
|
2023 { |
|
2024 *aProtocolFlags = NS_HTTP_PROTOCOL_FLAGS | URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT; |
|
2025 return NS_OK; |
|
2026 } |
|
2027 |
|
2028 NS_IMETHODIMP |
|
2029 nsHttpsHandler::NewURI(const nsACString &aSpec, |
|
2030 const char *aOriginCharset, |
|
2031 nsIURI *aBaseURI, |
|
2032 nsIURI **_retval) |
|
2033 { |
|
2034 return mozilla::net::NewURI(aSpec, aOriginCharset, aBaseURI, NS_HTTPS_DEFAULT_PORT, _retval); |
|
2035 } |
|
2036 |
|
2037 NS_IMETHODIMP |
|
2038 nsHttpsHandler::NewChannel(nsIURI *aURI, nsIChannel **_retval) |
|
2039 { |
|
2040 MOZ_ASSERT(gHttpHandler); |
|
2041 if (!gHttpHandler) |
|
2042 return NS_ERROR_UNEXPECTED; |
|
2043 return gHttpHandler->NewChannel(aURI, _retval); |
|
2044 } |
|
2045 |
|
2046 NS_IMETHODIMP |
|
2047 nsHttpsHandler::AllowPort(int32_t aPort, const char *aScheme, bool *_retval) |
|
2048 { |
|
2049 // don't override anything. |
|
2050 *_retval = false; |
|
2051 return NS_OK; |
|
2052 } |
|
2053 |
|
2054 } // namespace mozilla::net |
|
2055 } // namespace mozilla |