-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.mjs
106 lines (90 loc) · 3.62 KB
/
app.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import {promises as m_fs} from "fs";
import * as m_http from "http";
import * as m_https from "https";
import minimist from "minimist";
import * as m_socket_io from "socket.io";
import * as m_client from "./client/index.mjs";
import * as m_log from "./server/log.mjs";
import * as m_server from "./server/index.mjs";
import * as m_server_events from "./server/server_events.mjs";
const k_log = new m_log.Logger(m_log.e_log_level.info, "app");
const args = minimist(process.argv.slice(2));
const use_https = !args.insecure;
const server_options = {};
let default_port = 8080;
let default_host = "127.0.0.1";
if (use_https) {
default_port = 443;
default_host = "192.168.42.1";
const default_key_path = "/etc/letsencrypt/live/narcoticcats.net/privkey.pem";
const default_cert_path = "/etc/letsencrypt/live/narcoticcats.net/fullchain.pem";
const key_path = "key" in args ? args.key : default_key_path;
const cert_path = "cert" in args ? args.cert : default_cert_path;
server_options.key = await m_fs.readFile(key_path);
server_options.cert = await m_fs.readFile(cert_path);
}
const hostname = "host" in args ? args.host : default_host;
const port = "port" in args ? parseInt(args.port, 10) : default_port;
const control_c_buffer = Buffer.from([0x03]);
k_log.info("Initializing...");
await m_server.init(args);
async function handle_request(request, response) {
try {
request.setEncoding("utf8");
let request_body = "";
request.on("data", chunk => request_body += chunk);
await new Promise(resolve => request.on("end", resolve));
const url = new URL(request.url, `http://${request.headers.host}`);
k_log.debug("Got request for ", url.href);
const path_parts = url.pathname.split("/").filter(part => part.length > 0);
if (path_parts.length < 1) {
// The bare URL should get index.html, which is the client handler responsibility.
return m_client.handle(url, path_parts, request, request_body, response);
}
const module_name = path_parts.shift();
switch (module_name) {
case "client":
return m_client.handle(url, path_parts, request, request_body, response);
case "server":
return m_server.handle(url, path_parts, request, request_body, response);
}
response.writeHead(404, {"Content-Type": "text/plain"});
response.end(`Unknown module: ${module_name}`);
} catch (ex) {
k_log.error("Unhandled exception", ex);
response.writeHead(500, {"Content-Type": "text/plain"});
response.end(`Unhandled exception`);
}
};
let server;
if (use_https) {
server = m_https.createServer(server_options, handle_request);
} else {
server = m_http.createServer(server_options, handle_request);
}
const socket_io = new m_socket_io.Server(server);
await m_server_events.init(args, socket_io);
k_log.info("Initialization done.");
server.listen(port, hostname, () => {
k_log.info(`Started server at http://${hostname}:${port}/\n`);
});
server.listen(3000, hostname, () => {
k_log.info(`Started socket server at http://${hostname}:3000/\n`);
});
process.stdin.on("data", async key => {
if (key.compare(control_c_buffer) == 0) {
k_log.warn("\nGot Control+C. Exiting...");
// Closing everything we are using allows everything to shut down a bit more gracefully than
// just forcing the process to exit.
process.stdin.setRawMode(false);
process.stdin.destroy();
k_log.info("Closing handlers and database...");
await m_server_events.shutdown();
await m_server.shutdown();
k_log.info("Closing server...");
socket_io.close();
await new Promise(resolve => server.close(resolve));
k_log.info("Everything closed.");
}
});
process.stdin.setRawMode(true);