Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4267b92

Browse filesBrowse files
committed
http: use Keep-Alive by default in global agents
PR-URL: #43522 Fixes: #37184 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 8e19dab commit 4267b92
Copy full SHA for 4267b92
Expand file treeCollapse file tree

27 files changed

+173
-35
lines changed
Open diff view settings
Collapse file

‎doc/api/http.md‎

Copy file name to clipboardExpand all lines: doc/api/http.md
+15-1Lines changed: 15 additions & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1449,11 +1449,20 @@ type other than {net.Socket}.
14491449

14501450
<!-- YAML
14511451
added: v0.1.90
1452+
changes:
1453+
- version:
1454+
- REPLACEME
1455+
pr-url: https://github.com/nodejs/node/pull/43522
1456+
description: The method closes idle connections before returning.
1457+
14521458
-->
14531459

14541460
* `callback` {Function}
14551461

1456-
Stops the server from accepting new connections. See [`net.Server.close()`][].
1462+
Stops the server from accepting new connections and closes all connections
1463+
connected to this server which are not sending a request or waiting for
1464+
a response.
1465+
See [`net.Server.close()`][].
14571466

14581467
### `server.closeAllConnections()`
14591468

@@ -3214,6 +3223,11 @@ server.listen(8000);
32143223

32153224
<!-- YAML
32163225
added: v0.5.9
3226+
changes:
3227+
- version:
3228+
- REPLACEME
3229+
pr-url: https://github.com/nodejs/node/pull/43522
3230+
description: The agent now uses HTTP Keep-Alive by default.
32173231
-->
32183232

32193233
* {http.Agent}
Collapse file

‎doc/api/https.md‎

Copy file name to clipboardExpand all lines: doc/api/https.md
+5Lines changed: 5 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ https.get('https://encrypted.google.com/', (res) => {
309309

310310
<!-- YAML
311311
added: v0.5.9
312+
changes:
313+
- version:
314+
- REPLACEME
315+
pr-url: https://github.com/nodejs/node/pull/43522
316+
description: The agent now uses HTTP Keep-Alive by default.
312317
-->
313318

314319
Global instance of [`https.Agent`][] for all HTTPS client requests.
Collapse file

‎lib/_http_agent.js‎

Copy file name to clipboardExpand all lines: lib/_http_agent.js
+21-2Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ const {
3131
ArrayPrototypeSplice,
3232
FunctionPrototypeCall,
3333
NumberIsNaN,
34+
NumberParseInt,
3435
ObjectCreate,
3536
ObjectKeys,
3637
ObjectSetPrototypeOf,
3738
ObjectValues,
39+
RegExpPrototypeExec,
3840
StringPrototypeIndexOf,
3941
StringPrototypeSplit,
4042
StringPrototypeStartsWith,
@@ -492,7 +494,24 @@ Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) {
492494
socket.setKeepAlive(true, this.keepAliveMsecs);
493495
socket.unref();
494496

495-
const agentTimeout = this.options.timeout || 0;
497+
let agentTimeout = this.options.timeout || 0;
498+
499+
if (socket._httpMessage?.res) {
500+
const keepAliveHint = socket._httpMessage.res.headers['keep-alive'];
501+
502+
if (keepAliveHint) {
503+
const hint = RegExpPrototypeExec(/^timeout=(\d+)/, keepAliveHint)?.[1];
504+
505+
if (hint) {
506+
const serverHintTimeout = NumberParseInt(hint) * 1000;
507+
508+
if (serverHintTimeout < agentTimeout) {
509+
agentTimeout = serverHintTimeout;
510+
}
511+
}
512+
}
513+
}
514+
496515
if (socket.timeout !== agentTimeout) {
497516
socket.setTimeout(agentTimeout);
498517
}
@@ -542,5 +561,5 @@ function asyncResetHandle(socket) {
542561

543562
module.exports = {
544563
Agent,
545-
globalAgent: new Agent()
564+
globalAgent: new Agent({ keepAlive: true, scheduling: 'lifo', timeout: 5000 })
546565
};
Collapse file

‎lib/_http_server.js‎

Copy file name to clipboardExpand all lines: lib/_http_server.js
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ ObjectSetPrototypeOf(Server.prototype, net.Server.prototype);
478478
ObjectSetPrototypeOf(Server, net.Server);
479479

480480
Server.prototype.close = function() {
481+
this.closeIdleConnections();
481482
clearInterval(this[kConnectionsCheckingInterval]);
482483
ReflectApply(net.Server.prototype.close, this, arguments);
483484
};
Collapse file

‎lib/https.js‎

Copy file name to clipboardExpand all lines: lib/https.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ Agent.prototype._evictSession = function _evictSession(key) {
331331
delete this._sessionCache.map[key];
332332
};
333333

334-
const globalAgent = new Agent();
334+
const globalAgent = new Agent({ keepAlive: true, scheduling: 'lifo', timeout: 5000 });
335335

336336
/**
337337
* Makes a request to a secure web server.
Collapse file

‎test/async-hooks/test-graph.http.js‎

Copy file name to clipboardExpand all lines: test/async-hooks/test-graph.http.js
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const hooks = initHooks();
1212
hooks.enable();
1313

1414
const server = http.createServer(common.mustCall((req, res) => {
15+
res.writeHead(200, { 'Connection': 'close' });
1516
res.end();
1617
server.close(common.mustCall());
1718
}));
Collapse file
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const http = require('http');
6+
7+
const server = http.createServer(function(req, res) {
8+
res.writeHead(200);
9+
res.end();
10+
});
11+
12+
server.listen(0, common.mustCall(() => {
13+
const req = http.get({ port: server.address().port }, (res) => {
14+
assert.strictEqual(res.statusCode, 200);
15+
16+
res.resume();
17+
server.close();
18+
});
19+
20+
req.end();
21+
}));
22+
23+
// This timer should never go off as the server will close the socket
24+
setTimeout(common.mustNotCall(), 1000).unref();
Collapse file

‎test/parallel/test-http-client-agent.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-http-client-agent.js
+7-5Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const Countdown = require('../common/countdown');
2727

2828
let name;
2929
const max = 3;
30+
const agent = new http.Agent();
3031

3132
const server = http.Server(common.mustCall((req, res) => {
3233
if (req.url === '/0') {
@@ -40,27 +41,28 @@ const server = http.Server(common.mustCall((req, res) => {
4041
}
4142
}, max));
4243
server.listen(0, common.mustCall(() => {
43-
name = http.globalAgent.getName({ port: server.address().port });
44+
name = agent.getName({ port: server.address().port });
4445
for (let i = 0; i < max; ++i)
4546
request(i);
4647
}));
4748

4849
const countdown = new Countdown(max, () => {
49-
assert(!(name in http.globalAgent.sockets));
50-
assert(!(name in http.globalAgent.requests));
50+
assert(!(name in agent.sockets));
51+
assert(!(name in agent.requests));
5152
server.close();
5253
});
5354

5455
function request(i) {
5556
const req = http.get({
5657
port: server.address().port,
57-
path: `/${i}`
58+
path: `/${i}`,
59+
agent
5860
}, function(res) {
5961
const socket = req.socket;
6062
socket.on('close', common.mustCall(() => {
6163
countdown.dec();
6264
if (countdown.remaining > 0) {
63-
assert.strictEqual(http.globalAgent.sockets[name].includes(socket),
65+
assert.strictEqual(agent.sockets[name].includes(socket),
6466
false);
6567
}
6668
}));
Collapse file
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const http = require('http');
6+
7+
const server = http.createServer(function(req, res) {
8+
res.writeHead(200);
9+
res.end();
10+
});
11+
12+
server.listen(0, common.mustCall(() => {
13+
const req = http.get({ port: server.address().port }, (res) => {
14+
assert.strictEqual(res.statusCode, 200);
15+
res.resume();
16+
server.close();
17+
});
18+
19+
req.end();
20+
}));
21+
22+
// This timer should never go off as the server will close the socket
23+
setTimeout(common.mustNotCall(), common.platformTimeout(10000)).unref();
Collapse file

‎test/parallel/test-http-client-headers-array.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-http-client-headers-array.js
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function execute(options) {
1010
const expectHeaders = {
1111
'x-foo': 'boom',
1212
'cookie': 'a=1; b=2; c=3',
13-
'connection': 'close'
13+
'connection': 'keep-alive'
1414
};
1515

1616
// no Host header when you set headers an array
@@ -28,6 +28,7 @@ function execute(options) {
2828

2929
assert.deepStrictEqual(req.headers, expectHeaders);
3030

31+
res.writeHead(200, { 'Connection': 'close' });
3132
res.end();
3233
}).listen(0, function() {
3334
options = Object.assign(options, {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.