Skip to content

Commit 0f07abc

Browse files
ronagtargos
authored andcommitted
stream: finish pipeline if dst closes before src
If the destination stream is closed before the source has completed the pipeline should finnish with premature close. Fixes: #43682 PR-URL: #43701 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
1 parent c8cbec4 commit 0f07abc

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

lib/internal/streams/pipeline.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const {
2020
ERR_INVALID_RETURN_VALUE,
2121
ERR_MISSING_ARGS,
2222
ERR_STREAM_DESTROYED,
23+
ERR_STREAM_PREMATURE_CLOSE,
2324
},
2425
AbortError,
2526
} = require('internal/errors');
@@ -344,13 +345,24 @@ function pipelineImpl(streams, callback, opts) {
344345
}
345346

346347
function pipe(src, dst, finish, { end }) {
348+
let ended = false;
349+
dst.on('close', () => {
350+
if (!ended) {
351+
// Finish if the destination closes before the source has completed.
352+
finish(new ERR_STREAM_PREMATURE_CLOSE());
353+
}
354+
});
355+
347356
src.pipe(dst, { end });
348357

349358
if (end) {
350359
// Compat. Before node v10.12.0 stdio used to throw an error so
351360
// pipe() did/does not end() stdio destinations.
352361
// Now they allow it but "secretly" don't close the underlying fd.
353-
src.once('end', () => dst.end());
362+
src.once('end', () => {
363+
ended = true;
364+
dst.end();
365+
});
354366
} else {
355367
finish();
356368
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const { pipeline, Duplex, PassThrough } = require('stream');
5+
const assert = require('assert');
6+
7+
const remote = new PassThrough();
8+
const local = new Duplex({
9+
read() {},
10+
write(chunk, enc, callback) {
11+
callback();
12+
}
13+
});
14+
15+
pipeline(remote, local, remote, common.mustCall((err) => {
16+
assert.strictEqual(err.code, 'ERR_STREAM_PREMATURE_CLOSE');
17+
}));
18+
19+
setImmediate(() => {
20+
remote.end();
21+
});

0 commit comments

Comments
 (0)