fix(fetch): do not throw on empty response body with br encoding (#11708)

This commit is contained in:
Yury Semikhatsky 2022-01-28 12:58:58 -08:00 committed by GitHub
parent 7dc2dce709
commit 401cd9c0ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 14 deletions

View file

@ -328,6 +328,26 @@ export abstract class APIRequestContext extends SdkObject {
}
response.on('aborted', () => reject(new Error('aborted')));
const chunks: Buffer[] = [];
const notifyBodyFinished = () => {
const body = Buffer.concat(chunks);
notifyRequestFinished(body);
fulfill({
url: response.url || url.toString(),
status: response.statusCode || 0,
statusText: response.statusMessage || '',
headers: toHeadersArray(response.rawHeaders),
body
});
};
// These requests don't have response body.
if (['HEAD', 'PUT', 'TRACE'].includes(options.method!)) {
notifyBodyFinished();
request.destroy();
return;
}
let body: Readable = response;
let transform: Transform | undefined;
const encoding = response.headers['content-encoding'];
@ -348,20 +368,9 @@ export abstract class APIRequestContext extends SdkObject {
});
}
const chunks: Buffer[] = [];
body.on('data', chunk => chunks.push(chunk));
body.on('end', () => {
const body = Buffer.concat(chunks);
notifyRequestFinished(body);
fulfill({
url: response.url || url.toString(),
status: response.statusCode || 0,
statusText: response.statusMessage || '',
headers: toHeadersArray(response.rawHeaders),
body
});
});
body.on('error',reject);
body.on('end', notifyBodyFinished);
body.on('error', reject);
});
request.on('error', reject);

View file

@ -50,7 +50,7 @@ for (const method of ['fetch', 'delete', 'get', 'head', 'patch', 'post', 'put']
expect(response.ok()).toBeTruthy();
expect(response.headers()['content-type']).toBe('application/json; charset=utf-8');
expect(response.headersArray()).toContainEqual({ name: 'Content-Type', value: 'application/json; charset=utf-8' });
expect(await response.text()).toBe(method === 'head' ? '' : '{"foo": "bar"}\n');
expect(await response.text()).toBe(['head', 'put'].includes(method) ? '' : '{"foo": "bar"}\n');
});
}
@ -344,3 +344,22 @@ it(`should have nice toString`, async ({ playwright, server }) => {
expect(str).toContain(` ${name}: ${value}`);
await request.dispose();
});
it('should not fail on empty body with encoding', async ({ playwright, server }) => {
const request = await playwright.request.newContext();
for (const method of ['head', 'put']) {
for (const encoding of ['br', 'gzip', 'deflate']) {
server.setRoute('/empty.html', (req, res) => {
res.writeHead(200, {
'Content-Encoding': encoding,
'Content-Type': 'text/plain',
});
res.end();
});
const response = await request[method](server.EMPTY_PAGE);
expect(response.status()).toBe(200);
expect((await response.body()).length).toBe(0);
}
}
await request.dispose();
});