Mercurial > hg > rlgwebd
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/'); |