Skip to content

Commit

Permalink
stream: finished waits for 'close' on OutgoingMessage
Browse files Browse the repository at this point in the history
Don't invoke finished callback until OutgoingMessagehas
emitted 'close'.

PR-URL: #36648
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: James M Snell <[email protected]>
  • Loading branch information
ronag authored and danielleadams committed Jan 12, 2021
1 parent cc37ff2 commit abae61e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
12 changes: 11 additions & 1 deletion lib/internal/streams/end-of-stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ function isRequest(stream) {
return stream.setHeader && typeof stream.abort === 'function';
}

function isServerResponse(stream) {
return (
typeof stream._sent100 === 'boolean' &&
typeof stream._removedConnection === 'boolean' &&
typeof stream._removedContLen === 'boolean' &&
typeof stream._removedTE === 'boolean' &&
typeof stream._closed === 'boolean'
);
}

function isReadable(stream) {
return typeof stream.readable === 'boolean' ||
typeof stream.readableEnded === 'boolean' ||
Expand Down Expand Up @@ -72,7 +82,7 @@ function eos(stream, options, callback) {
// TODO (ronag): Improve soft detection to include core modules and
// common ecosystem modules that do properly emit 'close' but fail
// this generic check.
let willEmitClose = (
let willEmitClose = isServerResponse(stream) || (
state &&
state.autoDestroy &&
state.emitClose &&
Expand Down
32 changes: 32 additions & 0 deletions test/parallel/test-http-outgoing-finished.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict';
const common = require('../common');
const { finished } = require('stream');

const http = require('http');
const assert = require('assert');

const server = http.createServer(function(req, res) {
let closed = false;
res
.on('close', common.mustCall(() => {
closed = true;
finished(res, common.mustCall(() => {
server.close();
}));
}))
.end();
finished(res, common.mustCall(() => {
assert.strictEqual(closed, true);
}));

}).listen(0, function() {
http
.request({
port: this.address().port,
method: 'GET'
})
.on('response', function(res) {
res.resume();
})
.end();
});

0 comments on commit abae61e

Please sign in to comment.