Bug 1243594 (part 3) - leave the utf-8 encoding of the payload to rest.js instead of directly in loop. r=Standard8
authorMark Hammond <mhammond@skippinet.com.au>
Fri, 26 Feb 2016 15:46:30 +1100
changeset 322054 4e0bcdfc72de10bbfd2216a0d08081d9aecc3709
parent 322053 19950e70819a7f7a6089059cea59e04b9ef078fc
child 322055 a97d22a2418febbac21e5f6117046a3d739d5c5a
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersStandard8
bugs1243594
milestone47.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 1243594 (part 3) - leave the utf-8 encoding of the payload to rest.js instead of directly in loop. r=Standard8
browser/extensions/loop/chrome/content/modules/MozLoopService.jsm
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_hawk_request.js
services/common/hawkclient.js
services/common/rest.js
--- a/browser/extensions/loop/chrome/content/modules/MozLoopService.jsm
+++ b/browser/extensions/loop/chrome/content/modules/MozLoopService.jsm
@@ -608,17 +608,19 @@ var MozLoopServiceInternal = {
     }
 
     if (sessionToken) {
       // true = use a hex key, as required by the server (see bug 1032738).
       credentials = deriveHawkCredentials(sessionToken, "sessionToken",
                                           2 * 32, true);
     }
 
-    if (payloadObj) {
+    // Later versions of Firefox will do utf-8 encoding of the request, but
+    // we need to do it ourselves for older versions.
+    if (!gHawkClient.willUTF8EncodeRequests && payloadObj) {
       // Note: we must copy the object rather than mutate it, to avoid
       // mutating the values of the object passed in.
       let newPayloadObj = {};
       for (let property of Object.getOwnPropertyNames(payloadObj)) {
         if (typeof payloadObj[property] == "string") {
           newPayloadObj[property] = CommonUtils.encodeUTF8(payloadObj[property]);
         } else {
           newPayloadObj[property] = payloadObj[property];
--- a/browser/extensions/loop/chrome/test/xpcshell/test_loopservice_hawk_request.js
+++ b/browser/extensions/loop/chrome/test/xpcshell/test_loopservice_hawk_request.js
@@ -7,22 +7,23 @@
 
 "use strict";
 
 /* exported run_test */
 
 Cu.import("resource://services-common/utils.js");
 
 add_task(function* request_with_unicode() {
-  const unicodeName = "yøü";
+  // Note unicodeName must be unicode, not utf-8
+  const unicodeName = "y\xf8\xfc"; // "yøü"
 
   loopServer.registerPathHandler("/fake", (request, response) => {
     let body = CommonUtils.readBytesFromInputStream(request.bodyInputStream);
-    let jsonBody = JSON.parse(body);
-    Assert.equal(jsonBody.name, CommonUtils.encodeUTF8(unicodeName));
+    let jsonBody = JSON.parse(CommonUtils.decodeUTF8(body));
+    Assert.equal(jsonBody.name, unicodeName);
 
     response.setStatusLine(null, 200, "OK");
     response.processAsync();
     response.finish();
   });
 
   yield MozLoopServiceInternal.hawkRequestInternal(LOOP_SESSION_TYPE.GUEST, "/fake", "POST", { name: unicodeName }).then(
     () => Assert.ok(true, "Should have accepted"),
--- a/services/common/hawkclient.js
+++ b/services/common/hawkclient.js
@@ -96,16 +96,21 @@ this.HawkClient = function(host) {
   // Clock offset in milliseconds between our client's clock and the date
   // reported in responses from our host.
   this._localtimeOffsetMsec = 0;
 }
 
 this.HawkClient.prototype = {
 
   /*
+   * A boolean for feature detection.
+   */
+  willUTF8EncodeRequests: HAWKAuthenticatedRESTRequest.prototype.willUTF8EncodeObjectRequests,
+
+  /*
    * Construct an error message for a response.  Private.
    *
    * @param restResponse
    *        A RESTResponse object from a RESTRequest
    *
    * @param error
    *        A string or object describing the error
    */
--- a/services/common/rest.js
+++ b/services/common/rest.js
@@ -100,16 +100,23 @@ RESTRequest.prototype = {
     Ci.nsIBadCertListener2,
     Ci.nsIInterfaceRequestor,
     Ci.nsIChannelEventSink
   ]),
 
   /*** Public API: ***/
 
   /**
+   * A constant boolean that indicates whether this object will automatically
+   * utf-8 encode request bodies passed as an object. Used for feature detection
+   * so, eg, loop can use the same source code for old and new Firefox versions.
+   */
+  willUTF8EncodeObjectRequests: true,
+
+  /**
    * URI for the request (an nsIURI object).
    */
   uri: null,
 
   /**
    * HTTP method (e.g. "GET")
    */
   method: null,