Bug 1055139 - Retrieve Simple Push Server URL from Loop Server r=mhammond,Standard8
authorAdam Roach [:abr] <adam@nostrum.com>
Mon, 18 Aug 2014 12:43:37 -0500
changeset 203220 c8dc98469fc0950aef15c589473f4440cd19e115
parent 203219 19ad1a4a9bb2d7bc7e8643cd732baec1f419b71c
child 203221 53ab51cc4eb0a8b475ff1e8e1db8e59688c8b97e
push id27424
push userryanvm@gmail.com
push dateWed, 03 Sep 2014 19:35:53 +0000
treeherdermozilla-central@bfef88becbba [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhammond, Standard8
bugs1055139
milestone35.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 1055139 - Retrieve Simple Push Server URL from Loop Server r=mhammond,Standard8
browser/components/loop/MozLoopPushHandler.jsm
browser/components/loop/test/mochitest/head.js
browser/components/loop/test/xpcshell/test_looppush_initialize.js
browser/components/loop/test/xpcshell/test_loopservice_expiry.js
browser/components/loop/test/xpcshell/test_loopservice_initialize.js
browser/components/loop/test/xpcshell/test_loopservice_locales.js
browser/components/loop/test/xpcshell/test_loopservice_loop_prefs.js
--- a/browser/components/loop/MozLoopPushHandler.jsm
+++ b/browser/components/loop/MozLoopPushHandler.jsm
@@ -16,17 +16,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/devtools/Console.jsm");
 
 /**
  * We don't have push notifications on desktop currently, so this is a
  * workaround to get them going for us.
  */
 let MozLoopPushHandler = {
   // This is the uri of the push server.
-  pushServerUri: Services.prefs.getCharPref("services.push.serverURL"),
+  pushServerUri: undefined,
   // This is the channel id we're using for notifications
   channelID: "8b1081ce-9b35-42b5-b8f5-3ff8cb813a50",
   // This is the UserAgent UUID assigned by the PushServer
   uaID: undefined,
   // Stores the push url if we're registered and we have one.
   pushUrl: undefined,
   // Set to true once the channelID has been registered with the PushServer.
   registered: false,
@@ -206,18 +206,61 @@ let MozLoopPushHandler = {
                         .createInstance(Ci.nsIWebSocketChannel);
     } else {
       this._registerCallback("offline");
       console.warn("MozLoopPushHandler - IO offline");
       return;
     }
 
     this._websocket.protocol = "push-notification";
-    let uri = Services.io.newURI(this.pushServerUri, null, null);
-    this._websocket.asyncOpen(uri, this.pushServerUri, this, null);
+
+    let performOpen = () => {
+      let uri = Services.io.newURI(this.pushServerUri, null, null);
+      this._websocket.asyncOpen(uri, this.pushServerUri, this, null);
+    }
+
+    let pushServerURLFetchError = () => {
+      console.warn("MozLoopPushHandler - Could not retrieve push server URL from Loop server; using default");
+      this.pushServerUri = Services.prefs.getCharPref("services.push.serverURL");
+      performOpen();
+    }
+
+    if (!this.pushServerUri) {
+      // Get push server to use from the Loop server
+      let pushUrlEndpoint = Services.prefs.getCharPref("loop.server") + "/push-server-config";
+      let req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+                createInstance(Ci.nsIXMLHttpRequest);
+      req.open("GET", pushUrlEndpoint);
+      req.onload = () => {
+        if (req.status >= 200 && req.status < 300) {
+          let pushServerConfig;
+          try {
+            pushServerConfig = JSON.parse(req.responseText);
+          } catch (e) {
+            console.warn("MozLoopPushHandler - Error parsing JSON response for push server URL");
+            pushServerURLFetchError();
+          }
+          if (pushServerConfig.pushServerURI) {
+            this.pushServerUri = pushServerConfig.pushServerURI;
+            performOpen();
+          } else {
+            console.warn("MozLoopPushHandler - push server URL config lacks pushServerURI parameter");
+            pushServerURLFetchError();
+          }
+        } else {
+          console.warn("MozLoopPushHandler - push server URL retrieve error: " + req.status);
+          pushServerURLFetchError();
+        }
+      };
+      req.onerror = pushServerURLFetchError;
+      req.send();
+    } else {
+      // this.pushServerUri already set -- just open the channel
+      performOpen();
+    }
   },
 
   /**
    * Handles registering a service
    */
   _registerChannel: function() {
     this.registered = false;
     try { // in case websocket has closed
--- a/browser/components/loop/test/mochitest/head.js
+++ b/browser/components/loop/test/mochitest/head.js
@@ -52,19 +52,27 @@ function promiseGetMozLoopAPI() {
  *
  * This assumes that the tests are running in a generatorTest.
  */
 function loadLoopPanel() {
   // Set prefs to ensure we don't access the network externally.
   Services.prefs.setCharPref("services.push.serverURL", "ws://localhost/");
   Services.prefs.setCharPref("loop.server", "http://localhost/");
 
+  // Turn off the network for loop tests, so that we don't
+  // try to access the remote servers. If we want to turn this
+  // back on in future, be careful to check for intermittent
+  // failures.
+  let wasOffline = Services.io.offline;
+  Services.io.offline = true;
+
   registerCleanupFunction(function() {
     Services.prefs.clearUserPref("services.push.serverURL");
     Services.prefs.clearUserPref("loop.server");
+    Services.io.offline = wasOffline;
   });
 
   // Turn off animations to make tests quicker.
   let loopPanel = document.getElementById("loop-notification-panel");
   loopPanel.setAttribute("animate", "false");
 
   // Now get the actual API.
   yield promiseGetMozLoopAPI();
--- a/browser/components/loop/test/xpcshell/test_looppush_initialize.js
+++ b/browser/components/loop/test/xpcshell/test_looppush_initialize.js
@@ -49,15 +49,17 @@
   add_test(function test_retry_registration() {
     MozLoopPushHandler.uaID = undefined;
     MozLoopPushHandler.pushUrl = undefined; //Do this to force a new registration callback.
     mockWebSocket.initRegStatus = 500;
     mockWebSocket.stop();
   });
 
   function run_test() {
+    setupFakeLoopServer();
+
     Services.prefs.setCharPref("services.push.serverURL", kServerPushUrl);
     Services.prefs.setIntPref("loop.retry_delay.start", 10); // 10 ms
     Services.prefs.setIntPref("loop.retry_delay.limit", 20); // 20 ms
 
     run_next_test();
   };
 }
--- a/browser/components/loop/test/xpcshell/test_loopservice_expiry.js
+++ b/browser/components/loop/test/xpcshell/test_loopservice_expiry.js
@@ -2,16 +2,18 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 function expiryTimePref() {
   return Services.prefs.getIntPref("loop.urlsExpiryTimeSeconds");
 }
 
 function run_test()
 {
+  setupFakeLoopServer();
+
   Services.prefs.setIntPref("loop.urlsExpiryTimeSeconds", 0);
 
   MozLoopService.noteCallUrlExpiry(1000);
 
   Assert.equal(expiryTimePref(), 1000, "should be equal to set value");
 
   MozLoopService.noteCallUrlExpiry(900);
 
--- a/browser/components/loop/test/xpcshell/test_loopservice_initialize.js
+++ b/browser/components/loop/test/xpcshell/test_loopservice_initialize.js
@@ -45,16 +45,18 @@ add_task(function test_initialize_starts
   MozLoopService.initialize();
 
   Assert.equal(startTimerCalled, true,
     "should start the timer when expiry time is in the future");
 });
 
 function run_test()
 {
+  setupFakeLoopServer();
+
   // Override MozLoopService's initializeTimer, so that we can verify the timeout is called
   // correctly.
   MozLoopService.initializeTimerFunc = function() {
     startTimerCalled = true;
   };
 
   run_next_test();
 }
--- a/browser/components/loop/test/xpcshell/test_loopservice_locales.js
+++ b/browser/components/loop/test/xpcshell/test_loopservice_locales.js
@@ -17,11 +17,13 @@ function test_getStrings() {
   // XXX This depends on the L10n values, which I'd prefer not to do, but is the
   // simplest way for now.
   Assert.equal(MozLoopService.getStrings("share_link_header_text"),
                '{"textContent":"Share this link to invite someone to talk:"}');
 }
 
 function run_test()
 {
+  setupFakeLoopServer();
+
   test_locale();
   test_getStrings();
 }
--- a/browser/components/loop/test/xpcshell/test_loopservice_loop_prefs.js
+++ b/browser/components/loop/test/xpcshell/test_loopservice_loop_prefs.js
@@ -84,16 +84,18 @@ function test_getLoopBoolPref_not_found(
 
   Assert.equal(returnedPref, null,
     "Should return null if a preference is not found");
 }
 
 
 function run_test()
 {
+  setupFakeLoopServer();
+
   test_getLoopCharPref();
   test_getLoopCharPref_not_found();
   test_getLoopCharPref_non_coercible_type();
   test_setLoopCharPref();
   test_setLoopCharPref_new();
   test_setLoopCharPref_non_coercible_type();
 
   test_getLoopBoolPref();