const http = require("node:http"); const fs = require("node:fs"); function akLogMessage(type, message) { console.log(type+": "+message); } const serverOptions = { keepAliveTimeout: 60000 }; function printRequest(req) { console.log(req.connection.remoteAddress); console.log(req.headers); console.log(req.method, req.url); console.log('HTTP/' + req.httpVersion); } function respondError(res, errorMessage) { res.writeHead(404, { 'Content-Type': 'application/json'}); res.end(JSON.stringify({ error: errorMessage })); } function respondJSON(res, hash) { test = /[0-9a-f]{128}/ if(test.test(hash)) { var filename = '../hashes/' + hash; var stat = fs.statSync(filename); res.writeHead(200, { 'Content-Type': 'application/json', 'Content-Length': stat.size}); var readStream = fs.createReadStream(filename); readStream.pipe(res); } else { respondError(res, 'Not found'); } } function testRootRoute(req, res) { notImplemented(req, res); } function testRoute(req, res) { respondError(res, "Mpla mpla"); } function applicationRoutes(req, res, args) { if (args[4] === 'undefined') { respondError(res, 'Bye'); return; } switch(args[3]) { case 'json': respondJSON(res, args[4]); break; default: notImplemented(req, res); } } // Audio returns function respondOGG(res, hash) { test = /[0-9a-f]{128}/ if(test.test(hash)) { var filename = '../hashes/' + hash; var stat = fs.statSync(filename); res.writeHead(200, { 'Content-Type': 'audio/ogg', 'Content-Length': stat.size}); var readStream = fs.createReadStream(filename); readStream.pipe(res); } else { respondError(res, 'Not found'); } } function audioRoutes(req, res, args) { if (args.length < 4 || args[4] === '') { respondError(res, 'No hash'); return; } if (args.length < 3 || args[3] === '') { respondError(res, 'No filetype/extension'); return; } switch(args[3]) { case 'ogg': respondOGG(res, args[4]); break; default: notImplemented(req, res); } } function getLatestList(req, res) { res.writeHead(200, { 'Content-Type': 'application/json'}); res.end(JSON.stringify(JSON.parse(fs.readFileSync('../hashes/list')))); } function getRoutes(req, res) { var args = req.url.split('/'); if (args[1] === 'v0' && args.length > 2 && args[2] !== ""){ switch(args[2]) { case 'test': testRoute(req, res); break; case 'list': getLatestList(req, res); break; case 'application': applicationRoutes(req, res, args); break; case 'audio': audioRoutes(req, res, args); break; default: notImplemented(req, res); } } else { notImplemented(req, res); } } function postRoutes(req, res) { switch(req.url) { default: notImplemented(req, res); } } function notImplemented(req, res) { res.writeHead(404, { 'Content-Type': 'application/json'}); res.end(JSON.stringify({ url: req.url, error: 'not implemented' })); } function optionsHeader(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Request-Method', '*'); res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET'); res.setHeader('Access-Control-Allow-Headers', '*'); if ( req.method === 'OPTIONS' ) { res.writeHead(200); res.end(); } } function processMethod(req, res) { switch(req.method) { case 'GET': getRoutes(req, res); break; case 'POST': postRoutes(req, res); break; case 'OPTIONS': optionsHeader(req, res); break; default: notImplemented(req, res); } } function requestParser(req, res) { printRequest(req); akLogMessage('INFO', `Incoming from [${req.connection.remoteAddress}]:${req.socket._peername.port} @ ${req.headers.host}${req.url}`); res.setHeader('Access-Control-Allow-Origin', '*'); processMethod(req, res); } const server = http.createServer(serverOptions, requestParser); server.listen(8010);