fix: fulfill intercepted response with empty body (#8151)

This commit is contained in:
Yury Semikhatsky 2021-08-11 14:47:05 -07:00 committed by GitHub
parent f434c41523
commit 59df541de5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 10 deletions

View file

@ -265,7 +265,7 @@ export class Route extends ChannelOwner<channels.RouteChannel, channels.RouteIni
async fulfill(options: { status?: number, headers?: Headers, contentType?: string, body?: string | Buffer, path?: string } = {}) {
return this._wrapApiCall(async (channel: channels.RouteChannel) => {
let body = '';
let body = undefined;
let isBase64 = false;
let length = 0;
if (options.path) {

View file

@ -179,15 +179,25 @@ const internalCauseToResourceType: {[key: string]: string} = {
class InterceptableRequest {
readonly request: network.Request;
readonly _id: string;
private _redirectedTo: InterceptableRequest | undefined;
constructor(frame: frames.Frame, redirectedFrom: InterceptableRequest | null, payload: Protocol.Network.requestWillBeSentPayload) {
this._id = payload.requestId;
if (redirectedFrom)
redirectedFrom._redirectedTo = this;
let postDataBuffer = null;
if (payload.postData)
postDataBuffer = Buffer.from(payload.postData, 'base64');
this.request = new network.Request(frame, redirectedFrom ? redirectedFrom.request : null, payload.navigationId,
payload.url, internalCauseToResourceType[payload.internalCause] || causeToResourceType[payload.cause] || 'other', payload.method, postDataBuffer, payload.headers);
}
_finalRequest(): InterceptableRequest {
let request: InterceptableRequest = this;
while (request._redirectedTo)
request = request._redirectedTo;
return request;
}
}
class FFRouteImpl implements network.RouteDelegate {
@ -199,12 +209,9 @@ class FFRouteImpl implements network.RouteDelegate {
this._request = request;
}
async responseBody(forFulfill: boolean): Promise<Buffer> {
// Empty buffer will result in the response being used.
if (forFulfill)
return Buffer.from('');
async responseBody(): Promise<Buffer> {
const response = await this._session.send('Network.getResponseBody', {
requestId: this._request._id
requestId: this._request._finalRequest()._id
});
return Buffer.from(response.base64body, 'base64');
}

View file

@ -222,9 +222,9 @@ export class Route extends SdkObject {
this._handled = true;
let body = overrides.body;
let isBase64 = overrides.isBase64 || false;
if (!body) {
if (body === undefined) {
if (this._response) {
body = (await this._delegate.responseBody(true)).toString('utf8');
body = (await this._delegate.responseBody()).toString('utf8');
isBase64 = false;
} else {
body = '';
@ -254,7 +254,7 @@ export class Route extends SdkObject {
async responseBody(): Promise<Buffer> {
assert(!this._handled, 'Route is already handled!');
return this._delegate.responseBody(false);
return this._delegate.responseBody();
}
}
@ -474,7 +474,7 @@ export interface RouteDelegate {
abort(errorCode: string): Promise<void>;
fulfill(response: types.NormalizedFulfillResponse): Promise<void>;
continue(request: Request, overrides: types.NormalizedContinueOverrides): Promise<InterceptedResponse|null>;
responseBody(forFulfill: boolean): Promise<Buffer>;
responseBody(): Promise<Buffer>;
}
// List taken from https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml with extra 306 and 418 codes.

View file

@ -40,6 +40,21 @@ it('should fulfill intercepted response', async ({page, server, browserName}) =>
expect(await page.evaluate(() => document.body.textContent)).toBe('Yo, page!');
});
it('should fulfill response with empty body', async ({page, server, browserName}) => {
it.fail(browserName === 'firefox');
await page.route('**/*', async route => {
// @ts-expect-error
await route._intercept({});
await route.fulfill({
status: 201,
body: ''
});
});
const response = await page.goto(server.PREFIX + '/title.html');
expect(response.status()).toBe(201);
expect(await response.text()).toBe('');
});
it('should throw on continue after intercept', async ({page, server, browserName}) => {
let routeCallback;
const routePromise = new Promise<Route>(f => routeCallback = f);