feat: respond multiple headers with same key (#8183)

This commit is contained in:
Junyan 2022-04-05 17:06:35 +08:00 committed by GitHub
parent 24e1469e15
commit c1dcd857e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 9 deletions

View File

@ -5122,7 +5122,7 @@ ResourceType will be one of the following: `document`, `stylesheet`, `image`, `m
- `response` <[Object]> Response that will fulfill this request
- `status` <[number]> Response status code, defaults to `200`.
- `headers` <[Object]> Optional response headers. Header values will be converted to a string.
- `headers` <[Object]> Optional response headers. Header values should be a string or a string array.
- `contentType` <[string]> If set, equals to setting `Content-Type` response header
- `body` <[string]|[Buffer]> Optional response body
- `priority` <[number]> - Optional intercept abort priority. If provided, intercept will be resolved using coopeative handling rules. Otherwise, intercept will be resolved immediately.

View File

@ -555,12 +555,15 @@ export class HTTPRequest {
? Buffer.from(response.body)
: (response.body as Buffer) || null;
const responseHeaders: Record<string, string> = {};
const responseHeaders: Record<string, string | string[]> = {};
if (response.headers) {
for (const header of Object.keys(response.headers))
responseHeaders[header.toLowerCase()] = String(
response.headers[header]
);
for (const header of Object.keys(response.headers)) {
const value = response.headers[header];
responseHeaders[header.toLowerCase()] = Array.isArray(value)
? value.map((item) => String(item))
: String(value);
}
}
if (response.contentType)
responseHeaders['content-type'] = response.contentType;
@ -696,12 +699,17 @@ const errorReasons: Record<ErrorCode, Protocol.Network.ErrorReason> = {
export type ActionResult = 'continue' | 'abort' | 'respond';
function headersArray(
headers: Record<string, string>
headers: Record<string, string | string[]>
): Array<{ name: string; value: string }> {
const result = [];
for (const name in headers) {
if (!Object.is(headers[name], undefined))
result.push({ name, value: headers[name] + '' });
const value = headers[name];
if (!Object.is(value, undefined)) {
const values = Array.isArray(value) ? value : [value];
result.push(...values.map((value) => ({ name, value: value + '' })));
}
}
return result;
}

View File

@ -710,6 +710,33 @@ describe('request interception', function () {
);
expect(response.url()).toBe(server.EMPTY_PAGE);
});
it('should allow mocking multiple headers with same key', async () => {
const { page, server } = getTestState();
await page.setRequestInterception(true);
page.on('request', (request) => {
request.respond({
status: 200,
headers: {
foo: 'bar',
arr: ['1', '2'],
'set-cookie': ['first=1', 'second=2'],
},
body: 'Hello world',
});
});
const response = await page.goto(server.EMPTY_PAGE);
const cookies = await page.cookies();
const firstCookie = cookies.find((cookie) => cookie.name === 'first');
const secondCookie = cookies.find((cookie) => cookie.name === 'second');
expect(response.status()).toBe(200);
expect(response.headers().foo).toBe('bar');
expect(response.headers().arr).toBe('1\n2');
// request.respond() will not trigger Network.responseReceivedExtraInfo
// fail to get 'set-cookie' header from response
expect(firstCookie?.value).toBe('1');
expect(secondCookie?.value).toBe('2');
});
it('should allow mocking binary responses', async () => {
const { page, server } = getTestState();