diff --git a/README.md b/README.md index 1927748..3be8cd4 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,8 @@ This is the relay server for CrewLink, an Among Us proximity voice chat program. Optional environment variables: - `PORT`: Specifies the port that the server runs on. Defaults to `443` if `HTTPS` is enabled, and `9736` if not. - - `ADDRESS` **(REQUIRED)**: Specifies the server domain - - `NAME`: Specifies the server name + - `ADDRESS` : Specifies the server domain. If not provided, `ADDRESS` is determined automatically (and possibly incorrectly) from HTTP Request headers. + - `NAME`: Specifies the server name. - `HTTPS`: Enables https. You must place `privkey.pem` and `fullchain.pem` in your CWD. - `SSLPATH`: Specifies an alternate path to SSL certificates. diff --git a/src/index.ts b/src/index.ts index 090103a..c33dbd0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -42,25 +42,46 @@ interface Signal { to: string; } -app.set('view engine', 'pug') -app.use(morgan('combined')) +app.set('view engine', 'pug'); +app.use(morgan('combined')); + +// TRUST_PROXY can be used to set which proxies can be trusted based on IP +// address. This is an advanced, undocumented environment variable. +// For more details see: https://expressjs.com/en/guide/behind-proxies.html +app.set('trust proxy', process.env.TRUST_PROXY ?? true ); let connectionCount = 0; let address = process.env.ADDRESS; + +/** + * Derives the address used from ExpressJS Request properties. + * The ExpressJS Request properties for hostname and protocol take into account + * the x-forwarded- parameters, so the resulting address is proxy friendly. + * @param req An HTTPRequest object. + */ +function addressFromRequest(req: express.Request) { + let p = ( 'x-forwarded-port' in req.headers ? req.headers['x-forwarded-port'] : port); + if ( p == '80' || p == '443' ) { + return `${req.protocol}://${req.hostname}`; + } else { + return `${req.protocol}://${req.hostname}:${p}` + } +} + if (!address) { - logger.error('You must set the ADDRESS environment variable.'); - process.exit(1); + logger.info('ADDRESS environment variable not set.'); + logger.info('Advertised server address will be derived from HTTP request headers.'); } -app.get('/', (_, res) => { - res.render('index', { connectionCount, address }); +app.get('/', (req, res) => { + res.render('index', { connectionCount, address: (address || addressFromRequest(req)), headers: req.headers }); }); app.get('/health', (req, res) => { res.json({ uptime: process.uptime(), connectionCount, - address, + address: (address || addressFromRequest(req)), name: process.env.NAME }); }) @@ -168,5 +189,5 @@ io.on('connection', (socket: socketIO.Socket) => { server.listen(port); (async () => { - logger.info('CrewLink Server started: %s', address); -})(); + logger.info('CrewLink Server started: %s', address || '[ADDRESS not set]'); +})(); \ No newline at end of file