diff --git a/src/server/fetch.ts b/src/server/fetch.ts index 0f724c3323..5027641cab 100644 --- a/src/server/fetch.ts +++ b/src/server/fetch.ts @@ -138,6 +138,18 @@ async function sendRequest(context: BrowserContext, url: URL, options: http.Requ return; } } + if (response.statusCode === 401 && !options.headers!['authorization']) { + const auth = response.headers['www-authenticate']; + const credentials = context._options.httpCredentials; + if (auth?.trim().startsWith('Basic ') && credentials) { + const {username, password} = credentials; + const encoded = Buffer.from(`${username || ''}:${password || ''}`).toString('base64'); + options.headers!['authorization'] = `Basic ${encoded}`; + fulfill(sendRequest(context, url, options, postData)); + request.abort(); + return; + } + } const chunks: Buffer[] = []; response.on('data', chunk => chunks.push(chunk)); response.on('end', () => { diff --git a/tests/browsercontext-fetch.spec.ts b/tests/browsercontext-fetch.spec.ts index d97dcf4cee..55fe552a51 100644 --- a/tests/browsercontext-fetch.spec.ts +++ b/tests/browsercontext-fetch.spec.ts @@ -241,6 +241,26 @@ it('should work with http credentials', async ({context, server}) => { expect(request.url).toBe('/empty.html'); }); +it('should work with setHTTPCredentials', async ({context, browser, server}) => { + server.setAuth('/empty.html', 'user', 'pass'); + // @ts-expect-error + const response1 = await context._fetch(server.EMPTY_PAGE); + expect(response1.status()).toBe(401); + + await context.setHTTPCredentials({ username: 'user', password: 'pass' }); + // @ts-expect-error + const response2 = await context._fetch(server.EMPTY_PAGE); + expect(response2.status()).toBe(200); +}); + +it('should return error with wrong credentials', async ({context, browser, server}) => { + server.setAuth('/empty.html', 'user', 'pass'); + await context.setHTTPCredentials({ username: 'user', password: 'wrong' }); + // @ts-expect-error + const response2 = await context._fetch(server.EMPTY_PAGE); + expect(response2.status()).toBe(401); +}); + it('should support post data', async ({context, server}) => { const [request, response] = await Promise.all([ server.waitForRequest('/simple.json'),