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
This commit is contained in:
Dmitriy Dudkevich 2022-11-24 13:00:03 +03:00 committed by GitHub
parent da92055e9c
commit 937fffaedc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 12 deletions

View File

@ -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<string, string>;
}
```
## Remarks
Only works in the Node.js environment.

View File

@ -15,7 +15,8 @@ export interface ConnectOptions extends BrowserConnectOptions
## Properties ## Properties
| Property | Modifiers | Type | Description | Default | | Property | Modifiers | Type | Description | Default |
| --------------------------------------------------------------------- | --------- | --------------------------------------------------------- | ----------------- | ------- | | --------------------------------------------------------------------- | --------- | --------------------------------------------------------- | --------------------------------------------------------------- | ------- |
| [browserURL?](./puppeteer.connectoptions.browserurl.md) | | string | <i>(Optional)</i> | | | [browserURL?](./puppeteer.connectoptions.browserurl.md) | | string | <i>(Optional)</i> | |
| [browserWSEndpoint?](./puppeteer.connectoptions.browserwsendpoint.md) | | string | <i>(Optional)</i> | | | [browserWSEndpoint?](./puppeteer.connectoptions.browserwsendpoint.md) | | string | <i>(Optional)</i> | |
| [headers?](./puppeteer.connectoptions.headers.md) | | Record&lt;string, string&gt; | <i>(Optional)</i> Headers to use for the web socket connection. | |
| [transport?](./puppeteer.connectoptions.transport.md) | | [ConnectionTransport](./puppeteer.connectiontransport.md) | <i>(Optional)</i> | | | [transport?](./puppeteer.connectoptions.transport.md) | | [ConnectionTransport](./puppeteer.connectiontransport.md) | <i>(Optional)</i> | |

View File

@ -24,6 +24,8 @@ import {Connection} from './Connection.js';
import {ConnectionTransport} from './ConnectionTransport.js'; import {ConnectionTransport} from './ConnectionTransport.js';
import {getFetch} from './fetch.js'; import {getFetch} from './fetch.js';
import {Viewport} from './PuppeteerViewport.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 * Generic browser options that can be passed when launching any browser or when
* connecting to an existing browser instance. * connecting to an existing browser instance.
@ -73,11 +75,7 @@ const getWebSocketTransportClass = async () => {
* @internal * @internal
*/ */
export async function _connectToCDPBrowser( export async function _connectToCDPBrowser(
options: BrowserConnectOptions & { options: BrowserConnectOptions & ConnectOptions
browserWSEndpoint?: string;
browserURL?: string;
transport?: ConnectionTransport;
}
): Promise<CDPBrowser> { ): Promise<CDPBrowser> {
const { const {
browserWSEndpoint, browserWSEndpoint,
@ -85,6 +83,7 @@ export async function _connectToCDPBrowser(
ignoreHTTPSErrors = false, ignoreHTTPSErrors = false,
defaultViewport = {width: 800, height: 600}, defaultViewport = {width: 800, height: 600},
transport, transport,
headers = {},
slowMo = 0, slowMo = 0,
targetFilter, targetFilter,
_isPageTarget: isPageTarget, _isPageTarget: isPageTarget,
@ -102,7 +101,7 @@ export async function _connectToCDPBrowser(
} else if (browserWSEndpoint) { } else if (browserWSEndpoint) {
const WebSocketClass = await getWebSocketTransportClass(); const WebSocketClass = await getWebSocketTransportClass();
const connectionTransport: ConnectionTransport = const connectionTransport: ConnectionTransport =
await WebSocketClass.create(browserWSEndpoint); await WebSocketClass.create(browserWSEndpoint, headers);
connection = new Connection(browserWSEndpoint, connectionTransport, slowMo); connection = new Connection(browserWSEndpoint, connectionTransport, slowMo);
} else if (browserURL) { } else if (browserURL) {
const connectionURL = await getWSEndpoint(browserURL); const connectionURL = await getWSEndpoint(browserURL);

View File

@ -21,7 +21,10 @@ import {packageVersion} from '../generated/version.js';
* @internal * @internal
*/ */
export class NodeWebSocketTransport implements ConnectionTransport { export class NodeWebSocketTransport implements ConnectionTransport {
static create(url: string): Promise<NodeWebSocketTransport> { static create(
url: string,
headers?: Record<string, string>
): Promise<NodeWebSocketTransport> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const ws = new NodeWebSocket(url, [], { const ws = new NodeWebSocket(url, [], {
followRedirects: true, followRedirects: true,
@ -29,6 +32,7 @@ export class NodeWebSocketTransport implements ConnectionTransport {
maxPayload: 256 * 1024 * 1024, // 256Mb maxPayload: 256 * 1024 * 1024, // 256Mb
headers: { headers: {
'User-Agent': `Puppeteer ${packageVersion}`, 'User-Agent': `Puppeteer ${packageVersion}`,
...headers,
}, },
}); });

View File

@ -42,6 +42,12 @@ export interface ConnectOptions extends BrowserConnectOptions {
browserWSEndpoint?: string; browserWSEndpoint?: string;
browserURL?: string; browserURL?: string;
transport?: ConnectionTransport; transport?: ConnectionTransport;
/**
* Headers to use for the web socket connection.
* @remarks
* Only works in the Node.js environment.
*/
headers?: Record<string, string>;
} }
/** /**