fix: correctly report overridden headers on redirected requests (#31409)

Fixes https://github.com/microsoft/playwright/issues/31351
This commit is contained in:
Yury Semikhatsky 2024-06-21 17:44:58 -07:00 committed by GitHub
parent 2285bcd55d
commit d74ddaebe7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 6 deletions

View File

@ -332,12 +332,13 @@ export class CRNetworkManager {
}
let route = null;
let headersOverride: types.HeadersArray | undefined;
if (requestPausedEvent) {
// We do not support intercepting redirects.
if (redirectedFrom || (!this._userRequestInterceptionEnabled && this._protocolRequestInterceptionEnabled)) {
// Chromium does not preserve header overrides between redirects, so we have to do it ourselves.
const headers = redirectedFrom?._originalRequestRoute?._alreadyContinuedParams?.headers;
requestPausedSessionInfo!.session._sendMayFail('Fetch.continueRequest', { requestId: requestPausedEvent.requestId, headers });
headersOverride = redirectedFrom?._originalRequestRoute?._alreadyContinuedParams?.headers;
requestPausedSessionInfo!.session._sendMayFail('Fetch.continueRequest', { requestId: requestPausedEvent.requestId, headers: headersOverride });
} else {
route = new RouteImpl(requestPausedSessionInfo!.session, requestPausedEvent.requestId);
}
@ -353,7 +354,8 @@ export class CRNetworkManager {
route,
requestWillBeSentEvent,
requestPausedEvent,
redirectedFrom
redirectedFrom,
headersOverride: headersOverride || null,
});
this._requestIdToRequest.set(requestWillBeSentEvent.requestId, request);
@ -361,7 +363,7 @@ export class CRNetworkManager {
// We will not receive extra info when intercepting the request.
// Use the headers from the Fetch.requestPausedPayload and release the allHeaders()
// right away, so that client can call it from the route handler.
request.request.setRawRequestHeaders(headersObjectToArray(requestPausedEvent.request.headers, '\n'));
request.request.setRawRequestHeaders(headersOverride ?? headersObjectToArray(requestPausedEvent.request.headers, '\n'));
}
(this._page?._frameManager || this._serviceWorker)!.requestStarted(request.request, route || undefined);
}
@ -568,8 +570,9 @@ class InterceptableRequest {
requestWillBeSentEvent: Protocol.Network.requestWillBeSentPayload;
requestPausedEvent: Protocol.Fetch.requestPausedPayload | undefined;
redirectedFrom: InterceptableRequest | null;
headersOverride: types.HeadersArray | null;
}) {
const { session, context, frame, documentId, route, requestWillBeSentEvent, requestPausedEvent, redirectedFrom, serviceWorker } = options;
const { session, context, frame, documentId, route, requestWillBeSentEvent, requestPausedEvent, redirectedFrom, serviceWorker, headersOverride } = options;
this.session = session;
this._timestamp = requestWillBeSentEvent.timestamp;
this._wallTime = requestWillBeSentEvent.wallTime;
@ -591,7 +594,7 @@ class InterceptableRequest {
if (entries && entries.length)
postDataBuffer = Buffer.concat(entries.map(entry => Buffer.from(entry.bytes!, 'base64')));
this.request = new network.Request(context, frame, serviceWorker, redirectedFrom?.request || null, documentId, url, type, method, postDataBuffer, headersObjectToArray(headers));
this.request = new network.Request(context, frame, serviceWorker, redirectedFrom?.request || null, documentId, url, type, method, postDataBuffer, headersOverride || headersObjectToArray(headers));
}
}

View File

@ -412,6 +412,27 @@ it('continue should propagate headers to redirects', async ({ page, server, brow
expect(serverRequest.headers['custom']).toBe('value');
});
it('redirected requests should report overridden headers', {
annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31351' }
}, async ({ page, server, browserName }) => {
it.fixme(browserName === 'firefox');
await server.setRedirect('/redirect', '/empty.html');
await page.route('**/redirect', route => {
const headers = route.request().headers();
headers['custom'] = 'value';
void route.fallback({ headers });
});
const [serverRequest, response] = await Promise.all([
server.waitForRequest('/empty.html'),
page.goto(server.PREFIX + '/redirect')
]);
expect(serverRequest.headers['custom']).toBe('value');
expect(response.request().url()).toBe(server.EMPTY_PAGE);
expect(response.request().headers()['custom']).toBe('value');
expect((await response.request().allHeaders())['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');