Skip to content

Commit

Permalink
fix: don't unblock on interception removed (#2135)
Browse files Browse the repository at this point in the history
Closes #2147
  • Loading branch information
Lightning00Blade authored Oct 17, 2024
1 parent 05973f5 commit b6cc9a1
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 19 deletions.
118 changes: 116 additions & 2 deletions src/bidiMapper/modules/cdp/CdpTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ import type {PreloadScriptStorage} from '../script/PreloadScriptStorage.js';
import type {RealmStorage} from '../script/RealmStorage.js';
import type {EventManager} from '../session/EventManager.js';

interface FetchStages {
request: boolean;
response: boolean;
auth: boolean;
}
export class CdpTarget {
readonly #id: Protocol.Target.TargetID;
readonly #cdpClient: CdpClient;
Expand All @@ -53,7 +58,7 @@ export class CdpTarget {
#deviceAccessEnabled = false;
#cacheDisableState = false;
#networkDomainEnabled = false;
#fetchDomainStages = {
#fetchDomainStages: FetchStages = {
request: false,
response: false,
auth: false,
Expand Down Expand Up @@ -290,7 +295,24 @@ export class CdpTarget {
handleAuthRequests: stages.auth,
});
} else {
await this.#cdpClient.sendCommand('Fetch.disable');
const blockedRequest = this.#networkStorage
.getRequestsByTarget(this)
.filter((request) => request.interceptPhase);
void Promise.allSettled(
blockedRequest.map((request) => request.waitNextPhase),
)
.then(async () => {
const blockedRequest = this.#networkStorage
.getRequestsByTarget(this)
.filter((request) => request.interceptPhase);
if (blockedRequest.length) {
return await this.toggleFetchIfNeeded();
}
return await this.#cdpClient.sendCommand('Fetch.disable');
})
.catch((error) => {
this.#logger?.(LogType.bidi, 'Disable failed', error);
});
}
}

Expand Down Expand Up @@ -400,6 +422,98 @@ export class CdpTarget {
});
}

async #toggleNetwork(enable: boolean): Promise<void> {
this.#networkDomainEnabled = enable;
try {
await this.#cdpClient.sendCommand(
enable ? 'Network.enable' : 'Network.disable',
);
} catch {
this.#networkDomainEnabled = !enable;
}
}

async #enableFetch(stages: FetchStages) {
const patterns: Protocol.Fetch.EnableRequest['patterns'] = [];

if (stages.request || stages.auth) {
// CDP quirk we need request interception when we intercept auth
patterns.push({
urlPattern: '*',
requestStage: 'Request',
});
}
if (stages.response) {
patterns.push({
urlPattern: '*',
requestStage: 'Response',
});
}
if (
// Only enable interception when Network is enabled
this.#networkDomainEnabled &&
patterns.length
) {
const oldStages = this.#fetchDomainStages;
this.#fetchDomainStages = stages;
try {
await this.#cdpClient.sendCommand('Fetch.enable', {
patterns,
handleAuthRequests: stages.auth,
});
} catch {
this.#fetchDomainStages = oldStages;
}
}
}

async #disableFetch() {
const blockedRequest = this.#networkStorage
.getRequestsByTarget(this)
.filter((request) => request.interceptPhase);

if (blockedRequest.length === 0) {
this.#fetchDomainStages = {
request: false,
response: false,
auth: false,
};
await this.#cdpClient.sendCommand('Fetch.disable');
}
}

async toggleNetwork() {
const stages = this.#networkStorage.getInterceptionStages(this.topLevelId);
const fetchEnable = Object.values(stages).some((value) => value);
const fetchChanged =
this.#fetchDomainStages.request !== stages.request ||
this.#fetchDomainStages.response !== stages.response ||
this.#fetchDomainStages.auth !== stages.auth;
const networkEnable = this.isSubscribedTo(BiDiModule.Network);
const networkChanged = this.#networkDomainEnabled !== networkEnable;

this.#logger?.(
LogType.debugInfo,
'Toggle Network',
`Fetch (${fetchEnable}) ${fetchChanged}`,
`Network (${networkEnable}) ${networkChanged}`,
);

if (networkEnable && networkChanged) {
await this.#toggleNetwork(true);
}
if (fetchEnable && fetchChanged) {
await this.#enableFetch(stages);
}
if (!fetchEnable && fetchChanged) {
await this.#disableFetch();
}

if (!networkEnable && networkChanged && !fetchEnable && !fetchChanged) {
await this.#toggleNetwork(false);
}
}

/**
* All the ProxyChannels from all the preload scripts of the given
* BrowsingContext.
Expand Down
4 changes: 2 additions & 2 deletions src/bidiMapper/modules/network/NetworkProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class NetworkProcessor {

await Promise.all(
this.#browsingContextStorage.getAllContexts().map((context) => {
return context.cdpTarget.toggleFetchIfNeeded();
return context.cdpTarget.toggleNetwork();
}),
);

Expand Down Expand Up @@ -181,7 +181,7 @@ export class NetworkProcessor {

await Promise.all(
this.#browsingContextStorage.getAllContexts().map((context) => {
return context.cdpTarget.toggleFetchIfNeeded();
return context.cdpTarget.toggleNetwork();
}),
);

Expand Down
4 changes: 4 additions & 0 deletions src/bidiMapper/modules/network/NetworkRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,10 @@ export class NetworkRequest {
this.#interceptPhase = undefined;
}

dispose() {
this.waitNextPhase.reject(new Error('waitNextPhase disposed'));
}

async #continueWithAuth(
authChallengeResponse: Protocol.Fetch.ContinueWithAuthRequest['authChallengeResponse'],
) {
Expand Down
11 changes: 11 additions & 0 deletions src/bidiMapper/modules/network/NetworkStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ export class NetworkStorage {
for (const request of this.#requests.values()) {
if (request.cdpClient.sessionId === sessionId) {
this.#requests.delete(request.id);
request.dispose();
}
}
}
Expand Down Expand Up @@ -298,6 +299,16 @@ export class NetworkStorage {
this.#intercepts.delete(intercept);
}

getRequestsByTarget(target: CdpTarget): NetworkRequest[] {
const requests: NetworkRequest[] = [];
for (const request of this.#requests.values()) {
if (request.cdpTarget === target) {
requests.push(request);
}
}
return requests;
}

getRequestById(id: Network.Request): NetworkRequest | undefined {
return this.#requests.get(id);
}
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

0 comments on commit b6cc9a1

Please sign in to comment.