diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index 5a83849086294f..d7352565454d89 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -370,18 +370,28 @@ OutgoingMessage.prototype._send = function _send(data, encoding, callback, byteL OutgoingMessage.prototype._writeRaw = _writeRaw; function _writeRaw(data, encoding, callback, size) { + if (typeof encoding === 'function') { + callback = encoding; + encoding = null; + } + + if (this.destroyed) { + if (typeof callback === 'function') { + process.nextTick(callback, new ERR_STREAM_DESTROYED('write')); + } + return false; + } + const conn = this[kSocket]; if (conn?.destroyed) { // The socket was destroyed. If we're still trying to write to it, // then we haven't gotten the 'close' event yet. + if (typeof callback === 'function') { + process.nextTick(callback, new ERR_STREAM_DESTROYED('write')); + } return false; } - if (typeof encoding === 'function') { - callback = encoding; - encoding = null; - } - if (conn && conn._httpMessage === this && conn.writable) { // There might be pending data in the this.output buffer. if (this.outputData.length) { diff --git a/test/parallel/test-http-outgoing-destroy.js b/test/parallel/test-http-outgoing-destroy.js index 47d5e948ab7970..7be803a87c4ce0 100644 --- a/test/parallel/test-http-outgoing-destroy.js +++ b/test/parallel/test-http-outgoing-destroy.js @@ -15,3 +15,23 @@ const OutgoingMessage = http.OutgoingMessage; })); msg.on('error', common.mustNotCall()); } + +{ + const msg = new OutgoingMessage(); + msg.destroy(); + + assert.strictEqual(msg._writeRaw('asd', common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_STREAM_DESTROYED'); + })), false); + msg.on('error', common.mustNotCall()); +} + +{ + const msg = new OutgoingMessage(); + msg.socket = { destroyed: true }; + + assert.strictEqual(msg._writeRaw('asd', common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_STREAM_DESTROYED'); + })), false); + msg.on('error', common.mustNotCall()); +}