From 4cdc5ea823458e5d4fe0b7767529785d41fcbd3e Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Sat, 16 Jan 2021 18:17:57 +0100 Subject: [PATCH] http: fix ClientRequest unhandled errors ClientRequest could someone cause an unhandled error from socket. Fixes: https://github.com/nodejs/node/issues/36931 PR-URL: https://github.com/nodejs/node/pull/36970 Reviewed-By: Luigi Pinca Reviewed-By: Matteo Collina Reviewed-By: Benjamin Gruenbaum --- lib/_http_client.js | 16 ++++++------ test/parallel/test-http-client-abort3.js | 32 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 test/parallel/test-http-client-abort3.js diff --git a/lib/_http_client.js b/lib/_http_client.js index fbaebacc1559ed..70c8a26f3fc17f 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -818,13 +818,15 @@ function onSocketNT(req, socket, err) { req.emit('close'); } - if (!err && req.agent) { - socket?.emit('free'); - } else if (socket) { - finished(socket.destroy(err || req[kError]), (er) => { - _destroy(req, er || err); - }); - return; + if (socket) { + if (!err && req.agent && !socket.destroyed) { + socket.emit('free'); + } else { + finished(socket.destroy(err || req[kError]), (er) => { + _destroy(req, er || err); + }); + return; + } } _destroy(req, err || req[kError]); diff --git a/test/parallel/test-http-client-abort3.js b/test/parallel/test-http-client-abort3.js new file mode 100644 index 00000000000000..4fb7d0fdba8d6b --- /dev/null +++ b/test/parallel/test-http-client-abort3.js @@ -0,0 +1,32 @@ +'use strict'; + +const common = require('../common'); +const http = require('http'); +const net = require('net'); + +function createConnection() { + const socket = new net.Socket(); + + process.nextTick(function() { + socket.destroy(new Error('Oops')); + }); + + return socket; +} + +{ + const req = http.get({ createConnection }); + + req.on('error', common.expectsError({ name: 'Error', message: 'Oops' })); + req.abort(); +} + +{ + class CustomAgent extends http.Agent {} + CustomAgent.prototype.createConnection = createConnection; + + const req = http.get({ agent: new CustomAgent() }); + + req.on('error', common.expectsError({ name: 'Error', message: 'Oops' })); + req.abort(); +}