From 5daaddbbf7331f3b75d9c4789b22f6ac93a2c723 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. Fixes: https://github.com/nodejs/node/commit/4d93e105bfad79ff6c6f01e4b7c2fdd70caeb43b#commitcomment-37751035 --- 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); +}