summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Xu <alex_y_xu@yahoo.ca>2014-12-09 19:18:15 -0500
committerAlex Xu <alex_y_xu@yahoo.ca>2014-12-09 22:03:17 -0500
commit74ea762eef32df4bc459fe48247ab32049138e8a (patch)
tree90d83730375d104a45571ee73f7a6211ebb4119b
parent3a93c00d336cc9e9201e41a9bacfcd2e916368b7 (diff)
downloadeib-74ea762eef32df4bc459fe48247ab32049138e8a.tar.xz
eib-74ea762eef32df4bc459fe48247ab32049138e8a.zip
Add features, XHR long polling.
-rw-r--r--src/.jshintrc3
-rw-r--r--src/bootstrap.js143
-rw-r--r--src/chrome/content/igb/trusted.html10
-rw-r--r--src/chrome/content/igb/trusted.js15
-rw-r--r--src/chrome/content/igb/unknown.html9
-rw-r--r--src/chrome/content/igb/untrusted.html12
6 files changed, 137 insertions, 55 deletions
diff --git a/src/.jshintrc b/src/.jshintrc
new file mode 100644
index 0000000..0460aba
--- /dev/null
+++ b/src/.jshintrc
@@ -0,0 +1,3 @@
+{
+ "moz": true
+}
diff --git a/src/bootstrap.js b/src/bootstrap.js
index 162c857..0fbc56e 100644
--- a/src/bootstrap.js
+++ b/src/bootstrap.js
@@ -6,70 +6,88 @@ if (typeof EIB === "undefined")
const Cc = Components.classes, Ci = Components.interfaces, Cu = Components.utils, CC = Components.Constructor, Cr = Components.results;
const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1", "nsIScriptableInputStream", "init");
+const FileInputStream = CC("@mozilla.org/network/file-input-stream;1", "nsIFileInputStream", "init");
+const LocalFileFromPath = CC("@mozilla.org/file/local;1", "nsILocalFile", "initWithPath");
Cu.import("resource://gre/modules/Services.jsm");
function install() {}
function uninstall() {}
-EIB.listen = function () {
- this.serverSocket = Cc["@mozilla.org/network/server-socket;1"]
- .createInstance(Ci.nsIServerSocket);
- this.serverSocket.init(26001, true, -1);
- const tm = Cc["@mozilla.org/thread-manager;1"].getService();
- this.serverSocket.asyncListen({
- onSocketAccepted: function (socket, transport) {
- var is = transport.openInputStream(0, 0, 0);
- var os = transport.openOutputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0);
- var sis = new ScriptableInputStream(is);
- var buf = "";
- // TODO: run on separate thread
- is.asyncWait({
- onInputStreamReady: function () {
- while (sis.available()) {
- buf += sis.read(2048);
- }
- if (buf.indexOf("\n\n") !== 2) {
- var headers = {};
- var rx = /\n(EVE_[^:]*): (.*)$/gm, arr;
- while ((arr = rx.exec(buf)) !== null) {
- headers[arr[1]] = arr[2];
- }
+var ServerListener = {
+ onSocketAccepted: function (socket, transport) {
+ var is = transport.openInputStream(0, 0, 0);
+ var os = transport.openOutputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0);
+ var sis = new ScriptableInputStream(is);
+ var buf = "";
+ is.asyncWait({
+ onInputStreamReady: function () {
+ while (sis.available())
+ buf += sis.read(2048);
+
+ if (buf.indexOf("\r\n\r\n") > -1) {
+ is.close();
+
+ // parse out headers
+ var headers = {};
+ var rx = /\n(EVE_[^:]*): (.*)$/gm, arr;
+ while ((arr = rx.exec(buf)) !== null)
+ headers[arr[1]] = arr[2];
+
+ if (headers.EVE_TRUSTED == "Yes")
EIB.headers = headers;
- var resp = "HTTP/1.0 200 OK\r\n";
- resp += "Content-Type: text/html\r\n\r\n";
- resp += "<!DOCTYPE html><html><head><title>EVE-IGB Bridge</title>";
- if (headers["EVE_TRUSTED"]) {
- resp += '<script>';
- if (headers["EVE_TRUSTED"] == "Yes") {
- var delay = 100;
- if (EIB.pending.length) {
- resp += EIB.pending.shift();
- delay = 1000;
- }
- resp += 'setTimeout(function () { location.reload(); }, ' + delay + ');';
- } else {
- resp += 'CCPEVE.requestTrust("http://127.0.0.1:' + EIB.serverSocket.port + '");';
+ // figure out what we're responding with
+ var type, file, code;
+ switch (/ ([^ ]*) /.exec(buf)[1]) {
+ case '/':
+ type = "text/html; charset=UTF-8";
+ file = headers.EVE_TRUSTED === "Yes" ? "trusted.html" :
+ headers.EVE_TRUSTED === "No" ? "untrusted.html" :
+ "unknown.html";
+ break;
+ case '/trusted.js':
+ type = "application/javascript";
+ file = "trusted.js";
+ break;
+ case '/trusted':
+ if (EIB.stream)
+ EIB.stream.close();
+ EIB.stream = os;
+ return;
+ }
+
+ // build the response
+ var resp = "HTTP/1.0 " + (type ?
+ "200 OK\r\nContent-Type: " + type + "\r\n\r\n" :
+ "404 Not Found\r\nContent-Type: text/plain\r\n\r\n404 Not Found\r\n");
+ os.write(resp, resp.length);
+ if (file) {
+ var channel = Services.io.newChannel("chrome://eib/content/igb/" + file, null, null);
+ channel.asyncOpen({
+ onStartRequest: function () {},
+ onDataAvailable: function (req, ctx, fis, offset, cnt) {
+ os.writeFrom(fis, cnt);
+ },
+ onStopRequest: function (req, ctx, status) {
+ os.close();
}
- resp += "</script></head><body>";
- resp += headers["EVE_TRUSTED"] == "Yes" ?
- "Connected to the EVE-IGB Bridge. Please do not close this window. You may minimize it, however. Note that this window will refresh repeatedly; this does not indicate a malfunction and will not count towards your internet data usage if you have one." :
- "Please grant trust to this site, then refresh the page.";
- resp += "</body></html>";
- } else {
- resp += "</head><body>Please open this page in the EVE in-game browser.</body></html>";
- }
- os.write(resp, resp.length);
-
- is.close();
+ }, null);
+ } else {
os.close();
}
}
- }, 0, 0, tm.mainThread);
- }
- });
-}
+ }
+ }, 0, 0, Services.tm.mainThread);
+ }
+};
+
+EIB.listen = function () {
+ this.serverSocket = Cc["@mozilla.org/network/server-socket;1"]
+ .createInstance(Ci.nsIServerSocket);
+ this.serverSocket.init(26001, true, -1);
+ this.serverSocket.asyncListen(ServerListener);
+};
var HttpObserver = {
observe: function (subject, topic, data) {
@@ -108,7 +126,7 @@ var WindowListener = {
var TrustedReparser = {
observe: function () {
EIB.trusted = EIB.prefs.prefHasUserValue("trusted") ?
- JSON.parse(EIB.prefs.getCharPref("trusted").map(function (v) { return new RegExp(v); }) :
+ JSON.parse(EIB.prefs.getCharPref("trusted")).map(function (v) { return new RegExp(v); }) :
[];
}
};
@@ -130,6 +148,10 @@ function shutdown(data, reason) {
if (reason === APP_SHUTDOWN)
return;
+ if (EIB.stream)
+ EIB.stream.close();
+ delete EIB.stream;
+
if (EIB.serverSocket)
EIB.serverSocket.close();
delete EIB.serverSocket;
@@ -148,14 +170,25 @@ function checkTrusted(href) {
});
}
+// We can't get this from the IGB because the properties aren't enumerable and it doesn't implement Object.getOwnPropertyNames.
+// We could test if the functions are available, but since there's only one IGB version, that wouldn't be particularly useful.
+const exportFunctions = ["openEveMail", "showInfo", "showPreview", "showRouteTo", "showMap", "showFitting", "showContract", "showMarketDetails", "setDestination", "addWaypoint", "joinChannel", "joinMailingList", "createContract", "buyType", "findInContracts", "addToMarketQuickBar", "addContact", "removeContact", "addCorpContact", "removeCorpContact", "block", "addBounty", "inviteToFleet", "startConversation", "showContracts", "showOnMap", "editMember", "awardDecoration", "sendMail", "showContents", "bookmark"];
+
function injectCCPEVE(e) {
var window = e.originalTarget.defaultView;
if (checkTrusted(window.location.href)) {
var CCPEVE = Cu.createObjectIn(window, {defineAs: "CCPEVE"});
- ["openEveMail", "showInfo", "showPreview", "showRouteTo", "showMap", "showFitting", "showContract", "showMarketDetails", "setDestination", "addWaypoint", "joinChannel", "joinMailingList", "createContract", "buyType", "findInContracts", "addToMarketQuickBar", "addContact", "removeContact", "addCorpContact", "removeCorpContact", "block", "addBounty", "inviteToFleet", "startConversation", "showContracts", "showOnMap", "editMember", "awardDecoration", "sendMail", "showContents", "bookmark"].forEach(function (n) {
+ exportFunctions.forEach(function (n) {
Object.defineProperty(CCPEVE, n, {
value: Cu.exportFunction(function () {
- EIB.pending.push('CCPEVE.' + n + '(' + JSON.stringify([].slice.call(arguments)).slice(1, -1) + ');');
+ if (EIB.stream) {
+ var resp = "HTTP/1.0 200 OK\r\nContent-Type: application/json\r\n";
+ var str = JSON.stringify([n, [].slice.call(arguments)]) + "\r\n";
+ resp += "Content-Length: " + str.length + "\r\n\r\n" + str;
+ EIB.stream.write(resp, resp.length);
+ EIB.stream.close();
+ }
+ delete EIB.stream;
return null;
}, CCPEVE)
});
diff --git a/src/chrome/content/igb/trusted.html b/src/chrome/content/igb/trusted.html
new file mode 100644
index 0000000..8867b73
--- /dev/null
+++ b/src/chrome/content/igb/trusted.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>EVE-IGB Bridge</title>
+ <script src="trusted.js"></script>
+ </head>
+ <body>
+ <p>Connected to the EVE-IGB Bridge. Please do not close this window. You may minimize it, however. Note that this window will refresh repeatedly; this does not indicate a malfunction and will not count towards your internet data usage if you have one.</p>
+ </body>
+</html>
diff --git a/src/chrome/content/igb/trusted.js b/src/chrome/content/igb/trusted.js
new file mode 100644
index 0000000..3c6a6c7
--- /dev/null
+++ b/src/chrome/content/igb/trusted.js
@@ -0,0 +1,15 @@
+window.onerror = function (e) { alert(e); };
+var xhr = new XMLHttpRequest();
+xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4) {
+ var obj = JSON.parse(xhr.responseText);
+ CCPEVE[obj[0]].apply(CCPEVE, obj[1]);
+ // IGB imposes a 1s delay between JS calls
+ setTimeout(function () {
+ xhr.open("GET", "trusted");
+ xhr.send();
+ }, 1000);
+ }
+};
+xhr.open("GET", "trusted");
+xhr.send();
diff --git a/src/chrome/content/igb/unknown.html b/src/chrome/content/igb/unknown.html
new file mode 100644
index 0000000..51170b3
--- /dev/null
+++ b/src/chrome/content/igb/unknown.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>EVE-IGB Bridge</title>
+ </head>
+ <body>
+ <p>Please open this site in the EVE in-game browser.</p>
+ </body>
+</html>
diff --git a/src/chrome/content/igb/untrusted.html b/src/chrome/content/igb/untrusted.html
new file mode 100644
index 0000000..1cb7499
--- /dev/null
+++ b/src/chrome/content/igb/untrusted.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>EVE-IGB Bridge</title>
+ <script>
+ CCPEVE.requestTrust("http://127.0.0.1:26001");
+ </script>
+ </head>
+ <body>
+ <p>Please grant trust to this site, then refresh the page.</p>
+ </body>
+</html>