From 937fffaedc340ea12d5f6636d3ba6598cb22e397 Mon Sep 17 00:00:00 2001 From: Dmitriy Dudkevich Date: Thu, 24 Nov 2022 13:00:03 +0300 Subject: [PATCH] feat: ability to send headers via ws connection to browser in node.js environment (#9314) **What kind of change does this PR introduce?** I have browsers pool in some cloud. I want that only users with access will be able to connect to them. So they must provide token through headers. But puppeteer does not allow to send headers when connected to browser by ws connection. So I added this feature. Closes #7218 --- docs/api/puppeteer.connectoptions.headers.md | 19 +++++++++++++++++++ docs/api/puppeteer.connectoptions.md | 11 ++++++----- .../src/common/BrowserConnector.ts | 11 +++++------ .../src/common/NodeWebSocketTransport.ts | 6 +++++- .../puppeteer-core/src/common/Puppeteer.ts | 6 ++++++ 5 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 docs/api/puppeteer.connectoptions.headers.md diff --git a/docs/api/puppeteer.connectoptions.headers.md b/docs/api/puppeteer.connectoptions.headers.md new file mode 100644 index 0000000000000..6971c6cc07646 --- /dev/null +++ b/docs/api/puppeteer.connectoptions.headers.md @@ -0,0 +1,19 @@ +--- +sidebar_label: ConnectOptions.headers +--- + +# ConnectOptions.headers property + +Headers to use for the web socket connection. + +#### Signature: + +```typescript +interface ConnectOptions { + headers?: Record; +} +``` + +## Remarks + +Only works in the Node.js environment. diff --git a/docs/api/puppeteer.connectoptions.md b/docs/api/puppeteer.connectoptions.md index 84e5a50ec9b7d..67b6826193333 100644 --- a/docs/api/puppeteer.connectoptions.md +++ b/docs/api/puppeteer.connectoptions.md @@ -14,8 +14,9 @@ export interface ConnectOptions extends BrowserConnectOptions ## Properties -| Property | Modifiers | Type | Description | Default | -| --------------------------------------------------------------------- | --------- | --------------------------------------------------------- | ----------------- | ------- | -| [browserURL?](./puppeteer.connectoptions.browserurl.md) | | string | (Optional) | | -| [browserWSEndpoint?](./puppeteer.connectoptions.browserwsendpoint.md) | | string | (Optional) | | -| [transport?](./puppeteer.connectoptions.transport.md) | | [ConnectionTransport](./puppeteer.connectiontransport.md) | (Optional) | | +| Property | Modifiers | Type | Description | Default | +| --------------------------------------------------------------------- | --------- | --------------------------------------------------------- | --------------------------------------------------------------- | ------- | +| [browserURL?](./puppeteer.connectoptions.browserurl.md) | | string | (Optional) | | +| [browserWSEndpoint?](./puppeteer.connectoptions.browserwsendpoint.md) | | string | (Optional) | | +| [headers?](./puppeteer.connectoptions.headers.md) | | Record<string, string> | (Optional) Headers to use for the web socket connection. | | +| [transport?](./puppeteer.connectoptions.transport.md) | | [ConnectionTransport](./puppeteer.connectiontransport.md) | (Optional) | | diff --git a/packages/puppeteer-core/src/common/BrowserConnector.ts b/packages/puppeteer-core/src/common/BrowserConnector.ts index 6c925a4609287..2d0647dbf834a 100644 --- a/packages/puppeteer-core/src/common/BrowserConnector.ts +++ b/packages/puppeteer-core/src/common/BrowserConnector.ts @@ -24,6 +24,8 @@ import {Connection} from './Connection.js'; import {ConnectionTransport} from './ConnectionTransport.js'; import {getFetch} from './fetch.js'; import {Viewport} from './PuppeteerViewport.js'; + +import type {ConnectOptions} from './Puppeteer.js'; /** * Generic browser options that can be passed when launching any browser or when * connecting to an existing browser instance. @@ -73,11 +75,7 @@ const getWebSocketTransportClass = async () => { * @internal */ export async function _connectToCDPBrowser( - options: BrowserConnectOptions & { - browserWSEndpoint?: string; - browserURL?: string; - transport?: ConnectionTransport; - } + options: BrowserConnectOptions & ConnectOptions ): Promise { const { browserWSEndpoint, @@ -85,6 +83,7 @@ export async function _connectToCDPBrowser( ignoreHTTPSErrors = false, defaultViewport = {width: 800, height: 600}, transport, + headers = {}, slowMo = 0, targetFilter, _isPageTarget: isPageTarget, @@ -102,7 +101,7 @@ export async function _connectToCDPBrowser( } else if (browserWSEndpoint) { const WebSocketClass = await getWebSocketTransportClass(); const connectionTransport: ConnectionTransport = - await WebSocketClass.create(browserWSEndpoint); + await WebSocketClass.create(browserWSEndpoint, headers); connection = new Connection(browserWSEndpoint, connectionTransport, slowMo); } else if (browserURL) { const connectionURL = await getWSEndpoint(browserURL); diff --git a/packages/puppeteer-core/src/common/NodeWebSocketTransport.ts b/packages/puppeteer-core/src/common/NodeWebSocketTransport.ts index fbe8e7c92c0c0..810a959a70d72 100644 --- a/packages/puppeteer-core/src/common/NodeWebSocketTransport.ts +++ b/packages/puppeteer-core/src/common/NodeWebSocketTransport.ts @@ -21,7 +21,10 @@ import {packageVersion} from '../generated/version.js'; * @internal */ export class NodeWebSocketTransport implements ConnectionTransport { - static create(url: string): Promise { + static create( + url: string, + headers?: Record + ): Promise { return new Promise((resolve, reject) => { const ws = new NodeWebSocket(url, [], { followRedirects: true, @@ -29,6 +32,7 @@ export class NodeWebSocketTransport implements ConnectionTransport { maxPayload: 256 * 1024 * 1024, // 256Mb headers: { 'User-Agent': `Puppeteer ${packageVersion}`, + ...headers, }, }); diff --git a/packages/puppeteer-core/src/common/Puppeteer.ts b/packages/puppeteer-core/src/common/Puppeteer.ts index 306e1eb9a87cd..31410e855d7d1 100644 --- a/packages/puppeteer-core/src/common/Puppeteer.ts +++ b/packages/puppeteer-core/src/common/Puppeteer.ts @@ -42,6 +42,12 @@ export interface ConnectOptions extends BrowserConnectOptions { browserWSEndpoint?: string; browserURL?: string; transport?: ConnectionTransport; + /** + * Headers to use for the web socket connection. + * @remarks + * Only works in the Node.js environment. + */ + headers?: Record; } /**