optimized api setup and handling

This commit is contained in:
Daniel Sommer 2022-03-18 13:26:51 +01:00
parent 797c32d5c6
commit 739c52fc84
2 changed files with 45 additions and 40 deletions

View file

@ -10,7 +10,7 @@
"api": [ "api": [
{ {
"url": "/tail", "url": "/tail",
"type": "get", "method": "get",
"command": "tail", "command": "tail",
"args": [ "args": [
"-f", "/tmp/test" "-f", "/tmp/test"
@ -19,7 +19,7 @@
}, },
{ {
"url": "/uptime", "url": "/uptime",
"type": "get", "method": "get",
"command": "uptime", "command": "uptime",
"args": [ "args": [
] ]

View file

@ -1,6 +1,7 @@
const logger = require('./logger.js'); const logger = require('./logger.js');
const commands = require('./commands.js'); const commands = require('./commands.js');
const http = require('http'); const http = require('http');
const { config } = require('process');
let server; let server;
let api; let api;
@ -15,7 +16,7 @@ async function start() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
server.listen(port, listen) server.listen(port, listen)
.on('listening', function () { .on('listening', function () {
logger.debug('server listening on ' + config.server.listen + ':' + config.server.port + '...'); logger.info('server listening on ' + global.config.server.listen + ':' + global.config.server.port + '...');
handleRequests(); handleRequests();
resolve(); resolve();
}); });
@ -25,46 +26,42 @@ async function start() {
function handleRequests() { function handleRequests() {
server.on('request', (request, response) => { server.on('request', (request, response) => {
request.timestamp = new Date().getTime(); request.timestamp = new Date().getTime();
respond(request, response, api.get(request.url)); respond(request, response);
}); });
} }
async function respond(request, response, endpoint) { async function respond(request, response) {
if (request === undefined || response === undefined) {
return;
}
let endpoint = api[request.method]?.[request.url];
if (endpoint === undefined) {
return finishRequest(request, response, { error: 'endpoint not defined' }, 501);
}
try {
endpoint.result = await commands.execute(endpoint);
} catch (err) {
endpoint.error = err.toString();
return finishRequest(request, response, endpoint, 501);
}
return finishRequest(request, response, endpoint);
}
function finishRequest(request, response, data, code) {
if (response === undefined) { if (response === undefined) {
return; return;
} }
let data = { if (code === undefined) {
status: 'ok', code = 200;
command: endpoint.command,
args: endpoint.args
};
if (endpoint.detached === true) {
data.detached = true;
} }
let code = 200; if (code === 200) {
if (endpoint === undefined) { data.status = 'ok';
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 { } else {
try {
const result = await commands.execute(endpoint);
if (result !== undefined) {
data.result = result;
}
} catch (err) {
code = 501;
data.status = 'error'; data.status = 'error';
data.msg = err.toString();
} }
} data.time = (new Date().getTime() - request.timestamp) + 'ms';
data.time = new Date().getTime() - request.timestamp + 'ms';
const json = JSON.stringify(data);
response.writeHead(code); response.writeHead(code);
const json = JSON.stringify(data);
response.end(json); response.end(json);
logger.http({ request: request, code: code, data: json }); logger.http({ request: request, code: code, data: json });
} }
@ -74,13 +71,21 @@ function setupAPI() {
if (apiConfig === undefined || apiConfig.length === 0) { if (apiConfig === undefined || apiConfig.length === 0) {
throw new Error('no api endpoints configured - aborting'); throw new Error('no api endpoints configured - aborting');
} }
api = new Map(); const now = new Date().getTime();
config.api.forEach(function (endpoint) { api = {};
let url = endpoint.url; logger.debug('setting up api...');
let tmp = endpoint; let index;
delete tmp.url; for (index = 0; index < global.config.api.length; index++) {
api.set(url, tmp); let endpoint = global.config.api[index];
}); let key = endpoint.url;
let method = endpoint.method.toUpperCase();
delete endpoint.method;
delete endpoint.url;
let methodApi = api[method] || {};
methodApi[key] = endpoint;
api[method] = methodApi;
}
logger.debug('api setup with ' + index + ' endpoints after ' + (new Date().getTime() - now) + 'ms');
} }
module.exports = { module.exports = {