Bug 1416094 - Force an update when safebrowsing tables are changed in preference. r?francois draft
authorDimiL <dlee@mozilla.com>
Wed, 29 Nov 2017 10:33:26 +0800
changeset 704832 b4aa2217679568aed5705cd3b684ea63ae6bfd60
parent 697453 e1d7427787f7a26983c92ea1a1ac99eb863edd6c
child 742176 2aa9ada3762a81046e61c827b289febc61c4fa58
push id91267
push userbmo:dlee@mozilla.com
push dateWed, 29 Nov 2017 02:47:03 +0000
reviewersfrancois
bugs1416094
milestone59.0a1
Bug 1416094 - Force an update when safebrowsing tables are changed in preference. r?francois MozReview-Commit-ID: 3Zh1pU8XaYo
browser/components/preferences/blocklists.js
browser/components/preferences/in-content/privacy.js
toolkit/components/url-classifier/nsIUrlListManager.idl
toolkit/components/url-classifier/nsUrlClassifierListManager.js
toolkit/content/aboutUrlClassifier.js
--- a/browser/components/preferences/blocklists.js
+++ b/browser/components/preferences/blocklists.js
@@ -3,17 +3,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 const BASE_LIST_ID = "base";
 const CONTENT_LIST_ID = "content";
 const TRACK_SUFFIX = "-track-digest256";
 const TRACKING_TABLE_PREF = "urlclassifier.trackingTable";
 const LISTS_PREF_BRANCH = "browser.safebrowsing.provider.mozilla.lists.";
-const UPDATE_TIME_PREF = "browser.safebrowsing.provider.mozilla.nextupdatetime";
 
 var gBlocklistManager = {
   _type: "",
   _blockLists: [],
   _brandShortName: null,
   _bundle: null,
   _tree: null,
 
@@ -114,17 +113,23 @@ var gBlocklistManager = {
     if (activeList !== selected.id) {
       let trackingTable = Services.prefs.getCharPref(TRACKING_TABLE_PREF);
       if (selected.id != CONTENT_LIST_ID) {
         trackingTable = trackingTable.replace("," + CONTENT_LIST_ID + TRACK_SUFFIX, "");
       } else {
         trackingTable += "," + CONTENT_LIST_ID + TRACK_SUFFIX;
       }
       Services.prefs.setCharPref(TRACKING_TABLE_PREF, trackingTable);
-      Services.prefs.setCharPref(UPDATE_TIME_PREF, 42);
+
+      // Force an update after changing the tracking protection table.
+      let listmanager = Components.classes["@mozilla.org/url-classifier/listmanager;1"]
+                        .getService(Components.interfaces.nsIUrlListManager);
+      if (listmanager) {
+        listmanager.forceUpdates(trackingTable);
+      }
     }
 
     window.close();
   },
 
   _loadBlockLists() {
     this._blockLists = [];
 
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -1110,16 +1110,23 @@ var gPrivacyPane = {
 
         malware.push("test-unwanted-simple");
       }
 
       // sort alphabetically to keep the pref consistent
       malware.sort();
 
       malwareTable.value = malware.join(",");
+
+      // Force an update after changing the malware table.
+      let listmanager = Components.classes["@mozilla.org/url-classifier/listmanager;1"]
+                        .getService(Components.interfaces.nsIUrlListManager);
+      if (listmanager) {
+        listmanager.forceUpdates(malwareTable.value);
+      }
     });
 
     // set initial values
 
     enableSafeBrowsing.checked = safeBrowsingPhishingPref.value && safeBrowsingMalwarePref.value;
     if (!enableSafeBrowsing.checked) {
       if (blockDownloads) {
         blockDownloads.setAttribute("disabled", "true");
--- a/toolkit/components/url-classifier/nsIUrlListManager.idl
+++ b/toolkit/components/url-classifier/nsIUrlListManager.idl
@@ -62,14 +62,22 @@ interface nsIUrlListManager : nsISupport
 
     /**
      * This is currently used by about:url-classifier to force an update
      * for the update url. Update may still fail because of backoff algorithm.
      */
     boolean checkForUpdates(in ACString updateUrl);
 
     /**
+     * Force updates for the given tables, updates are still restricted to
+     * backoff algorithm.
+     * @param tables  A string lists all the tables that we want to trigger updates.
+     *                table names are separated with ','.
+     */
+    boolean forceUpdates(in ACString tableNames);
+
+    /**
      * This is currently used by about:url-classifier to get back-off time
      * (in millisecond since epoch) for the given provider. Return 0 if we
      * are not in back-off mode.
      */
     uint64_t getBackOffTime(in ACString provider);
 };
--- a/toolkit/components/url-classifier/nsUrlClassifierListManager.js
+++ b/toolkit/components/url-classifier/nsUrlClassifierListManager.js
@@ -325,16 +325,52 @@ PROT_ListManager.prototype.maybeToggleUp
     }
   } else {
     log("Stopping managing lists (if currently active)");
     this.stopUpdateCheckers(); // Cancel pending updates
   }
 };
 
 /**
+ * Force updates for the given tables. This API may trigger more than one update
+ * if the table lists provided belong to multiple updateurl (multiple provider).
+ * Return false when any update is fail due to back-off algorithm.
+ */
+PROT_ListManager.prototype.forceUpdates = function(tables) {
+  log("forceUpdates with " + tables);
+  if (!tables) {
+    return false;
+  }
+
+  let updateUrls = new Set();
+  tables.split(",").forEach((table) => {
+    if (this.tablesData[table]) {
+      updateUrls.add(this.tablesData[table].updateUrl);
+    }
+  });
+
+  let ret = true;
+
+  updateUrls.forEach((url) => {
+    // Cancel current update timer for the url because we are forcing an update.
+    if (this.updateCheckers_[url]) {
+      this.updateCheckers_[url].cancel();
+      this.updateCheckers_[url] = null;
+    }
+
+    // Trigger an update for the given url.
+    if (!this.checkForUpdates(url)) {
+      ret = false;
+    }
+  });
+
+  return ret;
+}
+
+/**
  * Updates our internal tables from the update server
  *
  * @param updateUrl: request updates for tables associated with that url, or
  * for all tables if the url is empty.
  */
 PROT_ListManager.prototype.checkForUpdates = function(updateUrl) {
   log("checkForUpdates with " + updateUrl);
   // See if we've triggered the request backoff logic.
--- a/toolkit/content/aboutUrlClassifier.js
+++ b/toolkit/content/aboutUrlClassifier.js
@@ -169,21 +169,19 @@ var Provider = {
   },
 
   // Call update for the provider.
   update(provider) {
     let listmanager = Cc["@mozilla.org/url-classifier/listmanager;1"]
                       .getService(Ci.nsIUrlListManager);
 
     let pref = "browser.safebrowsing.provider." + provider + ".lists";
-    let tables = Services.prefs.getCharPref(pref, "").split(",");
-    let table = tables.find(t => listmanager.getUpdateUrl(t) != "");
+    let tables = Services.prefs.getCharPref(pref, "");
 
-    let updateUrl = listmanager.getUpdateUrl(table);
-    if (!listmanager.checkForUpdates(updateUrl)) {
+    if (!listmanager.forceUpdates(tables)) {
       // This may because of back-off algorithm.
       let elem = document.getElementById(provider + "-col-lastupdateresult");
       elem.childNodes[0].nodeValue = bundle.GetStringFromName("CannotUpdate");
     }
   },
 
 };