mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-01 08:34:02 +03:00
fix(chromium): make interception work with dedicated workers (#4658)
This commit is contained in:
parent
b9c959768c
commit
495085cbb2
@ -200,6 +200,11 @@ export class CRNetworkManager {
|
||||
}
|
||||
}
|
||||
let frame = requestWillBeSentEvent.frameId ? this._page._frameManager.frame(requestWillBeSentEvent.frameId) : workerFrame;
|
||||
// Requests from workers lack frameId, because we receive Network.requestWillBeSent
|
||||
// on the worker target. However, we receive Fetch.requestPaused on the page target,
|
||||
// and lack workerFrame there. Luckily, Fetch.requestPaused provides a frameId.
|
||||
if (!frame && requestPausedEvent && requestPausedEvent.frameId)
|
||||
frame = this._page._frameManager.frame(requestPausedEvent.frameId);
|
||||
|
||||
// Check if it's main resource request interception (targetId === main frame id).
|
||||
if (!frame && requestPausedEvent && requestWillBeSentEvent.frameId === (this._page._delegate as CRPage)._targetId) {
|
||||
@ -209,32 +214,36 @@ export class CRNetworkManager {
|
||||
frame = this._page._frameManager.frameAttached(requestWillBeSentEvent.frameId, null);
|
||||
}
|
||||
|
||||
if (!frame) {
|
||||
if (requestPausedEvent) {
|
||||
// CORS options request is generated by the network stack, it is not associated with the frame id.
|
||||
// If URL matches interception pattern, accept it, assuming that this was intended when setting route.
|
||||
if (requestPausedEvent.request.method === 'OPTIONS' && this._page._needsRequestInterception()) {
|
||||
const requestHeaders = requestPausedEvent.request.headers;
|
||||
const responseHeaders: Protocol.Fetch.HeaderEntry[] = [
|
||||
{ name: 'Access-Control-Allow-Origin', value: requestHeaders['Origin'] || '*' },
|
||||
{ name: 'Access-Control-Allow-Methods', value: requestHeaders['Access-Control-Request-Method'] || 'GET, POST, OPTIONS, DELETE' },
|
||||
{ name: 'Access-Control-Allow-Credentials', value: 'true' }
|
||||
];
|
||||
if (requestHeaders['Access-Control-Request-Headers'])
|
||||
responseHeaders.push({ name: 'Access-Control-Allow-Headers', value: requestHeaders['Access-Control-Request-Headers'] });
|
||||
this._client._sendMayFail('Fetch.fulfillRequest', {
|
||||
requestId: requestPausedEvent.requestId,
|
||||
responseCode: 204,
|
||||
responsePhrase: network.STATUS_TEXTS['204'],
|
||||
responseHeaders,
|
||||
body: '',
|
||||
});
|
||||
} else {
|
||||
this._client._sendMayFail('Fetch.continueRequest', { requestId: requestPausedEvent.requestId });
|
||||
}
|
||||
}
|
||||
// CORS options request is generated by the network stack. If interception is enabled,
|
||||
// we accept all CORS options, assuming that this was intended when setting route.
|
||||
//
|
||||
// Note: it would be better to match the URL against interception patterns, but
|
||||
// that information is only available to the client. Perhaps we can just route to the client?
|
||||
if (requestPausedEvent && requestPausedEvent.request.method === 'OPTIONS' && this._page._needsRequestInterception()) {
|
||||
const requestHeaders = requestPausedEvent.request.headers;
|
||||
const responseHeaders: Protocol.Fetch.HeaderEntry[] = [
|
||||
{ name: 'Access-Control-Allow-Origin', value: requestHeaders['Origin'] || '*' },
|
||||
{ name: 'Access-Control-Allow-Methods', value: requestHeaders['Access-Control-Request-Method'] || 'GET, POST, OPTIONS, DELETE' },
|
||||
{ name: 'Access-Control-Allow-Credentials', value: 'true' }
|
||||
];
|
||||
if (requestHeaders['Access-Control-Request-Headers'])
|
||||
responseHeaders.push({ name: 'Access-Control-Allow-Headers', value: requestHeaders['Access-Control-Request-Headers'] });
|
||||
this._client._sendMayFail('Fetch.fulfillRequest', {
|
||||
requestId: requestPausedEvent.requestId,
|
||||
responseCode: 204,
|
||||
responsePhrase: network.STATUS_TEXTS['204'],
|
||||
responseHeaders,
|
||||
body: '',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!frame) {
|
||||
if (requestPausedEvent)
|
||||
this._client._sendMayFail('Fetch.continueRequest', { requestId: requestPausedEvent.requestId });
|
||||
return;
|
||||
}
|
||||
|
||||
let allowInterception = this._userRequestInterceptionEnabled;
|
||||
if (redirectedFrom) {
|
||||
allowInterception = false;
|
||||
|
@ -88,18 +88,15 @@ it('should work with glob', async () => {
|
||||
expect(globToRegex('**/*.{png,jpg,jpeg}').test('https://localhost:8080/c.css')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should intercept network activity from worker', (test, {browserName}) => {
|
||||
// @see https://github.com/microsoft/playwright/issues/4487
|
||||
test.fixme(browserName === 'chromium');
|
||||
}, async function({page, server}) {
|
||||
it('should intercept network activity from worker', async function({page, server}) {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
server.setRoute('/data_for_worker', (req, res) => res.end('failed to intercept'));
|
||||
const url = server.PREFIX + '/data_for_worker';
|
||||
page.route(url, async route => {
|
||||
await route.fulfill({
|
||||
await page.route(url, route => {
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
body: 'intercepted',
|
||||
});
|
||||
}).catch(e => null);
|
||||
});
|
||||
const [msg] = await Promise.all([
|
||||
page.waitForEvent('console'),
|
||||
@ -110,6 +107,22 @@ it('should intercept network activity from worker', (test, {browserName}) => {
|
||||
expect(msg.text()).toBe('intercepted');
|
||||
});
|
||||
|
||||
it('should intercept network activity from worker', async function({page, server}) {
|
||||
const url = server.PREFIX + '/worker/worker.js';
|
||||
await page.route(url, route => {
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
body: 'console.log("intercepted");',
|
||||
contentType: 'application/javascript',
|
||||
}).catch(e => null);
|
||||
});
|
||||
const [msg] = await Promise.all([
|
||||
page.waitForEvent('console'),
|
||||
page.goto(server.PREFIX + '/worker/worker.html'),
|
||||
]);
|
||||
expect(msg.text()).toBe('intercepted');
|
||||
});
|
||||
|
||||
it('should work with regular expression passed from a different context', async ({page, server}) => {
|
||||
const ctx = vm.createContext();
|
||||
const regexp = vm.runInContext('new RegExp("empty\\.html")', ctx);
|
||||
|
Loading…
Reference in New Issue
Block a user