123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- let http = require("http");
- let fs = require("fs");
- let crypto = require("crypto");
- let urllib = require("url");
- let ws = require("ws");
- let mime = require('mime-types')
-
- let sessions = {};
-
- class Session {
- constructor(id) {
- this.id = id;
- this.masterPoll = null;
- this.timeout = null;
- this.resetTimeout();
- this.master = null;
- this.target = null;
- }
-
- resetTimeout() {
- if (this.timeout)
- clearTimeout(this.timeout);
-
- this.timeout = setTimeout(() => {
- console.log(`${this.id}: No activity for 5m, deleting session.`);
- sessions[this.id] = null;
- }, 5 * 60 * 1000);
- }
-
- onMaster(conn) {
- this.master = conn;
-
- this.sendTargetMessage({ type: "master-connect" });
- if (this.target)
- this.sendMasterMessage({ type: "target-connect" });
-
- conn.on("message", msg => {
- console.log(`${this.id}: Message from master: ${msg}`);
- this.resetTimeout();
- this.onMasterMessage(JSON.parse(msg));
- });
-
- conn.on("close", () => {
- this.master = null;
- this.sendTargetMessage({ type: "master-disconnect" });
- });
- }
-
- onTarget(conn) {
- this.target = conn;
-
- this.sendMasterMessage({ type: "target-connect" });
- if (this.master)
- this.sendTargetMessage({ type: "master-connect" });
-
- conn.on("message", msg => {
- console.log(`${this.id}: Message from target: ${msg}`);
- this.resetTimeout();
- this.onTargetMessage(JSON.parse(msg));
- });
-
- conn.on("close", () => {
- this.target = null;
- this.sendMasterMessage({ type: "target-disconnect" });
- });
- }
-
- onMasterMessage(msg) {
- console.log(`${this.id}: Forwarding from master:`, msg);
- this.sendTargetMessage(msg);
- }
-
- onTargetMessage(msg) {
- console.log(`${this.id}: Forwarding from target:`, msg);
- this.sendMasterMessage(msg);
- }
-
- sendMasterMessage(msg) {
- if (this.master)
- this.master.send(JSON.stringify(msg));
- }
-
- sendTargetMessage(msg) {
- if (this.target)
- this.target.send(JSON.stringify(msg));
- }
- }
-
- function createSession() {
- let id = crypto.randomBytes(16).toString("hex");
- sessions[id] = new Session(id);
- return id;
- }
-
- function sendFile(path, res) {
- let url = urllib.parse(path);
- let rs = fs.createReadStream(`web${url.pathname}`);
- rs.once("error", err => {
- if (err.code == "EISDIR") {
- if (url.pathname[url.pathname.length - 1] == "/") {
- return sendFile(`${url.pathname}index.html`, res);
- } else {
- res.writeHead(302, { location: `${url.pathname}/` });
- res.end();
- return;
- }
- }
-
- res.writeHead(400);
- res.end(err.toString());
- });
- rs.on("open", () => {
- res.writeHead(200, {
- "Content-Type": mime.lookup(url.pathname),
- });
- });
- rs.pipe(res);
- }
-
- let server = http.createServer((req, res) => {
- if (req.method == "GET" || req.method == "HEAD") {
- sendFile(req.url, res);
- } else if (req.method == "POST" && req.url == "/create") {
- let id = createSession(res);
- res.writeHead(302, {
- location: `/console/?${id}`,
- });
- res.end("Redirecting...");
- }
- });
- server.listen(8080);
-
- let wss = new ws.Server({ server });
-
- wss.on("connection", conn => {
- conn.on("message", function onMessage(msg) {
- let obj;
- try {
- obj = JSON.parse(msg);
- } catch (err) {
- console.log("Received invalid message");
- conn.send(JSON.stringify({
- type: "identify-response",
- err: "Invalid JSON",
- }));
- return;
- }
-
- if (obj.type != "identify-target" && obj.type != "identify-master") {
- conn.send(JSON.stringify({
- type: "identify-response",
- err: "Not identified",
- }));
- return;
- }
-
- if (!obj.id) {
- conn.send(JSON.stringify({
- type: "identify-response",
- err: "Empty session ID",
- }));
- return;
- }
-
- let sess = sessions[obj.id];
- if (sess == null) {
- conn.send(JSON.stringify({
- type: "identify-response",
- err: "Invalid session ID",
- }));
- return;
- }
-
- conn.send(JSON.stringify({ type: "identify-response", err: null }));
- conn.off("message", onMessage);
-
- if (obj.type == "identify-master")
- sess.onMaster(conn);
- else
- sess.onTarget(conn);
- });
- });
|