summaryrefslogtreecommitdiffstats
path: root/toolkit/components/url-classifier/content/xml-fetcher.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/url-classifier/content/xml-fetcher.js')
-rw-r--r--toolkit/components/url-classifier/content/xml-fetcher.js126
1 files changed, 126 insertions, 0 deletions
diff --git a/toolkit/components/url-classifier/content/xml-fetcher.js b/toolkit/components/url-classifier/content/xml-fetcher.js
new file mode 100644
index 000000000..39b116e00
--- /dev/null
+++ b/toolkit/components/url-classifier/content/xml-fetcher.js
@@ -0,0 +1,126 @@
+# 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/.
+
+// A simple class that encapsulates a request. You'll notice the
+// style here is different from the rest of the extension; that's
+// because this was re-used from really old code we had. At some
+// point it might be nice to replace this with something better
+// (e.g., something that has explicit onerror handler, ability
+// to set headers, and so on).
+
+/**
+ * Because we might be in a component, we can't just assume that
+ * XMLHttpRequest exists. So we use this tiny factory function to wrap the
+ * XPCOM version.
+ *
+ * @return XMLHttpRequest object
+ */
+this.PROT_NewXMLHttpRequest = function PROT_NewXMLHttpRequest() {
+ var Cc = Components.classes;
+ var Ci = Components.interfaces;
+ var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
+ .createInstance(Ci.nsIXMLHttpRequest);
+ // Need the following so we get onerror/load/progresschange
+ request.QueryInterface(Ci.nsIJSXMLHttpRequest);
+ return request;
+}
+
+/**
+ * A helper class that does HTTP GETs and calls back a function with
+ * the content it receives. Asynchronous, so uses a closure for the
+ * callback.
+ *
+ * Note, that XMLFetcher is only used for SafeBrowsing, therefore
+ * we inherit from nsILoadContext, so we can use the callbacks on the
+ * channel to separate the safebrowsing cookie based on a reserved
+ * appId.
+ * @constructor
+ */
+this.PROT_XMLFetcher = function PROT_XMLFetcher() {
+ this.debugZone = "xmlfetcher";
+ this._request = PROT_NewXMLHttpRequest();
+ // implements nsILoadContext
+ this.appId = Ci.nsIScriptSecurityManager.SAFEBROWSING_APP_ID;
+ this.isInIsolatedMozBrowserElement = false;
+ this.usePrivateBrowsing = false;
+ this.isContent = false;
+}
+
+PROT_XMLFetcher.prototype = {
+ /**
+ * Function that will be called back upon fetch completion.
+ */
+ _callback: null,
+
+
+ /**
+ * Fetches some content.
+ *
+ * @param page URL to fetch
+ * @param callback Function to call back when complete.
+ */
+ get: function(page, callback) {
+ this._request.abort(); // abort() is asynchronous, so
+ this._request = PROT_NewXMLHttpRequest();
+ this._callback = callback;
+ var asynchronous = true;
+ this._request.loadInfo.originAttributes = {
+ appId: this.appId,
+ inIsolatedMozBrowser: this.isInIsolatedMozBrowserElement
+ };
+ this._request.open("GET", page, asynchronous);
+ this._request.channel.notificationCallbacks = this;
+
+ // Create a closure
+ var self = this;
+ this._request.addEventListener("readystatechange", function() {
+ self.readyStateChange(self);
+ }, false);
+
+ this._request.send(null);
+ },
+
+ cancel: function() {
+ this._request.abort();
+ this._request = null;
+ },
+
+ /**
+ * Called periodically by the request to indicate some state change. 4
+ * means content has been received.
+ */
+ readyStateChange: function(fetcher) {
+ if (fetcher._request.readyState != 4)
+ return;
+
+ // If the request fails, on trunk we get status set to
+ // NS_ERROR_NOT_AVAILABLE. On 1.8.1 branch we get an exception
+ // forwarded from nsIHttpChannel::GetResponseStatus. To be consistent
+ // between branch and trunk, we send back NS_ERROR_NOT_AVAILABLE for
+ // http failures.
+ var responseText = null;
+ var status = Components.results.NS_ERROR_NOT_AVAILABLE;
+ try {
+ G_Debug(this, "xml fetch status code: \"" +
+ fetcher._request.status + "\"");
+ status = fetcher._request.status;
+ responseText = fetcher._request.responseText;
+ } catch(e) {
+ G_Debug(this, "Caught exception trying to read xmlhttprequest " +
+ "status/response.");
+ G_Debug(this, e);
+ }
+ if (fetcher._callback)
+ fetcher._callback(responseText, status);
+ },
+
+ // nsIInterfaceRequestor
+ getInterface: function(iid) {
+ return this.QueryInterface(iid);
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIInterfaceRequestor,
+ Ci.nsISupports,
+ Ci.nsILoadContext])
+};