mirror of https://github.com/nodejs/node.git
http: set IncomingMessage.destroyed
IncomingMessage is a Readable stream and should properly set the destroyed property. PR-URL: https://github.com/nodejs/node/pull/33131 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
This commit is contained in:
parent
96faea137e
commit
28e6626ce7
|
@ -422,10 +422,12 @@ function socketCloseListener() {
|
||||||
req.emit('close');
|
req.emit('close');
|
||||||
if (!res.aborted && res.readable) {
|
if (!res.aborted && res.readable) {
|
||||||
res.on('end', function() {
|
res.on('end', function() {
|
||||||
|
this.destroyed = true;
|
||||||
this.emit('close');
|
this.emit('close');
|
||||||
});
|
});
|
||||||
res.push(null);
|
res.push(null);
|
||||||
} else {
|
} else {
|
||||||
|
res.destroyed = true;
|
||||||
res.emit('close');
|
res.emit('close');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -539,6 +541,7 @@ function socketOnData(d) {
|
||||||
socket.readableFlowing = null;
|
socket.readableFlowing = null;
|
||||||
|
|
||||||
req.emit(eventName, res, socket, bodyHead);
|
req.emit(eventName, res, socket, bodyHead);
|
||||||
|
req.destroyed = true;
|
||||||
req.emit('close');
|
req.emit('close');
|
||||||
} else {
|
} else {
|
||||||
// Requested Upgrade or used CONNECT method, but have no handler.
|
// Requested Upgrade or used CONNECT method, but have no handler.
|
||||||
|
@ -710,6 +713,7 @@ function requestOnPrefinish() {
|
||||||
function emitFreeNT(req) {
|
function emitFreeNT(req) {
|
||||||
req.emit('close');
|
req.emit('close');
|
||||||
if (req.res) {
|
if (req.res) {
|
||||||
|
req.res.destroyed = true;
|
||||||
req.res.emit('close');
|
req.res.emit('close');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,8 @@ IncomingMessage.prototype._read = function _read(n) {
|
||||||
// any messages, before ever calling this. In that case, just skip
|
// any messages, before ever calling this. In that case, just skip
|
||||||
// it, since something else is destroying this connection anyway.
|
// it, since something else is destroying this connection anyway.
|
||||||
IncomingMessage.prototype.destroy = function destroy(error) {
|
IncomingMessage.prototype.destroy = function destroy(error) {
|
||||||
|
// TODO(ronag): Implement in terms of _destroy
|
||||||
|
this.destroyed = true;
|
||||||
if (this.socket)
|
if (this.socket)
|
||||||
this.socket.destroy(error);
|
this.socket.destroy(error);
|
||||||
};
|
};
|
||||||
|
|
|
@ -205,7 +205,10 @@ function onServerResponseClose() {
|
||||||
// Ergo, we need to deal with stale 'close' events and handle the case
|
// Ergo, we need to deal with stale 'close' events and handle the case
|
||||||
// where the ServerResponse object has already been deconstructed.
|
// where the ServerResponse object has already been deconstructed.
|
||||||
// Fortunately, that requires only a single if check. :-)
|
// Fortunately, that requires only a single if check. :-)
|
||||||
if (this._httpMessage) this._httpMessage.emit('close');
|
if (this._httpMessage) {
|
||||||
|
this._httpMessage.destroyed = true;
|
||||||
|
this._httpMessage.emit('close');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerResponse.prototype.assignSocket = function assignSocket(socket) {
|
ServerResponse.prototype.assignSocket = function assignSocket(socket) {
|
||||||
|
@ -534,6 +537,7 @@ function abortIncoming(incoming) {
|
||||||
while (incoming.length) {
|
while (incoming.length) {
|
||||||
const req = incoming.shift();
|
const req = incoming.shift();
|
||||||
req.aborted = true;
|
req.aborted = true;
|
||||||
|
req.destroyed = true;
|
||||||
req.emit('aborted');
|
req.emit('aborted');
|
||||||
req.emit('close');
|
req.emit('close');
|
||||||
}
|
}
|
||||||
|
@ -660,11 +664,13 @@ function clearIncoming(req) {
|
||||||
if (parser && parser.incoming === req) {
|
if (parser && parser.incoming === req) {
|
||||||
if (req.readableEnded) {
|
if (req.readableEnded) {
|
||||||
parser.incoming = null;
|
parser.incoming = null;
|
||||||
|
req.destroyed = true;
|
||||||
req.emit('close');
|
req.emit('close');
|
||||||
} else {
|
} else {
|
||||||
req.on('end', clearIncoming);
|
req.on('end', clearIncoming);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
req.destroyed = true;
|
||||||
req.emit('close');
|
req.emit('close');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -708,6 +714,7 @@ function resOnFinish(req, res, socket, state, server) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitCloseNT(self) {
|
function emitCloseNT(self) {
|
||||||
|
self.destroyed = true;
|
||||||
self.emit('close');
|
self.emit('close');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
'use strict';
|
||||||
|
const common = require('../common');
|
||||||
|
const assert = require('assert');
|
||||||
|
const http = require('http');
|
||||||
|
|
||||||
|
{
|
||||||
|
const server = http.createServer(common.mustCall((req, res) => {
|
||||||
|
res.end('asd');
|
||||||
|
}));
|
||||||
|
|
||||||
|
server.listen(0, common.mustCall(() => {
|
||||||
|
http.get({
|
||||||
|
port: server.address().port
|
||||||
|
}, common.mustCall((res) => {
|
||||||
|
assert.strictEqual(res.destroyed, false);
|
||||||
|
res.destroy();
|
||||||
|
assert.strictEqual(res.destroyed, true);
|
||||||
|
res.on('close', common.mustCall(() => {
|
||||||
|
server.close();
|
||||||
|
}));
|
||||||
|
}));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const server = http.createServer(common.mustCall((req, res) => {
|
||||||
|
res.end('asd');
|
||||||
|
}));
|
||||||
|
|
||||||
|
server.listen(0, common.mustCall(() => {
|
||||||
|
http.get({
|
||||||
|
port: server.address().port
|
||||||
|
}, common.mustCall((res) => {
|
||||||
|
assert.strictEqual(res.destroyed, false);
|
||||||
|
res.on('close', common.mustCall(() => {
|
||||||
|
assert.strictEqual(res.destroyed, true);
|
||||||
|
server.close();
|
||||||
|
})).resume();
|
||||||
|
}));
|
||||||
|
}));
|
||||||
|
}
|
|
@ -33,7 +33,10 @@ server.listen(0, common.mustCall(function() {
|
||||||
path: 'example.com:443'
|
path: 'example.com:443'
|
||||||
}, common.mustNotCall());
|
}, common.mustNotCall());
|
||||||
|
|
||||||
req.on('close', common.mustCall());
|
assert.strictEqual(req.destroyed, false);
|
||||||
|
req.on('close', common.mustCall(() => {
|
||||||
|
assert.strictEqual(req.destroyed, true);
|
||||||
|
}));
|
||||||
|
|
||||||
req.on('connect', common.mustCall(function(res, socket, firstBodyChunk) {
|
req.on('connect', common.mustCall(function(res, socket, firstBodyChunk) {
|
||||||
console.error('Client got CONNECT request');
|
console.error('Client got CONNECT request');
|
||||||
|
|
|
@ -62,7 +62,10 @@ server.listen(0, common.mustCall(() => {
|
||||||
assert.strictEqual(socket._httpMessage, req);
|
assert.strictEqual(socket._httpMessage, req);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
req.on('close', common.mustCall());
|
assert.strictEqual(req.destroyed, false);
|
||||||
|
req.on('close', common.mustCall(() => {
|
||||||
|
assert.strictEqual(req.destroyed, true);
|
||||||
|
}));
|
||||||
|
|
||||||
req.on('connect', common.mustCall((res, socket, firstBodyChunk) => {
|
req.on('connect', common.mustCall((res, socket, firstBodyChunk) => {
|
||||||
// Make sure this request got removed from the pool.
|
// Make sure this request got removed from the pool.
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
const common = require('../common');
|
const common = require('../common');
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
const server = http.Server(function(req, res) {
|
const server = http.Server(function(req, res) {
|
||||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||||
|
@ -43,6 +44,12 @@ server.listen(0, common.mustCall(function() {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
res.on('end', common.mustCall());
|
res.on('end', common.mustCall(() => {
|
||||||
|
assert.strictEqual(res.destroyed, false);
|
||||||
|
}));
|
||||||
|
assert.strictEqual(res.destroyed, false);
|
||||||
|
res.on('close', common.mustCall(() => {
|
||||||
|
assert.strictEqual(res.destroyed, true);
|
||||||
|
}));
|
||||||
}));
|
}));
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -8,13 +8,25 @@ const server = http.Server(common.mustCall((req, res) => {
|
||||||
let resClosed = false;
|
let resClosed = false;
|
||||||
|
|
||||||
res.end();
|
res.end();
|
||||||
|
let resFinished = false;
|
||||||
res.on('finish', common.mustCall(() => {
|
res.on('finish', common.mustCall(() => {
|
||||||
|
resFinished = true;
|
||||||
|
assert.strictEqual(resClosed, false);
|
||||||
|
assert.strictEqual(res.destroyed, false);
|
||||||
assert.strictEqual(resClosed, false);
|
assert.strictEqual(resClosed, false);
|
||||||
}));
|
}));
|
||||||
|
assert.strictEqual(req.destroyed, false);
|
||||||
res.on('close', common.mustCall(() => {
|
res.on('close', common.mustCall(() => {
|
||||||
resClosed = true;
|
resClosed = true;
|
||||||
|
assert.strictEqual(resFinished, true);
|
||||||
|
assert.strictEqual(res.destroyed, true);
|
||||||
|
}));
|
||||||
|
assert.strictEqual(req.destroyed, false);
|
||||||
|
req.on('end', common.mustCall(() => {
|
||||||
|
assert.strictEqual(req.destroyed, false);
|
||||||
}));
|
}));
|
||||||
req.on('close', common.mustCall(() => {
|
req.on('close', common.mustCall(() => {
|
||||||
|
assert.strictEqual(req.destroyed, true);
|
||||||
assert.strictEqual(req._readableState.ended, true);
|
assert.strictEqual(req._readableState.ended, true);
|
||||||
}));
|
}));
|
||||||
res.socket.on('close', () => server.close());
|
res.socket.on('close', () => server.close());
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
const common = require('../common');
|
const common = require('../common');
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
{
|
{
|
||||||
const server = http.createServer(
|
const server = http.createServer(
|
||||||
|
@ -39,7 +40,9 @@ const http = require('http');
|
||||||
res.on('data', common.mustCall(() => {
|
res.on('data', common.mustCall(() => {
|
||||||
res.destroy();
|
res.destroy();
|
||||||
}));
|
}));
|
||||||
|
assert.strictEqual(res.destroyed, false);
|
||||||
res.on('close', common.mustCall(() => {
|
res.on('close', common.mustCall(() => {
|
||||||
|
assert.strictEqual(res.destroyed, true);
|
||||||
server.close();
|
server.close();
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
|
@ -61,7 +64,12 @@ const http = require('http');
|
||||||
http.get(
|
http.get(
|
||||||
{ port: server.address().port },
|
{ port: server.address().port },
|
||||||
common.mustCall((res) => {
|
common.mustCall((res) => {
|
||||||
|
assert.strictEqual(res.destroyed, false);
|
||||||
|
res.on('end', common.mustCall(() => {
|
||||||
|
assert.strictEqual(res.destroyed, false);
|
||||||
|
}));
|
||||||
res.on('close', common.mustCall(() => {
|
res.on('close', common.mustCall(() => {
|
||||||
|
assert.strictEqual(res.destroyed, true);
|
||||||
server.close();
|
server.close();
|
||||||
}));
|
}));
|
||||||
res.resume();
|
res.resume();
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
require('../common');
|
require('../common');
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
const fork = require('child_process').fork;
|
const fork = require('child_process').fork;
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
if (process.env.NODE_TEST_FORK_PORT) {
|
if (process.env.NODE_TEST_FORK_PORT) {
|
||||||
const req = http.request({
|
const req = http.request({
|
||||||
|
@ -37,7 +38,9 @@ if (process.env.NODE_TEST_FORK_PORT) {
|
||||||
const server = http.createServer((req, res) => {
|
const server = http.createServer((req, res) => {
|
||||||
res.writeHead(200, { 'Content-Length': '42' });
|
res.writeHead(200, { 'Content-Length': '42' });
|
||||||
req.pipe(res);
|
req.pipe(res);
|
||||||
|
assert.strictEqual(req.destroyed, false);
|
||||||
req.on('close', () => {
|
req.on('close', () => {
|
||||||
|
assert.strictEqual(req.destroyed, true);
|
||||||
server.close();
|
server.close();
|
||||||
res.end();
|
res.end();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue