import { TlsOptions, Server as TlsServer, createServer as tlsCreateServer, } from 'tls'; import { createLogger } from '@/log'; import { Request } from './request'; import { Response } from './response'; import { Status } from './status'; type Handler = (req: Request, res: Response) => Promise | void; export declare interface Server { on(event: 'request', listener: Handler): this; } const log = createLogger(); export const createServer = ( options: TlsOptions, handler?: Handler, ): TlsServer & Server => { const server = tlsCreateServer( { allowHalfOpen: true, rejectUnauthorized: false, requestCert: true, ...options, }, async (socket) => { log.debug('socket connected'); const response = Response.fromSocket(socket); let request: Request; try { request = await Request.fromSocket(socket); if (handler !== undefined) { handler(request, response); } } catch (error: unknown) { log.error(error); try { response.sendStatus( Status.PERMANENT_FAILURE, error instanceof Error ? error.toString() : '', ); response.end(); } catch (error: unknown) { log.error(error); } return; } server.emit('request', request, response); }, ); server.on('tlsClientError', (error) => { log.error(error.toString()); }); server.on('listening', () => { let address = ''; const serverAddress = server.address(); if (serverAddress !== null) { if (typeof serverAddress === 'string') { address = serverAddress; } else { address = `${serverAddress.address}:${serverAddress.port}`; } } log.info(`listening on ${address}`); }); return server; }; process.on('uncaughtException', (error) => { log.error(error); });