annotate webtty.js @ 170:50e4c9feeac2

RLGWebD: fix simultaneous player bug. Multiple games can now run at the same time, and data will be sent to the proper place. The interaction of multiple players with watchers has not yet been tested.
author John "Elwin" Edwards
date Fri, 09 Jan 2015 13:06:41 -0500
parents c4a32007d2dc
children 5372f1f97cf5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1 #!/usr/bin/env node
137
f14e92f6d955 webtty: don't hardcode paths.
John "Elwin" Edwards
parents: 86
diff changeset
2
f14e92f6d955 webtty: don't hardcode paths.
John "Elwin" Edwards
parents: 86
diff changeset
3 var localModules = '/usr/lib/node_modules/';
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
4 var http = require('http');
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
5 var url = require('url');
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
6 var path = require('path');
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
7 var fs = require('fs');
137
f14e92f6d955 webtty: don't hardcode paths.
John "Elwin" Edwards
parents: 86
diff changeset
8 var pty = require(path.join(localModules, "pty.js"));
140
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
9 var child_process = require("child_process");
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
10 var webSocketServer = require(path.join(localModules, "websocket")).server;
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
11
137
f14e92f6d955 webtty: don't hardcode paths.
John "Elwin" Edwards
parents: 86
diff changeset
12 var serveStaticRoot = fs.realpathSync(".");
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
13 var sessions = {};
153
c4a32007d2dc WebTTY: remove polling.
John "Elwin" Edwards
parents: 140
diff changeset
14 var nsessid = 0;
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
15
2
98bf7c94c954 webtty.js: set up the environment and working directory.
John "Elwin" Edwards <elwin@sdf.org>
parents: 0
diff changeset
16 var env_dontuse = {"TMUX": true, "TMUX_PANE": true};
98bf7c94c954 webtty.js: set up the environment and working directory.
John "Elwin" Edwards <elwin@sdf.org>
parents: 0
diff changeset
17
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
18 /* Constructor for TermSessions. Note that it opens the terminal and
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
19 * adds itself to the sessions dict.
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
20 */
140
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
21 function TermSessionWS(conn, h, w) {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
22 var ss = this;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
23 /* Set up the sizes. */
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
24 w = Math.floor(Number(w));
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
25 if (!(w > 0 && w < 256))
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
26 w = 80;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
27 this.w = w;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
28 h = Math.floor(Number(h));
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
29 if (!(h > 0 && h < 256))
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
30 h = 25;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
31 this.h = h;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
32 this.conn = conn;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
33 /* Customize the environment. */
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
34 var childenv = {};
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
35 for (var key in process.env) {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
36 if (!(key in env_dontuse))
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
37 childenv[key] = process.env[key];
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
38 }
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
39 var spawnopts = {"env": childenv, "cwd": process.env["HOME"],
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
40 "rows": this.h, "cols": this.w};
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
41 this.term = pty.spawn("bash", [], spawnopts);
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
42 this.alive = true;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
43 this.term.on("data", function (datastr) {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
44 var buf = new Buffer(datastr);
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
45 if (ss.conn.connected)
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
46 ss.conn.sendUTF(JSON.stringify({"t": "d", "d": buf.toString("hex")}));
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
47 });
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
48 this.term.on("exit", function () {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
49 ss.alive = false;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
50 /* Wait for all the data to get collected */
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
51 setTimeout(ss.cleanup, 1000);
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
52 });
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
53 this.conn.on("message", function (msg) {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
54 try {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
55 var msgObj = JSON.parse(msg.utf8Data);
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
56 }
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
57 catch (e) {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
58 return;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
59 }
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
60 if (msgObj.t == "d") {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
61 var hexstr = msgObj["d"].replace(/[^0-9a-f]/gi, "");
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
62 if (hexstr.length % 2 != 0) {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
63 return;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
64 }
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
65 var keybuf = new Buffer(hexstr, "hex");
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
66 ss.term.write(keybuf);
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
67 }
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
68 });
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
69 this.conn.on("close", function (msg) {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
70 if (ss.alive)
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
71 ss.term.kill('SIGHUP');
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
72 console.log("WebSocket connection closed.");
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
73 });
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
74 this.cleanup = function () {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
75 /* Call this when the child is dead. */
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
76 if (ss.alive)
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
77 return;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
78 if (ss.conn.connected) {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
79 ss.conn.sendUTF(JSON.stringify({"t": "q"}));
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
80 }
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
81 };
153
c4a32007d2dc WebTTY: remove polling.
John "Elwin" Edwards
parents: 140
diff changeset
82 sessions[nsessid++] = this;
140
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
83 this.conn.sendUTF(JSON.stringify({"t": "l", "w": w, "h": h}));
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
84 console.log("New WebSocket connection.");
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
85 }
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
86
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
87 function randkey() {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
88 rnum = Math.floor(Math.random() * 65536 * 65536);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
89 hexstr = rnum.toString(16);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
90 while (hexstr.length < 8)
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
91 hexstr = "0" + hexstr;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
92 return hexstr;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
93 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
94
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
95 /* Returns a list of the cookies in the request, obviously. */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
96 function getCookies(req) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
97 cookies = [];
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
98 if ("cookie" in req.headers) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
99 cookstrs = req.headers["cookie"].split("; ");
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
100 for (var i = 0; i < cookstrs.length; i++) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
101 eqsign = cookstrs[i].indexOf("=");
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
102 if (eqsign > 0) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
103 name = cookstrs[i].slice(0, eqsign).toLowerCase();
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
104 val = cookstrs[i].slice(eqsign + 1);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
105 cookies[name] = val;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
106 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
107 else if (eqsign < 0)
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
108 cookies[cookstrs[i]] = null;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
109 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
110 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
111 return cookies;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
112 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
113
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
114 function urlDec(encstr) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
115 var decstr = "";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
116 var tnum;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
117 for (var i = 0; i < encstr.length; i++)
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
118 {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
119 if (encstr.charAt(i) == "+")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
120 decstr += " ";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
121 else if (encstr.charAt(i) == "%")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
122 {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
123 tnum = Number("0x" + encstr.slice(i + 1, 2));
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
124 if (!isNaN(tnum) && tnum >= 0)
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
125 decstr += String.fromCharCode(tnum);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
126 i += 2;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
127 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
128 else
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
129 decstr += encstr.charAt(i);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
130 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
131 return decstr;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
132 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
133
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
134 /* Returns the contents of a form */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
135 function getFormValues(formtext) {
13
bf7c26d0b66d webtty: switch upward protocol to JSON
John "Elwin" Edwards <elwin@sdf.org>
parents: 11
diff changeset
136 var jsonobj;
bf7c26d0b66d webtty: switch upward protocol to JSON
John "Elwin" Edwards <elwin@sdf.org>
parents: 11
diff changeset
137 try {
bf7c26d0b66d webtty: switch upward protocol to JSON
John "Elwin" Edwards <elwin@sdf.org>
parents: 11
diff changeset
138 jsonobj = JSON.parse(formtext);
bf7c26d0b66d webtty: switch upward protocol to JSON
John "Elwin" Edwards <elwin@sdf.org>
parents: 11
diff changeset
139 } catch (e) {
bf7c26d0b66d webtty: switch upward protocol to JSON
John "Elwin" Edwards <elwin@sdf.org>
parents: 11
diff changeset
140 if (e instanceof SyntaxError)
bf7c26d0b66d webtty: switch upward protocol to JSON
John "Elwin" Edwards <elwin@sdf.org>
parents: 11
diff changeset
141 return null;
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
142 }
13
bf7c26d0b66d webtty: switch upward protocol to JSON
John "Elwin" Edwards <elwin@sdf.org>
parents: 11
diff changeset
143 return jsonobj;
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
144 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
145
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
146 function serveStatic(req, res, fname) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
147 var nname = path.normalize(fname);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
148 if (nname == "" || nname == "/")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
149 nname = "index.html";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
150 if (nname.match(/\/$/))
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
151 path.join(nname, "index.html"); /* it was a directory */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
152 var realname = path.join(serveStaticRoot, nname);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
153 var extension = path.extname(realname);
81
e4773ac5d4d5 Switch to node v0.8.
John "Elwin" Edwards <elwin@sdf.org>
parents: 15
diff changeset
154 fs.exists(realname, function (exists) {
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
155 var resheaders = {};
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
156 if (!exists || !extension || extension == ".html")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
157 resheaders["Content-Type"] = "text/html";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
158 else if (extension == ".png")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
159 resheaders["Content-Type"] = "image/png";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
160 else if (extension == ".css")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
161 resheaders["Content-Type"] = "text/css";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
162 else if (extension == ".js")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
163 resheaders["Content-Type"] = "text/javascript";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
164 else if (extension == ".svg")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
165 resheaders["Content-Type"] = "image/svg+xml";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
166 else
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
167 resheaders["Content-Type"] = "application/octet-stream";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
168 if (exists) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
169 /* Not nice, not sensible. First see if it's readable, then respond
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
170 * 200 or 500. Don't throw nasty errors. */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
171 res.writeHead(200, resheaders);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
172 fs.readFile(realname, function (error, data) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
173 if (error) throw error;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
174 res.write(data);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
175 res.end();
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
176 });
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
177 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
178 else {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
179 res.writeHead(404, resheaders);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
180 res.write("<html><head><title>" + nname + "</title></head>\n<body><h1>" + nname + " Not Found</h1></body></html>\n");
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
181 res.end();
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
182 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
183 });
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
184 return;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
185 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
186
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
187 var errorcodes = [ "Generic Error", "Not logged in", "Invalid data" ];
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
188
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
189 function sendError(res, ecode) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
190 res.writeHead(200, { "Content-Type": "text/plain" });
11
481dcee353c9 webtty: switch all server responses to JSON.
John "Elwin" Edwards <elwin@sdf.org>
parents: 10
diff changeset
191 if (!(ecode >= 0 && ecode < errorcodes.length))
481dcee353c9 webtty: switch all server responses to JSON.
John "Elwin" Edwards <elwin@sdf.org>
parents: 10
diff changeset
192 ecode = 0;
481dcee353c9 webtty: switch all server responses to JSON.
John "Elwin" Edwards <elwin@sdf.org>
parents: 10
diff changeset
193 res.write(JSON.stringify({"t": "E", "c": ecode, "s": errorcodes[ecode]}));
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
194 res.end();
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
195 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
196
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
197 function handler(req, res) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
198 /* default headers for the response */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
199 var resheaders = {'Content-Type': 'text/html'};
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
200 /* The request body will be added to this as it arrives. */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
201 var reqbody = "";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
202 var formdata;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
203
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
204 /* Register a listener to get the body. */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
205 function moredata(chunk) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
206 reqbody += chunk;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
207 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
208 req.on('data', moredata);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
209
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
210 /* This will send the response once the whole request is here. */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
211 function respond() {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
212 var target = url.parse(req.url).pathname;
153
c4a32007d2dc WebTTY: remove polling.
John "Elwin" Edwards
parents: 140
diff changeset
213 /* Currently only static files and WebSockets are needed. */
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
214 if (req.method == 'POST') {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
215 formdata = getFormValues(reqbody);
153
c4a32007d2dc WebTTY: remove polling.
John "Elwin" Edwards
parents: 140
diff changeset
216 res.writeHead(405, resheaders);
c4a32007d2dc WebTTY: remove polling.
John "Elwin" Edwards
parents: 140
diff changeset
217 res.end();
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
218 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
219 else if (req.method == 'GET' || req.method == 'HEAD') {
153
c4a32007d2dc WebTTY: remove polling.
John "Elwin" Edwards
parents: 140
diff changeset
220 serveStatic(req, res, target);
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
221 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
222 else { /* Some other method */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
223 res.writeHead(501, resheaders);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
224 res.write("<html><head><title>501</title></head>\n<body><h1>501 Not Implemented</h1></body></html>\n");
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
225 res.end();
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
226 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
227 return;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
228 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
229 req.on('end', respond);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
230 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
231
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
232 process.on("exit", function () {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
233 for (var sessid in sessions) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
234 if (sessions[sessid].alive)
86
ad4229cf8321 WebTTY: use the pty.js module.
John "Elwin" Edwards <elwin@sdf.org>
parents: 81
diff changeset
235 sessions[sessid].term.kill('SIGHUP');
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
236 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
237 console.log("Quitting...");
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
238 return;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
239 });
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
240
140
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
241 function wsRespond(req) {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
242 var w, h, conn;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
243 if (req.resourceURL.pathname == "/sock") {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
244 w = parseInt(req.resourceURL.query.w);
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
245 if (isNaN(w) || w <= 0 || w > 256)
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
246 w = 80;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
247 h = parseInt(req.resourceURL.query.h);
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
248 if (isNaN(h) || h <= 0 || h > 256)
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
249 h = 25;
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
250 conn = req.accept(null, req.origin);
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
251 new TermSessionWS(conn, h, w);
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
252 }
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
253 else {
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
254 req.reject(404, "No such resource.");
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
255 }
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
256 }
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
257
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
258 /* The pty.js module doesn't wait for the processes it spawns, so they
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
259 * become zombies, which leads to unpleasantness when the system runs
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
260 * out of process table entries. But if the child_process module is
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
261 * initialized and a child spawned, node will continue waiting for any
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
262 * children.
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
263 * Someday, some developer will get the bright idea of tracking how many
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
264 * processes the child_process module has spawned, and not waiting if
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
265 * it's zero. Until then, the following useless line will protect us
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
266 * from the zombie hordes.
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
267 * Figuring this out was almost as interesting as the Rogue bug where
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
268 * printf debugging altered whether the high score list was checked.
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
269 */
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
270 child_process.spawn("/bin/true");
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
271
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
272 process.env["TERM"] = "xterm-256color";
140
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
273 var webServer = http.createServer(handler);
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
274 webServer.listen(8080, "127.0.0.1");
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
275 console.log('Server running at http://127.0.0.1:8080/');
140
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
276 var wsServer = new webSocketServer({"httpServer": webServer});
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
277 wsServer.on("request", wsRespond);
789c094675f4 WebTTY: use WebSockets when possible.
John "Elwin" Edwards
parents: 137
diff changeset
278 console.log('WebSockets online');