Skip to content

Commit 94b4764

Browse files
committed
http: start connections checking interval on listen
Fixes: #48604.
1 parent 32eb492 commit 94b4764

File tree

3 files changed

+61
-6
lines changed

3 files changed

+61
-6
lines changed

lib/_http_server.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -497,14 +497,14 @@ function storeHTTPOptions(options) {
497497
}
498498
}
499499

500-
function setupConnectionsTracking(server) {
500+
function setupConnectionsTracking() {
501501
// Start connection handling
502-
server[kConnections] = new ConnectionsList();
502+
this[kConnections] = new ConnectionsList();
503503

504504
// This checker is started without checking whether any headersTimeout or requestTimeout is non zero
505505
// otherwise it would not be started if such timeouts are modified after createServer.
506-
server[kConnectionsCheckingInterval] =
507-
setInterval(checkConnections.bind(server), server.connectionsCheckingInterval).unref();
506+
this[kConnectionsCheckingInterval] =
507+
setInterval(checkConnections.bind(this), this.connectionsCheckingInterval).unref();
508508
}
509509

510510
function httpServerPreClose(server) {
@@ -542,11 +542,12 @@ function Server(options, requestListener) {
542542
this.httpAllowHalfOpen = false;
543543

544544
this.on('connection', connectionListener);
545+
this.on('listening', setupConnectionsTracking);
545546

546547
this.timeout = 0;
547548
this.maxHeadersCount = null;
548549
this.maxRequestsPerSocket = 0;
549-
setupConnectionsTracking(this);
550+
550551
this[kUniqueHeaders] = parseUniqueHeadersOption(options.uniqueHeaders);
551552
}
552553
ObjectSetPrototypeOf(Server.prototype, net.Server.prototype);
@@ -558,6 +559,10 @@ Server.prototype.close = function() {
558559
};
559560

560561
Server.prototype.closeAllConnections = function() {
562+
if (!this[kConnections]) {
563+
return;
564+
}
565+
561566
const connections = this[kConnections].all();
562567

563568
for (let i = 0, l = connections.length; i < l; i++) {
@@ -566,6 +571,10 @@ Server.prototype.closeAllConnections = function() {
566571
};
567572

568573
Server.prototype.closeIdleConnections = function() {
574+
if (!this[kConnections]) {
575+
return;
576+
}
577+
569578
const connections = this[kConnections].idle();
570579

571580
for (let i = 0, l = connections.length; i < l; i++) {

lib/https.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,9 @@ function Server(opts, requestListener) {
9494

9595
this.timeout = 0;
9696
this.maxHeadersCount = null;
97-
setupConnectionsTracking(this);
97+
this.on('listening', setupConnectionsTracking);
9898
}
99+
99100
ObjectSetPrototypeOf(Server.prototype, tls.Server.prototype);
100101
ObjectSetPrototypeOf(Server, tls.Server);
101102

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
'use strict';
2+
3+
// Flags: --expose-gc
4+
5+
const common = require('../common');
6+
if (!common.hasCrypto) { common.skip('missing crypto'); }
7+
const onGC = require('../common/ongc');
8+
const http = require('http');
9+
const https = require('https');
10+
11+
// Check that creating a server without listening is not leaking resources.
12+
const max = 100;
13+
14+
// HTTP
15+
{
16+
const gcListener = common.mustCall(max);
17+
18+
for (let i = 0; i <= max; i++) {
19+
if (i % 100 === 0) {
20+
global.gc();
21+
}
22+
23+
const server = http.createServer((req, res) => {});
24+
onGC(server, { ongc: gcListener });
25+
}
26+
27+
global.gc();
28+
}
29+
30+
// HTTPS
31+
32+
{
33+
const gcListener = common.mustCall(max);
34+
35+
for (let i = 0; i <= max; i++) {
36+
if (i % 100 === 0) {
37+
global.gc();
38+
}
39+
40+
const server = https.createServer((req, res) => {});
41+
onGC(server, { ongc: gcListener });
42+
}
43+
44+
global.gc();
45+
}

0 commit comments

Comments
 (0)