Bug 1357116 - Load the blocklist updater module lazily r=florian
Importing the blocklist-updater module on each notification in nsBlocklistService
could cause us to periodically jank the browser UI.
This patch now lazy loads as many dependencies as possible.
MozReview-Commit-ID: HBGjSJi5PwE
--- a/services/common/blocklist-clients.js
+++ b/services/common/blocklist-clients.js
@@ -12,22 +12,26 @@ this.EXPORTED_SYMBOLS = ["AddonBlocklist
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const { OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
Cu.importGlobalProperties(["fetch"]);
-const { Kinto } = Cu.import("resource://services-common/kinto-offline-client.js", {});
-const { KintoHttpClient } = Cu.import("resource://services-common/kinto-http-client.js", {});
-const { FirefoxAdapter } = Cu.import("resource://services-common/kinto-storage-adapter.js", {});
-const { CanonicalJSON } = Components.utils.import("resource://gre/modules/CanonicalJSON.jsm", {});
-
-XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
+ "resource://gre/modules/FileUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Kinto",
+ "resource://services-common/kinto-offline-client.js");
+XPCOMUtils.defineLazyModuleGetter(this, "KintoHttpClient",
+ "resource://services-common/kinto-http-client.js");
+XPCOMUtils.defineLazyModuleGetter(this, "FirefoxAdapter",
+ "resource://services-common/kinto-storage-adapter.js");
+XPCOMUtils.defineLazyModuleGetter(this, "CanonicalJSON",
+ "resource://gre/modules/CanonicalJSON.jsm");
const KEY_APPDIR = "XCurProcD";
const PREF_SETTINGS_SERVER = "services.settings.server";
const PREF_BLOCKLIST_BUCKET = "services.blocklist.bucket";
const PREF_BLOCKLIST_ONECRL_COLLECTION = "services.blocklist.onecrl.collection";
const PREF_BLOCKLIST_ONECRL_CHECKED_SECONDS = "services.blocklist.onecrl.checked";
const PREF_BLOCKLIST_ADDONS_COLLECTION = "services.blocklist.addons.collection";
const PREF_BLOCKLIST_ADDONS_CHECKED_SECONDS = "services.blocklist.addons.checked";
@@ -90,20 +94,17 @@ class BlocklistClient {
constructor(collectionName, lastCheckTimePref, processCallback, bucketName, signerName) {
this.collectionName = collectionName;
this.lastCheckTimePref = lastCheckTimePref;
this.processCallback = processCallback;
this.bucketName = bucketName;
this.signerName = signerName;
- this._kinto = new Kinto({
- bucket: bucketName,
- adapter: FirefoxAdapter,
- });
+ this._kinto = null;
}
get identifier() {
return `${this.bucketName}/${this.collectionName}`;
}
get filename() {
// Replace slash by OS specific path separator (eg. Windows)
@@ -178,16 +179,23 @@ class BlocklistClient {
* @return {Promise} which rejects on sync or process failure.
*/
async maybeSync(lastModified, serverTime, options = {loadDump: true}) {
const {loadDump} = options;
const remote = Services.prefs.getCharPref(PREF_SETTINGS_SERVER);
const enforceCollectionSigning =
Services.prefs.getBoolPref(PREF_BLOCKLIST_ENFORCE_SIGNING);
+ if (!this._kinto) {
+ this._kinto = new Kinto({
+ bucket: this.bucketName,
+ adapter: FirefoxAdapter,
+ });
+ }
+
// if there is a signerName and collection signing is enforced, add a
// hook for incoming changes that validates the signature
let hooks;
if (this.signerName && enforceCollectionSigning) {
hooks = {
"incoming-changes": [(payload, collection) => {
return this.validateCollectionSignature(remote, payload, collection);
}]
--- a/services/common/blocklist-updater.js
+++ b/services/common/blocklist-updater.js
@@ -1,35 +1,38 @@
/* 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/. */
this.EXPORTED_SYMBOLS = ["checkVersions", "addTestBlocklistClient"];
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.importGlobalProperties(["fetch"]);
-const BlocklistClients = Cu.import("resource://services-common/blocklist-clients.js", {});
const PREF_SETTINGS_SERVER = "services.settings.server";
const PREF_SETTINGS_SERVER_BACKOFF = "services.settings.server.backoff";
const PREF_BLOCKLIST_CHANGES_PATH = "services.blocklist.changes.path";
const PREF_BLOCKLIST_LAST_UPDATE = "services.blocklist.last_update_seconds";
const PREF_BLOCKLIST_LAST_ETAG = "services.blocklist.last_etag";
const PREF_BLOCKLIST_CLOCK_SKEW_SECONDS = "services.blocklist.clock_skew_seconds";
-const gBlocklistClients = {
- [BlocklistClients.OneCRLBlocklistClient.collectionName]: BlocklistClients.OneCRLBlocklistClient,
- [BlocklistClients.AddonBlocklistClient.collectionName]: BlocklistClients.AddonBlocklistClient,
- [BlocklistClients.GfxBlocklistClient.collectionName]: BlocklistClients.GfxBlocklistClient,
- [BlocklistClients.PluginBlocklistClient.collectionName]: BlocklistClients.PluginBlocklistClient,
- [BlocklistClients.PinningPreloadClient.collectionName]: BlocklistClients.PinningPreloadClient
-};
+XPCOMUtils.defineLazyGetter(this, "gBlocklistClients", function() {
+ const BlocklistClients = Cu.import("resource://services-common/blocklist-clients.js", {});
+ return {
+ [BlocklistClients.OneCRLBlocklistClient.collectionName]: BlocklistClients.OneCRLBlocklistClient,
+ [BlocklistClients.AddonBlocklistClient.collectionName]: BlocklistClients.AddonBlocklistClient,
+ [BlocklistClients.GfxBlocklistClient.collectionName]: BlocklistClients.GfxBlocklistClient,
+ [BlocklistClients.PluginBlocklistClient.collectionName]: BlocklistClients.PluginBlocklistClient,
+ [BlocklistClients.PinningPreloadClient.collectionName]: BlocklistClients.PinningPreloadClient,
+ };
+});
// Add a blocklist client for testing purposes. Do not use for any other purpose
this.addTestBlocklistClient = (name, client) => { gBlocklistClients[name] = client; }
// This is called by the ping mechanism.
// returns a promise that rejects if something goes wrong
this.checkVersions = async function() {
--- a/toolkit/mozapps/extensions/nsBlocklistService.js
+++ b/toolkit/mozapps/extensions/nsBlocklistService.js
@@ -27,16 +27,23 @@ XPCOMUtils.defineLazyModuleGetter(this,
"resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ServiceRequest",
"resource://gre/modules/ServiceRequest.jsm");
+// The blocklist updater is the new system in charge of fetching remote data
+// securely and efficiently. It will replace the current XML-based system.
+// See Bug 1257565 and Bug 1252456.
+const BlocklistUpdater = {};
+XPCOMUtils.defineLazyModuleGetter(BlocklistUpdater, "checkVersions",
+ "resource://services-common/blocklist-updater.js");
+
const TOOLKIT_ID = "toolkit@mozilla.org";
const KEY_PROFILEDIR = "ProfD";
const KEY_APPDIR = "XCurProcD";
const FILE_BLOCKLIST = "blocklist.xml";
const PREF_BLOCKLIST_LASTUPDATETIME = "app.update.lastUpdateTime.blocklist-background-update-timer";
const PREF_BLOCKLIST_URL = "extensions.blocklist.url";
const PREF_BLOCKLIST_ITEM_URL = "extensions.blocklist.itemURL";
const PREF_BLOCKLIST_ENABLED = "extensions.blocklist.enabled";
@@ -594,24 +601,21 @@ Blocklist.prototype = {
request.addEventListener("load", event => this.onXMLLoad(event));
request.send(null);
// When the blocklist loads we need to compare it to the current copy so
// make sure we have loaded it.
if (!this._isBlocklistLoaded())
this._loadBlocklist();
- // If kinto update is enabled, do the kinto update
+ // If blocklist update via Kinto is enabled, poll for changes and sync.
+ // Currently certificates blocklist relies on it by default.
if (gPref.getBoolPref(PREF_BLOCKLIST_UPDATE_ENABLED)) {
- const updater =
- Components.utils.import("resource://services-common/blocklist-updater.js",
- {});
- updater.checkVersions().catch(() => {
- // Before we enable this in release, we want to collect telemetry on
- // failed kinto updates - see bug 1254099
+ BlocklistUpdater.checkVersions().catch(() => {
+ // Bug 1254099 - Telemetry (success or errors) will be collected during this process.
});
}
},
async onXMLLoad(aEvent) {
let request = aEvent.target;
try {
gCertUtils.checkCert(request.channel);