Bug 1325501 - move addons manager from XHR to ServiceRequest r?kmag
MozReview-Commit-ID: J0ytKWqDOr3
--- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm
+++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm
@@ -37,16 +37,19 @@ const PERSIST_ENABLED = true;
const PERSIST_BYPASS_CACHE = false;
const PERSIST_FILES = {
headerURL: "lightweighttheme-header",
footerURL: "lightweighttheme-footer"
};
XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeImageOptimizer",
"resource://gre/modules/addons/LightweightThemeImageOptimizer.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ServiceRequest",
+ "resource://gre/modules/ServiceRequest.jsm");
+
XPCOMUtils.defineLazyGetter(this, "_prefs", () => {
return Services.prefs.getBranch("lightweightThemes.");
});
Object.defineProperty(this, "_maxUsedThemes", {
get: function() {
delete this._maxUsedThemes;
@@ -249,18 +252,17 @@ this.LightweightThemeManager = {
} catch (e) {
return;
}
var theme = this.currentTheme;
if (!theme || !theme.updateURL)
return;
- var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
- .createInstance(Ci.nsIXMLHttpRequest);
+ var req = new ServiceRequest();
req.mozBackgroundRequest = true;
req.overrideMimeType("text/plain");
req.open("GET", theme.updateURL, true);
// Prevent the request from reading from the cache.
req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
// Prevent the request from writing to the cache.
req.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
--- a/toolkit/mozapps/extensions/internal/AddonRepository.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonRepository.jsm
@@ -21,16 +21,18 @@ XPCOMUtils.defineLazyModuleGetter(this,
XPCOMUtils.defineLazyModuleGetter(this, "DeferredSave",
"resource://gre/modules/DeferredSave.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonRepository_SQLiteMigrator",
"resource://gre/modules/addons/AddonRepository_SQLiteMigrator.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/Promise.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ServiceRequest",
+ "resource://gre/modules/ServiceRequest.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
this.EXPORTED_SYMBOLS = [ "AddonRepository" ];
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
const PREF_GETADDONS_CACHE_TYPES = "extensions.getAddons.cache.types";
@@ -95,20 +97,16 @@ const HTML_KEY_MAP = {
// A map between XML keys to AddonSearchResult keys for integer values
// that require no extra parsing from XML
const INTEGER_KEY_MAP = {
total_downloads: "totalDownloads",
weekly_downloads: "weeklyDownloads",
daily_users: "dailyUsers"
};
-// Wrap the XHR factory so that tests can override with a mock
-var XHRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1",
- "nsIXMLHttpRequest");
-
function convertHTMLToPlainText(html) {
if (!html)
return html;
var converter = Cc["@mozilla.org/widget/htmlformatconverter;1"].
createInstance(Ci.nsIFormatConverter);
var input = Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString);
@@ -1428,17 +1426,17 @@ this.AddonRepository = {
}
this._searching = true;
this._callback = aCallback;
this._maxResults = aMaxResults;
logger.debug("Requesting " + aURI);
- this._request = new XHRequest();
+ this._request = new ServiceRequest();
this._request.mozBackgroundRequest = true;
this._request.open("GET", aURI, true);
this._request.overrideMimeType("text/xml");
if (aTimeout) {
this._request.timeout = aTimeout;
}
this._request.addEventListener("error", aEvent => this._reportFailure(), false);
--- a/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm
@@ -30,16 +30,19 @@ Components.utils.import("resource://gre/
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonRepository",
"resource://gre/modules/addons/AddonRepository.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ServiceRequest",
+ "resource://gre/modules/ServiceRequest.jsm");
+
// Shared code for suppressing bad cert dialogs.
XPCOMUtils.defineLazyGetter(this, "CertUtils", function() {
let certUtils = {};
Components.utils.import("resource://gre/modules/CertUtils.jsm", certUtils);
return certUtils;
});
@@ -573,18 +576,17 @@ function UpdateParser(aId, aUpdateKey, a
try {
requireBuiltIn = Services.prefs.getBoolPref(PREF_UPDATE_REQUIREBUILTINCERTS);
}
catch (e) {
}
logger.debug("Requesting " + aUrl);
try {
- this.request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
- createInstance(Ci.nsIXMLHttpRequest);
+ this.request = new ServiceRequest();
this.request.open("GET", this.url, true);
this.request.channel.notificationCallbacks = new CertUtils.BadCertHandler(!requireBuiltIn);
this.request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
// Prevent the request from writing to cache.
this.request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
this.request.overrideMimeType("text/plain");
this.request.setRequestHeader("Moz-XPI-Update", "1", true);
this.request.timeout = TIMEOUT;
--- a/toolkit/mozapps/extensions/internal/ProductAddonChecker.jsm
+++ b/toolkit/mozapps/extensions/internal/ProductAddonChecker.jsm
@@ -37,25 +37,28 @@ Cu.import("resource://gre/modules/osfile
XPCOMUtils.defineLazyModuleGetter(this, "GMPPrefs",
"resource://gre/modules/GMPUtils.jsm");
/* globals OS */
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
-var logger = Log.repository.getLogger("addons.productaddons");
+XPCOMUtils.defineLazyModuleGetter(this, "ServiceRequest",
+ "resource://gre/modules/ServiceRequest.jsm");
// This exists so that tests can override the XHR behaviour for downloading
// the addon update XML file.
var CreateXHR = function() {
return Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
- createInstance(Ci.nsISupports);
+ createInstance(Ci.nsISupports);
}
+var logger = Log.repository.getLogger("addons.productaddons");
+
/**
* Number of milliseconds after which we need to cancel `downloadXML`.
*
* Bug 1087674 suggests that the XHR we use in `downloadXML` may
* never terminate in presence of network nuisances (e.g. strange
* antivirus behavior). This timeout is a defensive measure to ensure
* that we fail cleanly in such case.
*/
@@ -108,16 +111,21 @@ function downloadXML(url, allowNonBuiltI
request = request.wrappedJSObject;
}
request.open("GET", url, true);
request.channel.notificationCallbacks = new BadCertHandler(allowNonBuiltIn);
// Prevent the request from reading from the cache.
request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
// Prevent the request from writing to the cache.
request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
+ // Use conservative TLS settings. See bug 1325501.
+ // TODO move to ServiceRequest.
+ if (request.channel instanceof Ci.nsIHttpChannelInternal) {
+ request.channel.QueryInterface(Ci.nsIHttpChannelInternal).beConservative = true;
+ }
request.timeout = TIMEOUT_DELAY_MS;
request.overrideMimeType("text/xml");
// The Cache-Control header is only interpreted by proxies and the
// final destination. It does not help if a resource is already
// cached locally.
request.setRequestHeader("Cache-Control", "no-cache");
// HTTP/1.0 servers might not implement Cache-Control and
@@ -158,17 +166,17 @@ function downloadXML(url, allowNonBuiltI
logger.info("sending request to: " + url);
request.send(null);
});
}
function downloadJSON(uri) {
logger.info("fetching config from: " + uri);
return new Promise((resolve, reject) => {
- let xmlHttp = new XMLHttpRequest({mozAnon: true});
+ let xmlHttp = new ServiceRequest({mozAnon: true});
xmlHttp.onload = function(aResponse) {
resolve(JSON.parse(this.responseText));
};
xmlHttp.onerror = function(e) {
reject("Fetching " + uri + " results in error code: " + e.target.status);
};
@@ -285,18 +293,17 @@ function downloadLocalConfig() {
*
* @param url
* The url to download from.
* @return a promise that resolves to the path of a temporary file or rejects
* with a JS exception in case of error.
*/
function downloadFile(url) {
return new Promise((resolve, reject) => {
- let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
- createInstance(Ci.nsISupports);
+ let xhr = new XMLHttpRequest();
xhr.onload = function(response) {
logger.info("downloadXHR File download. status=" + xhr.status);
if (xhr.status != 200 && xhr.status != 206) {
reject(Components.Exception("File download failed", xhr.status));
return;
}
Task.spawn(function* () {
let f = yield OS.File.openUnique(OS.Path.join(OS.Constants.Path.tmpDir, "tmpaddon"));
@@ -318,16 +325,21 @@ function downloadFile(url) {
reject(ex);
};
xhr.addEventListener("error", fail);
xhr.addEventListener("abort", fail);
xhr.responseType = "arraybuffer";
try {
xhr.open("GET", url);
+ // Use conservative TLS settings. See bug 1325501.
+ // TODO move to ServiceRequest.
+ if (xhr.channel instanceof Ci.nsIHttpChannelInternal) {
+ xhr.channel.QueryInterface(Ci.nsIHttpChannelInternal).beConservative = true;
+ }
xhr.send(null);
} catch (ex) {
reject(ex);
}
});
}
/**
--- a/toolkit/mozapps/extensions/nsBlocklistService.js
+++ b/toolkit/mozapps/extensions/nsBlocklistService.js
@@ -24,16 +24,18 @@ try {
}
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"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");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
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";
@@ -603,18 +605,17 @@ Blocklist.prototype = {
}
catch (e) {
LOG("Blocklist::notify: There was an error creating the blocklist URI\r\n" +
"for: " + dsURI + ", error: " + e);
return;
}
LOG("Blocklist::notify: Requesting " + uri.spec);
- var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
- createInstance(Ci.nsIXMLHttpRequest);
+ let request = new ServiceRequest();
request.open("GET", uri.spec, true);
request.channel.notificationCallbacks = new gCertUtils.BadCertHandler();
request.overrideMimeType("text/xml");
request.setRequestHeader("Cache-Control", "no-cache");
request.QueryInterface(Components.interfaces.nsIJSXMLHttpRequest);
request.addEventListener("error", event => this.onXMLError(event), false);
request.addEventListener("load", event => this.onXMLLoad(event), false);
--- a/toolkit/mozapps/extensions/test/browser/browser_metadataTimeout.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_metadataTimeout.js
@@ -12,18 +12,18 @@ const PREF_METADATA_LASTUPDATE =
Components.utils.import("resource://gre/modules/Promise.jsm");
var repo = {};
var ARContext = Components.utils.import("resource://gre/modules/addons/AddonRepository.jsm", repo);
// Mock out the XMLHttpRequest factory for AddonRepository so
// we can reply with a timeout
var pXHRStarted = Promise.defer();
-var oldXHRConstructor = ARContext.XHRequest;
-ARContext.XHRequest = function() {
+var oldXHRConstructor = ARContext.ServiceRequest;
+ARContext.ServiceRequest = function() {
this._handlers = new Map();
this.mozBackgroundRequest = false;
this.timeout = undefined;
this.open = function(aMethod, aURI, aAsync) {
this.method = aMethod;
this.uri = aURI;
this.async = aAsync;
info("Opened XHR for " + aMethod + " " + aURI);
@@ -101,12 +101,12 @@ add_task(function* amo_ping_timeout() {
let xhr = yield pXHRStarted.promise;
is(xhr.timeout, 30000, "XHR request should have 30 second timeout");
ok(xhr._handlers.has("timeout"), "Timeout handler set on XHR");
// call back the timeout handler
xhr._handlers.get("timeout")();
// Put the old XHR constructor back
- ARContext.XHRequest = oldXHRConstructor;
+ ARContext.ServiceRequest = oldXHRConstructor;
// The window should close without further interaction
yield promise_window_close(compatWindow);
});