From 7647860000f07a3ed57cc78d92a6e9e6bcc64b58 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Tue, 21 Apr 2020 12:29:37 +0200 Subject: [PATCH] stream: finished should complete with read-only Duplex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If passed a Duplex where readable or writable has been explicitly disabled then don't assume 'close' will be emitted. Fixes: https://github.com/nodejs/node/issues/32965 PR-URL: https://github.com/nodejs/node/pull/32967 Reviewed-By: Matteo Collina Reviewed-By: Mathias Buus Reviewed-By: Rich Trott Reviewed-By: Juan José Arboleda --- lib/internal/streams/end-of-stream.js | 4 +++- test/parallel/test-stream-finished.js | 34 ++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/lib/internal/streams/end-of-stream.js b/lib/internal/streams/end-of-stream.js index 4742391fd71a7a..f1f1b3e5a77877 100644 --- a/lib/internal/streams/end-of-stream.js +++ b/lib/internal/streams/end-of-stream.js @@ -76,7 +76,9 @@ function eos(stream, opts, callback) { state && state.autoDestroy && state.emitClose && - state.closed === false + state.closed === false && + isReadable(stream) === readable && + isWritable(stream) === writable ); let writableFinished = stream.writableFinished || diff --git a/test/parallel/test-stream-finished.js b/test/parallel/test-stream-finished.js index ab35d402e31cfd..17ab976c6136f4 100644 --- a/test/parallel/test-stream-finished.js +++ b/test/parallel/test-stream-finished.js @@ -1,7 +1,7 @@ 'use strict'; const common = require('../common'); -const { Writable, Readable, Transform, finished } = require('stream'); +const { Writable, Readable, Transform, finished, Duplex } = require('stream'); const assert = require('assert'); const EE = require('events'); const fs = require('fs'); @@ -352,3 +352,35 @@ testClosed((opts) => new Writable({ write() {}, ...opts })); r.push(null); r.destroy(); } + +{ + const d = new Duplex({ + final(cb) { }, // Never close writable side for test purpose + read() { + this.push(null); + } + }); + + d.on('end', common.mustCall()); + + finished(d, { readable: true, writable: false }, common.mustCall()); + + d.end(); + d.resume(); +} + +{ + const d = new Duplex({ + final(cb) { }, // Never close writable side for test purpose + read() { + this.push(null); + } + }); + + d.on('end', common.mustCall()); + + d.end(); + finished(d, { readable: true, writable: false }, common.mustCall()); + + d.resume(); +}