summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrevor Norris <trev.norris@gmail.com>2017-07-21 17:10:56 -0600
committerRefael Ackermann <refack@gmail.com>2017-07-24 20:42:24 -0400
commit93f47b11546b2117b555695b38f505ed2779b5c3 (patch)
tree48028535912a11216f466340264ec89c55ee224c
parentb0a8a7c6baccea746da10e01bfb3dec18c0d723e (diff)
downloadnode-new-93f47b11546b2117b555695b38f505ed2779b5c3.tar.gz
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>
-rw-r--r--lib/_http_agent.js9
-rw-r--r--test/parallel/test-http-agent-uninitialized-with-handle.js30
-rw-r--r--test/parallel/test-http-agent-uninitialized.js25
3 files changed, 61 insertions, 3 deletions
diff --git a/lib/_http_agent.js b/lib/_http_agent.js
index 426cf5b502..ddd36c158e 100644
--- a/lib/_http_agent.js
+++ b/lib/_http_agent.js
@@ -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)
diff --git a/test/parallel/test-http-agent-uninitialized-with-handle.js b/test/parallel/test-http-agent-uninitialized-with-handle.js
new file mode 100644
index 0000000000..fab32ade45
--- /dev/null
+++ b/test/parallel/test-http-agent-uninitialized-with-handle.js
@@ -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();
+}));
diff --git a/test/parallel/test-http-agent-uninitialized.js b/test/parallel/test-http-agent-uninitialized.js
new file mode 100644
index 0000000000..c522b5fdbd
--- /dev/null
+++ b/test/parallel/test-http-agent-uninitialized.js
@@ -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();
+}));