@@ -286,6 +286,17 @@ export class MockHttpSocket extends MockSocket {
286286 } )
287287 }
288288
289+ let passthroughReadableEnded = false
290+ let passthroughCloseEmitted = false
291+ const emitPassthroughCloseOnce = ( hadError : boolean ) => {
292+ if ( passthroughCloseEmitted ) {
293+ return
294+ }
295+
296+ passthroughCloseEmitted = true
297+ this . emit ( 'close' , hadError )
298+ }
299+
289300 socket
290301 . on ( 'lookup' , ( ...args ) => this . emit ( 'lookup' , ...args ) )
291302 . on ( 'connect' , ( ) => {
@@ -311,8 +322,21 @@ export class MockHttpSocket extends MockSocket {
311322 . on ( 'timeout' , ( ) => this . emit ( 'timeout' ) )
312323 . on ( 'prefinish' , ( ) => this . emit ( 'prefinish' ) )
313324 . on ( 'finish' , ( ) => this . emit ( 'finish' ) )
314- . on ( 'close' , ( hadError ) => this . emit ( 'close' , hadError ) )
315- . on ( 'end' , ( ) => this . emit ( 'end' ) )
325+ . on ( 'close' , ( hadError ) => {
326+ if ( hadError || ! passthroughReadableEnded || this . readableEnded ) {
327+ emitPassthroughCloseOnce ( hadError )
328+ return
329+ }
330+
331+ // Node's HTTP client expects the response readable side to end before
332+ // the socket closes. The original socket can close before the pushed
333+ // EOF surfaces on this socket, so defer "close" to avoid an abort.
334+ this . once ( 'end' , ( ) => emitPassthroughCloseOnce ( hadError ) )
335+ } )
336+ . on ( 'end' , ( ) => {
337+ passthroughReadableEnded = true
338+ this . push ( null )
339+ } )
316340 }
317341
318342 /**
0 commit comments