mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(interception): make set-cookie work in chromium (#9299)
This commit is contained in:
parent
4171dfb57f
commit
c516729544
@ -514,13 +514,14 @@ class RouteImpl implements network.RouteDelegate {
|
|||||||
this._wasFulfilled = true;
|
this._wasFulfilled = true;
|
||||||
const body = response.isBase64 ? response.body : Buffer.from(response.body).toString('base64');
|
const body = response.isBase64 ? response.body : Buffer.from(response.body).toString('base64');
|
||||||
|
|
||||||
|
const responseHeaders = splitSetCookieHeader(response.headers);
|
||||||
// In certain cases, protocol will return error if the request was already canceled
|
// In certain cases, protocol will return error if the request was already canceled
|
||||||
// or the page was closed. We should tolerate these errors.
|
// or the page was closed. We should tolerate these errors.
|
||||||
await this._client._sendMayFail('Fetch.fulfillRequest', {
|
await this._client._sendMayFail('Fetch.fulfillRequest', {
|
||||||
requestId: this._interceptionId!,
|
requestId: this._interceptionId!,
|
||||||
responseCode: response.status,
|
responseCode: response.status,
|
||||||
responsePhrase: network.STATUS_TEXTS[String(response.status)],
|
responsePhrase: network.STATUS_TEXTS[String(response.status)],
|
||||||
responseHeaders: response.headers,
|
responseHeaders,
|
||||||
body,
|
body,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -537,6 +538,20 @@ class RouteImpl implements network.RouteDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function splitSetCookieHeader(headers: types.HeadersArray): types.HeadersArray {
|
||||||
|
const index = headers.findIndex(({ name }) => name.toLowerCase() === 'set-cookie');
|
||||||
|
if (index === -1)
|
||||||
|
return headers;
|
||||||
|
|
||||||
|
const header = headers[index];
|
||||||
|
const values = header.value.split('\n');
|
||||||
|
if (values.length === 1)
|
||||||
|
return headers;
|
||||||
|
const result = headers.slice();
|
||||||
|
result.splice(index, 1, ...values.map(value => ({ name: header.name, value })));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
const errorReasons: { [reason: string]: Protocol.Network.ErrorReason } = {
|
const errorReasons: { [reason: string]: Protocol.Network.ErrorReason } = {
|
||||||
'aborted': 'Aborted',
|
'aborted': 'Aborted',
|
||||||
'accessdenied': 'AccessDenied',
|
'accessdenied': 'AccessDenied',
|
||||||
|
|||||||
@ -248,3 +248,54 @@ it('should fetch original request and fulfill', async ({ page, server, isElectro
|
|||||||
expect(response.status()).toBe(200);
|
expect(response.status()).toBe(200);
|
||||||
expect(await page.title()).toEqual('Woof-Woof');
|
expect(await page.title()).toEqual('Woof-Woof');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should fulfill with multiple set-cookie', async ({ page, server, browserName }) => {
|
||||||
|
it.fail(browserName === 'webkit', 'Response contained invalid HTTP headers');
|
||||||
|
const cookies = ['a=b', 'c=d'];
|
||||||
|
await page.route('**/empty.html', async route => {
|
||||||
|
route.fulfill({
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
'X-Header-1': 'v1',
|
||||||
|
'Set-Cookie': cookies.join('\n'),
|
||||||
|
'X-Header-2': 'v2',
|
||||||
|
},
|
||||||
|
body: ''
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const response = await page.goto(server.EMPTY_PAGE);
|
||||||
|
expect((await page.evaluate(() => document.cookie)).split(';').map(s => s.trim()).sort()).toEqual(cookies);
|
||||||
|
expect(await response.headerValue('X-Header-1')).toBe('v1');
|
||||||
|
expect(await response.headerValue('X-Header-2')).toBe('v2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fulfill with fetch response that has multiple set-cookie', async ({ playwright, page, server, browserName }) => {
|
||||||
|
it.fail(browserName === 'webkit', 'Response contained invalid HTTP headers');
|
||||||
|
server.setRoute('/empty.html', (req, res) => {
|
||||||
|
res.setHeader('Set-Cookie', ['a=b', 'c=d']);
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
await page.route('**/empty.html', async route => {
|
||||||
|
const request = await playwright._newRequest();
|
||||||
|
const response = await request.fetch(route.request());
|
||||||
|
route.fulfill({ response });
|
||||||
|
});
|
||||||
|
await page.goto(server.EMPTY_PAGE);
|
||||||
|
const cookie = await page.evaluate(() => document.cookie);
|
||||||
|
expect(cookie.split(';').map(s => s.trim()).sort()).toEqual(['a=b', 'c=d']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('headerValue should return set-cookie from intercepted response', async ({ page, server, browserName }) => {
|
||||||
|
it.fail(browserName === 'chromium', 'Set-Cookie is missing in response after interception');
|
||||||
|
await page.route('**/empty.html', async route => {
|
||||||
|
route.fulfill({
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
'Set-Cookie': 'a=b',
|
||||||
|
},
|
||||||
|
body: ''
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const response = await page.goto(server.EMPTY_PAGE);
|
||||||
|
expect(await response.headerValue('Set-Cookie')).toBe('a=b');
|
||||||
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user