Skip to content

Commit a971179

Browse files
committed
http: use objects with null prototype in Agent
Fixes: nodejs#36364
1 parent bf31d3c commit a971179

9 files changed

+33
-19
lines changed

doc/api/http.md

+12
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ terminates them.
262262
### `agent.freeSockets`
263263
<!-- YAML
264264
added: v0.11.4
265+
changes:
266+
- version: REPLACEME
267+
pr-url: https://github.com/nodejs/node/pull/36409
268+
description: The property now has a `null` prototype.
265269
-->
266270

267271
* {Object}
@@ -328,6 +332,10 @@ can have open. Unlike `maxSockets`, this parameter applies across all origins.
328332
### `agent.requests`
329333
<!-- YAML
330334
added: v0.5.9
335+
changes:
336+
- version: REPLACEME
337+
pr-url: https://github.com/nodejs/node/pull/36409
338+
description: The property now has a `null` prototype.
331339
-->
332340

333341
* {Object}
@@ -338,6 +346,10 @@ sockets. Do not modify.
338346
### `agent.sockets`
339347
<!-- YAML
340348
added: v0.3.6
349+
changes:
350+
- version: REPLACEME
351+
pr-url: https://github.com/nodejs/node/pull/36409
352+
description: The property now has a `null` prototype.
341353
-->
342354

343355
* {Object}

lib/_http_agent.js

+9-7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
const {
2525
NumberIsNaN,
26+
ObjectCreate,
2627
ObjectKeys,
2728
ObjectSetPrototypeOf,
2829
ObjectValues,
@@ -83,13 +84,13 @@ function Agent(options) {
8384
this.defaultPort = 80;
8485
this.protocol = 'http:';
8586

86-
this.options = { ...options };
87+
this.options = { __proto__: null, ...options };
8788

8889
// Don't confuse net and make it think that we're connecting to a pipe
8990
this.options.path = null;
90-
this.requests = {};
91-
this.sockets = {};
92-
this.freeSockets = {};
91+
this.requests = ObjectCreate(null);
92+
this.sockets = ObjectCreate(null);
93+
this.freeSockets = ObjectCreate(null);
9394
this.keepAliveMsecs = this.options.keepAliveMsecs || 1000;
9495
this.keepAlive = this.options.keepAlive || false;
9596
this.maxSockets = this.options.maxSockets || Agent.defaultMaxSockets;
@@ -227,13 +228,14 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
227228
// Legacy API: addRequest(req, host, port, localAddress)
228229
if (typeof options === 'string') {
229230
options = {
231+
__proto__: null,
230232
host: options,
231233
port,
232234
localAddress
233235
};
234236
}
235237

236-
options = { ...options, ...this.options };
238+
options = { __proto__: null, ...options, ...this.options };
237239
if (options.socketPath)
238240
options.path = options.socketPath;
239241

@@ -294,7 +296,7 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
294296
};
295297

296298
Agent.prototype.createSocket = function createSocket(req, options, cb) {
297-
options = { ...options, ...this.options };
299+
options = { __proto__: null, ...options, ...this.options };
298300
if (options.socketPath)
299301
options.path = options.socketPath;
300302

@@ -435,7 +437,7 @@ Agent.prototype.removeSocket = function removeSocket(s, options) {
435437
// There might be older requests in a different origin, but
436438
// if the origin which releases the socket has pending requests
437439
// that will be prioritized.
438-
for (const prop in this.requests) {
440+
for (const prop of ObjectKeys(this.requests)) {
439441
// Check whether this specific origin is already at maxSockets
440442
if (this.sockets[prop] && this.sockets[prop].length) break;
441443
debug('removeSocket, have a request with different origin,' +

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ server.listen(0, common.mustCall(() => {
4646
}));
4747

4848
const countdown = new Countdown(max, () => {
49-
assert(!http.globalAgent.sockets.hasOwnProperty(name));
50-
assert(!http.globalAgent.requests.hasOwnProperty(name));
49+
assert(!(name in http.globalAgent.sockets));
50+
assert(!(name in http.globalAgent.requests));
5151
server.close();
5252
});
5353

test/parallel/test-http-client-override-global-agent.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ server.listen(0, common.mustCall(() => {
1414
http.globalAgent = agent;
1515

1616
makeRequest();
17-
assert(agent.sockets.hasOwnProperty(name)); // Agent has indeed been used
17+
assert(name in agent.sockets); // Agent has indeed been used
1818
}));
1919

2020
function makeRequest() {

test/parallel/test-http-connect-req-res.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ server.listen(0, common.mustCall(function() {
4343

4444
// Make sure this request got removed from the pool.
4545
const name = `localhost:${server.address().port}`;
46-
assert(!http.globalAgent.sockets.hasOwnProperty(name));
47-
assert(!http.globalAgent.requests.hasOwnProperty(name));
46+
assert(!(name in http.globalAgent.sockets));
47+
assert(!(name in http.globalAgent.requests));
4848

4949
// Make sure this socket has detached.
5050
assert(!socket.ondata);

test/parallel/test-http-connect.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ server.listen(0, common.mustCall(() => {
7070
req.on('connect', common.mustCall((res, socket, firstBodyChunk) => {
7171
// Make sure this request got removed from the pool.
7272
const name = `localhost:${server.address().port}`;
73-
assert(!http.globalAgent.sockets.hasOwnProperty(name));
74-
assert(!http.globalAgent.requests.hasOwnProperty(name));
73+
assert(!(name in http.globalAgent.sockets));
74+
assert(!(name in http.globalAgent.requests));
7575

7676
// Make sure this socket has detached.
7777
assert(!socket.ondata);

test/parallel/test-http-keep-alive.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ server.listen(0, common.mustCall(function() {
5959
}, common.mustCall((response) => {
6060
response.on('end', common.mustCall(() => {
6161
assert.strictEqual(agent.sockets[name].length, 1);
62-
assert(!agent.requests.hasOwnProperty(name));
62+
assert(!(name in agent.requests));
6363
server.close();
6464
}));
6565
response.resume();
6666
}));
6767
}));
6868

6969
process.on('exit', () => {
70-
assert(!agent.sockets.hasOwnProperty(name));
71-
assert(!agent.requests.hasOwnProperty(name));
70+
assert(!(name in agent.sockets));
71+
assert(!(name in agent.requests));
7272
});

test/parallel/test-http-upgrade-agent.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ server.listen(0, '127.0.0.1', common.mustCall(function() {
7878
assert.deepStrictEqual(expectedHeaders, res.headers);
7979

8080
// Make sure this request got removed from the pool.
81-
assert(!http.globalAgent.sockets.hasOwnProperty(name));
81+
assert(!(name in http.globalAgent.sockets));
8282

8383
req.on('close', common.mustCall(function() {
8484
socket.end();

test/parallel/test-https-client-override-global-agent.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ server.listen(0, common.mustCall(() => {
2525
https.globalAgent = agent;
2626

2727
makeRequest();
28-
assert(agent.sockets.hasOwnProperty(name)); // Agent has indeed been used
28+
assert(name in agent.sockets); // Agent has indeed been used
2929
}));
3030

3131
function makeRequest() {

0 commit comments

Comments
 (0)