import zlib from 'zlib' ; import { ClientRequest , IncomingMessage } from 'http' ; import { HandlerFunction } from 'got-cjs' ; import { PassThrough , Transform } from 'stream' ; import mimicResponse from 'mimic-response' ; const onResponse = ( response , propagate ) => { const encoding = response . headers [ 'content-encoding' ] ?. toLowerCase ( ) ; const zlibOptions = { flush : zlib . constants . Z_SYNC_FLUSH , finishFlush : zlib . constants . Z_SYNC_FLUSH , } ; const useDecompressor = ( decompressor ) => { delete response . headers [ 'content-encoding' ] ; const result = new PassThrough ( { autoDestroy : false , destroy ( error , callback ) { response . destroy ( ) ; callback ( error ) ; } , } ) ; decompressor . once ( 'error' , ( error ) => { result . destroy ( error ) ; } ) ; response . pipe ( decompressor ) . pipe ( result ) ; propagate ( mimicResponse ( response , result ) ) ; } ; if ( encoding === 'gzip' || encoding === 'x-gzip' ) { useDecompressor ( zlib . createGunzip ( zlibOptions ) ) ; } else if ( encoding === 'deflate' || encoding === 'x-deflate' ) { let read = false ; response . once ( 'data' , ( chunk ) => { read = true ; response . unshift ( chunk ) ; const decompressor = ( chunk [ 0 ] & 0x0F ) === 0x08 ? zlib . createInflate ( ) : zlib . createInflateRaw ( ) ; useDecompressor ( decompressor ) ; } ) ; response . once ( 'end' , ( ) => { if ( ! read ) { propagate ( response ) ; } } ) ; } else if ( encoding === 'br' ) { useDecompressor ( zlib . createBrotliDecompress ( ) ) ; } else { propagate ( response ) ; } } ; export const fixDecompress = ( options , next ) => { const result = next ( options ) ; result . on ( 'request' , ( request ) => { const emit = request . emit . bind ( request ) ; request . emit = ( event , ... args ) => { if ( event === 'response' && options . decompress ) { const response = args [ 0 ] as IncomingMessage ; const emitted = request . listenerCount ( 'response' ) !== 0 ; onResponse ( response , ( fixedResponse ) => { emit ( 'response' , fixedResponse ) ; } ) ; return emitted ; } return emit ( event , ... args ) ; } ; } ) ; return result ; } ;