import debug from "debug" ; import { ClientRequest , IncomingMessage , RequestOptions , ServerResponse , } from "http" ; import Mitm = require ( "mitm" ) ; import * as net from "net" ; import { ISerializedRequest , ISerializedResponse } from "unmock-core" ; import { IInterceptor , IInterceptorOptions , } from "unmock-core/dist/interceptor" ; import { serializeRequest } from "../serialize" ; import ClientRequestTracker from "./client-request-tracker" ; const debugLog = debug ( "unmock:node-interceptor" ) ; const respondFromSerializedResponse = ( serializedResponse , res ) => { res . writeHead ( serializedResponse . statusCode , serializedResponse . headers ) ; res . end ( serializedResponse . body ) ; } ; interface IBypassableSocket extends net . Socket { bypass : ( ) => void ; } param options class NodeInterceptor implements IInterceptor { private mitm : any ; param config constructor ( public readonly config ) { this . initialize ( config . shouldBypassHost ) ; } /**
     * Disable interceptor.
     */ public disable ( ) { if ( this . mitm ) { this . mitm . disable ( ) ; this . mitm = undefined ; } ClientRequestTracker . stop ( ) ; } private initialize ( shouldBypass ) { if ( this . mitm !== undefined ) { this . disable ( ) ; } this . mitm = Mitm ( ) ; this . mitm . on ( "connect" , ( socket , opts ) => { if ( shouldBypass ( opts . host || "" ) ) { socket . bypass ( ) ; } } ) ; ClientRequestTracker . start ( ) ; this . mitm . on ( "request" , async ( req , res ) => { debugLog ( "Handling incoming message..." ) ; req . on ( "error" , ( e ) => debugLog ( "Error on intercepted request:" , e ) ) ; req . on ( "abort" , ( ) => debugLog ( "Intercepted request aborted" ) ) ; const clientRequest = ClientRequestTracker . pop ( req ) ; let serializedRequest ; try { serializedRequest = await serializeRequest ( req ) ; } catch ( err ) { debugLog ( `Failed serializing request` ) ; clientRequest . emit ( "error" , err ) ; return ; } setImmediate ( ( ) => this . config . onSerializedRequest ( serializedRequest , ( serializedResponse ) => respondFromSerializedResponse ( serializedResponse , res ) , ( err ) => clientRequest . emit ( "error" , err ) ) ) ; } ) ; } } export default NodeInterceptor ;