Bug 717061 - compress telemetry pings; r=taras
authorNathan Froyd <froydnj@mozilla.com>
Wed, 25 Jan 2012 07:23:03 -0800
changeset 87747 9c63c2df568754cf76fcb1c390b6779a7b342447
parent 87746 71f16a6905eb68c40d7c167d42c115356b4246cc
child 87748 75c291e1c27ea96ed0401e2e960b6ea8c059904c
push id22143
push userphilringnalda@gmail.com
push dateSun, 26 Feb 2012 23:12:35 +0000
treeherdermozilla-central@b98fc24ac54b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstaras
bugs717061
milestone13.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 717061 - compress telemetry pings; r=taras
toolkit/components/telemetry/TelemetryPing.js
toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
--- a/toolkit/components/telemetry/TelemetryPing.js
+++ b/toolkit/components/telemetry/TelemetryPing.js
@@ -463,17 +463,17 @@ TelemetryPing.prototype = {
     let hsuccess = Telemetry.getHistogramById("TELEMETRY_SUCCESS");
 
     let url = server + submitPath;
     let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
                   .createInstance(Ci.nsIXMLHttpRequest);
     request.mozBackgroundRequest = true;
     request.open("POST", url, true);
     request.overrideMimeType("text/plain");
-    request.setRequestHeader("Content-Type", "application/json");
+    request.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
 
     let startTime = new Date();
 
     function finishRequest(channel) {
       let success = false;
       try {
         success = channel.QueryInterface(Ci.nsIHttpChannel).requestSucceeded;
       } catch(e) {
@@ -481,19 +481,47 @@ TelemetryPing.prototype = {
       hsuccess.add(success);
       hping.add(new Date() - startTime);
       if (isTestPing)
         Services.obs.notifyObservers(null, "telemetry-test-xhr-complete", null);
     }
     request.addEventListener("error", function(aEvent) finishRequest(request.channel), false);
     request.addEventListener("load", function(aEvent) finishRequest(request.channel), false);
 
-    request.send(data.payload);
+    request.setRequestHeader("Content-Encoding", "gzip");
+    let payloadStream = Cc["@mozilla.org/io/string-input-stream;1"]
+                        .createInstance(Ci.nsIStringInputStream);
+    payloadStream.data = this.gzipCompressString(data.payload);
+    request.send(payloadStream);
   },
-  
+
+  gzipCompressString: function gzipCompressString(string) {
+    let observer = {
+      buffer: "",
+      onStreamComplete: function(loader, context, status, length, result) {
+	this.buffer = String.fromCharCode.apply(this, result);
+      }
+    };
+
+    let scs = Cc["@mozilla.org/streamConverters;1"]
+              .getService(Ci.nsIStreamConverterService);
+    let listener = Cc["@mozilla.org/network/stream-loader;1"]
+                  .createInstance(Ci.nsIStreamLoader);
+    listener.init(observer);
+    let converter = scs.asyncConvertData("uncompressed", "gzip",
+                                         listener, null);
+    let stringStream = Cc["@mozilla.org/io/string-input-stream;1"]
+                       .createInstance(Ci.nsIStringInputStream);
+    stringStream.data = string;
+    converter.onStartRequest(null, null);
+    converter.onDataAvailable(null, null, stringStream, 0, string.length);
+    converter.onStopRequest(null, null, null);
+    return observer.buffer;
+  },
+
   attachObservers: function attachObservers() {
     if (!this._initialized)
       return;
     Services.obs.addObserver(this, "cycle-collector-begin", false);
     Services.obs.addObserver(this, "idle-daily", false);
   },
 
   detachObservers: function detachObservers() {
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
@@ -52,18 +52,41 @@ function telemetryObserver(aSubject, aTo
   Services.startup.interrupted = true;
   telemetry_ping();
 }
 
 function checkHistograms(request, response) {
   // do not need the http server anymore
   httpserver.stop(do_test_finished);
   let s = request.bodyInputStream;
-  let payload = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON)
-                                             .decodeFromStream(s, s.available());
+  let payload = null;
+  let decoder = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON)
+
+  if (request.getHeader("content-encoding") == "gzip") {
+    let observer = {
+      buffer: "",
+      onStreamComplete: function(loader, context, status, length, result) {
+	this.buffer = String.fromCharCode.apply(this, result);
+      }
+    };
+
+    let scs = Cc["@mozilla.org/streamConverters;1"]
+              .getService(Ci.nsIStreamConverterService);
+    let listener = Cc["@mozilla.org/network/stream-loader;1"]
+                  .createInstance(Ci.nsIStreamLoader);
+    listener.init(observer);
+    let converter = scs.asyncConvertData("gzip", "uncompressed",
+                                         listener, null);
+    converter.onStartRequest(null, null);
+    converter.onDataAvailable(null, null, s, 0, s.available());
+    converter.onStopRequest(null, null, null);
+    payload = decoder.decode(observer.buffer);
+  } else {
+    payload = decoder.decodeFromStream(s, s.available());
+  }
 
   do_check_eq(request.getHeader("content-type"), "application/json; charset=UTF-8");
   do_check_true(payload.simpleMeasurements.uptime >= 0);
   do_check_true(payload.simpleMeasurements.startupInterrupted === 1);
   // get rid of the non-deterministic field
   const expected_info = {
     reason: "test-ping",
     OS: "XPCShell",