mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
chore(webdriver): support options in request.continue
(#12155)
This commit is contained in:
parent
b144935789
commit
6edb80b2a5
@ -5,6 +5,9 @@
|
||||
*/
|
||||
import type {Protocol} from 'devtools-protocol';
|
||||
|
||||
import type {ProtocolError} from '../common/Errors.js';
|
||||
import {debugError} from '../common/util.js';
|
||||
|
||||
import type {CDPSession} from './CDPSession.js';
|
||||
import type {Frame} from './Frame.js';
|
||||
import type {HTTPResponse} from './HTTPResponse.js';
|
||||
@ -513,3 +516,16 @@ export const STATUS_TEXTS: Record<string, string> = {
|
||||
'510': 'Not Extended',
|
||||
'511': 'Network Authentication Required',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function handleError(error: ProtocolError): void {
|
||||
if (error.originalMessage.includes('Invalid header')) {
|
||||
throw error;
|
||||
}
|
||||
// In certain cases, protocol will return error if the request was
|
||||
// already canceled or the page was closed. We should tolerate these
|
||||
// errors.
|
||||
debugError(error);
|
||||
}
|
||||
|
@ -14,10 +14,10 @@ import {
|
||||
HTTPRequest,
|
||||
STATUS_TEXTS,
|
||||
type ResourceType,
|
||||
handleError,
|
||||
} from '../api/HTTPRequest.js';
|
||||
import {PageEvent} from '../api/Page.js';
|
||||
import {UnsupportedOperation} from '../common/Errors.js';
|
||||
import {isString} from '../common/util.js';
|
||||
|
||||
import type {Request} from './core/Request.js';
|
||||
import type {BidiFrame} from './Frame.js';
|
||||
@ -148,9 +148,33 @@ export class BidiHTTPRequest extends HTTPRequest {
|
||||
}
|
||||
|
||||
override async continue(
|
||||
_overrides: ContinueRequestOverrides = {}
|
||||
overrides: ContinueRequestOverrides = {}
|
||||
): Promise<void> {
|
||||
return await this.#request.continueRequest();
|
||||
if (!this.#request.isBlocked) {
|
||||
throw new Error('Request Interception is not enabled!');
|
||||
}
|
||||
// Request interception is not supported for data: urls.
|
||||
if (this.url().startsWith('data:')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const headers: Bidi.Network.Header[] = getBidiHeaders(overrides.headers);
|
||||
|
||||
return await this.#request
|
||||
.continueRequest({
|
||||
url: overrides.url,
|
||||
method: overrides.method,
|
||||
body: overrides.postData
|
||||
? {
|
||||
type: 'base64',
|
||||
value: btoa(overrides.postData),
|
||||
}
|
||||
: undefined,
|
||||
headers: headers.length > 0 ? headers : undefined,
|
||||
})
|
||||
.catch(error => {
|
||||
return handleError(error);
|
||||
});
|
||||
}
|
||||
|
||||
override responseForRequest(): never {
|
||||
@ -174,6 +198,13 @@ export class BidiHTTPRequest extends HTTPRequest {
|
||||
}
|
||||
|
||||
override async abort(): Promise<void> {
|
||||
if (!this.#request.isBlocked) {
|
||||
throw new Error('Request Interception is not enabled!');
|
||||
}
|
||||
// Request interception is not supported for data: urls.
|
||||
if (this.url().startsWith('data:')) {
|
||||
return;
|
||||
}
|
||||
return await this.#request.failRequest();
|
||||
}
|
||||
|
||||
@ -181,25 +212,25 @@ export class BidiHTTPRequest extends HTTPRequest {
|
||||
response: Partial<ResponseForRequest>,
|
||||
_priority?: number
|
||||
): Promise<void> {
|
||||
const responseBody: Buffer | null =
|
||||
response.body && isString(response.body)
|
||||
? Buffer.from(response.body)
|
||||
: (response.body as Buffer) || null;
|
||||
|
||||
const headers: Bidi.Network.Header[] = [];
|
||||
let hasContentLength = false;
|
||||
for (const [name, value] of Object.entries(response.headers ?? [])) {
|
||||
if (name.toLocaleLowerCase() === 'content-length') {
|
||||
hasContentLength = true;
|
||||
}
|
||||
headers.push({
|
||||
name: name.toLowerCase(),
|
||||
value: {
|
||||
type: 'string',
|
||||
value: String(value),
|
||||
},
|
||||
});
|
||||
if (!this.#request.isBlocked) {
|
||||
throw new Error('Request Interception is not enabled!');
|
||||
}
|
||||
// Request interception is not supported for data: urls.
|
||||
if (this.url().startsWith('data:')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const responseBody: string | undefined =
|
||||
response.body && response.body instanceof Uint8Array
|
||||
? response.body.toString('base64')
|
||||
: response.body
|
||||
? btoa(response.body)
|
||||
: undefined;
|
||||
|
||||
const headers: Bidi.Network.Header[] = getBidiHeaders(response.headers);
|
||||
const hasContentLength = headers.some(header => {
|
||||
return header.name === 'content-length';
|
||||
});
|
||||
|
||||
if (response.contentType) {
|
||||
headers.push({
|
||||
@ -210,16 +241,17 @@ export class BidiHTTPRequest extends HTTPRequest {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (responseBody && !hasContentLength) {
|
||||
const encoder = new TextEncoder();
|
||||
headers.push({
|
||||
name: 'content-length',
|
||||
value: {
|
||||
type: 'string',
|
||||
value: String(Buffer.byteLength(responseBody)),
|
||||
value: String(encoder.encode(responseBody).byteLength),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const status = response.status || 200;
|
||||
|
||||
return await this.#request.provideResponse({
|
||||
@ -229,9 +261,24 @@ export class BidiHTTPRequest extends HTTPRequest {
|
||||
body: responseBody
|
||||
? {
|
||||
type: 'base64',
|
||||
value: responseBody.toString('base64'),
|
||||
value: responseBody,
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getBidiHeaders(rawHeaders?: Record<string, unknown>) {
|
||||
const headers: Bidi.Network.Header[] = [];
|
||||
for (const [name, value] of Object.entries(rawHeaders ?? [])) {
|
||||
headers.push({
|
||||
name: name.toLowerCase(),
|
||||
value: {
|
||||
type: 'string',
|
||||
value: String(value),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
@ -141,29 +141,29 @@ export class Request extends EventEmitter<{
|
||||
get url(): string {
|
||||
return this.#event.request.url;
|
||||
}
|
||||
get isBlocked(): boolean {
|
||||
return this.#event.isBlocked;
|
||||
}
|
||||
// keep-sorted end
|
||||
|
||||
async continueRequest(): Promise<void> {
|
||||
if (!this.#event.isBlocked) {
|
||||
throw new Error('Request Interception is not enabled!');
|
||||
}
|
||||
// Request interception is not supported for data: urls.
|
||||
if (this.url.startsWith('data:')) {
|
||||
return;
|
||||
}
|
||||
async continueRequest({
|
||||
url,
|
||||
method,
|
||||
headers,
|
||||
cookies,
|
||||
body,
|
||||
}: Omit<Bidi.Network.ContinueRequestParameters, 'request'>): Promise<void> {
|
||||
await this.#session.send('network.continueRequest', {
|
||||
request: this.id,
|
||||
url,
|
||||
method,
|
||||
headers,
|
||||
body,
|
||||
cookies,
|
||||
});
|
||||
}
|
||||
|
||||
async failRequest(): Promise<void> {
|
||||
if (!this.#event.isBlocked) {
|
||||
throw new Error('Request Interception is not enabled!');
|
||||
}
|
||||
// Request interception is not supported for data: urls.
|
||||
if (this.url.startsWith('data:')) {
|
||||
return;
|
||||
}
|
||||
await this.#session.send('network.failRequest', {
|
||||
request: this.id,
|
||||
});
|
||||
@ -175,13 +175,6 @@ export class Request extends EventEmitter<{
|
||||
headers,
|
||||
body,
|
||||
}: Omit<Bidi.Network.ProvideResponseParameters, 'request'>): Promise<void> {
|
||||
if (!this.#event.isBlocked) {
|
||||
throw new Error('Request Interception is not enabled!');
|
||||
}
|
||||
// Request interception is not supported for data: urls.
|
||||
if (this.url.startsWith('data:')) {
|
||||
return;
|
||||
}
|
||||
await this.#session.send('network.provideResponse', {
|
||||
request: this.id,
|
||||
statusCode,
|
||||
|
@ -17,8 +17,8 @@ import {
|
||||
type ResourceType,
|
||||
type ResponseForRequest,
|
||||
STATUS_TEXTS,
|
||||
handleError,
|
||||
} from '../api/HTTPRequest.js';
|
||||
import type {ProtocolError} from '../common/Errors.js';
|
||||
import {debugError, isString} from '../common/util.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
|
||||
@ -438,13 +438,3 @@ const errorReasons: Record<ErrorCode, Protocol.Network.ErrorReason> = {
|
||||
timedout: 'TimedOut',
|
||||
failed: 'Failed',
|
||||
} as const;
|
||||
|
||||
async function handleError(error: ProtocolError) {
|
||||
if (['Invalid header'].includes(error.originalMessage)) {
|
||||
throw error;
|
||||
}
|
||||
// In certain cases, protocol will return error if the request was
|
||||
// already canceled or the page was closed. We should tolerate these
|
||||
// errors.
|
||||
debugError(error);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user