Bug 1388224 - Remove SyncStorageRequest HTTP wrapper class, which is no longer used r?kitcambridge draft
authorThom Chiovoloni <tchiovoloni@mozilla.com>
Wed, 01 Nov 2017 17:17:46 -0400
changeset 692253 1c030f64867c59d85a1ac086e8443fcf0e9bbb66
parent 692227 3502694e2053f9d8a730f8b8ea1c2e783e58dba3
child 738725 2d66527234dde7a14e72d94b4113691f86931332
push id87464
push userbmo:tchiovoloni@mozilla.com
push dateThu, 02 Nov 2017 21:57:34 +0000
reviewerskitcambridge
bugs1388224
milestone58.0a1
Bug 1388224 - Remove SyncStorageRequest HTTP wrapper class, which is no longer used r?kitcambridge MozReview-Commit-ID: EgExfizNll5
services/sync/modules/browserid_identity.js
services/sync/modules/constants.js
services/sync/modules/rest.js
services/sync/modules/service.js
services/sync/moz.build
services/sync/tests/unit/test_browserid_identity.js
services/sync/tests/unit/test_load_modules.js
services/sync/tests/unit/test_service_getStorageInfo.js
services/sync/tests/unit/test_syncstoragerequest.js
services/sync/tests/unit/test_warn_on_truncated_response.js
services/sync/tests/unit/xpcshell.ini
tools/lint/eslint/modules.json
--- a/services/sync/modules/browserid_identity.js
+++ b/services/sync/modules/browserid_identity.js
@@ -774,23 +774,16 @@ this.BrowserIDManager.prototype = {
     );
   },
 
   getResourceAuthenticator() {
     return this._getAuthenticationHeader.bind(this);
   },
 
   /**
-   * Obtain a function to be used for adding auth to RESTRequest instances.
-   */
-  getRESTRequestAuthenticator() {
-    return this._addAuthenticationHeader.bind(this);
-  },
-
-  /**
    * @return a Hawk HTTP Authorization Header, lightly wrapped, for the .uri
    * of a RESTRequest or AsyncResponse object.
    */
   _getAuthenticationHeader(httpObject, method) {
     let cb = Async.makeSpinningCallback();
     this._ensureValidToken().then(cb, cb);
     // Note that in failure states we return null, causing the request to be
     // made without authorization headers, thereby presumably causing a 401,
@@ -821,25 +814,16 @@ this.BrowserIDManager.prototype = {
       localtimeOffsetMsec: this._localtimeOffsetMsec,
       credentials,
     };
 
     let headerValue = CryptoUtils.computeHAWK(httpObject.uri, method, options);
     return {headers: {authorization: headerValue.field}};
   },
 
-  _addAuthenticationHeader(request, method) {
-    let header = this._getAuthenticationHeader(request, method);
-    if (!header) {
-      return null;
-    }
-    request.setHeader("authorization", header.headers.authorization);
-    return request;
-  },
-
   createClusterManager(service) {
     return new BrowserIDClusterManager(service);
   },
 
   // Tell Sync what the login status should be if it saw a 401 fetching
   // info/collections as part of login verification (typically immediately
   // after login.)
   // In our case, it almost certainly means a transient error fetching a token
--- a/services/sync/modules/constants.js
+++ b/services/sync/modules/constants.js
@@ -126,22 +126,16 @@ RESPONSE_OVER_QUOTA:                   "
 // engine failure status codes
 ENGINE_UPLOAD_FAIL:                    "error.engine.reason.record_upload_fail",
 ENGINE_DOWNLOAD_FAIL:                  "error.engine.reason.record_download_fail",
 ENGINE_UNKNOWN_FAIL:                   "error.engine.reason.unknown_fail",
 ENGINE_APPLY_FAIL:                     "error.engine.reason.apply_fail",
 // an upload failure where the batch was interrupted with a 412
 ENGINE_BATCH_INTERRUPTED:              "error.engine.reason.batch_interrupted",
 
-// info types for Service.getStorageInfo
-INFO_COLLECTIONS:                      "collections",
-INFO_COLLECTION_USAGE:                 "collection_usage",
-INFO_COLLECTION_COUNTS:                "collection_counts",
-INFO_QUOTA:                            "quota",
-
 // Ways that a sync can be disabled (messages only to be printed in debug log)
 kSyncMasterPasswordLocked:             "User elected to leave Master Password locked",
 kSyncWeaveDisabled:                    "Weave is disabled",
 kSyncNetworkOffline:                   "Network is offline",
 kSyncBackoffNotMet:                    "Trying to sync before the server said it's okay",
 kFirstSyncChoiceNotMade:               "User has not selected an action for first sync",
 kSyncNotConfigured:                    "Sync is not configured",
 
deleted file mode 100644
--- a/services/sync/modules/rest.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* 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/. */
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import("resource://services-common/rest.js");
-Cu.import("resource://services-sync/util.js");
-
-this.EXPORTED_SYMBOLS = ["SyncStorageRequest"];
-
-const STORAGE_REQUEST_TIMEOUT = 5 * 60; // 5 minutes
-
-/**
- * RESTRequest variant for use against a Sync storage server.
- */
-this.SyncStorageRequest = function SyncStorageRequest(uri) {
-  RESTRequest.call(this, uri);
-
-  this.authenticator = null;
-};
-SyncStorageRequest.prototype = {
-
-  __proto__: RESTRequest.prototype,
-
-  _logName: "Sync.StorageRequest",
-
-  /**
-   * Wait 5 minutes before killing a request.
-   */
-  timeout: STORAGE_REQUEST_TIMEOUT,
-
-  dispatch: function dispatch(method, data, onComplete, onProgress) {
-    // Compose a UA string fragment from the various available identifiers.
-    if (Svc.Prefs.get("sendVersionInfo", true)) {
-      this.setHeader("user-agent", Utils.userAgent);
-    }
-
-    if (this.authenticator) {
-      let result = this.authenticator(this, method);
-      if (result && result.headers) {
-        for (let [k, v] of Object.entries(result.headers)) {
-          this.setHeader(k, v);
-        }
-      }
-    } else {
-      this._log.debug("No authenticator found.");
-    }
-
-    return RESTRequest.prototype.dispatch.apply(this, arguments);
-  },
-
-  onStartRequest: function onStartRequest(channel) {
-    RESTRequest.prototype.onStartRequest.call(this, channel);
-    if (this.status == this.ABORTED) {
-      return;
-    }
-
-    let headers = this.response.headers;
-    // Save the latest server timestamp when possible.
-    if (headers["x-weave-timestamp"]) {
-      SyncStorageRequest.serverTime = parseFloat(headers["x-weave-timestamp"]);
-    }
-
-    // This is a server-side safety valve to allow slowing down
-    // clients without hurting performance.
-    if (headers["x-weave-backoff"]) {
-      Svc.Obs.notify("weave:service:backoff:interval",
-                     parseInt(headers["x-weave-backoff"], 10));
-    }
-
-    if (this.response.success && headers["x-weave-quota-remaining"]) {
-      Svc.Obs.notify("weave:service:quota:remaining",
-                     parseInt(headers["x-weave-quota-remaining"], 10));
-    }
-  },
-
-  onStopRequest: function onStopRequest(channel, context, statusCode) {
-    if (this.status != this.ABORTED) {
-      let resp = this.response;
-      let contentLength = resp.headers ? resp.headers["content-length"] : "";
-
-      if (resp.success && contentLength &&
-          contentLength != resp.body.length) {
-        this._log.warn("The response body's length of: " + resp.body.length +
-                       " doesn't match the header's content-length of: " +
-                       contentLength + ".");
-      }
-    }
-
-    RESTRequest.prototype.onStopRequest.apply(this, arguments);
-  }
-};
--- a/services/sync/modules/service.js
+++ b/services/sync/modules/service.js
@@ -25,17 +25,16 @@ Cu.import("resource://services-common/as
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://services-sync/constants.js");
 Cu.import("resource://services-sync/engines.js");
 Cu.import("resource://services-sync/engines/clients.js");
 Cu.import("resource://services-sync/main.js");
 Cu.import("resource://services-sync/policies.js");
 Cu.import("resource://services-sync/record.js");
 Cu.import("resource://services-sync/resource.js");
-Cu.import("resource://services-sync/rest.js");
 Cu.import("resource://services-sync/stages/enginesync.js");
 Cu.import("resource://services-sync/stages/declined.js");
 Cu.import("resource://services-sync/status.js");
 Cu.import("resource://services-sync/telemetry.js");
 Cu.import("resource://services-sync/util.js");
 
 function getEngineModules() {
   let result = {
@@ -58,21 +57,16 @@ function getEngineModules() {
     result.CreditCards = {
       module: "resource://formautofill/FormAutofillSync.jsm",
       symbol: "CreditCardsEngine",
     };
   }
   return result;
 }
 
-const STORAGE_INFO_TYPES = [INFO_COLLECTIONS,
-                            INFO_COLLECTION_USAGE,
-                            INFO_COLLECTION_COUNTS,
-                            INFO_QUOTA];
-
 // A unique identifier for this browser session. Used for logging so
 // we can easily see whether 2 logs are in the same browser session or
 // after the browser restarted.
 XPCOMUtils.defineLazyGetter(this, "browserSessionID", Utils.makeGUID);
 
 function Sync11Service() {
   this._notify = Utils.notify("weave:service:");
 }
@@ -481,26 +475,16 @@ Sync11Service.prototype = {
   resource: function resource(url) {
     let res = new Resource(url);
     res.authenticator = this.identity.getResourceAuthenticator();
 
     return res;
   },
 
   /**
-   * Obtain a SyncStorageRequest instance with authentication credentials.
-   */
-  getStorageRequest: function getStorageRequest(url) {
-    let request = new SyncStorageRequest(url);
-    request.authenticator = this.identity.getRESTRequestAuthenticator();
-
-    return request;
-  },
-
-  /**
    * Perform the info fetch as part of a login or key fetch, or
    * inside engine sync.
    */
   async _fetchInfo(url) {
     let infoURL = url || this.infoURL;
 
     this._log.trace("In _fetchInfo: " + infoURL);
     let info;
@@ -1372,63 +1356,16 @@ Sync11Service.prototype = {
 
       // Have each engine drop any temporary meta data
       for (let engine of engines) {
         await engine.resetClient();
       }
     })();
   },
 
-  /**
-   * Fetch storage info from the server.
-   *
-   * @param type
-   *        String specifying what info to fetch from the server. Must be one
-   *        of the INFO_* values. See Sync Storage Server API spec for details.
-   * @param callback
-   *        Callback function with signature (error, data) where `data' is
-   *        the return value from the server already parsed as JSON.
-   *
-   * @return RESTRequest instance representing the request, allowing callers
-   *         to cancel the request.
-   */
-  getStorageInfo: function getStorageInfo(type, callback) {
-    if (STORAGE_INFO_TYPES.indexOf(type) == -1) {
-      throw new Error(`Invalid value for 'type': ${type}`);
-    }
-
-    let info_type = "info/" + type;
-    this._log.trace("Retrieving '" + info_type + "'...");
-    let url = this.userBaseURL + info_type;
-    return this.getStorageRequest(url).get(function onComplete(error) {
-      // Note: 'this' is the request.
-      if (error) {
-        this._log.debug("Failed to retrieve '" + info_type + "'", error);
-        return callback(error);
-      }
-      if (this.response.status != 200) {
-        this._log.debug("Failed to retrieve '" + info_type +
-                        "': server responded with HTTP" +
-                        this.response.status);
-        return callback(this.response);
-      }
-
-      let result;
-      try {
-        result = JSON.parse(this.response.body);
-      } catch (ex) {
-        this._log.debug("Server returned invalid JSON for '" + info_type +
-                        "': " + this.response.body);
-        return callback(ex);
-      }
-      this._log.trace("Successfully retrieved '" + info_type + "'.");
-      return callback(null, result);
-    });
-  },
-
   recordTelemetryEvent(object, method, value, extra = undefined) {
     Svc.Obs.notify("weave:telemetry:event", { object, method, value, extra });
   },
 };
 
 this.Service = new Sync11Service();
 this.Service.promiseInitialized = new Promise(resolve => {
   this.Service.onStartup().then(resolve);
--- a/services/sync/moz.build
+++ b/services/sync/moz.build
@@ -27,17 +27,16 @@ EXTRA_JS_MODULES['services-sync'] += [
     'modules/constants.js',
     'modules/doctor.js',
     'modules/engines.js',
     'modules/keys.js',
     'modules/main.js',
     'modules/policies.js',
     'modules/record.js',
     'modules/resource.js',
-    'modules/rest.js',
     'modules/service.js',
     'modules/status.js',
     'modules/SyncedTabs.jsm',
     'modules/telemetry.js',
     'modules/UIState.jsm',
     'modules/util.js',
 ]
 
--- a/services/sync/tests/unit/test_browserid_identity.js
+++ b/services/sync/tests/unit/test_browserid_identity.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 Cu.import("resource://gre/modules/FxAccounts.jsm");
 Cu.import("resource://services-sync/browserid_identity.js");
-Cu.import("resource://services-sync/rest.js");
+Cu.import("resource://services-sync/resource.js");
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://services-crypto/utils.js");
 Cu.import("resource://testing-common/services/sync/utils.js");
 Cu.import("resource://testing-common/services/sync/fxa_utils.js");
 Cu.import("resource://services-common/hawkclient.js");
 Cu.import("resource://gre/modules/FxAccounts.jsm");
 Cu.import("resource://gre/modules/FxAccountsClient.jsm");
@@ -164,31 +164,16 @@ add_test(function test_getResourceAuthen
     do_check_true("authorization" in output.headers);
     do_check_true(output.headers.authorization.startsWith("Hawk"));
     _("Expected internal state after successful call.");
     do_check_eq(globalBrowseridManager._token.uid, globalIdentityConfig.fxaccount.token.uid);
     run_next_test();
   }
 );
 
-add_test(function test_getRESTRequestAuthenticator() {
-    _("BrowserIDManager supplies a REST Request Authenticator callback which sets a Hawk header on a request object.");
-    let request = new SyncStorageRequest(
-      "https://example.net/somewhere/over/the/rainbow");
-    let authenticator = globalBrowseridManager.getRESTRequestAuthenticator();
-    do_check_true(!!authenticator);
-    let output = authenticator(request, "GET");
-    do_check_eq(request.uri, output.uri);
-    do_check_true(output._headers.authorization.startsWith("Hawk"));
-    do_check_true(output._headers.authorization.includes("nonce"));
-    do_check_true(globalBrowseridManager.hasValidToken());
-    run_next_test();
-  }
-);
-
 add_test(function test_resourceAuthenticatorSkew() {
   _("BrowserIDManager Resource Authenticator compensates for clock skew in Hawk header.");
 
   // Clock is skewed 12 hours into the future
   // We pick a date in the past so we don't risk concealing bugs in code that
   // uses new Date() instead of our given date.
   let now = new Date("Fri Apr 09 2004 00:00:00 GMT-0700").valueOf() + 12 * HOUR_MS;
   let browseridManager = new BrowserIDManager();
@@ -237,17 +222,17 @@ add_test(function test_resourceAuthentic
   do_check_eq(browseridManager._fxaService.internal.now(), now);
   do_check_eq(browseridManager._fxaService.internal.localtimeOffsetMsec,
       localtimeOffsetMsec);
 
   do_check_eq(browseridManager._fxaService.now(), now);
   do_check_eq(browseridManager._fxaService.localtimeOffsetMsec,
       localtimeOffsetMsec);
 
-  let request = new SyncStorageRequest("https://example.net/i/like/pie/");
+  let request = new Resource("https://example.net/i/like/pie/");
   let authenticator = browseridManager.getResourceAuthenticator();
   let output = authenticator(request, "GET");
   dump("output" + JSON.stringify(output));
   let authHeader = output.headers.authorization;
   do_check_true(authHeader.startsWith("Hawk"));
 
   // Skew correction is applied in the header and we're within the two-minute
   // window.
@@ -284,17 +269,17 @@ add_test(function test_RESTResourceAuthe
 
   // Ensure the new FxAccounts mock has a signed-in user.
   fxa.internal.currentAccountState.signedInUser = browseridManager._fxaService.internal.currentAccountState.signedInUser;
 
   browseridManager._fxaService = fxa;
 
   do_check_eq(browseridManager._fxaService.internal.now(), now);
 
-  let request = new SyncStorageRequest("https://example.net/i/like/pie/");
+  let request = new Resource("https://example.net/i/like/pie/");
   let authenticator = browseridManager.getResourceAuthenticator();
   let output = authenticator(request, "GET");
   dump("output" + JSON.stringify(output));
   let authHeader = output.headers.authorization;
   do_check_true(authHeader.startsWith("Hawk"));
 
   // Skew correction is applied in the header and we're within the two-minute
   // window.
--- a/services/sync/tests/unit/test_load_modules.js
+++ b/services/sync/tests/unit/test_load_modules.js
@@ -16,17 +16,16 @@ const modules = [
   "engines/prefs.js",
   "engines/tabs.js",
   "engines.js",
   "keys.js",
   "main.js",
   "policies.js",
   "record.js",
   "resource.js",
-  "rest.js",
   "service.js",
   "stages/declined.js",
   "stages/enginesync.js",
   "status.js",
   "util.js",
 ];
 
 const testingModules = [
deleted file mode 100644
--- a/services/sync/tests/unit/test_service_getStorageInfo.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Cu.import("resource://services-common/rest.js");
-Cu.import("resource://services-sync/constants.js");
-Cu.import("resource://services-sync/service.js");
-Cu.import("resource://services-sync/util.js");
-Cu.import("resource://testing-common/services/sync/utils.js");
-
-var httpProtocolHandler = Cc["@mozilla.org/network/protocol;1?name=http"]
-                          .getService(Ci.nsIHttpProtocolHandler);
-
-var collections = {steam:  65.11328,
-                   petrol: 82.488281,
-                   diesel: 2.25488281};
-
-function run_test() {
-  Log.repository.getLogger("Sync.Service").level = Log.Level.Trace;
-  Log.repository.getLogger("Sync.StorageRequest").level = Log.Level.Trace;
-  initTestLogging();
-
-  run_next_test();
-}
-
-add_task(async function test_success() {
-  let handler = httpd_handler(200, "OK", JSON.stringify(collections));
-  let server = httpd_setup({"/1.1/johndoe/info/collections": handler});
-  await configureIdentity({ username: "johndoe" }, server);
-
-  let request = Service.getStorageInfo("collections", function(error, info) {
-    do_check_eq(error, null);
-    do_check_true(Utils.deepEquals(info, collections));
-
-    // Ensure that the request is sent off with the right bits.
-    do_check_true(has_hawk_header(handler.request));
-    let expectedUA = Services.appinfo.name + "/" + Services.appinfo.version +
-                     " (" + httpProtocolHandler.oscpu + ")" +
-                     " FxSync/" + WEAVE_VERSION + "." +
-                     Services.appinfo.appBuildID + ".desktop";
-    do_check_eq(handler.request.getHeader("User-Agent"), expectedUA);
-
-    server.stop(run_next_test);
-  });
-  do_check_true(request instanceof RESTRequest);
-});
-
-add_test(function test_invalid_type() {
-  do_check_throws(function() {
-    Service.getStorageInfo("invalid", function(error, info) {
-      do_throw("Shouldn't get here!");
-    });
-  });
-  run_next_test();
-});
-
-add_test(function test_network_error() {
-  Service.getStorageInfo(INFO_COLLECTIONS, function(error, info) {
-    do_check_eq(error.result, Cr.NS_ERROR_CONNECTION_REFUSED);
-    do_check_eq(info, null);
-    run_next_test();
-  });
-});
-
-add_task(async function test_http_error() {
-  let handler = httpd_handler(500, "Oh noez", "Something went wrong!");
-  let server = httpd_setup({"/1.1/johndoe/info/collections": handler});
-  await configureIdentity({ username: "johndoe" }, server);
-
-  Service.getStorageInfo(INFO_COLLECTIONS, function(error, info) {
-    do_check_eq(error.status, 500);
-    do_check_eq(info, null);
-    server.stop(run_next_test);
-  });
-});
-
-add_task(async function test_invalid_json() {
-  let handler = httpd_handler(200, "OK", "Invalid JSON");
-  let server = httpd_setup({"/1.1/johndoe/info/collections": handler});
-  await configureIdentity({ username: "johndoe" }, server);
-
-  Service.getStorageInfo(INFO_COLLECTIONS, function(error, info) {
-    do_check_eq(error.name, "SyntaxError");
-    do_check_eq(info, null);
-    server.stop(run_next_test);
-  });
-});
deleted file mode 100644
--- a/services/sync/tests/unit/test_syncstoragerequest.js
+++ /dev/null
@@ -1,219 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Cu.import("resource://gre/modules/Log.jsm");
-Cu.import("resource://services-common/utils.js");
-Cu.import("resource://services-sync/constants.js");
-Cu.import("resource://services-sync/rest.js");
-Cu.import("resource://services-sync/service.js");
-Cu.import("resource://services-sync/util.js");
-Cu.import("resource://testing-common/services/sync/utils.js");
-
-var httpProtocolHandler = Cc["@mozilla.org/network/protocol;1?name=http"]
-                          .getService(Ci.nsIHttpProtocolHandler);
-
-function run_test() {
-  Log.repository.getLogger("Sync.RESTRequest").level = Log.Level.Trace;
-  initTestLogging();
-
-  run_next_test();
-}
-
-add_test(function test_user_agent_desktop() {
-  let handler = httpd_handler(200, "OK");
-  let server = httpd_setup({"/resource": handler});
-
-  let expectedUA = Services.appinfo.name + "/" + Services.appinfo.version +
-                   " (" + httpProtocolHandler.oscpu + ")" +
-                   " FxSync/" + WEAVE_VERSION + "." +
-                   Services.appinfo.appBuildID + ".desktop";
-
-  let request = new SyncStorageRequest(server.baseURI + "/resource");
-  request.onComplete = function onComplete(error) {
-    do_check_eq(error, null);
-    do_check_eq(this.response.status, 200);
-    do_check_eq(handler.request.getHeader("User-Agent"), expectedUA);
-    server.stop(run_next_test);
-  };
-  do_check_eq(request.get(), request);
-});
-
-add_test(function test_user_agent_mobile() {
-  let handler = httpd_handler(200, "OK");
-  let server = httpd_setup({"/resource": handler});
-
-  Svc.Prefs.set("client.type", "mobile");
-  let expectedUA = Services.appinfo.name + "/" + Services.appinfo.version +
-                   " (" + httpProtocolHandler.oscpu + ")" +
-                   " FxSync/" + WEAVE_VERSION + "." +
-                   Services.appinfo.appBuildID + ".mobile";
-
-  let request = new SyncStorageRequest(server.baseURI + "/resource");
-  request.get(function(error) {
-    do_check_eq(error, null);
-    do_check_eq(this.response.status, 200);
-    do_check_eq(handler.request.getHeader("User-Agent"), expectedUA);
-    Svc.Prefs.resetBranch("");
-    server.stop(run_next_test);
-  });
-});
-
-add_task(async function test_auth() {
-  let handler = httpd_handler(200, "OK");
-  let server = httpd_setup({"/resource": handler});
-  await configureIdentity({ username: "foo" }, server);
-
-  let request = Service.getStorageRequest(server.baseURI + "/resource");
-  request.get(function(error) {
-    do_check_eq(error, null);
-    do_check_eq(this.response.status, 200);
-    do_check_true(has_hawk_header(handler.request));
-
-    Svc.Prefs.reset("");
-
-    server.stop(run_next_test);
-  });
-});
-
-/**
- *  The X-Weave-Timestamp header updates SyncStorageRequest.serverTime.
- */
-add_test(function test_weave_timestamp() {
-  const TIMESTAMP = 1274380461;
-  function handler(request, response) {
-    response.setHeader("X-Weave-Timestamp", "" + TIMESTAMP, false);
-    response.setStatusLine(request.httpVersion, 200, "OK");
-  }
-  let server = httpd_setup({"/resource": handler});
-
-  do_check_eq(SyncStorageRequest.serverTime, undefined);
-  let request = new SyncStorageRequest(server.baseURI + "/resource");
-  request.get(function(error) {
-    do_check_eq(error, null);
-    do_check_eq(this.response.status, 200);
-    do_check_eq(SyncStorageRequest.serverTime, TIMESTAMP);
-    delete SyncStorageRequest.serverTime;
-    server.stop(run_next_test);
-  });
-});
-
-/**
- * The X-Weave-Backoff header notifies an observer.
- */
-add_test(function test_weave_backoff() {
-  function handler(request, response) {
-    response.setHeader("X-Weave-Backoff", "600", false);
-    response.setStatusLine(request.httpVersion, 200, "OK");
-  }
-  let server = httpd_setup({"/resource": handler});
-
-  let backoffInterval;
-  Svc.Obs.add("weave:service:backoff:interval", function onBackoff(subject) {
-    Svc.Obs.remove("weave:service:backoff:interval", onBackoff);
-    backoffInterval = subject;
-  });
-
-  let request = new SyncStorageRequest(server.baseURI + "/resource");
-  request.get(function(error) {
-    do_check_eq(error, null);
-    do_check_eq(this.response.status, 200);
-    do_check_eq(backoffInterval, 600);
-    server.stop(run_next_test);
-  });
-});
-
-/**
- * X-Weave-Quota-Remaining header notifies observer on successful requests.
- */
-add_test(function test_weave_quota_notice() {
-  function handler(request, response) {
-    response.setHeader("X-Weave-Quota-Remaining", "1048576", false);
-    response.setStatusLine(request.httpVersion, 200, "OK");
-  }
-  let server = httpd_setup({"/resource": handler});
-
-  let quotaValue;
-  Svc.Obs.add("weave:service:quota:remaining", function onQuota(subject) {
-    Svc.Obs.remove("weave:service:quota:remaining", onQuota);
-    quotaValue = subject;
-  });
-
-  let request = new SyncStorageRequest(server.baseURI + "/resource");
-  request.get(function(error) {
-    do_check_eq(error, null);
-    do_check_eq(this.response.status, 200);
-    do_check_eq(quotaValue, 1048576);
-    server.stop(run_next_test);
-  });
-});
-
-/**
- * X-Weave-Quota-Remaining header doesn't notify observer on failed requests.
- */
-add_test(function test_weave_quota_error() {
-  function handler(request, response) {
-    response.setHeader("X-Weave-Quota-Remaining", "1048576", false);
-    response.setStatusLine(request.httpVersion, 400, "Bad Request");
-  }
-  let server = httpd_setup({"/resource": handler});
-
-  let quotaValue;
-  function onQuota(subject) {
-    quotaValue = subject;
-  }
-  Svc.Obs.add("weave:service:quota:remaining", onQuota);
-
-  let request = new SyncStorageRequest(server.baseURI + "/resource");
-  request.get(function(error) {
-    do_check_eq(error, null);
-    do_check_eq(this.response.status, 400);
-    do_check_eq(quotaValue, undefined);
-    Svc.Obs.remove("weave:service:quota:remaining", onQuota);
-    server.stop(run_next_test);
-  });
-});
-
-add_test(function test_abort() {
-  const TIMESTAMP = 1274380462;
-  function handler(request, response) {
-    response.setHeader("X-Weave-Timestamp", "" + TIMESTAMP, false);
-    response.setHeader("X-Weave-Quota-Remaining", "1048576", false);
-    response.setHeader("X-Weave-Backoff", "600", false);
-    response.setStatusLine(request.httpVersion, 200, "OK");
-  }
-  let server = httpd_setup({"/resource": handler});
-
-  let request = new SyncStorageRequest(server.baseURI + "/resource");
-
-  // Aborting a request that hasn't been sent yet is pointless and will throw.
-  do_check_throws(function() {
-    request.abort();
-  });
-
-  function throwy() {
-    do_throw("Shouldn't have gotten here!");
-  }
-
-  Svc.Obs.add("weave:service:backoff:interval", throwy);
-  Svc.Obs.add("weave:service:quota:remaining", throwy);
-  request.onProgress = request.onComplete = throwy;
-
-  request.get();
-  request.abort();
-  do_check_eq(request.status, request.ABORTED);
-
-  // Aborting an already aborted request is pointless and will throw.
-  do_check_throws(function() {
-    request.abort();
-  });
-
-  CommonUtils.nextTick(function() {
-    // Verify that we didn't try to process any of the values.
-    do_check_eq(SyncStorageRequest.serverTime, undefined);
-
-    Svc.Obs.remove("weave:service:backoff:interval", throwy);
-    Svc.Obs.remove("weave:service:quota:remaining", throwy);
-
-    server.stop(run_next_test);
-  });
-});
--- a/services/sync/tests/unit/test_warn_on_truncated_response.js
+++ b/services/sync/tests/unit/test_warn_on_truncated_response.js
@@ -1,16 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 Cu.import("resource://testing-common/httpd.js");
 Cu.import("resource://services-sync/resource.js");
-Cu.import("resource://services-sync/rest.js");
 
 function run_test() {
   initTestLogging("Trace");
   run_next_test();
 }
 
 var BODY = "response body";
 // contentLength needs to be longer than the response body
@@ -61,33 +60,8 @@ add_task(async function test_async_resou
   let warnMessages = getWarningMessages(asyncResource._log);
 
   let content = await asyncResource.get();
   equal(content, BODY);
   notEqual(warnMessages.length, 0, "test that warning was logged");
   notEqual(content.length, contentLength);
   await promiseStopServer(httpServer);
 });
-
-add_test(function test_sync_storage_request_logs_content_length_mismatch() {
-  _("Issuing request.");
-  let httpServer = httpd_setup({"/content": contentHandler});
-  let request = new SyncStorageRequest(httpServer.baseURI + "/content");
-  let warnMessages = getWarningMessages(request._log);
-
-  // Setting this affects how received data is read from the underlying
-  // nsIHttpChannel in rest.js.  If it's left as UTF-8 (the default) an
-  // nsIConverterInputStream is used and the data read from channel's stream
-  // isn't truncated at the null byte mark (\u0000). Therefore the
-  // content-length mismatch being tested for doesn't occur.  Setting it to
-  // a falsy value results in an nsIScriptableInputStream being used to read
-  // the stream, which stops reading at the null byte mark resulting in a
-  // content-length mismatch.
-  request.charset = "";
-
-  request.get(function(error) {
-    equal(error, null);
-    equal(this.response.body, BODY);
-    notEqual(warnMessages.length, 0, "test that a warning was logged");
-    notEqual(BODY.length, contentLength);
-    httpServer.stop(run_next_test);
-  });
-});
--- a/services/sync/tests/unit/xpcshell.ini
+++ b/services/sync/tests/unit/xpcshell.ini
@@ -40,17 +40,16 @@ run-sequentially = Restarts server, can'
 tags = addons
 [test_httpd_sync_server.js]
 
 # HTTP layers.
 [test_resource.js]
 [test_resource_async.js]
 [test_resource_header.js]
 [test_resource_ua.js]
-[test_syncstoragerequest.js]
 
 # Generic Sync types.
 [test_browserid_identity.js]
 [test_browserid_identity_telemetry.js]
 [test_collection_getBatched.js]
 [test_collections_recovery.js]
 [test_keys.js]
 [test_records_crypto.js]
@@ -69,17 +68,16 @@ run-sequentially = Frequent timeouts, bu
 [test_tracker_addChanged.js]
 
 # Service semantics.
 [test_service_attributes.js]
 # Bug 752243: Profile cleanup frequently fails
 skip-if = os == "mac" || os == "linux"
 [test_service_cluster.js]
 [test_service_detect_upgrade.js]
-[test_service_getStorageInfo.js]
 [test_service_login.js]
 [test_service_startOver.js]
 [test_service_startup.js]
 [test_service_sync_401.js]
 [test_service_sync_locked.js]
 [test_service_sync_remoteSetup.js]
 # Bug 676978: test hangs on Android (see also testing/xpcshell/xpcshell.ini)
 skip-if = os == "android"
--- a/tools/lint/eslint/modules.json
+++ b/tools/lint/eslint/modules.json
@@ -26,17 +26,17 @@
   "BootstrapMonitor.jsm": ["monitor"],
   "browser-loader.js": ["BrowserLoader"],
   "browserid_identity.js": ["BrowserIDManager", "AuthenticationError"],
   "CertUtils.jsm": ["BadCertHandler", "checkCert", "readCertPrefs", "validateCert"],
   "clients.js": ["ClientEngine", "ClientsRec"],
   "collection_repair.js": ["getRepairRequestor", "getAllRepairRequestors", "CollectionRepairRequestor", "getRepairResponder", "CollectionRepairResponder"],
   "collection_validator.js": ["CollectionValidator", "CollectionProblemData"],
   "Console.jsm": ["console", "ConsoleAPI"],
-  "constants.js": ["WEAVE_VERSION", "SYNC_API_VERSION", "USER_API_VERSION", "MISC_API_VERSION", "STORAGE_VERSION", "PREFS_BRANCH", "PWDMGR_HOST", "PWDMGR_PASSWORD_REALM", "PWDMGR_PASSPHRASE_REALM", "PWDMGR_KEYBUNDLE_REALM", "DEFAULT_KEYBUNDLE_NAME", "HMAC_INPUT", "SYNC_KEY_ENCODED_LENGTH", "SYNC_KEY_DECODED_LENGTH", "SYNC_KEY_HYPHENATED_LENGTH", "NO_SYNC_NODE_INTERVAL", "MAX_ERROR_COUNT_BEFORE_BACKOFF", "MAX_IGNORE_ERROR_COUNT", "MINIMUM_BACKOFF_INTERVAL", "MAXIMUM_BACKOFF_INTERVAL", "HMAC_EVENT_INTERVAL", "MASTER_PASSWORD_LOCKED_RETRY_INTERVAL", "DEFAULT_BLOCK_PERIOD", "DEFAULT_GUID_FETCH_BATCH_SIZE", "DEFAULT_MOBILE_GUID_FETCH_BATCH_SIZE", "DEFAULT_STORE_BATCH_SIZE", "HISTORY_STORE_BATCH_SIZE", "FORMS_STORE_BATCH_SIZE", "PASSWORDS_STORE_BATCH_SIZE", "ADDONS_STORE_BATCH_SIZE", "APPS_STORE_BATCH_SIZE", "DEFAULT_DOWNLOAD_BATCH_SIZE", "DEFAULT_MAX_RECORD_PAYLOAD_BYTES", "SINGLE_USER_THRESHOLD", "MULTI_DEVICE_THRESHOLD", "SCORE_INCREMENT_SMALL", "SCORE_INCREMENT_MEDIUM", "SCORE_INCREMENT_XLARGE", "SCORE_UPDATE_DELAY", "IDLE_OBSERVER_BACK_DELAY", "URI_LENGTH_MAX", "MAX_HISTORY_UPLOAD", "MAX_HISTORY_DOWNLOAD", "STATUS_OK", "SYNC_FAILED", "LOGIN_FAILED", "SYNC_FAILED_PARTIAL", "CLIENT_NOT_CONFIGURED", "STATUS_DISABLED", "MASTER_PASSWORD_LOCKED", "LOGIN_SUCCEEDED", "SYNC_SUCCEEDED", "ENGINE_SUCCEEDED", "LOGIN_FAILED_NO_USERNAME", "LOGIN_FAILED_NO_PASSWORD", "LOGIN_FAILED_NO_PASSPHRASE", "LOGIN_FAILED_NETWORK_ERROR", "LOGIN_FAILED_SERVER_ERROR", "LOGIN_FAILED_INVALID_PASSPHRASE", "LOGIN_FAILED_LOGIN_REJECTED", "METARECORD_DOWNLOAD_FAIL", "VERSION_OUT_OF_DATE", "DESKTOP_VERSION_OUT_OF_DATE", "SETUP_FAILED_NO_PASSPHRASE", "CREDENTIALS_CHANGED", "ABORT_SYNC_COMMAND", "NO_SYNC_NODE_FOUND", "OVER_QUOTA", "PROLONGED_SYNC_FAILURE", "SERVER_MAINTENANCE", "RESPONSE_OVER_QUOTA", "ENGINE_UPLOAD_FAIL", "ENGINE_DOWNLOAD_FAIL", "ENGINE_UNKNOWN_FAIL", "ENGINE_APPLY_FAIL", "ENGINE_METARECORD_DOWNLOAD_FAIL", "ENGINE_METARECORD_UPLOAD_FAIL", "ENGINE_BATCH_INTERRUPTED", "JPAKE_ERROR_CHANNEL", "JPAKE_ERROR_NETWORK", "JPAKE_ERROR_SERVER", "JPAKE_ERROR_TIMEOUT", "JPAKE_ERROR_INTERNAL", "JPAKE_ERROR_INVALID", "JPAKE_ERROR_NODATA", "JPAKE_ERROR_KEYMISMATCH", "JPAKE_ERROR_WRONGMESSAGE", "JPAKE_ERROR_USERABORT", "JPAKE_ERROR_DELAYUNSUPPORTED", "INFO_COLLECTIONS", "INFO_COLLECTION_USAGE", "INFO_COLLECTION_COUNTS", "INFO_QUOTA", "kSyncNotConfigured", "kSyncMasterPasswordLocked", "kSyncWeaveDisabled", "kSyncNetworkOffline", "kSyncBackoffNotMet", "kFirstSyncChoiceNotMade", "FIREFOX_ID", "FENNEC_ID", "SEAMONKEY_ID", "TEST_HARNESS_ID", "MIN_PP_LENGTH", "MIN_PASS_LENGTH", "DEVICE_TYPE_DESKTOP", "DEVICE_TYPE_MOBILE", "SQLITE_MAX_VARIABLE_NUMBER"],
+  "constants.js": ["WEAVE_VERSION", "SYNC_API_VERSION", "USER_API_VERSION", "MISC_API_VERSION", "STORAGE_VERSION", "PREFS_BRANCH", "PWDMGR_HOST", "PWDMGR_PASSWORD_REALM", "PWDMGR_PASSPHRASE_REALM", "PWDMGR_KEYBUNDLE_REALM", "DEFAULT_KEYBUNDLE_NAME", "HMAC_INPUT", "SYNC_KEY_ENCODED_LENGTH", "SYNC_KEY_DECODED_LENGTH", "SYNC_KEY_HYPHENATED_LENGTH", "NO_SYNC_NODE_INTERVAL", "MAX_ERROR_COUNT_BEFORE_BACKOFF", "MAX_IGNORE_ERROR_COUNT", "MINIMUM_BACKOFF_INTERVAL", "MAXIMUM_BACKOFF_INTERVAL", "HMAC_EVENT_INTERVAL", "MASTER_PASSWORD_LOCKED_RETRY_INTERVAL", "DEFAULT_BLOCK_PERIOD", "DEFAULT_GUID_FETCH_BATCH_SIZE", "DEFAULT_MOBILE_GUID_FETCH_BATCH_SIZE", "DEFAULT_STORE_BATCH_SIZE", "HISTORY_STORE_BATCH_SIZE", "FORMS_STORE_BATCH_SIZE", "PASSWORDS_STORE_BATCH_SIZE", "ADDONS_STORE_BATCH_SIZE", "APPS_STORE_BATCH_SIZE", "DEFAULT_DOWNLOAD_BATCH_SIZE", "DEFAULT_MAX_RECORD_PAYLOAD_BYTES", "SINGLE_USER_THRESHOLD", "MULTI_DEVICE_THRESHOLD", "SCORE_INCREMENT_SMALL", "SCORE_INCREMENT_MEDIUM", "SCORE_INCREMENT_XLARGE", "SCORE_UPDATE_DELAY", "IDLE_OBSERVER_BACK_DELAY", "URI_LENGTH_MAX", "MAX_HISTORY_UPLOAD", "MAX_HISTORY_DOWNLOAD", "STATUS_OK", "SYNC_FAILED", "LOGIN_FAILED", "SYNC_FAILED_PARTIAL", "CLIENT_NOT_CONFIGURED", "STATUS_DISABLED", "MASTER_PASSWORD_LOCKED", "LOGIN_SUCCEEDED", "SYNC_SUCCEEDED", "ENGINE_SUCCEEDED", "LOGIN_FAILED_NO_USERNAME", "LOGIN_FAILED_NO_PASSWORD", "LOGIN_FAILED_NO_PASSPHRASE", "LOGIN_FAILED_NETWORK_ERROR", "LOGIN_FAILED_SERVER_ERROR", "LOGIN_FAILED_INVALID_PASSPHRASE", "LOGIN_FAILED_LOGIN_REJECTED", "METARECORD_DOWNLOAD_FAIL", "VERSION_OUT_OF_DATE", "DESKTOP_VERSION_OUT_OF_DATE", "SETUP_FAILED_NO_PASSPHRASE", "CREDENTIALS_CHANGED", "ABORT_SYNC_COMMAND", "NO_SYNC_NODE_FOUND", "OVER_QUOTA", "PROLONGED_SYNC_FAILURE", "SERVER_MAINTENANCE", "RESPONSE_OVER_QUOTA", "ENGINE_UPLOAD_FAIL", "ENGINE_DOWNLOAD_FAIL", "ENGINE_UNKNOWN_FAIL", "ENGINE_APPLY_FAIL", "ENGINE_METARECORD_DOWNLOAD_FAIL", "ENGINE_METARECORD_UPLOAD_FAIL", "ENGINE_BATCH_INTERRUPTED", "JPAKE_ERROR_CHANNEL", "JPAKE_ERROR_NETWORK", "JPAKE_ERROR_SERVER", "JPAKE_ERROR_TIMEOUT", "JPAKE_ERROR_INTERNAL", "JPAKE_ERROR_INVALID", "JPAKE_ERROR_NODATA", "JPAKE_ERROR_KEYMISMATCH", "JPAKE_ERROR_WRONGMESSAGE", "JPAKE_ERROR_USERABORT", "JPAKE_ERROR_DELAYUNSUPPORTED", "kSyncNotConfigured", "kSyncMasterPasswordLocked", "kSyncWeaveDisabled", "kSyncNetworkOffline", "kSyncBackoffNotMet", "kFirstSyncChoiceNotMade", "FIREFOX_ID", "FENNEC_ID", "SEAMONKEY_ID", "TEST_HARNESS_ID", "MIN_PP_LENGTH", "MIN_PASS_LENGTH", "DEVICE_TYPE_DESKTOP", "DEVICE_TYPE_MOBILE", "SQLITE_MAX_VARIABLE_NUMBER"],
   "Constants.jsm": ["Roles", "Events", "Relations", "Filters", "States", "Prefilters"],
   "ContactDB.jsm": ["ContactDB", "DB_NAME", "STORE_NAME", "SAVED_GETALL_STORE_NAME", "REVISION_STORE", "DB_VERSION"],
   "content-server.jsm": ["init"],
   "content.jsm": ["registerContentFrame"],
   "ContentCrashHandlers.jsm": ["TabCrashHandler", "PluginCrashReporter", "UnsubmittedCrashHandler"],
   "ContentObservers.js": [],
   "ContentPrefUtils.jsm": ["ContentPref", "cbHandleResult", "cbHandleError", "cbHandleCompletion", "safeCallback", "_methodsCallableFromChild"],
   "controller.js": ["MozMillController", "globalEventRegistry", "sleep", "windowMap"],
@@ -178,17 +178,17 @@
   "record.js": ["WBORecord", "RecordManager", "CryptoWrapper", "CollectionKeyManager", "Collection"],
   "recursive_importA.jsm": ["foo", "bar"],
   "recursive_importB.jsm": ["baz", "qux"],
   "reflect.jsm": ["Reflect"],
   "RemoteFinder.jsm": ["RemoteFinder", "RemoteFinderListener"],
   "RemotePageManager.jsm": ["RemotePages", "RemotePageManager", "PageListener"],
   "RemoteWebProgress.jsm": ["RemoteWebProgressManager"],
   "resource.js": ["AsyncResource", "Resource"],
-  "rest.js": ["RESTRequest", "RESTResponse", "TokenAuthenticatedRESTRequest", "SyncStorageRequest"],
+  "rest.js": ["RESTRequest", "RESTResponse", "TokenAuthenticatedRESTRequest"],
   "rotaryengine.js": ["RotaryEngine", "RotaryRecord", "RotaryStore", "RotaryTracker"],
   "require.js": ["require"],
   "RTCStatsReport.jsm": ["convertToRTCStatsReport"],
   "scratchpad-manager.jsm": ["ScratchpadManager"],
   "server.js": ["server"],
   "service.js": ["Service"],
   "SharedPromptUtils.jsm": ["PromptUtils", "EnableDelayHelper"],
   "ShutdownLeaksCollector.jsm": ["ContentCollector"],