const logger = require('./logger.js'); const commands = require('./commands.js'); const http = require('http'); let server; let api; async function start() { const listen = global.config?.server?.listen || '0.0.0.0'; const port = global.config?.server?.port; setupAPI(); if (server === undefined) { server = http.createServer(); } return new Promise((resolve, reject) => { server.listen(port, listen) .on('listening', function () { logger.debug('server listening on ' + config.server.listen + ':' + config.server.port + '...'); handleRequests(); resolve(); }); }); } function handleRequests() { server.on('request', (request, response) => { request.timestamp = new Date().getTime(); respond(request, response, api.get(request.url)); }); } async function respond(request, response, endpoint) { if (response === undefined) { return; } let data = { status: 'ok', command: endpoint.command, args: endpoint.args }; if (endpoint.detached === true) { data.detached = true; } let code = 200; if (endpoint === undefined) { code = 501; data.status = 'error'; data.msg = 'endpoint not defined'; } else if (request.method.toLowerCase() !== (endpoint.type.toLowerCase())) { code = 405; data.status = 'error'; data.msg = 'endpoint does not support ' + request.method + ' requests'; } else { try { const result = await commands.execute(endpoint); if (result !== undefined) { data.result = result; } } catch (err) { code = 501; data.status = 'error'; data.msg = err.toString(); } } data.time = new Date().getTime() - request.timestamp + 'ms'; const json = JSON.stringify(data); response.writeHead(code); response.end(json); logger.http({ request: request, code: code, data: json }); } function setupAPI() { const apiConfig = global.config?.api; if (apiConfig === undefined || apiConfig.length === 0) { throw new Error('no api endpoints configured - aborting'); } api = new Map(); config.api.forEach(function (endpoint) { let url = endpoint.url; let tmp = endpoint; delete tmp.url; api.set(url, tmp); }); } module.exports = { start }