http.request({ timeout })
is not working for response timeout.- Agent timeout supercedes the option
- Doesn't leak because request.on('timeout') instead of socket.on('timeout'). It's easier because request is always thrown away.
- Then why header leaks?
- Print socket's
listeners('timeout').length
- Try
dropRequestAfter
together
- Print socket's
- Then why header leaks?
- agentkeepalive's timeout handler actually works without request.js's request.on('timeout')
request.setTimeout()
can set timeout after connection.
for timeout of lookup and connect, we can use agent’s options.timeout or request’s options.timeout.
agentkeepalive and the builtin agent overwrite timeout option!!!
But you may need request timeout option to propagate socket timeout event to request timeout event. request.on(‘timeout’)
is easier than socket.on(‘timeout’)
.
??? suggests to have a shorter timeout before a TCP connection timeout is established. This prevents ???. This timeout should be relatively shorter (200 ms - 300 ms) depending on the target server. If the timeout is shorter than expected response time of the API, we need to have different timeouts for one before TCP connection and one after it.
const req = http.request({ timeout: shortTimeout });
// ClientRequest.setTimeout() sets a timeout after connection
// https://github.com/nodejs/node/blob/v9.2.0/lib/_http_client.js#L707-L741
req.setTimeout(longTimeout);
req.on('timeout', () => {
// This handler will be called for both of shortTimeout and longTimeout.
req.abort();
reject(new Error('socket timeout'));
});
req.once('error', reject);
const http = require('http');
const Agent = require('agentkeepalive');
const agent = new Agent({ timeout: shortTimeout });
const req = http.request({ agent });
req.setTimeout(longTimeout);
// We don't need `timeout` handler here because agentkeepalive destroys the socket on socket timeout event, we can catch it with the error handler below.
// https://github.com/node-modules/agentkeepalive/blob/3.3.0/lib/_http_agent.js#L309-L316
req.once('error', reject);
const http = require('http');
const Agent = http.Agent;
const agent = new Agent({ timeout: shortTimeout });
// This timeout option is ignored as a timeout, but this is necessary to make ClientRequest to propagate Socket's timeout event.
// ignored option in Node.js stdlib: https://github.com/nodejs/node/blob/v9.2.0/lib/_http_agent.js#L149-L150
// timeout propagation needs timeout: https://github.com/nodejs/node/blob/v9.2.0/lib/_http_client.js#L647-L655
const req = http.request({ timeout: shortTimeout, agent });
req.setTimeout(longTimeout);
req.once(‘timeout’, () => {
req.abort();
// TODO: Do we need to call reject?
});
req.once('error', reject);