comparison rlgwebd.js @ 27:83f9a799a374

rlgwebd.js: read commands from the console The RLG-Web server can now be controlled with commands sent to stdin. Currently, the only one implemented is "quit". Some improvements to the shutdown process were also made.
author John "Elwin" Edwards <elwin@sdf.org>
date Mon, 04 Jun 2012 14:21:41 -0700
parents 9b58f8d3ea70
children 2ad2b6491aa9
comparison
equal deleted inserted replaced
26:9b58f8d3ea70 27:83f9a799a374
13 var dropToUID = 501; 13 var dropToUID = 501;
14 var dropToGID = 501; 14 var dropToGID = 501;
15 var serveStaticRoot = "/var/www/"; // inside the chroot 15 var serveStaticRoot = "/var/www/"; // inside the chroot
16 var passwdfile = "/dgldir/dgl-login"; 16 var passwdfile = "/dgldir/dgl-login";
17 var sessions = {}; 17 var sessions = {};
18 var allowlogin = true;
18 19
19 var games = { 20 var games = {
20 "rogue3": { 21 "rogue3": {
21 "name": "Rogue V3", 22 "name": "Rogue V3",
22 "uname": "rogue3", 23 "uname": "rogue3",
196 setTimeout(ss.remove, 8000); 197 setTimeout(ss.remove, 8000);
197 else 198 else
198 ss.remove(); 199 ss.remove();
199 }; 200 };
200 this.remove = function () { 201 this.remove = function () {
201 delete sessions[ss.sessid]; 202 var id = ss.sessid;
202 tslog("Session %s removed.", this.sessid); 203 delete sessions[id];
204 tslog("Session %s removed.", id);
203 }; 205 };
204 } 206 }
205 207
206 /* A few utility functions */ 208 /* A few utility functions */
207 function timestamp() { 209 function timestamp() {
303 // Real authentication not implemented 305 // Real authentication not implemented
304 return true; 306 return true;
305 } 307 }
306 308
307 function login(req, res, formdata) { 309 function login(req, res, formdata) {
310 if (!allowlogin) {
311 sendError(res, 6, null);
312 return;
313 }
308 if (!("game" in formdata)) { 314 if (!("game" in formdata)) {
309 sendError(res, 2, "No game specified."); 315 sendError(res, 2, "No game specified.");
310 return; 316 return;
311 } 317 }
312 else if (!("name" in formdata)) { 318 else if (!("name" in formdata)) {
519 var reply = {}; 525 var reply = {};
520 var result = term.read(); 526 var result = term.read();
521 if (result == null) { 527 if (result == null) {
522 if (term.alive) 528 if (term.alive)
523 reply.t = "n"; 529 reply.t = "n";
524 else 530 else {
525 reply.t = "q"; 531 if (allowlogin)
532 reply.t = "q";
533 else {
534 sendError(res, 6, null);
535 return;
536 }
537 }
526 } 538 }
527 else { 539 else {
528 reply.t = "d"; 540 reply.t = "d";
529 reply.n = term.nsend++; 541 reply.n = term.nsend++;
530 reply.d = result.toString("hex"); 542 reply.d = result.toString("hex");
537 sendError(res, 1, null); 549 sendError(res, 1, null);
538 } 550 }
539 } 551 }
540 552
541 var errorcodes = [ "Generic Error", "Not logged in", "Invalid data", 553 var errorcodes = [ "Generic Error", "Not logged in", "Invalid data",
542 "Login failed", "Already playing", "Game launch failed" ]; 554 "Login failed", "Already playing", "Game launch failed",
555 "Server shutting down" ];
543 556
544 function sendError(res, ecode, msg) { 557 function sendError(res, ecode, msg) {
545 res.writeHead(200, { "Content-Type": "text/plain" }); 558 res.writeHead(200, { "Content-Type": "text/plain" });
546 var edict = {"t": "E"}; 559 var edict = {"t": "E"};
547 if (!(ecode < errorcodes.length && ecode > 0)) 560 if (!(ecode < errorcodes.length && ecode > 0))
552 edict["s"] += ": " + msg; 565 edict["s"] += ": " + msg;
553 res.write(JSON.stringify(edict)); 566 res.write(JSON.stringify(edict));
554 res.end(); 567 res.end();
555 } 568 }
556 569
557 function handler(req, res) { 570 function webHandler(req, res) {
558 /* default headers for the response */ 571 /* default headers for the response */
559 var resheaders = {'Content-Type': 'text/html'}; 572 var resheaders = {'Content-Type': 'text/html'};
560 /* The request body will be added to this as it arrives. */ 573 /* The request body will be added to this as it arrives. */
561 var reqbody = ""; 574 var reqbody = "";
562 var formdata; 575 var formdata;
633 } 646 }
634 req.on('end', respond); 647 req.on('end', respond);
635 648
636 } 649 }
637 650
651 function shutdown () {
652 httpServer.close();
653 httpServer.removeAllListeners('request');
654 process.stdin.removeAllListeners('data');
655 tslog("Shutting down...");
656 process.exit();
657 }
658
659 function conHandler(chunk) {
660 var msg = chunk.toString().split('\n')[0];
661 if (msg == "quit") {
662 allowlogin = false;
663 tslog("Disconnecting...");
664 for (var sessid in sessions) {
665 sessions[sessid].close();
666 }
667 setTimeout(shutdown, 10000);
668 }
669 }
670
638 process.on("exit", function () { 671 process.on("exit", function () {
639 for (var sessid in sessions) { 672 for (var sessid in sessions) {
640 if (sessions[sessid].alive) 673 if (sessions[sessid].alive)
641 sessions[sessid].child.kill('SIGHUP'); 674 sessions[sessid].child.kill('SIGHUP');
642 } 675 }
673 catch (err) { 706 catch (err) {
674 tslog("Could not drop permissions: %s", err); 707 tslog("Could not drop permissions: %s", err);
675 process.exit(1); 708 process.exit(1);
676 } 709 }
677 710
678 http.createServer(handler).listen(8080, "127.0.0.1"); 711 process.stdin.on('data', conHandler);
712 process.stdin.resume();
713 var httpServer = http.createServer(webHandler);
714 httpServer.listen(8080, "127.0.0.1");
679 tslog('rlgwebd running at http://127.0.0.1:8080/'); 715 tslog('rlgwebd running at http://127.0.0.1:8080/');