Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4638c68

Browse files
mcollinaStephen Belanger
authored and
Stephen Belanger
committedSep 21, 2017
http: revert #14024 writable is never set to false
Setting writable = false in IncomingMessage.end made some errors being swallowed in some very popular OSS libraries that we must support. This commit add some of those use cases to the tests, so we avoid further regressions. We should reevaluate how to set writable = false in IncomingMessage in a way that does not break the ecosystem. See: nodejs/node#14024 Fixes: nodejs/node#15029 PR-URL: nodejs/node#15404 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent de55d51 commit 4638c68

4 files changed

+50
-8
lines changed
 

‎lib/_http_outgoing.js

-1
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,6 @@ OutgoingMessage.prototype.end = function end(chunk, encoding, callback) {
780780
this.connection.uncork();
781781

782782
this.finished = true;
783-
this.writable = false;
784783

785784
// There is the first message on the outgoing queue, and we've sent
786785
// everything to the socket.

‎test/parallel/test-http-outgoing-finish-writable.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@ const assert = require('assert');
44
const http = require('http');
55

66
// Verify that after calling end() on an `OutgoingMessage` (or a type that
7-
// inherits from `OutgoingMessage`), its `writable` property is set to false.
7+
// inherits from `OutgoingMessage`), its `writable` property is not set to false
88

99
const server = http.createServer(common.mustCall(function(req, res) {
1010
assert.strictEqual(res.writable, true);
1111
assert.strictEqual(res.finished, false);
1212
res.end();
13-
assert.strictEqual(res.writable, false);
13+
14+
// res.writable is set to false after it has finished sending
15+
// Ref: https://github.com/nodejs/node/issues/15029
16+
assert.strictEqual(res.writable, true);
1417
assert.strictEqual(res.finished, true);
1518

1619
server.close();
@@ -27,5 +30,9 @@ server.on('listening', common.mustCall(function() {
2730

2831
assert.strictEqual(clientRequest.writable, true);
2932
clientRequest.end();
30-
assert.strictEqual(clientRequest.writable, false);
33+
34+
// writable is still true when close
35+
// THIS IS LEGACY, we cannot change it
36+
// unless we break error detection
37+
assert.strictEqual(clientRequest.writable, true);
3138
}));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const { get, createServer } = require('http');
6+
7+
// res.writable should not be set to false after it has finished sending
8+
// Ref: https://github.com/nodejs/node/issues/15029
9+
10+
let external;
11+
12+
// Http server
13+
const internal = createServer((req, res) => {
14+
res.writeHead(200);
15+
setImmediate(common.mustCall(() => {
16+
external.abort();
17+
res.end('Hello World\n');
18+
}));
19+
}).listen(0);
20+
21+
// Proxy server
22+
const server = createServer(common.mustCall((req, res) => {
23+
get(`http://127.0.0.1:${internal.address().port}`, common.mustCall((inner) => {
24+
res.on('close', common.mustCall(() => {
25+
assert.strictEqual(res.writable, true);
26+
}));
27+
inner.pipe(res);
28+
}));
29+
})).listen(0, () => {
30+
external = get(`http://127.0.0.1:${server.address().port}`);
31+
external.on('error', common.mustCall((err) => {
32+
server.close();
33+
internal.close();
34+
}));
35+
});

‎test/parallel/test-pipe-outgoing-message-data-emitted-after-ended.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
'use strict';
22
const common = require('../common');
33
const http = require('http');
4+
const assert = require('assert');
45
const util = require('util');
56
const stream = require('stream');
67

78
// Verify that when piping a stream to an `OutgoingMessage` (or a type that
89
// inherits from `OutgoingMessage`), if data is emitted after the
9-
// `OutgoingMessage` was closed - no `write after end` error is raised (this
10-
// should be the case when piping - when writing data directly to the
11-
// `OutgoingMessage` this error should be raised).
10+
// `OutgoingMessage` was closed - a `write after end` error is raised
1211

1312
function MyStream() {
1413
stream.call(this);
@@ -22,8 +21,10 @@ const server = http.createServer(common.mustCall(function(req, res) {
2221
process.nextTick(common.mustCall(() => {
2322
res.end();
2423
myStream.emit('data', 'some data');
24+
res.on('error', common.mustCall(function(err) {
25+
assert.strictEqual(err.message, 'write after end');
26+
}));
2527

26-
// If we got here - 'write after end' wasn't raised and the test passed.
2728
process.nextTick(common.mustCall(() => server.close()));
2829
}));
2930
}));

0 commit comments

Comments
 (0)
Please sign in to comment.