blob: 43c3e451375f38663cda60ad648ac502b70e9a47 [file] [log] [blame]
Issam E. Maghni0ef4a362022-10-05 23:20:16 +00001/*
2 * Copyright (C) 2022 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation; either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
13 *
14 * You should have received a copy of the GNU Affero General Public
15 * License along with this program. If not, see
16 * <https://www.gnu.org/licenses/>.
17 */
18import 'reflect-metadata';
19
simon7d4386c2022-10-26 17:47:59 -040020import * as dotenv from 'dotenv';
21dotenv.config();
22
Issam E. Maghni0ef4a362022-10-05 23:20:16 +000023import { createServer } from 'node:http';
24
25import log from 'loglevel';
26import { Container } from 'typedi';
27
Misha Krieger-Raynauld708a9632022-10-14 22:55:59 -040028import { App } from './app.js';
Misha Krieger-Raynauld62a0da92022-10-22 13:46:59 -040029import { Jamid } from './jamid/jamid.js';
Misha Krieger-Raynauldb933fbb2022-11-15 15:11:09 -050030import { SigningKeys } from './storage/signing-keys.js';
31import { WebSocketServer } from './websocket/websocket-server.js';
Issam E. Maghni0ef4a362022-10-05 23:20:16 +000032
33log.setLevel(process.env.NODE_ENV === 'production' ? 'error' : 'trace');
34
Misha Krieger-Raynauld708a9632022-10-14 22:55:59 -040035const port: string | number = 5000;
36
Misha Krieger-Raynauldb933fbb2022-11-15 15:11:09 -050037await Container.get(SigningKeys).build();
Misha Krieger-Raynauld62a0da92022-10-22 13:46:59 -040038const jamid = Container.get(Jamid);
Misha Krieger-Raynauldb933fbb2022-11-15 15:11:09 -050039const app = Container.get(App);
40const webSocketServer = Container.get(WebSocketServer);
Issam E. Maghni0ef4a362022-10-05 23:20:16 +000041
Misha Krieger-Raynauld708a9632022-10-14 22:55:59 -040042const server = createServer();
43
Misha Krieger-Raynauldb933fbb2022-11-15 15:11:09 -050044server.on('request', app.app);
45server.on('upgrade', webSocketServer.upgrade.bind(webSocketServer));
Issam E. Maghni0ef4a362022-10-05 23:20:16 +000046
Misha Krieger-Raynauld708a9632022-10-14 22:55:59 -040047server.listen(port);
48server.on('error', onError);
49server.on('listening', onListening);
Issam E. Maghni0ef4a362022-10-05 23:20:16 +000050
Misha Krieger-Raynauld62a0da92022-10-22 13:46:59 -040051process.once('SIGTERM', shutdown);
52process.once('SIGINT', shutdown);
53process.once('SIGUSR2', shutdown);
54
Misha Krieger-Raynauld708a9632022-10-14 22:55:59 -040055function onError(error: NodeJS.ErrnoException) {
56 if (error.syscall !== 'listen') {
57 throw error;
58 }
59
60 const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port}`;
61
62 switch (error.code) {
63 case 'EACCESS':
64 log.error(bind + ' requires elevated privileges');
65 process.exit(1);
66 break;
67 case 'EADDRINUSE':
68 log.error(bind + ' is already in use');
69 process.exit(1);
70 break;
71 default:
72 throw error;
73 }
74}
75
76function onListening() {
77 const address = server.address();
78 const bind = typeof address === 'string' ? `pipe ${address}` : `port ${address?.port}`;
79 log.debug('Listening on ' + bind);
80}
Misha Krieger-Raynauld62a0da92022-10-22 13:46:59 -040081
82function shutdown(signal: NodeJS.Signals) {
83 log.debug(`${signal} received: shutting down server`);
84 jamid.stop();
85 server.close(() => {
86 log.debug('Server shut down');
87 // Needed in order to actually exit the process as its shutdown is blocked by something else
88 process.exit();
89 });
90}