Bug 568156: Use Sync client version as User-Agent. r=philiKON
authorRichard Newman <rnewman@mozilla.com>
Thu, 07 Apr 2011 13:55:02 -0700
changeset 67772 6795af6d25c4cc39418fcdd8e236a0deba15517c
parent 67771 f9299646f8eb451456a564ce82a3a31d17aa9dcd
child 67773 f73ae964d03329cb86fae0c12004c68e425f845c
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersphiliKON
bugs568156
milestone2.2a1pre
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 568156: Use Sync client version as User-Agent. r=philiKON
services/sync/modules/resource.js
services/sync/services-sync.js
services/sync/tests/unit/test_resource_ua.js
--- a/services/sync/modules/resource.js
+++ b/services/sync/modules/resource.js
@@ -137,16 +137,19 @@ function AsyncResource(uri) {
     Log4Moz.Level[Utils.prefs.getCharPref("log.logger.network.resources")];
   this.uri = uri;
   this._headers = {};
   this._onComplete = Utils.bind2(this, this._onComplete);
 }
 AsyncResource.prototype = {
   _logName: "Net.Resource",
 
+  // The string to use as the base User-Agent in Sync requests.
+  _userAgent: "FxSync/" + WEAVE_VERSION + "." + Svc.AppInfo.appBuildID + ".",
+
   // Wait 5 minutes before killing a request.
   ABORT_TIMEOUT: 300000,
 
   // ** {{{ Resource.authenticator }}} **
   //
   // Getter and setter for the authenticator module
   // responsible for this particular resource. The authenticator
   // module may modify the headers to perform authentication
@@ -219,16 +222,22 @@ AsyncResource.prototype = {
 
     // Always validate the cache:
     channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
     channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
 
     // Setup a callback to handle bad HTTPS certificates.
     channel.notificationCallbacks = new BadCertListener();
 
+    // Compose a UA string fragment from the various available identifiers.
+    if (Svc.Prefs.get("sendVersionInfo", true)) {
+      let ua = this._userAgent + Svc.Prefs.get("client.type", "desktop");
+      channel.setRequestHeader("user-agent", ua, false);
+    }
+    
     // Avoid calling the authorizer more than once.
     let headers = this.headers;
     for (let key in headers) {
       if (key == 'authorization')
         this._log.trace("HTTP Header " + key + ": ***** (suppressed)");
       else
         this._log.trace("HTTP Header " + key + ": " + headers[key]);
       channel.setRequestHeader(key, headers[key], false);
--- a/services/sync/services-sync.js
+++ b/services/sync/services-sync.js
@@ -4,16 +4,17 @@ pref("services.sync.userURL", "user/");
 pref("services.sync.miscURL", "misc/");
 pref("services.sync.termsURL", "https://services.mozilla.com/tos/");
 pref("services.sync.privacyURL", "https://services.mozilla.com/privacy-policy/");
 pref("services.sync.statusURL", "https://services.mozilla.com/status/");
 pref("services.sync.syncKeyHelpURL", "https://services.mozilla.com/help/synckey");
 
 pref("services.sync.lastversion", "firstrun");
 pref("services.sync.autoconnect", true);
+pref("services.sync.sendVersionInfo", true);
 
 pref("services.sync.engine.bookmarks", true);
 pref("services.sync.engine.history", true);
 pref("services.sync.engine.passwords", true);
 pref("services.sync.engine.prefs", true);
 pref("services.sync.engine.tabs", true);
 pref("services.sync.engine.tabs.filteredUrls", "^(about:.*|chrome://weave/.*|wyciwyg:.*|file:.*)$");
 
new file mode 100644
--- /dev/null
+++ b/services/sync/tests/unit/test_resource_ua.js
@@ -0,0 +1,91 @@
+Cu.import("resource://services-sync/constants.js");
+Cu.import("resource://services-sync/resource.js");
+Cu.import("resource://services-sync/service.js");
+
+function test_resource_user_agent() {
+  let meta_global = new ServerWBO('global');
+
+  // Tracking info/collections.
+  let collectionsHelper = track_collections_helper();
+  let collections = collectionsHelper.collections;
+
+  let ua;
+  function uaHandler(f) {
+    return function(request, response) {
+      ua = request.getHeader("User-Agent");
+      return f(request, response);
+    };
+  }
+
+  do_test_pending();
+  let server = httpd_setup({
+    "/1.0/johndoe/info/collections": uaHandler(collectionsHelper.handler),
+    "/1.0/johndoe/storage/meta/global": uaHandler(meta_global.handler()),
+  });
+
+  Weave.Service.serverURL  = "http://localhost:8080/";
+  Weave.Service.clusterURL = "http://localhost:8080/";
+  Weave.Service.username   = "johndoe";
+  Weave.Service.password   = "ilovejane";
+
+  let expectedUA = "FxSync/" + WEAVE_VERSION +
+                   "." + Svc.AppInfo.appBuildID;
+
+  function test_fetchInfo(next) {
+    _("Testing _fetchInfo.");
+    Weave.Service._fetchInfo();
+    _("User-Agent: " + ua);
+    do_check_eq(ua, expectedUA + ".desktop");
+    ua = "";
+    next();
+  }
+
+  function test_desktop_post(next) {
+    _("Testing direct Resource POST.");
+    let r = new AsyncResource("http://localhost:8080/1.0/johndoe/storage/meta/global");
+    r.post("foo=bar", function (error, content) {
+      _("User-Agent: " + ua);
+      do_check_eq(ua, expectedUA + ".desktop");
+      ua = "";
+      next();
+    });
+  }
+
+  function test_desktop_get(next) {
+    _("Testing async.");
+    Svc.Prefs.set("client.type", "desktop");
+    let r = new AsyncResource("http://localhost:8080/1.0/johndoe/storage/meta/global");
+    r.get(function(error, content) {
+      _("User-Agent: " + ua);
+      do_check_eq(ua, expectedUA + ".desktop");
+      ua = "";
+      next();
+    });
+  }
+
+  function test_mobile_get(next) {
+    _("Testing mobile.");
+    Svc.Prefs.set("client.type", "mobile");
+    let r = new AsyncResource("http://localhost:8080/1.0/johndoe/storage/meta/global");
+    r.get(function (error, content) {
+      _("User-Agent: " + ua);
+      do_check_eq(ua, expectedUA + ".mobile");
+      ua = "";
+      next();
+    });
+  }
+
+  Utils.asyncChain(
+    test_fetchInfo,
+    test_desktop_post,
+    test_desktop_get,
+    test_mobile_get,
+    function (next) {
+      server.stop(next);
+    },
+    do_test_finished)();
+}
+
+function run_test() {
+  test_resource_user_agent();
+}