feat(fetch): support new headers api (#8843)
This commit is contained in:
parent
b1b801a3a7
commit
ebdad167f2
|
|
@ -555,6 +555,10 @@ export class FetchResponse {
|
|||
return { ...this._headers };
|
||||
}
|
||||
|
||||
headersArray(): string[][] {
|
||||
return this._initializer.headers.map(({name, value}) => [name, value]);
|
||||
}
|
||||
|
||||
async body(): Promise<Buffer> {
|
||||
return this._context._wrapApiCall(async (channel: channels.BrowserContextChannel) => {
|
||||
const result = await channel.fetchResponseBody({ fetchUid: this._fetchUid() });
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ async function sendRequest(context: BrowserContext, url: URL, options: https.Req
|
|||
url: response.url || url.toString(),
|
||||
status: response.statusCode || 0,
|
||||
statusText: response.statusMessage || '',
|
||||
headers: flattenHeaders(response.headers),
|
||||
headers: toHeadersArray(response.rawHeaders),
|
||||
body
|
||||
});
|
||||
});
|
||||
|
|
@ -219,18 +219,10 @@ async function sendRequest(context: BrowserContext, url: URL, options: https.Req
|
|||
});
|
||||
}
|
||||
|
||||
function flattenHeaders(headers: http.IncomingHttpHeaders): types.HeadersArray {
|
||||
function toHeadersArray(rawHeaders: string[]): types.HeadersArray {
|
||||
const result: types.HeadersArray = [];
|
||||
for (const [name, values] of Object.entries(headers)) {
|
||||
if (values === undefined)
|
||||
continue;
|
||||
if (typeof values === 'string') {
|
||||
result.push({name, value: values as string});
|
||||
} else {
|
||||
for (const value of values)
|
||||
result.push({name, value});
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < rawHeaders.length; i += 2)
|
||||
result.push({ name: rawHeaders[i], value: rawHeaders[i + 1] });
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import http from 'http';
|
|||
import zlib from 'zlib';
|
||||
import { pipeline } from 'stream';
|
||||
import { contextTest as it, expect } from './config/browserTest';
|
||||
import type { Response } from '..';
|
||||
import { suppressCertificateWarning } from './config/utils';
|
||||
|
||||
it.skip(({ mode }) => mode !== 'default');
|
||||
|
|
@ -43,13 +42,14 @@ it.afterAll(() => {
|
|||
|
||||
it('should work', async ({context, server}) => {
|
||||
// @ts-expect-error
|
||||
const response: Response = await context._fetch(server.PREFIX + '/simple.json');
|
||||
const response = await context._fetch(server.PREFIX + '/simple.json');
|
||||
expect(response.url()).toBe(server.PREFIX + '/simple.json');
|
||||
expect(response.status()).toBe(200);
|
||||
expect(response.statusText()).toBe('OK');
|
||||
expect(response.ok()).toBeTruthy();
|
||||
expect(response.url()).toBe(server.PREFIX + '/simple.json');
|
||||
expect(response.headers()['content-type']).toBe('application/json; charset=utf-8');
|
||||
expect(response.headersArray()).toContainEqual(['Content-Type', 'application/json; charset=utf-8']);
|
||||
expect(await response.text()).toBe('{"foo": "bar"}\n');
|
||||
});
|
||||
|
||||
|
|
@ -264,6 +264,30 @@ it('should handle cookies on redirects', async ({context, server, browserName, i
|
|||
]));
|
||||
});
|
||||
|
||||
it('should return raw headers', async ({context, page, server}) => {
|
||||
server.setRoute('/headers', (req, res) => {
|
||||
// Headers array is only supported since Node v14.14.0 so we write directly to the socket.
|
||||
// res.writeHead(200, ['name-a', 'v1','name-b', 'v4','Name-a', 'v2', 'name-A', 'v3']);
|
||||
const conn = res.connection;
|
||||
conn.write('HTTP/1.1 200 OK\r\n');
|
||||
conn.write('Name-A: v1\r\n');
|
||||
conn.write('name-b: v4\r\n');
|
||||
conn.write('Name-a: v2\r\n');
|
||||
conn.write('name-A: v3\r\n');
|
||||
conn.write('\r\n');
|
||||
conn.uncork();
|
||||
conn.end();
|
||||
});
|
||||
// @ts-expect-error
|
||||
const response = await context._fetch(`${server.PREFIX}/headers`);
|
||||
expect(response.status()).toBe(200);
|
||||
const headers = response.headersArray().filter(([name, value]) => name.toLowerCase().includes('name-'));
|
||||
expect(headers).toEqual([['Name-A', 'v1'], ['name-b', 'v4'], ['Name-a', 'v2'], ['name-A', 'v3']]);
|
||||
// Last value wins, this matches Response.headers()
|
||||
expect(response.headers()['name-a']).toBe('v3');
|
||||
expect(response.headers()['name-b']).toBe('v4');
|
||||
});
|
||||
|
||||
it('should work with context level proxy', async ({browserOptions, browserType, contextOptions, server, proxyServer}) => {
|
||||
server.setRoute('/target.html', async (req, res) => {
|
||||
res.end('<title>Served by the proxy</title>');
|
||||
|
|
|
|||
Loading…
Reference in a new issue