fix(chromium): preserve header overrides in redirects (#28962)

Reference https://github.com/microsoft/playwright/issues/28758
This commit is contained in:
Yury Semikhatsky 2024-01-12 08:55:20 -08:00 committed by GitHub
parent 69c9e985bf
commit 8936885a67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 7 deletions

View File

@ -285,10 +285,16 @@ export class CRNetworkManager {
let route = null;
if (requestPausedEvent) {
// We do not support intercepting redirects.
if (redirectedFrom || (!this._userRequestInterceptionEnabled && this._protocolRequestInterceptionEnabled))
this._session._sendMayFail('Fetch.continueRequest', { requestId: requestPausedEvent.requestId });
else
if (redirectedFrom || (!this._userRequestInterceptionEnabled && this._protocolRequestInterceptionEnabled)) {
let headers = undefined;
const previousHeaderOverrides = redirectedFrom?._originalRequestRoute?._alreadyContinuedParams?.headers;
// Chromium does not preserve header overrides between redirects, so we have to do it ourselves.
if (previousHeaderOverrides)
headers = network.mergeHeaders([headersObjectToArray(requestPausedEvent.request.headers, '\n'), previousHeaderOverrides]);
this._session._sendMayFail('Fetch.continueRequest', { requestId: requestPausedEvent.requestId, headers });
} else {
route = new RouteImpl(this._session, requestPausedEvent.requestId);
}
}
const isNavigationRequest = requestWillBeSentEvent.requestId === requestWillBeSentEvent.loaderId && requestWillBeSentEvent.type === 'Document';
const documentId = isNavigationRequest ? requestWillBeSentEvent.loaderId : undefined;
@ -384,8 +390,6 @@ export class CRNetworkManager {
_deleteRequest(request: InterceptableRequest) {
this._requestIdToRequest.delete(request._requestId);
if (request._route)
request._route._alreadyContinuedParams = undefined;
if (request._interceptionId)
this._attemptedAuthentications.delete(request._interceptionId);
}
@ -508,6 +512,9 @@ class InterceptableRequest {
readonly _timestamp: number;
readonly _wallTime: number;
readonly _route: RouteImpl | null;
// Only first request in the chain can be intercepted, so this will
// store the first and only Route in the chain (if any).
readonly _originalRequestRoute: RouteImpl | undefined;
session: CRSession;
constructor(options: {
@ -529,6 +536,7 @@ class InterceptableRequest {
this._interceptionId = requestPausedEvent && requestPausedEvent.requestId;
this._documentId = documentId;
this._route = route;
this._originalRequestRoute = route ?? redirectedFrom?._originalRequestRoute;
const {
headers,

View File

@ -395,13 +395,13 @@ it('should continue preload link requests', async ({ page, server, browserName }
it('continue should propagate headers to redirects', async ({ page, server, browserName }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/28758' });
it.fixme(browserName !== 'webkit');
it.fixme(browserName === 'firefox');
await server.setRedirect('/redirect', '/empty.html');
await page.route('**/redirect', route => {
void route.continue({
headers: {
...route.request().headers(),
'custom': 'value'
custom: 'value'
}
});
});
@ -412,6 +412,38 @@ it('continue should propagate headers to redirects', async ({ page, server, brow
expect(serverRequest.headers['custom']).toBe('value');
});
it('continue should delete headers on redirects', async ({ page, server, browserName }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/13106' });
it.fixme(browserName === 'firefox');
await page.goto(server.PREFIX + '/empty.html');
server.setRoute('/something', (request, response) => {
response.writeHead(200, { 'Access-Control-Allow-Origin': '*' });
response.end('done');
});
await server.setRedirect('/redirect', '/something');
await page.route('**/redirect', route => {
void route.continue({
headers: {
...route.request().headers(),
foo: undefined
}
});
});
const [text, serverRequest] = await Promise.all([
page.evaluate(async url => {
const data = await fetch(url, {
headers: {
foo: 'a',
}
});
return data.text();
}, server.PREFIX + '/redirect'),
server.waitForRequest('/something')
]);
expect(text).toBe('done');
expect(serverRequest.headers.foo).toBeFalsy();
});
it('should intercept css variable with background url', async ({ page, server }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/19158' });