From 2bfb3403ed5d996fc0faf0f0b13a30b6e219e21f Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Wed, 11 Mar 2020 13:56:24 +0100 Subject: [PATCH] stream: avoid destroying writable source User might still want to be able to use the writable side of src. This is in the case where e.g. the Duplex input is not directly connected to its output. Such a case could happen when the Duplex is reading from a socket and then echos the data back on the same socket. PR-URL: https://github.com/nodejs/node/pull/32198 Refs: https://github.com/nodejs/node/commit/4d93e105bfad79ff6c6f01e4b7c2fdd70caeb43b#commitcomment-37751035 Reviewed-By: James M Snell Reviewed-By: Matteo Collina --- lib/internal/streams/pipeline.js | 4 ++++ test/parallel/test-stream-pipeline.js | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/internal/streams/pipeline.js b/lib/internal/streams/pipeline.js index a446d5792e64bc..51bd99b654f23d 100644 --- a/lib/internal/streams/pipeline.js +++ b/lib/internal/streams/pipeline.js @@ -50,6 +50,10 @@ function destroyer(stream, reading, writing, final, callback) { return callback(); } + if (!err && reading && !writing && stream.writable) { + return callback(); + } + if (err || !final || !stream.readable) { destroyImpl.destroyer(stream, err); } diff --git a/test/parallel/test-stream-pipeline.js b/test/parallel/test-stream-pipeline.js index 6629e749238bda..d4f7f147ee362f 100644 --- a/test/parallel/test-stream-pipeline.js +++ b/test/parallel/test-stream-pipeline.js @@ -1032,3 +1032,19 @@ const { promisify } = require('util'); req.on('error', common.mustNotCall()); }); } + +{ + // Might still want to be able to use the writable side + // of src. This is in the case where e.g. the Duplex input + // is not directly connected to its output. Such a case could + // happen when the Duplex is reading from a socket and then echos + // the data back on the same socket. + const src = new PassThrough(); + assert.strictEqual(src.writable, true); + const dst = new PassThrough(); + pipeline(src, dst, common.mustCall((err) => { + assert.strictEqual(src.writable, true); + assert.strictEqual(src.destroyed, false); + })); + src.push(null); +}