@@ -113,6 +113,7 @@ export class MockttpServer extends AbstractMockttp implements Mockttp {
113113
114114 private requestRuleSets : { [ priority : number ] : RequestRule [ ] } = { } ;
115115 private webSocketRuleSets : { [ priority : number ] : WebSocketRule [ ] } = { } ;
116+ private rulesNeedResponseTracking : boolean = false ;
116117
117118 private httpsOptions : MockttpHttpsOptions | undefined ;
118119 private isHttp2Enabled : boolean | 'fallback' ;
@@ -287,6 +288,7 @@ export class MockttpServer extends AbstractMockttp implements Mockttp {
287288
288289 const rules = ruleData . map ( ( ruleDatum ) => new RequestRule ( ruleDatum ) ) ;
289290 this . requestRuleSets = _ . groupBy ( rules , r => r . priority ) ;
291+ this . rulesNeedResponseTracking = rules . some ( r => r . needsResponseTracking ) ;
290292
291293 return Promise . resolve ( rules . map ( r => new ServerMockedEndpoint ( r ) ) ) ;
292294 }
@@ -295,6 +297,7 @@ export class MockttpServer extends AbstractMockttp implements Mockttp {
295297 return Promise . resolve ( ruleData . map ( ( ruleDatum ) => {
296298 const rule = new RequestRule ( ruleDatum ) ;
297299 this . addToRuleSets ( this . requestRuleSets , rule ) ;
300+ if ( rule . needsResponseTracking ) this . rulesNeedResponseTracking = true ;
298301 return new ServerMockedEndpoint ( rule ) ;
299302 } ) ) ;
300303 }
@@ -384,6 +387,47 @@ export class MockttpServer extends AbstractMockttp implements Mockttp {
384387 } ) ;
385388 }
386389
390+ private prepareResponse (
391+ rawResponse : http . ServerResponse ,
392+ request : OngoingRequest
393+ ) : { response : OngoingResponse , hasResponseListener : boolean } {
394+ const hasResponseListener = this . eventEmitter . listenerCount ( 'response' ) > 0 ;
395+ const needsResponseTracking = hasResponseListener
396+ || this . eventEmitter . listenerCount ( 'response-initiated' ) > 0
397+ || this . eventEmitter . listenerCount ( 'response-body-data' ) > 0
398+ || this . eventEmitter . listenerCount ( 'abort' ) > 0 // Abort events include response timing data
399+ || this . rulesNeedResponseTracking ;
400+
401+ let response : OngoingResponse ;
402+ if ( needsResponseTracking ) {
403+ response = trackResponse (
404+ rawResponse ,
405+ request . timingEvents ,
406+ request . tags ,
407+ {
408+ maxSize : this . maxBodySize ,
409+ onWriteHead : ( ) => this . announceInitialResponseAsync ( response ) ,
410+ onBodyData : this . eventEmitter . listenerCount ( 'response-body-data' ) > 0
411+ ? this . announceBodyDataAsync . bind ( this , 'response' )
412+ : undefined
413+ }
414+ ) ;
415+ if ( hasResponseListener ) {
416+ // Start buffering response body if there's somebody who
417+ // might want to hear about it later
418+ response . body . asBuffer ( ) . catch ( ( ) => { } ) ;
419+ }
420+ } else {
421+ // When no response-related events are registered, skip the tracking overhead
422+ // (PassThrough stream creation, write/writeHead/end interception)
423+ response = rawResponse as OngoingResponse ;
424+ response . timingEvents = request . timingEvents ;
425+ response . tags = request . tags ;
426+ }
427+
428+ return { response, hasResponseListener } ;
429+ }
430+
387431 private announceInitialRequestAsync ( request : OngoingRequest ) {
388432 if ( this . eventEmitter . listenerCount ( 'request-initiated' ) === 0 ) return ;
389433
@@ -698,24 +742,7 @@ export class MockttpServer extends AbstractMockttp implements Mockttp {
698742
699743 this . announceInitialRequestAsync ( request ) ;
700744
701- const response = trackResponse (
702- rawResponse ,
703- request . timingEvents ,
704- request . tags ,
705- {
706- maxSize : this . maxBodySize ,
707- onWriteHead : ( ) => this . announceInitialResponseAsync ( response ) ,
708- onBodyData : this . eventEmitter . listenerCount ( 'response-body-data' ) > 0
709- ? this . announceBodyDataAsync . bind ( this , 'response' )
710- : undefined
711- }
712- ) ;
713- const hasResponseListener = this . eventEmitter . listenerCount ( 'response' ) > 0 ;
714- if ( hasResponseListener ) {
715- // Start buffering response body if there's somebody who
716- // might want to hear about it later
717- response . body . asBuffer ( ) . catch ( ( ) => { } ) ;
718- }
745+ const { response, hasResponseListener } = this . prepareResponse ( rawResponse , request ) ;
719746
720747 response . id = request . id ;
721748 response . on ( 'error' , ( error ) => {
0 commit comments