import { EventEmitter } from 'events'; import { Logger } from '@cirrusct/logging'; import { WebServerStartupOptions, HttpServerInstances, HttpServerInstance, HttpServerProtocolType, Polka, } from './types'; import { get } from 'lodash'; import { createServer as createHttpsServer, ServerOptions as HttpsServerOptions } from 'https'; import { Server as NodeHttpServer, createServer as createHttpServer } from 'http'; export class HttpServerInstanceManager { private _eventEmitter: EventEmitter = new EventEmitter(); private _instances: HttpServerInstances = {}; constructor( private polka: Polka, private startupConfig: WebServerStartupOptions, private logger: Logger, private httpsOptions?: HttpsServerOptions ) { // support http, https, and http2 (http2 should mostly work, essentially uses https options) // this server hosts 0 or 1 instances per protocol as defined in config this.initInstances(); } public get instances(): HttpServerInstances { return this._instances; } private createServer = (protocol: HttpServerProtocolType, httpsOptions?: HttpsServerOptions) => { switch (protocol) { case 'http': // if (!this.polka.server) { // this.polka.server = createHttpServer() // } // return this.polka.server; return createHttpServer(this.polka.handler); case 'https': return createHttpsServer(httpsOptions, this.polka.handler); default: throw new Error(`Unsupported Server Protocol: ${protocol}`); } }; private initInstances = () => { for (const protocol in this.startupConfig) { if (get(this.startupConfig, [protocol, 'enabled'], true)) { let port = get(this.startupConfig, [protocol, 'port']); if (!port) { throw new Error(`Startup Config for Protocol ${protocol} does not specify port`); } else { port = parseInt(port); } const server = this.createServer(protocol as HttpServerProtocolType); this._instances[protocol] = { protocol: protocol, server: server, port: port, }; } } }; public start() { for (const protocol in this.instances) { const instance = this.instances[protocol]; const server: NodeHttpServer = instance.server; //if (['http', 'https'].indexOf(protocol) >= 0) { // server.on('listening', () => { // }); //} server.listen(instance.port, () => { this.emitOnListening(instance); }); //server.on('error', e => { // console.error('listen error', e.stack); //}); //server.on('close', () => { // console.error('listen server closed'); //}); } } private emitOnListening = (instance: HttpServerInstance) => { this._eventEmitter.emit('listening', instance); }; public onListening = (listener: (instance: HttpServerInstance) => void) => { this._eventEmitter.on('listening', listener); }; }