fix(fetch): be compatible with a 0 timeout (#9071)

This commit is contained in:
Max Schmitt 2021-09-22 19:30:56 +02:00 committed by GitHub
parent c66d72bddb
commit 449a593050
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 10 deletions

View file

@ -111,7 +111,7 @@ export abstract class FetchRequest extends SdkObject {
} }
const timeout = defaults.timeoutSettings.timeout(params); const timeout = defaults.timeoutSettings.timeout(params);
const deadline = monotonicTime() + timeout; const deadline = timeout && (monotonicTime() + timeout);
const options: https.RequestOptions & { maxRedirects: number, deadline: number } = { const options: https.RequestOptions & { maxRedirects: number, deadline: number } = {
method, method,
@ -279,16 +279,20 @@ export abstract class FetchRequest extends SdkObject {
body.on('error',reject); body.on('error',reject);
}); });
request.on('error', reject); request.on('error', reject);
const rejectOnTimeout = () => {
reject(new Error(`Request timed out after ${options.timeout}ms`)); if (options.deadline) {
request.abort(); const rejectOnTimeout = () => {
}; reject(new Error(`Request timed out after ${options.timeout}ms`));
const remaining = options.deadline - monotonicTime(); request.abort();
if (remaining <= 0) { };
rejectOnTimeout(); const remaining = options.deadline - monotonicTime();
return; if (remaining <= 0) {
rejectOnTimeout();
return;
}
request.setTimeout(remaining, rejectOnTimeout);
} }
request.setTimeout(remaining, rejectOnTimeout);
if (postData) if (postData)
request.write(postData); request.write(postData);
request.end(); request.end();

View file

@ -659,6 +659,23 @@ it('should support timeout option', async function({context, server}) {
expect(error.message).toContain(`Request timed out after 10ms`); expect(error.message).toContain(`Request timed out after 10ms`);
}); });
it('should support a timeout of 0', async function({context, server}) {
server.setRoute('/slow', (req, res) => {
res.writeHead(200, {
'content-length': 4,
'content-type': 'text/html',
});
setTimeout(() => {
res.end('done');
}, 50);
});
const response = await context._request.get(server.PREFIX + '/slow', {
timeout: 0,
});
expect(await response.text()).toBe('done');
});
it('should respect timeout after redirects', async function({context, server}) { it('should respect timeout after redirects', async function({context, server}) {
server.setRedirect('/redirect', '/slow'); server.setRedirect('/redirect', '/slow');
server.setRoute('/slow', (req, res) => { server.setRoute('/slow', (req, res) => {