@browserless.io/browserless 2.12.0-beta-3 → 2.12.0-beta-6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/browserless.d.ts +3 -3
- package/build/browserless.js +6 -6
- package/build/browsers/chromium.cdp.d.ts +13 -13
- package/build/browsers/chromium.cdp.js +79 -67
- package/build/browsers/chromium.playwright.d.ts +12 -12
- package/build/browsers/chromium.playwright.js +44 -36
- package/build/browsers/firefox.playwright.d.ts +12 -12
- package/build/browsers/firefox.playwright.js +44 -36
- package/build/browsers/index.d.ts +17 -16
- package/build/browsers/index.js +63 -42
- package/build/browsers/webkit.playwright.d.ts +12 -12
- package/build/browsers/webkit.playwright.js +47 -39
- package/build/config.d.ts +65 -63
- package/build/config.js +162 -102
- package/build/file-system.d.ts +4 -4
- package/build/file-system.js +8 -8
- package/build/hooks.d.ts +2 -2
- package/build/hooks.js +4 -4
- package/build/limiter.d.ts +4 -4
- package/build/limiter.js +10 -10
- package/build/logger.d.ts +6 -6
- package/build/logger.js +12 -12
- package/build/metrics.d.ts +12 -12
- package/build/metrics.js +23 -23
- package/build/monitoring.d.ts +4 -4
- package/build/monitoring.js +8 -8
- package/build/router.d.ts +8 -8
- package/build/router.js +74 -70
- package/build/routes/chrome/http/pdf.post.body.json +8 -8
- package/build/routes/chrome/http/scrape.post.body.json +8 -8
- package/build/routes/chrome/http/screenshot.post.body.json +8 -8
- package/build/routes/chromium/http/content.post.body.json +8 -8
- package/build/routes/chromium/http/pdf.post.body.json +8 -8
- package/build/routes/chromium/http/scrape.post.body.json +8 -8
- package/build/routes/chromium/http/screenshot.post.body.json +8 -8
- package/build/routes/firefox/ws/playwright.d.ts +1 -1
- package/build/routes/firefox/ws/playwright.js +2 -2
- package/build/routes/management/http/active.get.d.ts +1 -1
- package/build/routes/management/http/active.get.js +3 -1
- package/build/routes/management/http/config.get.d.ts +1 -1
- package/build/routes/management/http/config.get.js +2 -2
- package/build/routes/management/http/metrics-total.get.d.ts +1 -1
- package/build/routes/management/http/metrics-total.get.js +2 -2
- package/build/routes/management/http/metrics.get.d.ts +1 -1
- package/build/routes/management/http/metrics.get.js +2 -2
- package/build/routes/management/http/pressure.get.d.ts +1 -1
- package/build/routes/management/http/pressure.get.js +2 -2
- package/build/routes/management/http/sessions.get.d.ts +1 -1
- package/build/routes/management/http/sessions.get.js +2 -2
- package/build/routes/management/http/static.get.d.ts +1 -1
- package/build/routes/management/http/static.get.js +2 -2
- package/build/routes/webkit/ws/playwright.d.ts +1 -1
- package/build/routes/webkit/ws/playwright.js +2 -2
- package/build/server.d.ts +5 -5
- package/build/server.js +11 -11
- package/build/shared/browser.ws.d.ts +1 -1
- package/build/shared/browser.ws.js +3 -1
- package/build/shared/chromium.playwright.ws.d.ts +1 -1
- package/build/shared/chromium.playwright.ws.js +2 -2
- package/build/shared/chromium.ws.d.ts +1 -1
- package/build/shared/chromium.ws.js +3 -1
- package/build/shared/content.http.d.ts +1 -1
- package/build/shared/content.http.js +2 -2
- package/build/shared/download.http.d.ts +1 -1
- package/build/shared/download.http.js +60 -58
- package/build/shared/function.http.d.ts +1 -1
- package/build/shared/function.http.js +2 -2
- package/build/shared/json-list.http.d.ts +1 -1
- package/build/shared/json-list.http.js +2 -2
- package/build/shared/json-new.http.d.ts +1 -1
- package/build/shared/json-new.http.js +2 -2
- package/build/shared/json-protocol.http.d.ts +1 -1
- package/build/shared/json-protocol.http.js +2 -2
- package/build/shared/json-version.http.d.ts +1 -1
- package/build/shared/json-version.http.js +2 -2
- package/build/shared/page.ws.d.ts +1 -1
- package/build/shared/page.ws.js +3 -1
- package/build/shared/pdf.http.d.ts +1 -1
- package/build/shared/pdf.http.js +2 -2
- package/build/shared/performance.http.d.ts +1 -1
- package/build/shared/performance.http.js +2 -2
- package/build/shared/scrape.http.d.ts +1 -1
- package/build/shared/scrape.http.js +2 -2
- package/build/shared/screenshot.http.d.ts +1 -1
- package/build/shared/screenshot.http.js +2 -2
- package/build/shared/utils/function/client.d.ts +1 -1
- package/build/shared/utils/function/client.js +3 -1
- package/build/shim.d.ts +1 -1
- package/build/shim.js +2 -2
- package/build/token.d.ts +3 -3
- package/build/token.js +6 -6
- package/build/types.d.ts +5 -5
- package/build/webhooks.d.ts +2 -2
- package/build/webhooks.js +4 -4
- package/extensions/ublock/_locales/eu/messages.json +4 -4
- package/extensions/ublock/_locales/hi/messages.json +5 -5
- package/extensions/ublock/_locales/kn/messages.json +11 -11
- package/extensions/ublock/_locales/nb/messages.json +2 -2
- package/extensions/ublock/_locales/no/messages.json +2 -2
- package/extensions/ublock/_locales/ro/messages.json +1 -1
- package/extensions/ublock/_locales/sv/messages.json +1 -1
- package/extensions/ublock/_locales/zh_CN/messages.json +2 -2
- package/extensions/ublock/assets/assets.json +3 -8
- package/extensions/ublock/assets/resources/scriptlets.js +128 -31
- package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +4870 -3560
- package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +662 -173
- package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +10 -42
- package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +241 -80
- package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +2093 -1224
- package/extensions/ublock/assets/ublock/badlists.txt +2 -0
- package/extensions/ublock/assets/ublock/badware.min.txt +408 -287
- package/extensions/ublock/assets/ublock/filters.min.txt +947 -645
- package/extensions/ublock/assets/ublock/privacy.min.txt +43 -8
- package/extensions/ublock/assets/ublock/quick-fixes.min.txt +55 -93
- package/extensions/ublock/assets/ublock/unbreak.min.txt +52 -19
- package/extensions/ublock/css/1p-filters.css +2 -0
- package/extensions/ublock/css/codemirror.css +2 -2
- package/extensions/ublock/css/dashboard.css +2 -5
- package/extensions/ublock/css/epicker-ui.css +3 -3
- package/extensions/ublock/css/fa-icons.css +3 -0
- package/extensions/ublock/css/logger-ui-inspector.css +1 -0
- package/extensions/ublock/css/logger-ui.css +44 -32
- package/extensions/ublock/img/fontawesome/fontawesome-defs.svg +1 -0
- package/extensions/ublock/js/3p-filters.js +4 -5
- package/extensions/ublock/js/biditrie.js +16 -11
- package/extensions/ublock/js/cachestorage.js +37 -37
- package/extensions/ublock/js/contentscript-extra.js +0 -2
- package/extensions/ublock/js/contentscript.js +1 -6
- package/extensions/ublock/js/epicker-ui.js +28 -36
- package/extensions/ublock/js/fa-icons.js +1 -0
- package/extensions/ublock/js/hntrie.js +19 -13
- package/extensions/ublock/js/logger-ui-inspector.js +6 -13
- package/extensions/ublock/js/logger-ui.js +264 -264
- package/extensions/ublock/js/s14e-serializer.js +267 -264
- package/extensions/ublock/js/scriptlet-filtering.js +12 -18
- package/extensions/ublock/js/scriptlets/dom-inspector.js +1 -5
- package/extensions/ublock/js/scriptlets/epicker.js +53 -59
- package/extensions/ublock/js/start.js +0 -8
- package/extensions/ublock/js/storage.js +2 -9
- package/extensions/ublock/js/vapi-background.js +19 -20
- package/extensions/ublock/js/vapi-common.js +2 -7
- package/extensions/ublock/js/vapi.js +0 -4
- package/extensions/ublock/js/webext.js +23 -15
- package/extensions/ublock/logger-ui.html +24 -15
- package/extensions/ublock/manifest.json +2 -3
- package/package.json +4 -4
- package/src/browserless.ts +6 -6
- package/src/browsers/chromium.cdp.ts +35 -25
- package/src/browsers/chromium.playwright.ts +30 -23
- package/src/browsers/firefox.playwright.ts +30 -24
- package/src/browsers/index.ts +81 -50
- package/src/browsers/webkit.playwright.ts +33 -26
- package/src/config.ts +166 -104
- package/src/file-system.ts +9 -9
- package/src/hooks.ts +4 -4
- package/src/limiter.ts +12 -12
- package/src/logger.ts +12 -12
- package/src/metrics.ts +23 -23
- package/src/monitoring.ts +9 -9
- package/src/router.ts +31 -31
- package/src/routes/chrome/tests/websocket.spec.ts +2 -2
- package/src/routes/chromium/tests/websocket.spec.ts +2 -2
- package/src/routes/firefox/tests/websocket.spec.ts +2 -4
- package/src/routes/firefox/ws/playwright.ts +3 -3
- package/src/routes/management/http/active.get.ts +3 -2
- package/src/routes/management/http/config.get.ts +2 -2
- package/src/routes/management/http/metrics-total.get.ts +2 -2
- package/src/routes/management/http/metrics.get.ts +2 -2
- package/src/routes/management/http/pressure.get.ts +2 -2
- package/src/routes/management/http/sessions.get.ts +2 -2
- package/src/routes/management/http/static.get.ts +3 -3
- package/src/routes/webkit/tests/websocket.spec.ts +2 -3
- package/src/routes/webkit/ws/playwright.ts +3 -3
- package/src/server.ts +14 -16
- package/src/shared/browser.ws.ts +4 -2
- package/src/shared/chromium.playwright.ws.ts +3 -3
- package/src/shared/chromium.ws.ts +4 -2
- package/src/shared/content.http.ts +3 -3
- package/src/shared/download.http.ts +4 -3
- package/src/shared/function.http.ts +3 -3
- package/src/shared/json-list.http.ts +2 -2
- package/src/shared/json-new.http.ts +2 -2
- package/src/shared/json-protocol.http.ts +2 -6
- package/src/shared/json-version.http.ts +2 -6
- package/src/shared/page.ws.ts +4 -2
- package/src/shared/pdf.http.ts +3 -3
- package/src/shared/performance.http.ts +3 -3
- package/src/shared/scrape.http.ts +3 -3
- package/src/shared/screenshot.http.ts +3 -3
- package/src/shared/utils/function/client.ts +3 -1
- package/src/shim.ts +2 -2
- package/src/token.ts +7 -7
- package/src/types.ts +8 -8
- package/src/utils.ts +1 -1
- package/src/webhooks.ts +4 -4
- package/static/docs/swagger.json +1 -1
- package/static/docs/swagger.min.json +1 -1
- package/static/function/client.js +3 -1
- package/static/function/index.html +3 -1
package/build/browserless.d.ts
CHANGED
|
@@ -36,9 +36,9 @@ export declare class Browserless extends EventEmitter {
|
|
|
36
36
|
token?: Browserless['token'];
|
|
37
37
|
webhooks?: Browserless['webhooks'];
|
|
38
38
|
});
|
|
39
|
-
protected loadPwVersions
|
|
40
|
-
protected saveMetrics
|
|
41
|
-
setMetricsSaveInterval
|
|
39
|
+
protected loadPwVersions(): Promise<void>;
|
|
40
|
+
protected saveMetrics(): Promise<void>;
|
|
41
|
+
setMetricsSaveInterval(interval: number): void;
|
|
42
42
|
protected routeIsDisabled(route: routeInstances): boolean;
|
|
43
43
|
setStaticSDKDir(dir: string): void;
|
|
44
44
|
disableRoutes(...routeNames: string[]): void;
|
package/build/browserless.js
CHANGED
|
@@ -45,11 +45,11 @@ export class Browserless extends EventEmitter {
|
|
|
45
45
|
router ||
|
|
46
46
|
new Router(this.config, this.browserManager, this.limiter, this.Logger);
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
async loadPwVersions() {
|
|
49
49
|
const { playwrightVersions } = JSON.parse((await fs.readFile('package.json')).toString());
|
|
50
50
|
this.config.setPwVersions(playwrightVersions);
|
|
51
|
-
}
|
|
52
|
-
|
|
51
|
+
}
|
|
52
|
+
async saveMetrics() {
|
|
53
53
|
const metricsPath = this.config.getMetricsJSONPath();
|
|
54
54
|
const { cpu, memory } = await this.monitoring.getMachineStats();
|
|
55
55
|
const metrics = await this.metrics.get();
|
|
@@ -76,15 +76,15 @@ export class Browserless extends EventEmitter {
|
|
|
76
76
|
this.logger.info(`Saving metrics to "${metricsPath}"`);
|
|
77
77
|
this.fileSystem.append(metricsPath, JSON.stringify(aggregatedStats), false);
|
|
78
78
|
}
|
|
79
|
-
}
|
|
80
|
-
setMetricsSaveInterval
|
|
79
|
+
}
|
|
80
|
+
setMetricsSaveInterval(interval) {
|
|
81
81
|
if (interval <= 0) {
|
|
82
82
|
return console.warn(`Interval value of "${interval}" must be greater than 1. Ignoring`);
|
|
83
83
|
}
|
|
84
84
|
clearInterval(this.metricsSaveInterval);
|
|
85
85
|
this.metricsSaveInterval = interval;
|
|
86
86
|
this.metricsSaveIntervalID = setInterval(this.saveMetrics, this.metricsSaveInterval);
|
|
87
|
-
}
|
|
87
|
+
}
|
|
88
88
|
routeIsDisabled(route) {
|
|
89
89
|
return this.disabledRouteNames.some((name) => name === route.name);
|
|
90
90
|
}
|
|
@@ -26,17 +26,17 @@ export declare class ChromiumCDP extends EventEmitter {
|
|
|
26
26
|
userDataDir: ChromiumCDP['userDataDir'];
|
|
27
27
|
});
|
|
28
28
|
protected cleanListeners(): void;
|
|
29
|
-
|
|
30
|
-
getPageId
|
|
31
|
-
protected onTargetCreated
|
|
32
|
-
isRunning
|
|
33
|
-
newPage
|
|
34
|
-
close
|
|
35
|
-
pages
|
|
36
|
-
process
|
|
37
|
-
launch
|
|
38
|
-
wsEndpoint
|
|
39
|
-
publicWSEndpoint
|
|
40
|
-
proxyPageWebSocket
|
|
41
|
-
proxyWebSocket
|
|
29
|
+
keepUntil(): number;
|
|
30
|
+
getPageId(page: Page): string;
|
|
31
|
+
protected onTargetCreated(target: Target): Promise<void>;
|
|
32
|
+
isRunning(): boolean;
|
|
33
|
+
newPage(): Promise<Page>;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
pages(): Promise<Page[]>;
|
|
36
|
+
process(): import("child_process").ChildProcess | null;
|
|
37
|
+
launch(options?: CDPLaunchOptions): Promise<Browser>;
|
|
38
|
+
wsEndpoint(): string | null;
|
|
39
|
+
publicWSEndpoint(token: string | null): string | null;
|
|
40
|
+
proxyPageWebSocket(req: Request, socket: Duplex, head: Buffer): Promise<void>;
|
|
41
|
+
proxyWebSocket(req: Request, socket: Duplex, head: Buffer): Promise<void>;
|
|
42
42
|
}
|
|
@@ -32,14 +32,14 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
32
32
|
this.browser?.removeAllListeners();
|
|
33
33
|
this.removeAllListeners();
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
return
|
|
35
|
+
keepUntil() {
|
|
36
|
+
return 0;
|
|
37
37
|
}
|
|
38
|
-
getPageId
|
|
38
|
+
getPageId(page) {
|
|
39
39
|
// @ts-ignore
|
|
40
40
|
return page.target()._targetId;
|
|
41
|
-
}
|
|
42
|
-
|
|
41
|
+
}
|
|
42
|
+
async onTargetCreated(target) {
|
|
43
43
|
if (target.type() === 'page') {
|
|
44
44
|
const page = await target.page().catch((e) => {
|
|
45
45
|
this.logger.error(`Error in ${this.constructor.name} new page ${e}`);
|
|
@@ -83,15 +83,17 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
83
83
|
this.emit('newPage', page);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
-
}
|
|
87
|
-
isRunning
|
|
88
|
-
|
|
86
|
+
}
|
|
87
|
+
isRunning() {
|
|
88
|
+
return this.running;
|
|
89
|
+
}
|
|
90
|
+
async newPage() {
|
|
89
91
|
if (!this.browser) {
|
|
90
92
|
throw new ServerError(`${this.constructor.name} hasn't been launched yet!`);
|
|
91
93
|
}
|
|
92
94
|
return this.browser.newPage();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
+
}
|
|
96
|
+
async close() {
|
|
95
97
|
if (this.browser) {
|
|
96
98
|
this.logger.info(`Closing ${this.constructor.name} process and all listeners`);
|
|
97
99
|
this.emit('close');
|
|
@@ -102,10 +104,14 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
102
104
|
this.browser = null;
|
|
103
105
|
this.browserWSEndpoint = null;
|
|
104
106
|
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
}
|
|
108
|
+
async pages() {
|
|
109
|
+
return this.browser?.pages() || [];
|
|
110
|
+
}
|
|
111
|
+
process() {
|
|
112
|
+
return this.browser?.process() || null;
|
|
113
|
+
}
|
|
114
|
+
async launch(options = {}) {
|
|
109
115
|
this.port = await getPort();
|
|
110
116
|
this.logger.info(`${this.constructor.name} got open port ${this.port}`);
|
|
111
117
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -130,14 +136,16 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
130
136
|
: puppeteer.launch.bind(puppeteer);
|
|
131
137
|
this.logger.info(finalOptions, `Launching ${this.constructor.name} Handler`);
|
|
132
138
|
this.browser = (await launch(finalOptions));
|
|
133
|
-
this.browser.on('targetcreated', this.onTargetCreated);
|
|
139
|
+
this.browser.on('targetcreated', this.onTargetCreated.bind(this));
|
|
134
140
|
this.running = true;
|
|
135
141
|
this.browserWSEndpoint = this.browser.wsEndpoint();
|
|
136
142
|
this.logger.info(`${this.constructor.name} is running on ${this.browserWSEndpoint}`);
|
|
137
143
|
return this.browser;
|
|
138
|
-
}
|
|
139
|
-
wsEndpoint
|
|
140
|
-
|
|
144
|
+
}
|
|
145
|
+
wsEndpoint() {
|
|
146
|
+
return this.browserWSEndpoint;
|
|
147
|
+
}
|
|
148
|
+
publicWSEndpoint(token) {
|
|
141
149
|
if (!this.browserWSEndpoint) {
|
|
142
150
|
return null;
|
|
143
151
|
}
|
|
@@ -148,55 +156,59 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
148
156
|
externalURL.searchParams.set('token', token);
|
|
149
157
|
}
|
|
150
158
|
return externalURL.href;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
proxyWebSocket = async (req, socket, head) => new Promise((resolve, reject) => {
|
|
177
|
-
if (!this.browserWSEndpoint) {
|
|
178
|
-
throw new ServerError(`No browserWSEndpoint found, did you launch first?`);
|
|
179
|
-
}
|
|
180
|
-
const close = once(() => {
|
|
181
|
-
this.browser?.off('close', close);
|
|
182
|
-
this.browser?.process()?.off('close', close);
|
|
183
|
-
socket.off('close', close);
|
|
184
|
-
return resolve();
|
|
159
|
+
}
|
|
160
|
+
async proxyPageWebSocket(req, socket, head) {
|
|
161
|
+
return new Promise(async (resolve, reject) => {
|
|
162
|
+
if (!this.browserWSEndpoint || !this.browser) {
|
|
163
|
+
throw new ServerError(`No browserWSEndpoint found, did you launch first?`);
|
|
164
|
+
}
|
|
165
|
+
socket.once('close', resolve);
|
|
166
|
+
this.logger.info(`Proxying ${req.parsed.href} to ${this.constructor.name}`);
|
|
167
|
+
const shouldMakePage = req.parsed.pathname.includes(BLESS_PAGE_IDENTIFIER);
|
|
168
|
+
const page = shouldMakePage ? await this.browser.newPage() : null;
|
|
169
|
+
const pathname = page
|
|
170
|
+
? path.join('/devtools', '/page', this.getPageId(page))
|
|
171
|
+
: req.parsed.pathname;
|
|
172
|
+
const target = new URL(pathname, this.browserWSEndpoint).href;
|
|
173
|
+
req.url = '';
|
|
174
|
+
// Delete headers known to cause issues
|
|
175
|
+
delete req.headers.origin;
|
|
176
|
+
this.proxy.ws(req, socket, head, {
|
|
177
|
+
changeOrigin: true,
|
|
178
|
+
target,
|
|
179
|
+
}, (error) => {
|
|
180
|
+
this.logger.error(`Error proxying session to ${this.constructor.name}: ${error}`);
|
|
181
|
+
this.close();
|
|
182
|
+
return reject(error);
|
|
183
|
+
});
|
|
185
184
|
});
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
this.close
|
|
199
|
-
|
|
185
|
+
}
|
|
186
|
+
async proxyWebSocket(req, socket, head) {
|
|
187
|
+
return new Promise((resolve, reject) => {
|
|
188
|
+
if (!this.browserWSEndpoint) {
|
|
189
|
+
throw new ServerError(`No browserWSEndpoint found, did you launch first?`);
|
|
190
|
+
}
|
|
191
|
+
const close = once(() => {
|
|
192
|
+
this.browser?.off('close', close);
|
|
193
|
+
this.browser?.process()?.off('close', close);
|
|
194
|
+
socket.off('close', close);
|
|
195
|
+
return resolve();
|
|
196
|
+
});
|
|
197
|
+
this.browser?.once('close', close);
|
|
198
|
+
this.browser?.process()?.once('close', close);
|
|
199
|
+
socket.once('close', close);
|
|
200
|
+
this.logger.info(`Proxying ${req.parsed.href} to ${this.constructor.name} ${this.browserWSEndpoint}`);
|
|
201
|
+
req.url = '';
|
|
202
|
+
// Delete headers known to cause issues
|
|
203
|
+
delete req.headers.origin;
|
|
204
|
+
this.proxy.ws(req, socket, head, {
|
|
205
|
+
changeOrigin: true,
|
|
206
|
+
target: this.browserWSEndpoint,
|
|
207
|
+
}, (error) => {
|
|
208
|
+
this.logger.error(`Error proxying session to ${this.constructor.name}: ${error}`);
|
|
209
|
+
this.close();
|
|
210
|
+
return reject(error);
|
|
211
|
+
});
|
|
200
212
|
});
|
|
201
|
-
}
|
|
213
|
+
}
|
|
202
214
|
}
|
|
@@ -22,16 +22,16 @@ export declare class ChromiumPlaywright extends EventEmitter {
|
|
|
22
22
|
userDataDir: ChromiumPlaywright['userDataDir'];
|
|
23
23
|
});
|
|
24
24
|
protected cleanListeners(): void;
|
|
25
|
-
|
|
26
|
-
isRunning
|
|
27
|
-
close
|
|
28
|
-
pages
|
|
29
|
-
getPageId
|
|
30
|
-
makeLiveURL
|
|
31
|
-
newPage
|
|
32
|
-
launch
|
|
33
|
-
wsEndpoint
|
|
34
|
-
publicWSEndpoint
|
|
35
|
-
proxyPageWebSocket
|
|
36
|
-
proxyWebSocket
|
|
25
|
+
keepUntil(): number;
|
|
26
|
+
isRunning(): boolean;
|
|
27
|
+
close(): Promise<void>;
|
|
28
|
+
pages(): Promise<[]>;
|
|
29
|
+
getPageId(): string;
|
|
30
|
+
makeLiveURL(): void;
|
|
31
|
+
newPage(): Promise<Page>;
|
|
32
|
+
launch(options?: BrowserServerOptions, version?: string): Promise<playwright.BrowserServer>;
|
|
33
|
+
wsEndpoint(): string | null;
|
|
34
|
+
publicWSEndpoint(token: string | null): string | null;
|
|
35
|
+
proxyPageWebSocket(): Promise<void>;
|
|
36
|
+
proxyWebSocket(req: Request, socket: Duplex, head: Buffer): Promise<void>;
|
|
37
37
|
}
|
|
@@ -22,11 +22,13 @@ export class ChromiumPlaywright extends EventEmitter {
|
|
|
22
22
|
cleanListeners() {
|
|
23
23
|
this.removeAllListeners();
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
return
|
|
25
|
+
keepUntil() {
|
|
26
|
+
return 0;
|
|
27
27
|
}
|
|
28
|
-
isRunning
|
|
29
|
-
|
|
28
|
+
isRunning() {
|
|
29
|
+
return this.running;
|
|
30
|
+
}
|
|
31
|
+
async close() {
|
|
30
32
|
if (this.browser) {
|
|
31
33
|
this.logger.info(`Closing ${this.constructor.name} process and all listeners`);
|
|
32
34
|
this.emit('close');
|
|
@@ -36,22 +38,24 @@ export class ChromiumPlaywright extends EventEmitter {
|
|
|
36
38
|
this.browser = null;
|
|
37
39
|
this.browserWSEndpoint = null;
|
|
38
40
|
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
}
|
|
42
|
+
async pages() {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
getPageId() {
|
|
42
46
|
throw new ServerError(`#getPageId is not yet supported with ${this.constructor.name}.`);
|
|
43
|
-
}
|
|
44
|
-
makeLiveURL
|
|
47
|
+
}
|
|
48
|
+
makeLiveURL() {
|
|
45
49
|
throw new ServerError(`Live URLs are not yet supported with ${this.constructor.name}. In the future this will be at "${this.config.getExternalAddress()}"`);
|
|
46
|
-
}
|
|
47
|
-
|
|
50
|
+
}
|
|
51
|
+
async newPage() {
|
|
48
52
|
if (!this.browser || !this.browserWSEndpoint) {
|
|
49
53
|
throw new ServerError(`${this.constructor.name} hasn't been launched yet!`);
|
|
50
54
|
}
|
|
51
55
|
const browser = await playwright.chromium.connect(this.browserWSEndpoint);
|
|
52
56
|
return await browser.newPage();
|
|
53
|
-
}
|
|
54
|
-
|
|
57
|
+
}
|
|
58
|
+
async launch(options = {}, version) {
|
|
55
59
|
this.logger.info(`Launching ${this.constructor.name} Handler`);
|
|
56
60
|
const opts = {
|
|
57
61
|
...options,
|
|
@@ -69,9 +73,11 @@ export class ChromiumPlaywright extends EventEmitter {
|
|
|
69
73
|
this.running = true;
|
|
70
74
|
this.browserWSEndpoint = browserWSEndpoint;
|
|
71
75
|
return this.browser;
|
|
72
|
-
}
|
|
73
|
-
wsEndpoint
|
|
74
|
-
|
|
76
|
+
}
|
|
77
|
+
wsEndpoint() {
|
|
78
|
+
return this.browserWSEndpoint;
|
|
79
|
+
}
|
|
80
|
+
publicWSEndpoint(token) {
|
|
75
81
|
if (!this.browserWSEndpoint) {
|
|
76
82
|
return null;
|
|
77
83
|
}
|
|
@@ -82,26 +88,28 @@ export class ChromiumPlaywright extends EventEmitter {
|
|
|
82
88
|
externalURL.searchParams.set('token', token);
|
|
83
89
|
}
|
|
84
90
|
return externalURL.href;
|
|
85
|
-
}
|
|
86
|
-
|
|
91
|
+
}
|
|
92
|
+
async proxyPageWebSocket() {
|
|
87
93
|
this.logger.warn(`${this.constructor.name} Not yet implemented`);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
94
|
+
}
|
|
95
|
+
async proxyWebSocket(req, socket, head) {
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
if (!this.browserWSEndpoint) {
|
|
98
|
+
throw new ServerError(`No browserWSEndpoint found, did you launch first?`);
|
|
99
|
+
}
|
|
100
|
+
socket.once('close', resolve);
|
|
101
|
+
this.logger.info(`Proxying ${req.parsed.href} to ${this.constructor.name} ${this.browserWSEndpoint}`);
|
|
102
|
+
// Delete headers known to cause issues
|
|
103
|
+
delete req.headers.origin;
|
|
104
|
+
req.url = '';
|
|
105
|
+
this.proxy.ws(req, socket, head, {
|
|
106
|
+
changeOrigin: true,
|
|
107
|
+
target: this.browserWSEndpoint,
|
|
108
|
+
}, (error) => {
|
|
109
|
+
this.logger.error(`Error proxying session to ${this.constructor.name}: ${error}`);
|
|
110
|
+
this.close();
|
|
111
|
+
return reject(error);
|
|
112
|
+
});
|
|
105
113
|
});
|
|
106
|
-
}
|
|
114
|
+
}
|
|
107
115
|
}
|
|
@@ -21,16 +21,16 @@ export declare class FirefoxPlaywright extends EventEmitter {
|
|
|
21
21
|
userDataDir: FirefoxPlaywright['userDataDir'];
|
|
22
22
|
});
|
|
23
23
|
protected cleanListeners(): void;
|
|
24
|
-
|
|
25
|
-
isRunning
|
|
26
|
-
close
|
|
27
|
-
pages
|
|
28
|
-
getPageId
|
|
29
|
-
makeLiveURL
|
|
30
|
-
newPage
|
|
31
|
-
launch
|
|
32
|
-
wsEndpoint
|
|
33
|
-
publicWSEndpoint
|
|
34
|
-
proxyPageWebSocket
|
|
35
|
-
proxyWebSocket
|
|
24
|
+
keepUntil(): number;
|
|
25
|
+
isRunning(): boolean;
|
|
26
|
+
close(): Promise<void>;
|
|
27
|
+
pages(): Promise<[]>;
|
|
28
|
+
getPageId(): string;
|
|
29
|
+
makeLiveURL(): void;
|
|
30
|
+
newPage(): Promise<Page>;
|
|
31
|
+
launch(options?: BrowserServerOptions, version?: string): Promise<playwright.BrowserServer>;
|
|
32
|
+
wsEndpoint(): string | null;
|
|
33
|
+
publicWSEndpoint(token: string | null): string | null;
|
|
34
|
+
proxyPageWebSocket(): Promise<void>;
|
|
35
|
+
proxyWebSocket(req: Request, socket: Duplex, head: Buffer): Promise<void>;
|
|
36
36
|
}
|
|
@@ -21,11 +21,13 @@ export class FirefoxPlaywright extends EventEmitter {
|
|
|
21
21
|
cleanListeners() {
|
|
22
22
|
this.removeAllListeners();
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
return
|
|
24
|
+
keepUntil() {
|
|
25
|
+
return 0;
|
|
26
26
|
}
|
|
27
|
-
isRunning
|
|
28
|
-
|
|
27
|
+
isRunning() {
|
|
28
|
+
return this.running;
|
|
29
|
+
}
|
|
30
|
+
async close() {
|
|
29
31
|
if (this.browser) {
|
|
30
32
|
this.logger.trace(`Closing ${this.constructor.name} process and all listeners`);
|
|
31
33
|
this.emit('close');
|
|
@@ -35,18 +37,20 @@ export class FirefoxPlaywright extends EventEmitter {
|
|
|
35
37
|
this.browser = null;
|
|
36
38
|
this.browserWSEndpoint = null;
|
|
37
39
|
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
}
|
|
41
|
+
async pages() {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
getPageId() {
|
|
41
45
|
throw new ServerError(`#getPageId is not yet supported with ${this.constructor.name}.`);
|
|
42
|
-
}
|
|
43
|
-
makeLiveURL
|
|
46
|
+
}
|
|
47
|
+
makeLiveURL() {
|
|
44
48
|
throw new ServerError(`Live URLs are not yet supported with ${this.constructor.name}.`);
|
|
45
|
-
}
|
|
46
|
-
|
|
49
|
+
}
|
|
50
|
+
async newPage() {
|
|
47
51
|
throw new ServerError(`Can't create new page with ${this.constructor.name}`);
|
|
48
|
-
}
|
|
49
|
-
|
|
52
|
+
}
|
|
53
|
+
async launch(options = {}, version) {
|
|
50
54
|
this.logger.info(`Launching ${this.constructor.name} Handler`);
|
|
51
55
|
const opts = {
|
|
52
56
|
...options,
|
|
@@ -63,9 +67,11 @@ export class FirefoxPlaywright extends EventEmitter {
|
|
|
63
67
|
this.browserWSEndpoint = browserWSEndpoint;
|
|
64
68
|
this.running = true;
|
|
65
69
|
return this.browser;
|
|
66
|
-
}
|
|
67
|
-
wsEndpoint
|
|
68
|
-
|
|
70
|
+
}
|
|
71
|
+
wsEndpoint() {
|
|
72
|
+
return this.browserWSEndpoint;
|
|
73
|
+
}
|
|
74
|
+
publicWSEndpoint(token) {
|
|
69
75
|
if (!this.browserWSEndpoint) {
|
|
70
76
|
return null;
|
|
71
77
|
}
|
|
@@ -76,26 +82,28 @@ export class FirefoxPlaywright extends EventEmitter {
|
|
|
76
82
|
externalURL.searchParams.set('token', token);
|
|
77
83
|
}
|
|
78
84
|
return externalURL.href;
|
|
79
|
-
}
|
|
80
|
-
|
|
85
|
+
}
|
|
86
|
+
async proxyPageWebSocket() {
|
|
81
87
|
this.logger.warn(`Not yet implemented in ${this.constructor.name}`);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
88
|
+
}
|
|
89
|
+
async proxyWebSocket(req, socket, head) {
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
if (!this.browserWSEndpoint) {
|
|
92
|
+
throw new ServerError(`No browserWSEndpoint found, did you launch first?`);
|
|
93
|
+
}
|
|
94
|
+
socket.once('close', resolve);
|
|
95
|
+
this.logger.info(`Proxying ${req.parsed.href} to ${this.constructor.name} ${this.browserWSEndpoint}`);
|
|
96
|
+
// Delete headers known to cause issues
|
|
97
|
+
delete req.headers.origin;
|
|
98
|
+
req.url = '';
|
|
99
|
+
this.proxy.ws(req, socket, head, {
|
|
100
|
+
changeOrigin: true,
|
|
101
|
+
target: this.browserWSEndpoint,
|
|
102
|
+
}, (error) => {
|
|
103
|
+
this.logger.error(`Error proxying session to ${this.constructor.name}: ${error}`);
|
|
104
|
+
this.close();
|
|
105
|
+
return reject(error);
|
|
106
|
+
});
|
|
99
107
|
});
|
|
100
|
-
}
|
|
108
|
+
}
|
|
101
109
|
}
|
|
@@ -1,36 +1,37 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { BrowserHTTPRoute, BrowserInstance, BrowserServerOptions, BrowserWebsocketRoute, BrowserlessSession, BrowserlessSessionJSON, CDPJSONPayload, CDPLaunchOptions, ChromiumCDP, Config, Hooks, Logger, Request } from '@browserless.io/browserless';
|
|
2
3
|
import { Page } from 'puppeteer-core';
|
|
3
4
|
export declare class BrowserManager {
|
|
4
5
|
protected config: Config;
|
|
5
6
|
protected hooks: Hooks;
|
|
6
7
|
protected browsers: Map<BrowserInstance, BrowserlessSession>;
|
|
7
|
-
protected timers: Map<string,
|
|
8
|
+
protected timers: Map<string, NodeJS.Timeout>;
|
|
8
9
|
protected log: Logger;
|
|
9
10
|
protected chromeBrowsers: (typeof ChromiumCDP)[];
|
|
10
11
|
protected playwrightBrowserNames: string[];
|
|
11
12
|
constructor(config: Config, hooks: Hooks);
|
|
12
|
-
protected browserIsChrome
|
|
13
|
-
protected removeUserDataDir
|
|
14
|
-
protected onNewPage
|
|
13
|
+
protected browserIsChrome(b: BrowserInstance): boolean;
|
|
14
|
+
protected removeUserDataDir(userDataDir: string | null): Promise<void>;
|
|
15
|
+
protected onNewPage(req: Request, page: Page): Promise<unknown>;
|
|
15
16
|
/**
|
|
16
17
|
* Returns the /json/protocol API contents from Chromium or Chrome, whichever is installed,
|
|
17
18
|
* and modifies URLs to set them to the appropriate addresses configured.
|
|
18
19
|
* When both Chrome and Chromium are installed, defaults to Chromium.
|
|
19
20
|
*/
|
|
20
|
-
getProtocolJSON
|
|
21
|
+
getProtocolJSON(logger: Logger): Promise<object>;
|
|
21
22
|
/**
|
|
22
23
|
* Returns the /json/version API from Chromium or Chrome, whichever is installed,
|
|
23
24
|
* and modifies URLs to set them to the appropriate addresses configured.
|
|
24
25
|
* When both Chrome and Chromium are installed, defaults to Chromium.
|
|
25
26
|
*/
|
|
26
|
-
getVersionJSON
|
|
27
|
+
getVersionJSON(logger: Logger): Promise<CDPJSONPayload>;
|
|
27
28
|
/**
|
|
28
29
|
* Returns a list of all Chrome-like browsers (both Chromium and Chrome) with
|
|
29
30
|
* their respective /json/list contents. URLs are modified so that subsequent
|
|
30
31
|
* calls can be forwarded to the appropriate destination
|
|
31
32
|
*/
|
|
32
|
-
getJSONList
|
|
33
|
-
protected generateSessionJson
|
|
33
|
+
getJSONList(): Promise<Array<CDPJSONPayload>>;
|
|
34
|
+
protected generateSessionJson(browser: BrowserInstance, session: BrowserlessSession): Promise<{
|
|
34
35
|
browser: string;
|
|
35
36
|
browserId: string;
|
|
36
37
|
initialConnectURL: string;
|
|
@@ -38,23 +39,23 @@ export declare class BrowserManager {
|
|
|
38
39
|
running: boolean;
|
|
39
40
|
timeAliveMs: number;
|
|
40
41
|
type: string;
|
|
41
|
-
id: string
|
|
42
|
+
id: string;
|
|
42
43
|
isTempDataDir: boolean;
|
|
43
44
|
launchOptions: CDPLaunchOptions | BrowserServerOptions;
|
|
44
45
|
numbConnected: number;
|
|
45
|
-
resolver
|
|
46
|
+
resolver(val: unknown): void;
|
|
46
47
|
routePath: string | string[];
|
|
47
48
|
startedOn: number;
|
|
48
49
|
ttl: number;
|
|
49
50
|
userDataDir: string | null;
|
|
50
51
|
}[]>;
|
|
51
|
-
close
|
|
52
|
-
getAllSessions
|
|
53
|
-
complete
|
|
54
|
-
getBrowserForRequest
|
|
55
|
-
shutdown
|
|
52
|
+
close(browser: BrowserInstance, session: BrowserlessSession): Promise<void>;
|
|
53
|
+
getAllSessions(): Promise<BrowserlessSessionJSON[]>;
|
|
54
|
+
complete(browser: BrowserInstance): Promise<void>;
|
|
55
|
+
getBrowserForRequest(req: Request, router: BrowserHTTPRoute | BrowserWebsocketRoute, logger: Logger): Promise<BrowserInstance>;
|
|
56
|
+
shutdown(): Promise<void>;
|
|
56
57
|
/**
|
|
57
58
|
* Left blank for downstream SDK modules to optionally implement.
|
|
58
59
|
*/
|
|
59
|
-
stop
|
|
60
|
+
stop(): void;
|
|
60
61
|
}
|