Skip to content

Commit a0f3d2b

Browse files
committed
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: 4d93e10#commitcomment-37751035 Backport-PR-URL: #32211
1 parent 28cd36a commit a0f3d2b

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

lib/internal/streams/pipeline.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ function destroyer(stream, reading, writing, final, callback) {
3737
eos(stream, { readable: reading, writable: writing }, (err) => {
3838
if (destroyed) return;
3939
destroyed = true;
40+
41+
if (!err && reading && !writing && stream.writable) {
42+
return callback();
43+
}
44+
4045
const readable = stream.readable || isRequest(stream);
4146
if (err || !final || !readable) {
4247
destroyImpl.destroyer(stream, err);

test/parallel/test-stream-pipeline.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,3 +995,19 @@ const { promisify } = require('util');
995995
assert.strictEqual(res, '');
996996
}));
997997
}
998+
999+
{
1000+
// Might still want to be able to use the writable side
1001+
// of src. This is in the case where e.g. the Duplex input
1002+
// is not directly connected to its output. Such a case could
1003+
// happen when the Duplex is reading from a socket and then echos
1004+
// the data back on the same socket.
1005+
const src = new PassThrough();
1006+
assert.strictEqual(src.writable, true);
1007+
const dst = new PassThrough();
1008+
pipeline(src, dst, common.mustCall((err) => {
1009+
assert.strictEqual(src.writable, true);
1010+
assert.strictEqual(src.destroyed, false);
1011+
}));
1012+
src.push(null);
1013+
}

0 commit comments

Comments
 (0)