Skip to content

Commit

Permalink
http: OutgoingMessage change writable after end
Browse files Browse the repository at this point in the history
When an OutgoingMessage is closed (for example, using the `end`
method), its 'writable' property should be changed to false - since it
is not writable anymore. The 'writable' property should have the
opposite value of the 'finished' property.

PR-URL: #14024
Fixes: #14023
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
  • Loading branch information
Kasher authored and MylesBorins committed Aug 16, 2017
1 parent f766d35 commit 0230a35
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,7 @@ OutgoingMessage.prototype.end = function(data, encoding, callback) {
this.connection.uncork();

this.finished = true;
this.writable = false;

// There is the first message on the outgoing queue, and we've sent
// everything to the socket.
Expand Down
31 changes: 31 additions & 0 deletions test/parallel/test-http-outgoing-finish-writable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');

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

const server = http.createServer(common.mustCall(function(req, res) {
assert.strictEqual(res.writable, true);
assert.strictEqual(res.finished, false);
res.end();
assert.strictEqual(res.writable, false);
assert.strictEqual(res.finished, true);

server.close();
}));

server.listen(0);

server.on('listening', common.mustCall(function() {
const clientRequest = http.request({
port: server.address().port,
method: 'GET',
path: '/'
});

assert.strictEqual(clientRequest.writable, true);
clientRequest.end();
assert.strictEqual(clientRequest.writable, false);
}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict';
const common = require('../common');
const http = require('http');
const util = require('util');
const stream = require('stream');

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

function MyStream() {
stream.call(this);
}
util.inherits(MyStream, stream);

const server = http.createServer(common.mustCall(function(req, res) {
const myStream = new MyStream();
myStream.pipe(res);

process.nextTick(common.mustCall(() => {
res.end();
myStream.emit('data', 'some data');

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

server.listen(0);

server.on('listening', common.mustCall(function() {
http.request({
port: server.address().port,
method: 'GET',
path: '/'
}).end();
}));

0 comments on commit 0230a35

Please sign in to comment.