import http from 'http' ; import https from 'https' ; import ip from 'ip' ; import net from 'net' ; import { createSecureContext } from 'tls' ; import configManager from './manager/config-manager' ; import { createCert } from '../lib/cert' ; const plugins = [ ] ; async function httpHandler ( req , resp ) { try { let handled = false ; for ( let i in plugins ) { if ( ! await plugins [ i ] ( req , resp ) ) { handled = true ; break ; } } if ( ! handled ) { resp . writeHead ( 404 , { 'Content-Type' : 'text/plain;charset=utf-8' } ) ; resp . end ( ) ; } } catch ( err ) { console . error ( err ) ; resp . writeHead ( 500 , { 'Content-Type' : 'text/plain;charset=utf-8' } ) ; resp . end ( err . toString ( ) ) ; } } function use ( fn ) { plugins . push ( fn ) ; } const httpServer = http . createServer ( httpHandler ) ; const httpsServerPromise = ( async ( ) => { const serverCrt = await createCert ( ip . address ( ) ) ; return https . createServer ( { async SNICallback ( servername , cb ) { const { cert , key } = await createCert ( servername ) ; cb ( null , createSecureContext ( { cert , key } ) ) ; } , cert : serverCrt . cert , key : serverCrt . key } , httpHandler ) ; } ) ( ) ; async function getHttpsServer ( ) { return await httpsServerPromise ; } async function run ( { httpPort , httpsPort } ) { httpServer . on ( 'connect' , ( req , socket ) => { let proxyPort = httpPort ; const [ , targetPort ] = req . url . split ( ':' ) ; if ( targetPort === '443' ) { proxyPort = httpsPort ; } try { const conn = net . connect ( proxyPort , '127.0.0.1' , ( ) => { socket . write ( 'HTTP/' + req . httpVersion + ' 200 OK\r\n\r\n' , 'UTF-8' , ( ) => { conn . pipe ( socket ) ; socket . pipe ( conn ) ; } ) ; } ) ; } catch ( err ) { console . error ( err ) ; } } ) ; httpServer . listen ( httpPort , '0.0.0.0' , ( ) => { console . log ( `本地代理服务已启动，http_proxy=http://${ ip . address ( ) }:${ httpPort }` ) ; } ) ; ( await getHttpsServer ( ) ) . listen ( httpsPort , '0.0.0.0' , ( ) => { console . log ( `erra管理界面地址，https://${ ip . address ( ) }:${ httpsPort }/erra` ) ; } ) ; } export default { httpServer , getHttpsServer , run , use , isLocalServer ( req ) { return req . headers . host . includes ( `:${ configManager . get ( 'SERVICE_CONFIG' ) . httpsPort }` ) && [ 'localhost' , '127.0.0.1' , '0.0.0.0' , ip . address ( ) ] . some ( ( host ) => req . headers . host . includes ( host ) ) ; } } ;