Bug 1363421 - Part 2, delay the initialization of UserAgentOverrides.jsm until first nsHttpChannel is created. r=mcmanus
UAOverridesBootstrapper.js is introduced to delay the initialization of
UserAgentOverrides.jsm until the creation of the first nsHttpChannel.
Uninit will be triggered at profile-change-net-teardown because no network
traffice after this point.
MozReview-Commit-ID: F8Lpn6RyZEm
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -29,17 +29,17 @@ XPCOMUtils.defineLazyServiceGetter(this,
LightweightThemeManager:false, LoginHelper:false, LoginManagerParent:false,
NetUtil:false, NewTabUtils:false, OS:false,
PageThumbs:false, PdfJs:false, PermissionUI:false, PlacesBackups:false,
PlacesUtils:false, PluralForm:false, PrivateBrowsingUtils:false,
ProcessHangMonitor:false, ReaderParent:false, RecentWindow:false,
RemotePrompt:false, SelfSupportBackend:false, SessionStore:false,
ShellService:false, SimpleServiceDiscovery:false, TabCrashHandler:false,
Task:false, UITour:false, WebChannel:false,
- WindowsRegistry:false, webrtcUI:false, UserAgentOverrides: false */
+ WindowsRegistry:false, webrtcUI:false */
/**
* IF YOU ADD OR REMOVE FROM THIS LIST, PLEASE UPDATE THE LIST ABOVE AS WELL.
* XXX Bug 1325373 is for making eslint detect these automatically.
*/
let initializedModules = {};
@@ -85,17 +85,16 @@ let initializedModules = {};
["ShellService", "resource:///modules/ShellService.jsm"],
["SimpleServiceDiscovery", "resource://gre/modules/SimpleServiceDiscovery.jsm"],
["TabCrashHandler", "resource:///modules/ContentCrashHandlers.jsm"],
["Task", "resource://gre/modules/Task.jsm"],
["UITour", "resource:///modules/UITour.jsm"],
["WebChannel", "resource://gre/modules/WebChannel.jsm"],
["WindowsRegistry", "resource://gre/modules/WindowsRegistry.jsm"],
["webrtcUI", "resource:///modules/webrtcUI.jsm", "init"],
- ["UserAgentOverrides", "resource://gre/modules/UserAgentOverrides.jsm"],
].forEach(([name, resource, init]) => {
if (init) {
XPCOMUtils.defineLazyGetter(this, name, () => {
Cu.import(resource, initializedModules);
initializedModules[name][init]();
return initializedModules[name];
});
} else {
@@ -525,18 +524,16 @@ BrowserGlue.prototype = {
this._flashHangCount = 0;
this._firstWindowReady = new Promise(resolve => this._firstWindowLoaded = resolve);
if (AppConstants.platform == "macosx") {
// Handles prompting to inform about incompatibilites when accessibility
// and e10s are active together.
E10SAccessibilityCheck.init();
}
-
- UserAgentOverrides.init();
},
// cleanup (called on application shutdown)
_dispose: function BG__dispose() {
let os = Services.obs;
os.removeObserver(this, "notifications-open-settings");
os.removeObserver(this, "prefservice:after-app-defaults");
os.removeObserver(this, "final-ui-startup");
@@ -566,18 +563,16 @@ BrowserGlue.prototype = {
os.removeObserver(this, "handle-xul-text-link");
os.removeObserver(this, "profile-before-change");
if (AppConstants.MOZ_TELEMETRY_REPORTING) {
os.removeObserver(this, "keyword-search");
}
os.removeObserver(this, "browser-search-engine-modified");
os.removeObserver(this, "flash-plugin-hang");
os.removeObserver(this, "xpi-signature-changed");
-
- UserAgentOverrides.uninit();
},
_onAppDefaults: function BG__onAppDefaults() {
// apply distribution customizations (prefs)
// other customizations are applied in _finalUIStartup()
this._distributionCustomizer.applyPrefDefaults();
},
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -354,16 +354,18 @@
; JavaScript components
@RESPATH@/components/ConsoleAPI.manifest
@RESPATH@/components/ConsoleAPIStorage.js
@RESPATH@/components/BrowserElementParent.manifest
@RESPATH@/components/BrowserElementParent.js
@RESPATH@/components/FeedProcessor.manifest
@RESPATH@/components/FeedProcessor.js
+@RESPATH@/components/UAOverridesBootstrapper.js
+@RESPATH@/components/UAOverridesBootstrapper.manifest
@RESPATH@/components/WellKnownOpportunisticUtils.js
@RESPATH@/components/WellKnownOpportunisticUtils.manifest
#ifndef XP_MACOSX
; OSX uses native platform impl. Windows, Linux, and Android uses fallback JS impl.
@BINPATH@/components/nsDNSServiceDiscovery.manifest
@BINPATH@/components/nsDNSServiceDiscovery.js
#endif
@RESPATH@/browser/components/BrowserFeeds.manifest
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -453,17 +453,16 @@ var BrowserApp = {
NativeWindow.init();
FormAssistant.init();
IndexedDB.init();
XPInstallObserver.init();
CharacterEncoding.init();
ActivityObserver.init();
RemoteDebugger.init();
- UserAgentOverrides.init();
DesktopUserAgent.init();
Distribution.init();
Tabs.init();
SearchEngines.init();
Experiments.init();
// XXX maybe we don't do this if the launch was kicked off from external
Services.io.offline = false;
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -273,16 +273,18 @@
@BINPATH@/components/Push.js
@BINPATH@/components/Push.manifest
@BINPATH@/components/PushComponents.js
#endif
@BINPATH@/components/BrowserElementParent.manifest
@BINPATH@/components/BrowserElementParent.js
@BINPATH@/components/FeedProcessor.manifest
@BINPATH@/components/FeedProcessor.js
+@BINPATH@/components/UAOverridesBootstrapper.js
+@BINPATH@/components/UAOverridesBootstrapper.manifest
@BINPATH@/components/WellKnownOpportunisticUtils.js
@BINPATH@/components/WellKnownOpportunisticUtils.manifest
@BINPATH@/components/mozProtocolHandler.js
@BINPATH@/components/mozProtocolHandler.manifest
@BINPATH@/components/nsDNSServiceDiscovery.manifest
@BINPATH@/components/nsDNSServiceDiscovery.js
@BINPATH@/components/toolkitsearch.manifest
@BINPATH@/components/nsSearchService.js
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/UAOverridesBootstrapper.js
@@ -0,0 +1,36 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/UserAgentOverrides.jsm");
+
+function UAOverridesBootstrapper() {
+ this.init();
+}
+
+UAOverridesBootstrapper.prototype = {
+ init: function uaob_init() {
+ Services.obs.addObserver(this, "profile-change-net-teardown", false);
+ UserAgentOverrides.init();
+ },
+
+ observe: function uaob_observe(aSubject, aTopic, aData) {
+ if (aTopic == "profile-change-net-teardown") {
+ Services.obs.removeObserver(this, "profile-change-net-teardown");
+ UserAgentOverrides.uninit();
+ }
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
+ classID: Components.ID("{965b0ca8-155b-11e7-93ae-92361f002671}")
+};
+
+const components = [UAOverridesBootstrapper];
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/UAOverridesBootstrapper.manifest
@@ -0,0 +1,3 @@
+# UAOverridesBootstrapper.js
+component {965b0ca8-155b-11e7-93ae-92361f002671} UAOverridesBootstrapper.js process=main
+contract @mozilla.org/network/ua-overrides-bootstrapper;1 {965b0ca8-155b-11e7-93ae-92361f002671} process=main
--- a/netwerk/protocol/http/UserAgentOverrides.jsm
+++ b/netwerk/protocol/http/UserAgentOverrides.jsm
@@ -44,28 +44,34 @@ this.UserAgentOverrides = {
Services.prefs.addObserver(PREF_OVERRIDES_ENABLED, buildOverrides);
try {
Services.obs.addObserver(HTTP_on_useragent_request, "http-on-useragent-request");
} catch (x) {
// The http-on-useragent-request notification is disallowed in content processes.
}
- UserAgentUpdates.init(function(overrides) {
- gOverrideForHostCache.clear();
- if (overrides) {
- for (let domain in overrides) {
- overrides[domain] = getUserAgentFromOverride(overrides[domain]);
+ try {
+ UserAgentUpdates.init(function(overrides) {
+ gOverrideForHostCache.clear();
+ if (overrides) {
+ for (let domain in overrides) {
+ overrides[domain] = getUserAgentFromOverride(overrides[domain]);
+ }
+ overrides.get = function(key) { return this[key]; };
}
- overrides.get = function(key) { return this[key]; };
- }
- gUpdatedOverrides = overrides;
- });
+ gUpdatedOverrides = overrides;
+ });
- buildOverrides();
+ buildOverrides();
+ } catch (e) {
+ // UserAgentOverrides is initialized before profile is ready.
+ // UA override might not work correctly.
+ }
+
gInitialized = true;
},
addComplexOverride: function uao_addComplexOverride(callback) {
// Add to front of array so complex overrides have precedence
gOverrideFunctions.unshift(callback);
},
--- a/netwerk/protocol/http/moz.build
+++ b/netwerk/protocol/http/moz.build
@@ -114,16 +114,18 @@ include('/ipc/chromium/chromium-config.m
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/dom/base',
'/netwerk/base',
]
EXTRA_COMPONENTS += [
+ 'UAOverridesBootstrapper.js',
+ 'UAOverridesBootstrapper.manifest',
'WellKnownOpportunisticUtils.js',
'WellKnownOpportunisticUtils.manifest',
]
if CONFIG['OS_TARGET'] == 'Darwin':
if CONFIG['HOST_MAJOR_VERSION'] == '15':
DEFINES.update(
HAS_CONNECTX=True,
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -321,16 +321,29 @@ nsHttpHandler::SetFastOpenOSSupport()
}
}
#endif
LOG(("nsHttpHandler::SetFastOpenOSSupport %s supported.\n",
mFastOpenSupported ? "" : "not"));
}
+void
+nsHttpHandler::EnsureUAOverridesInit()
+{
+ MOZ_ASSERT(XRE_IsParentProcess());
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsresult rv;
+ nsCOMPtr<nsISupports> bootstrapper
+ = do_GetService("@mozilla.org/network/ua-overrides-bootstrapper;1", &rv);
+ MOZ_ASSERT(bootstrapper);
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+}
+
nsHttpHandler::~nsHttpHandler()
{
LOG(("Deleting nsHttpHandler [this=%p]\n", this));
// make sure the connection manager is shutdown
if (mConnMgr) {
nsresult rv = mConnMgr->Shutdown();
if (NS_FAILED(rv)) {
@@ -2087,16 +2100,21 @@ nsHttpHandler::NewProxiedChannel2(nsIURI
uint32_t caps = mCapabilities;
if (!IsNeckoChild()) {
// HACK: make sure PSM gets initialized on the main thread.
net_EnsurePSMInit();
}
+ if (XRE_IsParentProcess()) {
+ // Load UserAgentOverrides.jsm before any HTTP request is issued.
+ EnsureUAOverridesInit();
+ }
+
uint64_t channelId;
rv = NewChannelId(channelId);
NS_ENSURE_SUCCESS(rv, rv);
rv = httpChannel->Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI, channelId);
if (NS_FAILED(rv))
return rv;
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -394,16 +394,18 @@ private:
MOZ_MUST_USE nsresult SetAcceptLanguages();
MOZ_MUST_USE nsresult SetAcceptEncodings(const char *, bool mIsSecure);
MOZ_MUST_USE nsresult InitConnectionMgr();
void NotifyObservers(nsIHttpChannel *chan, const char *event);
void SetFastOpenOSSupport();
+
+ void EnsureUAOverridesInit();
private:
// cached services
nsMainThreadPtrHandle<nsIIOService> mIOService;
nsMainThreadPtrHandle<nsIStreamConverterService> mStreamConvSvc;
nsMainThreadPtrHandle<nsICookieService> mCookieService;
nsMainThreadPtrHandle<nsISiteSecurityService> mSSService;
nsMainThreadPtrHandle<nsIThrottlingService> mThrottlingService;