Skip to content

Commit

Permalink
feat(core): default browser context
Browse files Browse the repository at this point in the history
  • Loading branch information
blakebyrnes committed Sep 13, 2021
1 parent 936f894 commit cbdeacf
Show file tree
Hide file tree
Showing 12 changed files with 70 additions and 30 deletions.
1 change: 1 addition & 0 deletions core/lib/GlobalPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ export default class GlobalPool {
sessionId: session.id,
}),
session.getMitmProxy(),
session.useIncognitoContext(),
);
await session.initialize(browserContext);

Expand Down
7 changes: 6 additions & 1 deletion core/lib/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,12 +294,17 @@ export default class Session
};
}

public useIncognitoContext(): boolean {
const options = this.options;
return !(options.showBrowser === true && options.sessionKeepAlive === true);
}

public async registerWithMitm(
sharedMitmProxy: MitmProxy,
doesPuppetSupportBrowserContextProxy: boolean,
): Promise<void> {
let mitmProxy = sharedMitmProxy;
if (doesPuppetSupportBrowserContextProxy) {
if (doesPuppetSupportBrowserContextProxy && this.useIncognitoContext()) {
this.isolatedMitmProxy = await MitmProxy.start(GlobalPool.localProxyPortStart, Core.dataDir);
mitmProxy = this.isolatedMitmProxy;
}
Expand Down
3 changes: 3 additions & 0 deletions interfaces/IDevtoolsSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ProtocolMapping } from 'devtools-protocol/types/protocol-mapping';
import Protocol from 'devtools-protocol';
import ITypedEventEmitter from '@ulixee/commons/interfaces/ITypedEventEmitter';
import { FilterFlags, FilterOutFlags } from './AllowedNames';
import RemoteObject = Protocol.Runtime.RemoteObject;

export declare type DevtoolsEvents = {
[Key in keyof ProtocolMapping.Events]: ProtocolMapping.Events[Key][0];
Expand All @@ -16,6 +17,8 @@ type RequiredParamsCommands = keyof FilterOutFlags<DevtoolsCommandParams, void |
export default interface IDevtoolsSession
extends Omit<ITypedEventEmitter<DevtoolsEvents>, 'waitOn'> {
id: string;
disposeRemoteObject(object: RemoteObject): void;

send<T extends RequiredParamsCommands>(
method: T,
params: DevtoolsCommandParams[T],
Expand Down
1 change: 1 addition & 0 deletions interfaces/IPuppetBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default interface IPuppetBrowser {
plugins: ICorePlugins,
logger: IBoundLog,
proxy?: IProxyConnectionOptions,
isIncognito?: boolean,
): Promise<IPuppetContext>;
close(): Promise<void>;
}
1 change: 1 addition & 0 deletions interfaces/IPuppetContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface IPuppetPageOptions {
export interface IPuppetContextEvents {
page: { page: IPuppetPage };
worker: { worker: IPuppetWorker };
close: void;
'devtools-message': {
direction: 'send' | 'receive';
timestamp: Date;
Expand Down
4 changes: 2 additions & 2 deletions plugins/default-browser-emulator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ import configureDeviceProfile from './lib/helpers/configureDeviceProfile';
import configureHttp2Session from './lib/helpers/configureHttp2Session';

const dataLoader = new DataLoader(__dirname);
export const latestBrowserEngineId = 'chrome-88-0';
export const latestChromeBrowserVersion = { major: '88', minor: '0' };
export const latestBrowserEngineId = 'chrome-89-0';
export const latestChromeBrowserVersion = { major: '89', minor: '0' };

@BrowserEmulatorClassDecorator
export default class DefaultBrowserEmulator extends BrowserEmulator {
Expand Down
2 changes: 1 addition & 1 deletion plugins/default-browser-emulator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Browser emulator generated from DoubleAgent data",
"main": "index.js",
"dependencies": {
"@ulixee/chrome-88-0": "^4324.182.4",
"@ulixee/chrome-89-0": "^4389.128.4",
"@ulixee/commons": "1.5.5",
"@ulixee/hero-interfaces": "1.5.4",
"@ulixee/hero-plugin-utils": "1.5.4",
Expand Down
47 changes: 37 additions & 10 deletions puppet-chrome/lib/Browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ const { log } = Log(module);
let browserIdCounter = 0;

export class Browser extends TypedEventEmitter<IBrowserEvents> implements IPuppetBrowser {
public readonly browserContextsById = new Map<string, BrowserContext>();
public readonly devtoolsSession: DevtoolsSession;
public onDevtoolsAttached?: (session: DevtoolsSession) => Promise<any>;

public id: string;

public get name(): string {
Expand All @@ -38,11 +36,16 @@ export class Browser extends TypedEventEmitter<IBrowserEvents> implements IPuppe
return this.fullVersion?.split('.').map(Number).shift();
}

private readonly browserContextsById = new Map<string, BrowserContext>();

private readonly connection: Connection;

private readonly closeCallback: () => void;

private version: GetVersionResponse;
private get defaultBrowserContext(): BrowserContext {
return this.browserContextsById.get(undefined);
}

constructor(connection: Connection, closeCallback: () => void) {
super();
Expand All @@ -63,20 +66,33 @@ export class Browser extends TypedEventEmitter<IBrowserEvents> implements IPuppe
plugins: ICorePlugins,
logger: IBoundLog,
proxy?: IProxyConnectionOptions,
isIncognito = true,
): Promise<BrowserContext> {
const proxySettings = proxy?.address
? {
proxyBypassList: '<-loopback>',
proxyServer: proxy.address,
}
: {};
if (!isIncognito) {
if (!this.browserContextsById.has(undefined)) {
this.createBrowserContext(undefined, plugins, logger, proxy);
}
const context = this.browserContextsById.get(undefined);
context.proxy = proxy;
return context;
}

// Creates a new incognito browser context. This won't share cookies/cache with other browser contexts.
const { browserContextId } = await this.devtoolsSession.send('Target.createBrowserContext', {
disposeOnDetach: true,
...proxySettings,
});
return this.createBrowserContext(browserContextId, plugins, logger, proxy);
}

return new BrowserContext(this, plugins, browserContextId, logger, proxy);
public getBrowserContext(id: string) {
return this.browserContextsById.get(id) ?? this.defaultBrowserContext;
}

public async close(): Promise<void> {
Expand Down Expand Up @@ -108,20 +124,18 @@ export class Browser extends TypedEventEmitter<IBrowserEvents> implements IPuppe
private onAttachedToTarget(event: Protocol.Target.AttachedToTargetEvent) {
const { targetInfo, sessionId } = event;

if (!targetInfo.browserContextId) {
assert(targetInfo.browserContextId, `targetInfo: ${JSON.stringify(targetInfo, null, 2)}`);
}
assert(targetInfo.browserContextId, `targetInfo: ${JSON.stringify(targetInfo, null, 2)}`);

if (targetInfo.type === 'page') {
const devtoolsSession = this.connection.getSession(sessionId);
const context = this.browserContextsById.get(targetInfo.browserContextId);
const context = this.getBrowserContext(targetInfo.browserContextId);
context?.onPageAttached(devtoolsSession, targetInfo).catch(() => null);
return;
}

if (targetInfo.type === 'shared_worker') {
const devtoolsSession = this.connection.getSession(sessionId);
const context = this.browserContextsById.get(targetInfo.browserContextId);
const context = this.getBrowserContext(targetInfo.browserContextId);
context?.onSharedWorkerAttached(devtoolsSession, targetInfo).catch(() => null);
}

Expand Down Expand Up @@ -156,11 +170,11 @@ export class Browser extends TypedEventEmitter<IBrowserEvents> implements IPuppe
private async onTargetCreated(event: Protocol.Target.TargetCreatedEvent) {
const { targetInfo } = event;
if (targetInfo.type === 'page' && !targetInfo.attached) {
const context = this.browserContextsById.get(targetInfo.browserContextId);
const context = this.getBrowserContext(targetInfo.browserContextId);
await context?.attachToTarget(targetInfo.targetId);
}
if (targetInfo.type === 'shared_worker') {
const context = this.browserContextsById.get(targetInfo.browserContextId);
const context = this.getBrowserContext(targetInfo.browserContextId);
await context?.attachToWorker(targetInfo);
}
}
Expand Down Expand Up @@ -188,6 +202,19 @@ export class Browser extends TypedEventEmitter<IBrowserEvents> implements IPuppe
}
}

private createBrowserContext(
browserContextId: string,
plugins: ICorePlugins,
logger: IBoundLog,
proxy?: IProxyConnectionOptions,
) {
const context = new BrowserContext(this, plugins, browserContextId, logger, proxy);
this.browserContextsById.set(browserContextId, context);
context.on('close', () => this.browserContextsById.delete(browserContextId));

return context;
}

public static async create(
connection: Connection,
browserEngine: IBrowserEngine,
Expand Down
17 changes: 9 additions & 8 deletions puppet-chrome/lib/BrowserContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ export class BrowserContext
browserContextId: contextId,
});
this.proxy = proxy;
this.browser.browserContextsById.set(this.id, this);

this.subscribeToDevtoolsMessages(this.browser.devtoolsSession, {
sessionType: 'browser',
Expand Down Expand Up @@ -227,15 +226,17 @@ export class BrowserContext

if (this.browser.devtoolsSession.isConnected()) {
await Promise.all([...this.pagesById.values()].map(x => x.close()));
await this.sendWithBrowserDevtoolsSession('Target.disposeBrowserContext', {
browserContextId: this.id,
}).catch(err => {
if (err instanceof CanceledPromiseError) return;
throw err;
});
if (this.id) {
await this.sendWithBrowserDevtoolsSession('Target.disposeBrowserContext', {
browserContextId: this.id,
}).catch(err => {
if (err instanceof CanceledPromiseError) return;
throw err;
});
}
}
removeEventListeners(this.eventListeners);
this.browser.browserContextsById.delete(this.id);
this.emit('close');
}

async getCookies(url?: URL): Promise<ICookie[]> {
Expand Down
4 changes: 2 additions & 2 deletions puppet-chrome/lib/Frame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,12 +342,12 @@ export default class Frame extends TypedEventEmitter<IPuppetFrameEvents> impleme

public removeContextId(executionContextId: number): void {
if (this.defaultContextId === executionContextId) this.defaultContextId = null;
if (this.isolatedContextId === executionContextId) this.defaultContextId = null;
if (this.isolatedContextId === executionContextId) this.isolatedContextId = null;
}

public clearContextIds(): void {
this.defaultContextId = null;
this.defaultContextId = null;
this.isolatedContextId = null;
}

public addContextId(executionContextId: number, isDefault: boolean): void {
Expand Down
5 changes: 3 additions & 2 deletions puppet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const { log } = Log(module);
let puppBrowserCounter = 1;
export default class Puppet extends TypedEventEmitter<{ close: void }> {
public get browserId(): string {
return this.browser.id;
return this.browser?.id;
}

public readonly id: number;
Expand Down Expand Up @@ -79,12 +79,13 @@ export default class Puppet extends TypedEventEmitter<{ close: void }> {
plugins: ICorePlugins,
logger: IBoundLog,
proxy?: IProxyConnectionOptions,
isIncognito = true,
): Promise<IPuppetContext> {
if (!this.isStarted || !this.browser) {
throw new Error('This Puppet instance has not had start() called on it');
}
if (this.isShuttingDown) throw new Error('Shutting down');
return this.browser.newContext(plugins, logger, proxy);
return this.browser.newContext(plugins, logger, proxy, isIncognito);
}

public async close() {
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2145,10 +2145,10 @@
"@typescript-eslint/types" "4.28.3"
eslint-visitor-keys "^2.0.0"

"@ulixee/chrome-88-0@^4324.182.4":
version "4324.182.4"
resolved "https://registry.yarnpkg.com/@ulixee/chrome-88-0/-/chrome-88-0-4324.182.4.tgz#b5de2e5e8569a380b6bff99074ef8d66c6bbb686"
integrity sha512-HZBSbZEVjWyjnkj/UYbnYd8dvHiXroeGPNGG3anOLHIW8dIDVnPtdwJXD/7Kcm6hUXVmZY2q3w1y5i8L94V9uQ==
"@ulixee/chrome-89-0@^4389.128.4":
version "4389.128.4"
resolved "https://registry.yarnpkg.com/@ulixee/chrome-89-0/-/chrome-89-0-4389.128.4.tgz#a71f9739078c90d93e97bb26a2eac145ce397a45"
integrity sha512-BmoLbzC2ACmep5pAXnpK2HvvWbjeMxsum/9PDsyzdVlHzJ3HbdTVZuaqPrJ5h12ZYZbEK9PYlamy9twaaulDfA==
dependencies:
"@ulixee/chrome-app" "^1.0.2"

Expand Down

0 comments on commit cbdeacf

Please sign in to comment.