Skip to content

Commit abae61e

Browse files
ronagdanielleadams
authored andcommitted
stream: finished waits for 'close' on OutgoingMessage
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]>
1 parent cc37ff2 commit abae61e

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

lib/internal/streams/end-of-stream.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ function isRequest(stream) {
1313
return stream.setHeader && typeof stream.abort === 'function';
1414
}
1515

16+
function isServerResponse(stream) {
17+
return (
18+
typeof stream._sent100 === 'boolean' &&
19+
typeof stream._removedConnection === 'boolean' &&
20+
typeof stream._removedContLen === 'boolean' &&
21+
typeof stream._removedTE === 'boolean' &&
22+
typeof stream._closed === 'boolean'
23+
);
24+
}
25+
1626
function isReadable(stream) {
1727
return typeof stream.readable === 'boolean' ||
1828
typeof stream.readableEnded === 'boolean' ||
@@ -72,7 +82,7 @@ function eos(stream, options, callback) {
7282
// TODO (ronag): Improve soft detection to include core modules and
7383
// common ecosystem modules that do properly emit 'close' but fail
7484
// this generic check.
75-
let willEmitClose = (
85+
let willEmitClose = isServerResponse(stream) || (
7686
state &&
7787
state.autoDestroy &&
7888
state.emitClose &&
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
const common = require('../common');
3+
const { finished } = require('stream');
4+
5+
const http = require('http');
6+
const assert = require('assert');
7+
8+
const server = http.createServer(function(req, res) {
9+
let closed = false;
10+
res
11+
.on('close', common.mustCall(() => {
12+
closed = true;
13+
finished(res, common.mustCall(() => {
14+
server.close();
15+
}));
16+
}))
17+
.end();
18+
finished(res, common.mustCall(() => {
19+
assert.strictEqual(closed, true);
20+
}));
21+
22+
}).listen(0, function() {
23+
http
24+
.request({
25+
port: this.address().port,
26+
method: 'GET'
27+
})
28+
.on('response', function(res) {
29+
res.resume();
30+
})
31+
.end();
32+
});

0 commit comments

Comments
 (0)