Skip to content

Commit 751e873

Browse files
trevnorrisaddaleax
authored andcommitted
http: check for handle before running asyncReset()
If an uninitialized or user supplied Socket is in the freeSockets list of the Agent it would automatically attempt to run ._handle.asyncReset(), but would throw from those not existing. Guard against that by first checking that they exist. PR-URL: #14419 Fixes: #13539 Refs: #13352 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Refael Ackermann <[email protected]>
1 parent 142ce5c commit 751e873

3 files changed

+61
-3
lines changed

lib/_http_agent.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,12 @@ Agent.prototype.addRequest = function addRequest(req, options, port/*legacy*/,
167167
if (freeLen) {
168168
// we have a free socket, so use that.
169169
var socket = this.freeSockets[name].shift();
170-
// Assign the handle a new asyncId and run any init() hooks.
171-
socket._handle.asyncReset();
172-
socket[async_id_symbol] = socket._handle.getAsyncId();
170+
// Guard against an uninitialized or user supplied Socket.
171+
if (socket._handle && typeof socket._handle.asyncReset === 'function') {
172+
// Assign the handle a new asyncId and run any init() hooks.
173+
socket._handle.asyncReset();
174+
socket[async_id_symbol] = socket._handle.getAsyncId();
175+
}
173176

174177
// don't leak
175178
if (!this.freeSockets[name].length)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const http = require('http');
5+
const net = require('net');
6+
7+
const agent = new http.Agent({
8+
keepAlive: true,
9+
});
10+
const socket = new net.Socket();
11+
// If _handle exists then internals assume a couple methods exist.
12+
socket._handle = {
13+
ref() { },
14+
readStart() { },
15+
};
16+
const req = new http.ClientRequest(`http://localhost:${common.PORT}/`);
17+
18+
const server = http.createServer(common.mustCall((req, res) => {
19+
res.end();
20+
})).listen(common.PORT, common.mustCall(() => {
21+
// Manually add the socket without a _handle.
22+
agent.freeSockets[agent.getName(req)] = [socket];
23+
// Now force the agent to use the socket and check that _handle exists before
24+
// calling asyncReset().
25+
agent.addRequest(req, {});
26+
req.on('response', common.mustCall(() => {
27+
server.close();
28+
}));
29+
req.end();
30+
}));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const http = require('http');
5+
const net = require('net');
6+
7+
const agent = new http.Agent({
8+
keepAlive: true,
9+
});
10+
const socket = new net.Socket();
11+
const req = new http.ClientRequest(`http://localhost:${common.PORT}/`);
12+
13+
const server = http.createServer(common.mustCall((req, res) => {
14+
res.end();
15+
})).listen(common.PORT, common.mustCall(() => {
16+
// Manually add the socket without a _handle.
17+
agent.freeSockets[agent.getName(req)] = [socket];
18+
// Now force the agent to use the socket and check that _handle exists before
19+
// calling asyncReset().
20+
agent.addRequest(req, {});
21+
req.on('response', common.mustCall(() => {
22+
server.close();
23+
}));
24+
req.end();
25+
}));

0 commit comments

Comments
 (0)