Hatch always sends origin; utf8 str length repair
authorBill Erickson <berickxx@gmail.com>
Mon, 28 Nov 2016 17:11:45 +0000 (12:11 -0500)
committerBill Erickson <berickxx@gmail.com>
Mon, 28 Nov 2016 17:11:45 +0000 (12:11 -0500)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
extension/app/extension.js
logging.properties
src/org/evergreen_ils/hatch/MessageIO.java
src/org/evergreen_ils/hatch/RequestHandler.java
src/org/evergreen_ils/hatch/TestHatch.java

index a8a72ff..f13c13d 100644 (file)
@@ -19,39 +19,54 @@ var hatchPort = null;
 
 // Map of tab identifers to tab-specific connection ports.
 var browserPorts = {};
-
+const HATCH_EXT_NAME = 'org.evergreen_ils.hatch';
+const HATCH_RECONNECT_TIME = 5; // seconds
+
+var hatchHostUnavailable = false;
+function connectToHatch() {
+    console.debug("Connecting to native messaging host: " + HATCH_EXT_NAME);
+    try {
+        hatchPort = chrome.runtime.connectNative(HATCH_EXT_NAME);
+        hatchPort.onMessage.addListener(onNativeMessage);
+        hatchPort.onDisconnect.addListener(onDisconnected);
+    } catch (E) {
+        console.warn("Hatch host connection failed: " + E);
+        hatchHostUnavailable = true;
+    }
+}
 
 /**
- * Handle response messages received from Hatch.
+ * Called when the connection to Hatch goes away.
  */
-function onNativeMessage(message) {
-    var tabId = message.clientid;
+function onDisconnected() {
+  console.warn("Hatch disconnected: " + chrome.runtime.lastError.message);
+  hatchPort = null;
 
-    if (tabId) {
-        if (browserPorts[tabId]) {
-            message.from = 'extension';
-            browserPorts[tabId].postMessage(message);
+  if (hatchHostUnavailable) return;
 
-        } else {
-            console.warn(
-                "Hatch message contains port ID " + tabId +
-                " which was not found in the browser tab map. " +
-                "Unable to deliver response to browser");
-        }
+  // If we can reasonablly assume a connection to the Hatch host 
+  // is possible, attempt to reconnect after a failure.
+  setTimeout(connectToHatch, HATCH_RECONNECT_TIME  * 1000); 
 
-    } else {
-        console.warn("Hatch response does not contain a 'clientid' value. " +
-            "Unable to deliver response to browser");
-    }
+  console.debug("Reconnecting to Hatch after connection failure in " +
+    HATCH_RECONNECT_TIME + " seconds...");
 }
 
+
 /**
- * Called when the connection to Hatch goes away.
+ * Handle response messages received from Hatch.
  */
-function onDisconnected() {
-  console.warn("Hatch connection failed: " + chrome.runtime.lastError.message);
-  hatchPort = null;
-  browserPorts = {};
+function onNativeMessage(message) {
+    var tabId = message.clientid;
+
+    if (tabId && browserPorts[tabId]) {
+        message.from = 'extension';
+        browserPorts[tabId].postMessage(message);
+    } else {
+        // if browserPorts[tabId] is empty, it generally means the
+        // user navigated away before receiving the response. 
+    }
 }
 
 
@@ -67,20 +82,20 @@ chrome.runtime.onConnect.addListener(function(port) {
     port.onMessage.addListener(function(msg) {
         console.debug("Received message from browser on port " + tabId);
 
-        if (!msg) { // belt+suspenders
-            console.warn("Received NULL message");
+        if (!hatchPort) {
+            // TODO: we could queue failed messages for redelivery
+            // after a reconnect.  Not sure yet if that level of 
+            // sophistication is necessary.
+            console.debug("Cannot send message " + 
+                msg.msgid + " - no Hatch connection present");
             return;
         }
 
         // tag the message with the browser tab ID for response routing.
         msg.clientid = tabId;
 
-        if (msg.action == 'init') {
-            // "init" messages require origin info.
-            // Extract just the protocol + host
-            msg.origin = port.sender.url.match(/https?:\/\/[^\/]+/)[0];
-            console.debug("Init'ing message with origin: " + msg.origin);
-        }
+        // Stamp the origin (protocol + host) on every request.
+        msg.origin = port.sender.url.match(/https?:\/\/[^\/]+/)[0];
 
         hatchPort.postMessage(msg);
     });
@@ -131,17 +146,9 @@ chrome.browserAction.onClicked.addListener(function (tab) {
 });
 
 
-/**
- * Link the page action icon to loading the content script
- */
+// Link the page action icon to loading the content script
 chrome.runtime.onInstalled.addListener(setPageActionRules);
 
-/**
- * Connect to Hatch on startup.
- */
-var hostName = "org.evergreen_ils.hatch";
-console.debug("Connecting to native messaging host: " + hostName);
-hatchPort = chrome.runtime.connectNative(hostName);
-hatchPort.onMessage.addListener(onNativeMessage);
-hatchPort.onDisconnect.addListener(onDisconnected);
+// Connect to Hatch on startup.
+connectToHatch();
 
index 566df9a..3f70e8a 100644 (file)
@@ -8,7 +8,7 @@ java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
 
 # log files go to $SYSTEM_TMP/hatch.log
 java.util.logging.FileHandler.pattern = %h/.evergreen/hatch.log
-java.util.logging.FileHandler.limit = 50000
+java.util.logging.FileHandler.limit = 50000000
 
 # Log everything everywhre
 org.evergreen_ils.hatch.level=ALL
index 5e2b3cd..b764c57 100644 (file)
@@ -195,7 +195,7 @@ public class MessageIO {
          */
         public void writeOneMessage(String message) throws IOException {
             logger.finest("MessageWriter sending: " + message);
-            System.out.write(intToBytes(message.length()));
+            System.out.write(intToBytes(message.getBytes("UTF-8").length));
             System.out.write(message.getBytes("UTF-8"));
             System.out.flush();
         }
index f221fb6..f399a1a 100644 (file)
@@ -33,9 +33,6 @@ public class RequestHandler extends Thread {
     /** Root directory for all FileIO operations */
     private static String profileDirectory = null;
 
-    /** Origin host/domain used for segregating files by browser host */
-    private static String origin = null;
-
     private void configure() {
 
         // Find the profile directory.
@@ -60,20 +57,14 @@ public class RequestHandler extends Thread {
         JSONObject request, JSONObject response) throws JSONException {
 
         String action = request.getString("action");
+        String origin = request.getString("origin");
 
         logger.info("Received message id=" + 
             response.get("msgid") + " action=" + action);
 
-        // init must be called first to set the origin info. Init may be
-        // called multiple times.  Each call will update the origin info.
-        if (action.equals("init")) {
-            origin = request.getString("origin");
-            return false;
-        }
-
-        if (origin == null) {
-            response.put("status", 400); 
-            response.put("message", "'init' action must be called first!");
+        if ("".equals(origin)) {
+            response.put("status", 404); 
+            response.put("message", "'origin' parameter required");
             return false;
         }
 
index 3389ffc..ee85154 100644 (file)
@@ -18,9 +18,11 @@ package org.evergreen_ils.hatch;
 import java.util.logging.Logger;
 import org.json.*;
 
+
 public class TestHatch {
     static MessageIO io;
     static final Logger logger = Logger.getLogger("org.evergreen_ils.hatch");
+    static final String origin = "https://test.hatch.evergreen-ils.org";
 
     public static void pause() {
         try {
@@ -31,21 +33,13 @@ public class TestHatch {
     public static void doSends() {
         int msgid = 1;
         int clientid = 1;
-
-        // initialize connection to set origin info
-        JSONObject obj = new JSONObject();
-        obj.put("msgid", msgid++);
-        obj.put("clientid", clientid);
-        obj.put("action", "init");
-        obj.put("origin", "https://test.hatch.evergreen-ils.org");
-        io.sendMessage(obj);
-
-        pause();
+        JSONObject obj;
 
         // get a list of stored keys
         obj = new JSONObject();
         obj.put("msgid", msgid++);
         obj.put("clientid", clientid);
+        obj.put("origin", origin);
         obj.put("action", "keys");
         io.sendMessage(obj);
 
@@ -55,9 +49,10 @@ public class TestHatch {
         obj = new JSONObject();
         obj.put("msgid", msgid++);
         obj.put("clientid", clientid);
+        obj.put("origin", origin);
         obj.put("action", "set");
         obj.put("key", "eg.hatch.test.key1");
-        obj.put("content", "Rando content, now with cheese");
+        obj.put("content", "Rando content, now with cheese and AljamĂ­a");
         io.sendMessage(obj);
 
         pause();
@@ -66,6 +61,7 @@ public class TestHatch {
         obj = new JSONObject();
         obj.put("msgid", msgid++);
         obj.put("clientid", clientid);
+        obj.put("origin", origin);
         obj.put("action", "get");
         obj.put("key", "eg.hatch.test.key1");
         io.sendMessage(obj);
@@ -74,6 +70,7 @@ public class TestHatch {
         obj = new JSONObject();
         obj.put("msgid", msgid++);
         obj.put("clientid", clientid);
+        obj.put("origin", origin);
         obj.put("action", "set");
         obj.put("key", "eg.hatch.test.key2");
         JSONArray arr = new JSONArray();
@@ -87,6 +84,7 @@ public class TestHatch {
         obj = new JSONObject();
         obj.put("msgid", msgid++);
         obj.put("clientid", clientid);
+        obj.put("origin", origin);
         obj.put("action", "get");
         obj.put("key", "eg.hatch.test.key2");
         io.sendMessage(obj);
@@ -96,6 +94,7 @@ public class TestHatch {
         obj = new JSONObject();
         obj.put("msgid", msgid++);
         obj.put("clientid", clientid);
+        obj.put("origin", origin);
         obj.put("action", "keys");
         io.sendMessage(obj);
 
@@ -105,6 +104,7 @@ public class TestHatch {
         obj = new JSONObject();
         obj.put("msgid", msgid++);
         obj.put("clientid", clientid);
+        obj.put("origin", origin);
         obj.put("action", "printers");
         io.sendMessage(obj);
 
@@ -114,6 +114,7 @@ public class TestHatch {
         obj = new JSONObject();
         obj.put("msgid", msgid++);
         obj.put("clientid", clientid);
+        obj.put("origin", origin);
         obj.put("action", "printer-options");
         io.sendMessage(obj);
 
@@ -125,6 +126,7 @@ public class TestHatch {
         obj = new JSONObject();
         obj.put("msgid", msgid++);
         obj.put("clientid", clientid);
+        obj.put("origin", origin);
         obj.put("action", "print");
         obj.put("contentType", "text/plain");
         obj.put("content", "Hello, World!");
@@ -136,6 +138,7 @@ public class TestHatch {
         obj = new JSONObject();
         obj.put("msgid", msgid++);
         obj.put("clientid", clientid);
+        obj.put("origin", origin);
         obj.put("action", "print");
         obj.put("contentType", "text/html");
         obj.put("content", "<html><body><b>HELLO WORLD</b><img src='" +