http: make timeout event work with agent timeout

The `'timeout'` event is currently not emitted on the `ClientRequest`
instance when the socket timeout expires if only the `timeout` option
of the agent is set. This happens because, under these circumstances,
`listenSocketTimeout()` is not called.

This commit fixes the issue by calling it also when only the agent
`timeout` option is set.

PR-URL: https://github.com/nodejs/node/pull/25488
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Luigi Pinca 2019-01-14 09:14:13 +01:00
parent 16362cb868
commit 4b6e4c1eb1
2 changed files with 27 additions and 1 deletions

View File

@ -653,7 +653,10 @@ function tickOnSocket(req, socket) {
socket.on('end', socketOnEnd);
socket.on('close', socketCloseListener);
if (req.timeout !== undefined) {
if (
req.timeout !== undefined ||
(req.agent && req.agent.options && req.agent.options.timeout)
) {
listenSocketTimeout(req);
}
req.emit('socket', socket);

View File

@ -0,0 +1,23 @@
'use strict';
const { expectsError, mustCall } = require('../common');
const { Agent, get } = require('http');
// Test that the `'timeout'` event is emitted on the `ClientRequest` instance
// when the socket timeout set via the `timeout` option of the `Agent` expires.
const request = get({
agent: new Agent({ timeout: 500 }),
// Non-routable IP address to prevent the connection from being established.
host: '192.0.2.1'
});
request.on('error', expectsError({
type: Error,
code: 'ECONNRESET',
message: 'socket hang up'
}));
request.on('timeout', mustCall(() => {
request.abort();
}));