Skip to content

Commit 1effe5e

Browse files
committed
http: remove stale timeout listeners
1 parent 4fffe32 commit 1effe5e

File tree

2 files changed

+52
-15
lines changed

2 files changed

+52
-15
lines changed

lib/_http_client.js

+8-15
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ function tickOnSocket(req, socket) {
562562
socket.on('close', socketCloseListener);
563563

564564
if (req.timeout) {
565-
socket.once('timeout', () => req.emit('timeout'));
565+
req.setTimeout(req.timeout);
566566
}
567567
req.emit('socket', socket);
568568
}
@@ -620,28 +620,21 @@ ClientRequest.prototype.setTimeout = function setTimeout(msecs, callback) {
620620
self.emit('timeout');
621621
}
622622

623-
if (this.socket && this.socket.writable) {
624-
if (this.timeoutCb)
625-
this.socket.setTimeout(0, this.timeoutCb);
626-
this.timeoutCb = emitTimeout;
627-
this.socket.setTimeout(msecs, emitTimeout);
628-
return this;
629-
}
623+
// Remove any existing timeout listener
624+
if (this.timeoutCb)
625+
this.socket.setTimeout(0, this.timeoutCb);
630626

631627
// Set timeoutCb so that it'll get cleaned up on request end
632628
this.timeoutCb = emitTimeout;
629+
633630
if (this.socket) {
634-
var sock = this.socket;
635-
this.socket.once('connect', function() {
631+
this.socket.setTimeout(msecs, emitTimeout);
632+
} else {
633+
this.once('socket', function(sock) {
636634
sock.setTimeout(msecs, emitTimeout);
637635
});
638-
return this;
639636
}
640637

641-
this.once('socket', function(sock) {
642-
sock.setTimeout(msecs, emitTimeout);
643-
});
644-
645638
return this;
646639
};
647640

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use strict';
2+
const common = require('../common');
3+
const http = require('http');
4+
const assert = require('assert');
5+
6+
const agent = new http.Agent({ keepAlive: true });
7+
8+
const server = http.createServer((req, res) => {
9+
res.end('');
10+
});
11+
12+
const options = {
13+
agent,
14+
method: 'GET',
15+
port: undefined,
16+
host: common.localhostIPv4,
17+
path: '/',
18+
timeout: common.platformTimeout(100)
19+
};
20+
21+
server.listen(0, options.host, common.mustCall(() => {
22+
options.port = server.address().port;
23+
doRequest(common.mustCall((numListeners) => {
24+
assert.strictEqual(numListeners, 1);
25+
doRequest(common.mustCall((numListeners) => {
26+
assert.strictEqual(numListeners, 1);
27+
server.close();
28+
agent.destroy();
29+
}));
30+
}));
31+
}));
32+
33+
function doRequest(cb) {
34+
http.request(options, common.mustCall((response) => {
35+
const sockets = agent.sockets[`${options.host}:${options.port}:`];
36+
assert.strictEqual(sockets.length, 1);
37+
const socket = sockets[0];
38+
const numListeners = socket.listeners('timeout').length;
39+
response.resume();
40+
response.once('end', common.mustCall(() => {
41+
process.nextTick(cb, numListeners);
42+
}));
43+
})).end();
44+
}

0 commit comments

Comments
 (0)