mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
http: use listenerCount when adding noop event
PR-URL: https://github.com/nodejs/node/pull/46769 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
f94ef7c2e8
commit
0d3faaef90
@ -822,10 +822,29 @@ const requestHeaderFieldsTooLargeResponse = Buffer.from(
|
||||
`HTTP/1.1 431 ${STATUS_CODES[431]}\r\n` +
|
||||
'Connection: close\r\n\r\n', 'ascii',
|
||||
);
|
||||
|
||||
function warnUnclosedSocket() {
|
||||
if (warnUnclosedSocket.emitted) {
|
||||
return;
|
||||
}
|
||||
|
||||
warnUnclosedSocket.emitted = true;
|
||||
process.emitWarning(
|
||||
'An error event has already been emitted on the socket. ' +
|
||||
'Please use the destroy method on the socket while handling ' +
|
||||
"a 'clientError' event.",
|
||||
);
|
||||
}
|
||||
|
||||
function socketOnError(e) {
|
||||
// Ignore further errors
|
||||
this.removeListener('error', socketOnError);
|
||||
this.on('error', noop);
|
||||
|
||||
if (this.listenerCount('error', noop) === 0) {
|
||||
this.on('error', noop);
|
||||
} else {
|
||||
warnUnclosedSocket();
|
||||
}
|
||||
|
||||
if (!this.server.emit('clientError', e, this)) {
|
||||
// Caution must be taken to avoid corrupting the remote peer.
|
||||
|
47
test/parallel/test-http-socket-error-listeners.js
Normal file
47
test/parallel/test-http-socket-error-listeners.js
Normal file
@ -0,0 +1,47 @@
|
||||
// Flags: --no-warnings
|
||||
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
const net = require('net');
|
||||
|
||||
// This test sends an invalid character to a HTTP server and purposely
|
||||
// does not handle clientError (even if it sets an event handler).
|
||||
//
|
||||
// The idea is to let the server emit multiple errors on the socket,
|
||||
// mostly due to parsing error, and make sure they don't result
|
||||
// in leaking event listeners.
|
||||
|
||||
{
|
||||
let i = 0;
|
||||
let socket;
|
||||
process.on('warning', common.mustCall());
|
||||
|
||||
const server = http.createServer(common.mustNotCall());
|
||||
|
||||
server.on('clientError', common.mustCallAtLeast((err) => {
|
||||
assert.strictEqual(err.code, 'HPE_INVALID_METHOD');
|
||||
assert.strictEqual(err.rawPacket.toString(), '*');
|
||||
|
||||
if (i === 20) {
|
||||
socket.end();
|
||||
} else {
|
||||
socket.write('*');
|
||||
i++;
|
||||
}
|
||||
}, 1));
|
||||
|
||||
server.listen(0, () => {
|
||||
socket = net.createConnection({ port: server.address().port });
|
||||
|
||||
socket.on('connect', () => {
|
||||
socket.write('*');
|
||||
});
|
||||
|
||||
socket.on('close', () => {
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user