Permalink
Browse files

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 <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
  • Loading branch information...
trevnorris authored and refack committed Jul 21, 2017
1 parent b0a8a7c commit 93f47b11546b2117b555695b38f505ed2779b5c3
View
@@ -167,9 +167,12 @@ Agent.prototype.addRequest = function addRequest(req, options, port/*legacy*/,
if (freeLen) {
// we have a free socket, so use that.
var socket = this.freeSockets[name].shift();
// Assign the handle a new asyncId and run any init() hooks.
socket._handle.asyncReset();
socket[async_id_symbol] = socket._handle.getAsyncId();
// 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.
socket._handle.asyncReset();
socket[async_id_symbol] = socket._handle.getAsyncId();
}
// don't leak
if (!this.freeSockets[name].length)
@@ -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();
}));
@@ -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();
}));

0 comments on commit 93f47b1

Please sign in to comment.