UNPKG

camstreamerlib

Version:

Helper library for CamStreamer ACAP applications.

93 lines (92 loc) 3.3 kB
import http from 'http'; import url from 'url'; import fs from 'fs'; import path from 'path'; import EventEmitter from 'events'; export class HttpServer extends EventEmitter { host; port; registeredPaths; server; sockets; constructor(options) { super(); this.host = options?.host ?? process.env.HTTP_HOST ?? '0.0.0.0'; this.port = options?.port ?? parseInt(process.env.HTTP_PORT ?? '80'); this.registeredPaths = new Map(); this.server = http.createServer((req, res) => { this.emit('access', req.method + ' ' + req.url); const parsedUrl = url.parse(req.url ?? ''); parsedUrl.pathname ??= ''; const requestCallback = this.registeredPaths.get(parsedUrl.pathname); if (requestCallback) { requestCallback(req, res); return; } let pathname = `./html${parsedUrl.pathname}`; const ext = path.parse(pathname).ext; const map = { '.ico': 'image/x-icon', '.html': 'text/html', '.js': 'text/javascript', '.json': 'application/json', '.css': 'text/css', '.png': 'image/png', '.jpg': 'image/jpeg', '.wav': 'audio/wav', '.mp3': 'audio/mpeg', '.svg': 'image/svg+xml', '.pdf': 'application/pdf', '.doc': 'application/msword', }; fs.access(pathname, fs.constants.R_OK, (err) => { if (err) { res.statusCode = 404; res.end(`File ${pathname} not found!`); this.emit('error', `File ${pathname} not found!`); return; } if (fs.statSync(pathname).isDirectory()) { pathname += `/index${ext}`; } fs.readFile(pathname, (error, data) => { if (error) { res.statusCode = 500; res.end(`Error getting the file: ${error}`); this.emit('error', `Error getting the file: ${error}`); } else { res.setHeader('Content-type', map[ext] ?? 'text/plain'); res.setHeader('Access-Control-Allow-Origin', '*'); res.end(data); } }); }); }); this.server.on('error', (err) => { this.emit('error', err); }); this.server.listen(this.port, this.host); this.sockets = {}; let idTracker = 0; this.server.on('connection', (socket) => { const socketID = idTracker++; this.sockets[socketID] = socket; socket.on('close', () => { delete this.sockets[socketID]; }); }); } getServer() { return this.server; } onRequest(pathName, callback) { this.registeredPaths.set(pathName, callback); } close() { this.server.close(); for (const key in this.sockets) { this.sockets[key]?.destroy(); } } }