import type * as express from 'express' ; import type { Options } from './types' ; import type * as httpProxy from 'http-proxy' ; import { getInstance } from './logger' ; const logger = getInstance ( ) ; export function init ( proxy , option ) { const handlers = getHandlers ( option ) ; for ( const eventName of Object . keys ( handlers ) ) { proxy . on ( eventName , handlers [ eventName ] ) ; } logger . debug ( '[HPM] Subscribed to http-proxy events:' , Object . keys ( handlers ) ) ; } type HttpProxyEventName = 'error' | 'proxyReq' | 'proxyReqWs' | 'proxyRes' | 'open' | 'close' ; export function getHandlers ( options ) { const proxyEventsMap = { error : 'onError' , proxyReq : 'onProxyReq' , proxyReqWs : 'onProxyReqWs' , proxyRes : 'onProxyRes' , open : 'onOpen' , close : 'onClose' , } ; const handlers = { } ; for ( const [ eventName , onEventName ] of Object . entries ( proxyEventsMap ) ) { const fnHandler = options ? options [ onEventName ] : null ; if ( typeof fnHandler === 'function' ) { handlers [ eventName ] = fnHandler ; } } if ( typeof handlers . error !== 'function' ) { handlers . error = defaultErrorHandler ; } if ( typeof handlers . close !== 'function' ) { handlers . close = logClose ; } return handlers ; } function defaultErrorHandler ( err , req , res ) { if ( ! req && ! res ) { throw err ; } const host = req . headers && req . headers . host ; const code = err . code ; if ( res . writeHead && ! res . headersSent ) { if ( /HPE_INVALID/ . test ( code ) ) { res . writeHead ( 502 ) ; } else { switch ( code ) { case 'ECONNRESET' : case 'ENOTFOUND' : case 'ECONNREFUSED' : case 'ETIMEDOUT' : res . writeHead ( 504 ) ; break ; default : res . writeHead ( 500 ) ; } } } res . end ( `Error occurred while trying to proxy: ${ host }${ req . url }` ) ; } function logClose ( req , socket , head ) { logger . info ( '[HPM] Client disconnected' ) ; }