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: https://github.com/nodejs/node/pull/14419 Fixes: https://github.com/nodejs/node/issues/13539 Refs: https://github.com/nodejs/node/issues/13352 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com>
This commit is contained in:
parent
b0a8a7c6ba
commit
93f47b1154
@ -167,9 +167,12 @@ Agent.prototype.addRequest = function addRequest(req, options, port/*legacy*/,
|
|||||||
if (freeLen) {
|
if (freeLen) {
|
||||||
// we have a free socket, so use that.
|
// we have a free socket, so use that.
|
||||||
var socket = this.freeSockets[name].shift();
|
var socket = this.freeSockets[name].shift();
|
||||||
|
// Guard against an uninitialized or user supplied Socket.
|
||||||
|
if (socket._handle && typeof socket._handle.asyncReset === 'function') {
|
||||||
// Assign the handle a new asyncId and run any init() hooks.
|
// Assign the handle a new asyncId and run any init() hooks.
|
||||||
socket._handle.asyncReset();
|
socket._handle.asyncReset();
|
||||||
socket[async_id_symbol] = socket._handle.getAsyncId();
|
socket[async_id_symbol] = socket._handle.getAsyncId();
|
||||||
|
}
|
||||||
|
|
||||||
// don't leak
|
// don't leak
|
||||||
if (!this.freeSockets[name].length)
|
if (!this.freeSockets[name].length)
|
||||||
|
30
test/parallel/test-http-agent-uninitialized-with-handle.js
Normal file
30
test/parallel/test-http-agent-uninitialized-with-handle.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const common = require('../common');
|
||||||
|
const http = require('http');
|
||||||
|
const net = require('net');
|
||||||
|
|
||||||
|
const agent = new http.Agent({
|
||||||
|
keepAlive: true,
|
||||||
|
});
|
||||||
|
const socket = new net.Socket();
|
||||||
|
// If _handle exists then internals assume a couple methods exist.
|
||||||
|
socket._handle = {
|
||||||
|
ref() { },
|
||||||
|
readStart() { },
|
||||||
|
};
|
||||||
|
const req = new http.ClientRequest(`http://localhost:${common.PORT}/`);
|
||||||
|
|
||||||
|
const server = http.createServer(common.mustCall((req, res) => {
|
||||||
|
res.end();
|
||||||
|
})).listen(common.PORT, common.mustCall(() => {
|
||||||
|
// Manually add the socket without a _handle.
|
||||||
|
agent.freeSockets[agent.getName(req)] = [socket];
|
||||||
|
// Now force the agent to use the socket and check that _handle exists before
|
||||||
|
// calling asyncReset().
|
||||||
|
agent.addRequest(req, {});
|
||||||
|
req.on('response', common.mustCall(() => {
|
||||||
|
server.close();
|
||||||
|
}));
|
||||||
|
req.end();
|
||||||
|
}));
|
25
test/parallel/test-http-agent-uninitialized.js
Normal file
25
test/parallel/test-http-agent-uninitialized.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const common = require('../common');
|
||||||
|
const http = require('http');
|
||||||
|
const net = require('net');
|
||||||
|
|
||||||
|
const agent = new http.Agent({
|
||||||
|
keepAlive: true,
|
||||||
|
});
|
||||||
|
const socket = new net.Socket();
|
||||||
|
const req = new http.ClientRequest(`http://localhost:${common.PORT}/`);
|
||||||
|
|
||||||
|
const server = http.createServer(common.mustCall((req, res) => {
|
||||||
|
res.end();
|
||||||
|
})).listen(common.PORT, common.mustCall(() => {
|
||||||
|
// Manually add the socket without a _handle.
|
||||||
|
agent.freeSockets[agent.getName(req)] = [socket];
|
||||||
|
// Now force the agent to use the socket and check that _handle exists before
|
||||||
|
// calling asyncReset().
|
||||||
|
agent.addRequest(req, {});
|
||||||
|
req.on('response', common.mustCall(() => {
|
||||||
|
server.close();
|
||||||
|
}));
|
||||||
|
req.end();
|
||||||
|
}));
|
Loading…
x
Reference in New Issue
Block a user