From 5f386a05ce0637c79e95d29863c55079a44ebf25 Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Wed, 22 Sep 2021 20:27:54 +0200 Subject: [PATCH] cherry-pick(1.15): fix(fetch): be compatible with a 0 timeout (#9071) (#9084) --- src/server/fetch.ts | 24 ++++++++++++++---------- tests/browsercontext-fetch.spec.ts | 17 +++++++++++++++++ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/server/fetch.ts b/src/server/fetch.ts index 1ba6d6fe46..77af08ddbe 100644 --- a/src/server/fetch.ts +++ b/src/server/fetch.ts @@ -111,7 +111,7 @@ export abstract class FetchRequest extends SdkObject { } const timeout = defaults.timeoutSettings.timeout(params); - const deadline = monotonicTime() + timeout; + const deadline = timeout && (monotonicTime() + timeout); const options: https.RequestOptions & { maxRedirects: number, deadline: number } = { method, @@ -276,16 +276,20 @@ export abstract class FetchRequest extends SdkObject { body.on('error',reject); }); request.on('error', reject); - const rejectOnTimeout = () => { - reject(new Error(`Request timed out after ${options.timeout}ms`)); - request.abort(); - }; - const remaining = options.deadline - monotonicTime(); - if (remaining <= 0) { - rejectOnTimeout(); - return; + + if (options.deadline) { + const rejectOnTimeout = () => { + reject(new Error(`Request timed out after ${options.timeout}ms`)); + request.abort(); + }; + const remaining = options.deadline - monotonicTime(); + if (remaining <= 0) { + rejectOnTimeout(); + return; + } + request.setTimeout(remaining, rejectOnTimeout); } - request.setTimeout(remaining, rejectOnTimeout); + if (postData) request.write(postData); request.end(); diff --git a/tests/browsercontext-fetch.spec.ts b/tests/browsercontext-fetch.spec.ts index a1b0b73a40..f14cc37f49 100644 --- a/tests/browsercontext-fetch.spec.ts +++ b/tests/browsercontext-fetch.spec.ts @@ -645,6 +645,23 @@ it('should support timeout option', async function({context, server}) { 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}) { server.setRedirect('/redirect', '/slow'); server.setRoute('/slow', (req, res) => {