Skip to content

Commit

Permalink
prototype network request interception
Browse files Browse the repository at this point in the history
  • Loading branch information
Thiago Perrotta committed Jun 16, 2023
1 parent 9335b4b commit 2c80473
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 15 deletions.
22 changes: 12 additions & 10 deletions src/bidiMapper/domains/network/networkRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ export class NetworkRequest {

#getBaseEventParams(): Network.BaseParameters {
return {
isBlocked: false, // TODO: Implement.
context: this.#requestWillBeSentEvent?.frameId ?? null,
navigation: this.#requestWillBeSentEvent?.loaderId ?? null,
// TODO: implement.
Expand All @@ -183,12 +184,9 @@ export class NetworkRequest {
url: this.#requestWillBeSentEvent?.request.url ?? NetworkRequest.#unknown,
method:
this.#requestWillBeSentEvent?.request.method ?? NetworkRequest.#unknown,
headers: Object.keys(
this.#requestWillBeSentEvent?.request.headers ?? []
).map((key) => ({
name: key,
value: this.#requestWillBeSentEvent?.request.headers[key],
})),
headers: NetworkRequest.#getHeaders(
this.#requestWillBeSentEvent?.request.headers
),
cookies,
// TODO: implement.
headersSize: -1,
Expand Down Expand Up @@ -322,10 +320,14 @@ export class NetworkRequest {
);
}

static #getHeaders(headers: Protocol.Network.Headers): Network.Header[] {
return Object.keys(headers).map((key) => ({
name: key,
value: headers[key],
static #getHeaders(headers?: Protocol.Network.Headers): Network.Header[] {
if (!headers) {
return [];
}

return Object.entries(headers).map(([name, value]) => ({
name,
value,
}));
}

Expand Down
75 changes: 70 additions & 5 deletions src/protocol/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

import type {ProtocolMapping} from 'devtools-protocol/types/protocol-mapping.js';

import type {Range} from './types.js';

interface EventResponse<MethodType, ParamsType> {
method: MethodType;
params: ParamsType;
Expand Down Expand Up @@ -56,6 +58,7 @@ export namespace Message {
export type CommandResponse = ResultData & Pick<RawCommandRequest, 'id'>;

export type EmptyCommand = never;
export type EmptyMessage = Record<string, never>;
export type EmptyParams = Record<string, never>;
export type EmptyResult = {result: Record<string, never>};

Expand Down Expand Up @@ -97,6 +100,7 @@ export namespace Message {
NoSuchElement = 'no such element',
NoSuchFrame = 'no such frame',
NoSuchHandle = 'no such handle',
NoSuchIntercept = 'no such intercept',
NoSuchNode = 'no such node',
NoSuchScript = 'no such script',
SessionNotCreated = 'session not created',
Expand Down Expand Up @@ -177,6 +181,12 @@ export namespace Message {
}
}

export class NoSuchInterceptException extends ErrorResponse {
constructor(message: string, stacktrace?: string) {
super(ErrorCode.NoSuchIntercept, message, stacktrace);
}
}

export class NoSuchScriptException extends ErrorResponse {
constructor(message: string, stacktrace?: string) {
super(ErrorCode.NoSuchScript, message, stacktrace);
Expand Down Expand Up @@ -1051,7 +1061,7 @@ export namespace Log {
}

export namespace Network {
export type Command = Message.EmptyCommand;
export type Command = AddInterceptCommand;

export type Result = Message.EmptyResult;

Expand Down Expand Up @@ -1081,16 +1091,22 @@ export namespace Network {
FetchErrorParams
>;

export type StringHeaderValue = {
value: string;
};

export type BinaryHeaderValue = {
binaryValue: Range<0, 255>[];
};

export type Header = {
name: string;
value?: string;
binaryValue?: number[];
};
} & (StringHeaderValue | BinaryHeaderValue);

export type Cookie = {
name: string;
value?: string;
binaryValue?: number[];
binaryValue?: Range<0, 255>[];
domain: string;
path: string;
expires?: number;
Expand Down Expand Up @@ -1129,12 +1145,16 @@ export namespace Network {
timings: FetchTimingInfo;
};

export type Intercept = string;

export type BaseParameters = {
context: CommonDataTypes.BrowsingContext | null;
isBlocked: boolean;
navigation: BrowsingContext.Navigation | null;
redirectCount: number;
request: RequestData;
timestamp: number;
intercepts?: Intercept[];
};

export type Initiator = {
Expand All @@ -1161,6 +1181,7 @@ export namespace Network {
headersSize: number | null;
bodySize: number | null;
content: ResponseContent;
authChallenge?: AuthChallenge;
};

export type BeforeRequestSentParams = BaseParameters & {
Expand All @@ -1179,6 +1200,50 @@ export namespace Network {
errorText: string;
};

export type AuthChallenge = {
scheme: string;
realm: string;
};

export type AuthCredentials = {
type: 'password'; // XXX: 'credentials'?
username: string;
password: string;
};

export type Body = StringBody | Base64Body;

export type StringBody = {
type: 'string';
value: string;
};

export type Base64Body = {
type: 'base64';
value: string;
};

export type AddInterceptCommand = {
method: 'network.addIntercept';
params: AddInterceptParameters;
};

export type AddInterceptParameters = {
phases: InterceptPhase[];
urlPatterns?: string[];
};

export type InterceptPhase =
| 'beforeRequestSent'
| 'responseStarted'
| 'authRequired';

export type AddInterceptResult = {
result: {
intercept: Intercept;
};
};

export const AllEvents = 'network';

export enum EventNames {
Expand Down
29 changes: 29 additions & 0 deletions src/protocol/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/** @see: https://stackoverflow.com/a/70307091 */
export type Enumerate<
N extends number,
Acc extends number[] = []
> = Acc['length'] extends N
? Acc[number]
: Enumerate<N, [...Acc, Acc['length']]>;

export type Range<F extends number, T extends number> = Exclude<
Enumerate<T>,
Enumerate<F>
>;
2 changes: 2 additions & 0 deletions tests/test_browsing_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,7 @@ async def test_browsingContext_ignoreCache(websocket, context_id, ignoreCache):
assert response == {
"method": "network.beforeRequestSent",
"params": {
"isBlocked": False,
"context": context_id,
"initiator": ANY_DICT,
"navigation": ANY_STR,
Expand All @@ -907,6 +908,7 @@ async def test_browsingContext_ignoreCache(websocket, context_id, ignoreCache):
assert response == {
"method": "network.responseCompleted",
"params": {
"isBlocked": False,
"context": context_id,
"navigation": ANY_STR,
"redirectCount": 0,
Expand Down
5 changes: 5 additions & 0 deletions tests/test_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ async def test_network_before_request_sent_event_emitted(
assert resp == {
"method": "network.beforeRequestSent",
"params": {
"isBlocked": False,
"context": context_id,
"navigation": ANY_STR,
"redirectCount": 0,
Expand Down Expand Up @@ -159,6 +160,7 @@ async def test_network_before_request_sent_event_with_cookies_emitted(
assert resp == {
"method": "network.beforeRequestSent",
"params": {
"isBlocked": False,
"context": context_id,
"navigation": ANY_STR,
"redirectCount": 0,
Expand Down Expand Up @@ -210,6 +212,7 @@ async def test_network_network_response_completed_event_emitted(
assert resp == {
"method": "network.responseCompleted",
"params": {
"isBlocked": False,
"context": context_id,
"navigation": ANY_STR,
"redirectCount": 0,
Expand Down Expand Up @@ -264,6 +267,7 @@ async def test_network_bad_ssl(websocket, context_id):
assert resp == {
"method": "network.fetchError",
"params": {
"isBlocked": False,
"context": context_id,
"navigation": ANY_STR,
"redirectCount": 0,
Expand Down Expand Up @@ -301,6 +305,7 @@ async def test_network_before_request_sent_event_with_data_url_emitted(
assert resp == {
"method": "network.beforeRequestSent",
"params": {
"isBlocked": False,
"context": context_id,
"navigation": ANY_STR,
"redirectCount": 0,
Expand Down

0 comments on commit 2c80473

Please sign in to comment.