Skip to content

Commit cda1287

Browse files
ShogunPandatargos
authored andcommitted
http: do not leak error listeners
PR-URL: #43587 Fixes: #43548 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Ricky Zhou <[email protected]> Reviewed-By: Mohammed Keyvanzadeh <[email protected]>
1 parent 2a830e0 commit cda1287

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

lib/_http_server.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,10 @@ const requestHeaderFieldsTooLargeResponse = Buffer.from(
692692
function socketOnError(e) {
693693
// Ignore further errors
694694
this.removeListener('error', socketOnError);
695-
this.on('error', noop);
695+
696+
if (this.listenerCount('error') === 0) {
697+
this.on('error', noop);
698+
}
696699

697700
if (!this.server.emit('clientError', e, this)) {
698701
if (this.writable && this.bytesWritten === 0) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const http = require('http');
6+
const net = require('net');
7+
8+
// This test sends an invalid character to a HTTP server and purposely
9+
// does not handle clientError (even if it sets an event handler).
10+
//
11+
// The idea is to let the server emit multiple errors on the socket,
12+
// mostly due to parsing error, and make sure they don't result
13+
// in leaking event listeners.
14+
15+
let i = 0;
16+
let socket;
17+
18+
process.on('warning', common.mustNotCall());
19+
20+
const server = http.createServer(common.mustNotCall());
21+
22+
server.on('clientError', common.mustCallAtLeast((err) => {
23+
assert.strictEqual(err.code, 'HPE_INVALID_METHOD');
24+
assert.strictEqual(err.rawPacket.toString(), '*');
25+
26+
if (i === 20) {
27+
socket.end();
28+
} else {
29+
socket.write('*');
30+
i++;
31+
}
32+
}, 1));
33+
34+
server.listen(0, () => {
35+
socket = net.createConnection({ port: server.address().port });
36+
37+
socket.on('connect', () => {
38+
socket.write('*');
39+
});
40+
41+
socket.on('close', () => {
42+
server.close();
43+
});
44+
});

0 commit comments

Comments
 (0)