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 };
|
return { ...this._headers };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
headersArray(): string[][] {
|
||||||
|
return this._initializer.headers.map(({name, value}) => [name, value]);
|
||||||
|
}
|
||||||
|
|
||||||
async body(): Promise<Buffer> {
|
async body(): Promise<Buffer> {
|
||||||
return this._context._wrapApiCall(async (channel: channels.BrowserContextChannel) => {
|
return this._context._wrapApiCall(async (channel: channels.BrowserContextChannel) => {
|
||||||
const result = await channel.fetchResponseBody({ fetchUid: this._fetchUid() });
|
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(),
|
url: response.url || url.toString(),
|
||||||
status: response.statusCode || 0,
|
status: response.statusCode || 0,
|
||||||
statusText: response.statusMessage || '',
|
statusText: response.statusMessage || '',
|
||||||
headers: flattenHeaders(response.headers),
|
headers: toHeadersArray(response.rawHeaders),
|
||||||
body
|
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 = [];
|
const result: types.HeadersArray = [];
|
||||||
for (const [name, values] of Object.entries(headers)) {
|
for (let i = 0; i < rawHeaders.length; i += 2)
|
||||||
if (values === undefined)
|
result.push({ name: rawHeaders[i], value: rawHeaders[i + 1] });
|
||||||
continue;
|
|
||||||
if (typeof values === 'string') {
|
|
||||||
result.push({name, value: values as string});
|
|
||||||
} else {
|
|
||||||
for (const value of values)
|
|
||||||
result.push({name, value});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import http from 'http';
|
||||||
import zlib from 'zlib';
|
import zlib from 'zlib';
|
||||||
import { pipeline } from 'stream';
|
import { pipeline } from 'stream';
|
||||||
import { contextTest as it, expect } from './config/browserTest';
|
import { contextTest as it, expect } from './config/browserTest';
|
||||||
import type { Response } from '..';
|
|
||||||
import { suppressCertificateWarning } from './config/utils';
|
import { suppressCertificateWarning } from './config/utils';
|
||||||
|
|
||||||
it.skip(({ mode }) => mode !== 'default');
|
it.skip(({ mode }) => mode !== 'default');
|
||||||
|
|
@ -43,13 +42,14 @@ it.afterAll(() => {
|
||||||
|
|
||||||
it('should work', async ({context, server}) => {
|
it('should work', async ({context, server}) => {
|
||||||
// @ts-expect-error
|
// @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.url()).toBe(server.PREFIX + '/simple.json');
|
||||||
expect(response.status()).toBe(200);
|
expect(response.status()).toBe(200);
|
||||||
expect(response.statusText()).toBe('OK');
|
expect(response.statusText()).toBe('OK');
|
||||||
expect(response.ok()).toBeTruthy();
|
expect(response.ok()).toBeTruthy();
|
||||||
expect(response.url()).toBe(server.PREFIX + '/simple.json');
|
expect(response.url()).toBe(server.PREFIX + '/simple.json');
|
||||||
expect(response.headers()['content-type']).toBe('application/json; charset=utf-8');
|
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');
|
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}) => {
|
it('should work with context level proxy', async ({browserOptions, browserType, contextOptions, server, proxyServer}) => {
|
||||||
server.setRoute('/target.html', async (req, res) => {
|
server.setRoute('/target.html', async (req, res) => {
|
||||||
res.end('<title>Served by the proxy</title>');
|
res.end('<title>Served by the proxy</title>');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue