Bug 1158208 - Enforce that tiles HTTP requests don't have cookies [r=adw]
authorEd Lee <edilee@mozilla.com>
Mon, 11 May 2015 17:09:29 -0700
changeset 243616 cca3ce6947c2bbf6cd3ca2526e7047882dc4538a
parent 243615 6ffbd3150f6c45e3085f96a19adb54d8f1c46dc0
child 243617 d44f5512d5845d7746bd61d183767872b08e1785
push id28744
push userkwierso@gmail.com
push dateWed, 13 May 2015 18:12:16 +0000
treeherdermozilla-central@324c3423deaf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersadw
bugs1158208
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1158208 - Enforce that tiles HTTP requests don't have cookies [r=adw]
browser/docs/DirectoryLinksProvider.rst
browser/modules/DirectoryLinksProvider.jsm
browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
--- a/browser/docs/DirectoryLinksProvider.rst
+++ b/browser/docs/DirectoryLinksProvider.rst
@@ -18,17 +18,17 @@ 3 kinds of links:
 To power the above features, DirectoryLinksProvider module downloads, at most
 once per 24 hours, the directory source links as JSON with enough data for
 Firefox to determine what should be shown or not. This module also handles
 reporting back data about the tiles via asynchronous pings that don't return
 data from the server.
 
 For the directory source and ping endpoints, the default preference values point
 to Mozilla key-pinned servers with encryption. No cookies are set by the servers
-but not enforced by Firefox.
+and Firefox enforces this by making anonymous requests.
 
 - default directory source endpoint:
   https://tiles.services.mozilla.com/v3/links/fetch/%LOCALE%/%CHANNEL%
 - default directory ping endpoint: https://tiles.services.mozilla.com/v3/links/
 
 
 Preferences
 ===========
--- a/browser/modules/DirectoryLinksProvider.jsm
+++ b/browser/modules/DirectoryLinksProvider.jsm
@@ -4,18 +4,18 @@
 
 "use strict";
 
 this.EXPORTED_SYMBOLS = ["DirectoryLinksProvider"];
 
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 const Cu = Components.utils;
-const XMLHttpRequest =
-  Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1", "nsIXMLHttpRequest");
+
+Cu.importGlobalProperties(["XMLHttpRequest"]);
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
   "resource://gre/modules/NetUtil.jsm");
@@ -264,17 +264,17 @@ let DirectoryLinksProvider = {
   },
 
   _fetchAndCacheLinks: function DirectoryLinksProvider_fetchAndCacheLinks(uri) {
     // Replace with the same display locale used for selecting links data
     uri = uri.replace("%LOCALE%", this.locale);
     uri = uri.replace("%CHANNEL%", UpdateChannel.get());
 
     let deferred = Promise.defer();
-    let xmlHttp = new XMLHttpRequest();
+    let xmlHttp = this._newXHR();
 
     let self = this;
     xmlHttp.onload = function(aResponse) {
       let json = this.responseText;
       if (this.status && this.status != 200) {
         json = "{}";
       }
       OS.File.writeAtomic(self._directoryFilePath, json, {tmpPath: self._directoryFilePath + ".tmp"})
@@ -342,16 +342,23 @@ let DirectoryLinksProvider = {
     // fail if last download occured less then 24 hours ago
     if ((Date.now() - this._lastDownloadMS) > this._downloadIntervalMS) {
       return true;
     }
     return false;
   },
 
   /**
+   * Create a new XMLHttpRequest that is anonymous, i.e., doesn't send cookies
+   */
+  _newXHR() {
+    return new XMLHttpRequest({mozAnon: true});
+  },
+
+  /**
    * Reads directory links file and parses its content
    * @return a promise resolved to an object with keys 'directory' and 'suggested',
    *         each containing a valid list of links,
    *         or {'directory': [], 'suggested': []} if read or parse fails.
    */
   _readDirectoryLinksFile: function DirectoryLinksProvider_readDirectoryLinksFile() {
     let emptyOutput = {directory: [], suggested: [], enhanced: []};
     return OS.File.read(this._directoryFilePath).then(binaryData => {
@@ -532,17 +539,17 @@ let DirectoryLinksProvider = {
     };
 
     // Provide a direct index to the tile triggering the action
     if (actionIndex !== undefined) {
       data[action] = actionIndex;
     }
 
     // Package the data to be sent with the ping
-    let ping = new XMLHttpRequest();
+    let ping = this._newXHR();
     ping.open("POST", pingEndPoint + (action == "view" ? "view" : "click"));
     ping.send(JSON.stringify(data));
 
     return Task.spawn(function* () {
       // since we updated views/clicks we need write _frequencyCaps to disk
       yield this._writeFrequencyCapFile();
       // Use this as an opportunity to potentially fetch new links
       yield this._fetchAndCacheLinksIfNecessary();
--- a/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
+++ b/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
@@ -1667,8 +1667,12 @@ add_task(function test_DirectoryLinksPro
 
   // verify that disk written data is kosher
   data = yield readJsonFile(DirectoryLinksProvider._frequencyCapFilePath);
   do_check_false(data[landingUrl].hasOwnProperty("clicked"));
   do_check_false(data["http://bar.com"].hasOwnProperty("clicked"));
 
   yield promiseCleanDirectoryLinksProvider();
 });
+
+add_task(function test_DirectoryLinksProvider_anonymous() {
+  do_check_true(DirectoryLinksProvider._newXHR().mozAnon);
+});