diff --git a/core/packages/teeny-request/src/index.ts b/core/packages/teeny-request/src/index.ts index 931861ad798c..8de26e72f3f0 100644 --- a/core/packages/teeny-request/src/index.ts +++ b/core/packages/teeny-request/src/index.ts @@ -276,13 +276,19 @@ function teenyRequest( const requestStream = streamEvents(new PassThrough()); // eslint-disable-next-line @typescript-eslint/no-explicit-any let responseStream: any; + const pipeResponseStream = () => { + if (requestStream.destroyed) { + responseStream.destroy(); + return; + } + + pipeline(responseStream, requestStream, () => {}); + }; requestStream.once('reading', () => { if (responseStream) { - pipeline(responseStream, requestStream, () => {}); + pipeResponseStream(); } else { - requestStream.once('response', () => { - pipeline(responseStream, requestStream, () => {}); - }); + requestStream.once('response', pipeResponseStream); } }); options.compress = false; diff --git a/core/packages/teeny-request/test/index.ts b/core/packages/teeny-request/test/index.ts index e34d697a2a58..abd047c98eba 100644 --- a/core/packages/teeny-request/test/index.ts +++ b/core/packages/teeny-request/test/index.ts @@ -275,6 +275,23 @@ describe('teeny', () => { }); }); + it('should discard the response if the request stream is destroyed before piping', async () => { + const scope = mockJson(); + const stream = teenyRequest({uri}); + const responseClosed = new Promise((resolve, reject) => { + stream.once('error', reject); + stream.once('response', response => { + response.body.once('error', reject); + response.body.once('close', resolve); + stream.destroy(); + }); + }); + + stream.resume(); + await responseClosed; + scope.done(); + }); + it('should not pipe response stream to user unless they ask for it', async () => { const scope = mockJson(); const stream = teenyRequest({uri}).on('error', err => {