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 225327 193f3c50bcd39a079aa93867d36cd7130d06773d
parent 225326 243d04bda211c14942852b0c1e8c9f6ba9f932a9
child 225328 17628eb25daf7e3023b778b07839163d3401b71f
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhammond, Standard8
bugs1055139
milestone34.0a2
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
--- 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();