fix(chromium): preserve header overrides in redirects (#28962)
Reference https://github.com/microsoft/playwright/issues/28758
This commit is contained in:
parent
69c9e985bf
commit
8936885a67
|
@ -285,10 +285,16 @@ export class CRNetworkManager {
|
||||||
let route = null;
|
let route = null;
|
||||||
if (requestPausedEvent) {
|
if (requestPausedEvent) {
|
||||||
// We do not support intercepting redirects.
|
// We do not support intercepting redirects.
|
||||||
if (redirectedFrom || (!this._userRequestInterceptionEnabled && this._protocolRequestInterceptionEnabled))
|
if (redirectedFrom || (!this._userRequestInterceptionEnabled && this._protocolRequestInterceptionEnabled)) {
|
||||||
this._session._sendMayFail('Fetch.continueRequest', { requestId: requestPausedEvent.requestId });
|
let headers = undefined;
|
||||||
else
|
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);
|
route = new RouteImpl(this._session, requestPausedEvent.requestId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const isNavigationRequest = requestWillBeSentEvent.requestId === requestWillBeSentEvent.loaderId && requestWillBeSentEvent.type === 'Document';
|
const isNavigationRequest = requestWillBeSentEvent.requestId === requestWillBeSentEvent.loaderId && requestWillBeSentEvent.type === 'Document';
|
||||||
const documentId = isNavigationRequest ? requestWillBeSentEvent.loaderId : undefined;
|
const documentId = isNavigationRequest ? requestWillBeSentEvent.loaderId : undefined;
|
||||||
|
@ -384,8 +390,6 @@ export class CRNetworkManager {
|
||||||
|
|
||||||
_deleteRequest(request: InterceptableRequest) {
|
_deleteRequest(request: InterceptableRequest) {
|
||||||
this._requestIdToRequest.delete(request._requestId);
|
this._requestIdToRequest.delete(request._requestId);
|
||||||
if (request._route)
|
|
||||||
request._route._alreadyContinuedParams = undefined;
|
|
||||||
if (request._interceptionId)
|
if (request._interceptionId)
|
||||||
this._attemptedAuthentications.delete(request._interceptionId);
|
this._attemptedAuthentications.delete(request._interceptionId);
|
||||||
}
|
}
|
||||||
|
@ -508,6 +512,9 @@ class InterceptableRequest {
|
||||||
readonly _timestamp: number;
|
readonly _timestamp: number;
|
||||||
readonly _wallTime: number;
|
readonly _wallTime: number;
|
||||||
readonly _route: RouteImpl | null;
|
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;
|
session: CRSession;
|
||||||
|
|
||||||
constructor(options: {
|
constructor(options: {
|
||||||
|
@ -529,6 +536,7 @@ class InterceptableRequest {
|
||||||
this._interceptionId = requestPausedEvent && requestPausedEvent.requestId;
|
this._interceptionId = requestPausedEvent && requestPausedEvent.requestId;
|
||||||
this._documentId = documentId;
|
this._documentId = documentId;
|
||||||
this._route = route;
|
this._route = route;
|
||||||
|
this._originalRequestRoute = route ?? redirectedFrom?._originalRequestRoute;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
headers,
|
headers,
|
||||||
|
|
|
@ -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('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.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 server.setRedirect('/redirect', '/empty.html');
|
||||||
await page.route('**/redirect', route => {
|
await page.route('**/redirect', route => {
|
||||||
void route.continue({
|
void route.continue({
|
||||||
headers: {
|
headers: {
|
||||||
...route.request().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');
|
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('should intercept css variable with background url', async ({ page, server }) => {
|
||||||
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/19158' });
|
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/19158' });
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue