throw when proxy is provided

This commit is contained in:
Max Schmitt 2024-07-05 17:15:09 +02:00
parent e995f4a6f9
commit d6628657da
6 changed files with 54 additions and 27 deletions

View file

@ -523,7 +523,11 @@ Does not enforce fixed viewport, allows resizing window in the headed mode.
- `passphrase` ?<[string]> Passphrase for the private key (PEM or PFX).
- `pfx` ?<[string]> PFX or PKCS12 encoded private key and certificate chain.
An array of client certificates to be used. Each certificate object must have `cert` and `key` or `pfx` to load the client certificate. Optionally, `passphrase` property should be provided if the private key is encrypted. If the certificate is issued by a custom certificate authority, the `ca` property should be provided with the path to the file with the certificate authority's certificate. If the certificate is valid only for specific URLs, the `url` property should be provided with a glob pattern to match the URLs that the certificate is valid for.
An array of client certificates to be used. Each certificate object must have `cert` and `key` or `pfx` to load the client certificate. Optionally, `passphrase` property should be provided if the private key is encrypted. If the certificate is issued by a custom certificate authority, the `ignoreHTTPSErrors` needs to be set. If the certificate is valid only for specific URLs, the `url` property should be provided with a glob pattern to match the URLs that the certificate is valid for.
:::note
Using Client Certificates in combination with Proxy Servers is not supported.
:::
## context-option-useragent
- `userAgent` <[string]>

View file

@ -28,7 +28,7 @@ import { Worker } from './worker';
import { Events } from './events';
import { TimeoutSettings } from '../common/timeoutSettings';
import { Waiter } from './waiter';
import type { URLMatch, Headers, WaitForEventOptions, BrowserContextOptions, StorageState, LaunchOptions, ClientCertificate } from './types';
import type { URLMatch, Headers, WaitForEventOptions, BrowserContextOptions, StorageState, LaunchOptions } from './types';
import { headersObjectToArray, isRegExp, isString, urlMatchesEqual } from '../utils';
import { mkdirIfNeeded } from '../utils/fileUtils';
import type * as api from '../../types/types';
@ -529,7 +529,7 @@ export async function prepareBrowserContextParams(options: BrowserContextOptions
reducedMotion: options.reducedMotion === null ? 'no-override' : options.reducedMotion,
forcedColors: options.forcedColors === null ? 'no-override' : options.forcedColors,
acceptDownloads: toAcceptDownloadsProtocol(options.acceptDownloads),
clientCertificates: await toClientCertificatesProtocol(options.clientCertificates),
clientCertificates: await toClientCertificatesProtocol(options.proxy, options.clientCertificates),
};
if (!contextParams.recordVideo && options.videosPath) {
contextParams.recordVideo = {
@ -550,9 +550,11 @@ function toAcceptDownloadsProtocol(acceptDownloads?: boolean) {
return 'deny';
}
export async function toClientCertificatesProtocol(clientCertificates?: ClientCertificate[]): Promise<channels.PlaywrightNewRequestParams['clientCertificates']> {
export async function toClientCertificatesProtocol(proxy: BrowserContextOptions['proxy'], clientCertificates?: BrowserContextOptions['clientCertificates']): Promise<channels.PlaywrightNewRequestParams['clientCertificates']> {
if (!clientCertificates)
return undefined;
if (proxy)
throw new Error('Cannot specify both proxy and clientCertificates');
return await Promise.all(clientCertificates.map(async clientCertificate => {
if (clientCertificate.certs.length === 0)
throw new Error('No certs specified for url: ' + clientCertificate.url);

View file

@ -76,7 +76,7 @@ export class APIRequest implements api.APIRequest {
extraHTTPHeaders: options.extraHTTPHeaders ? headersObjectToArray(options.extraHTTPHeaders) : undefined,
storageState,
tracesDir,
clientCertificates: await toClientCertificatesProtocol(options.clientCertificates),
clientCertificates: await toClientCertificatesProtocol(options.proxy, options.clientCertificates),
})).request);
this._contexts.add(context);
context._request = this;

View file

@ -15593,9 +15593,11 @@ export interface APIRequest {
/**
* An array of client certificates to be used. Each certificate object must have `cert` and `key` or `pfx` to load the
* client certificate. Optionally, `passphrase` property should be provided if the private key is encrypted. If the
* certificate is issued by a custom certificate authority, the `ca` property should be provided with the path to the
* file with the certificate authority's certificate. If the certificate is valid only for specific URLs, the `url`
* property should be provided with a glob pattern to match the URLs that the certificate is valid for.
* certificate is issued by a custom certificate authority, the `ignoreHTTPSErrors` needs to be set. If the
* certificate is valid only for specific URLs, the `url` property should be provided with a glob pattern to match the
* URLs that the certificate is valid for.
*
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
*/
clientCertificates?: Array<{
/**
@ -16783,9 +16785,11 @@ export interface Browser extends EventEmitter {
/**
* An array of client certificates to be used. Each certificate object must have `cert` and `key` or `pfx` to load the
* client certificate. Optionally, `passphrase` property should be provided if the private key is encrypted. If the
* certificate is issued by a custom certificate authority, the `ca` property should be provided with the path to the
* file with the certificate authority's certificate. If the certificate is valid only for specific URLs, the `url`
* property should be provided with a glob pattern to match the URLs that the certificate is valid for.
* certificate is issued by a custom certificate authority, the `ignoreHTTPSErrors` needs to be set. If the
* certificate is valid only for specific URLs, the `url` property should be provided with a glob pattern to match the
* URLs that the certificate is valid for.
*
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
*/
clientCertificates?: Array<{
/**
@ -20254,9 +20258,11 @@ export interface BrowserContextOptions {
/**
* An array of client certificates to be used. Each certificate object must have `cert` and `key` or `pfx` to load the
* client certificate. Optionally, `passphrase` property should be provided if the private key is encrypted. If the
* certificate is issued by a custom certificate authority, the `ca` property should be provided with the path to the
* file with the certificate authority's certificate. If the certificate is valid only for specific URLs, the `url`
* property should be provided with a glob pattern to match the URLs that the certificate is valid for.
* certificate is issued by a custom certificate authority, the `ignoreHTTPSErrors` needs to be set. If the
* certificate is valid only for specific URLs, the `url` property should be provided with a glob pattern to match the
* URLs that the certificate is valid for.
*
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
*/
clientCertificates?: Array<{
/**

View file

@ -5204,9 +5204,11 @@ export interface PlaywrightTestOptions {
/**
* An array of client certificates to be used. Each certificate object must have `cert` and `key` or `pfx` to load the
* client certificate. Optionally, `passphrase` property should be provided if the private key is encrypted. If the
* certificate is issued by a custom certificate authority, the `ca` property should be provided with the path to the
* file with the certificate authority's certificate. If the certificate is valid only for specific URLs, the `url`
* property should be provided with a glob pattern to match the URLs that the certificate is valid for.
* certificate is issued by a custom certificate authority, the `ignoreHTTPSErrors` needs to be set. If the
* certificate is valid only for specific URLs, the `url` property should be provided with a glob pattern to match the
* URLs that the certificate is valid for.
*
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
*
* **Usage**
*

View file

@ -19,6 +19,7 @@ import path from 'path';
import { expect, playwrightTest as base } from '../config/browserTest';
import https from 'https';
import type net from 'net';
import type { BrowserContextOptions } from 'packages/playwright-test';
const test = base.extend<{ serverURL: string, serverURLRewrittenToLocalhost: string }>({
serverURL: async ({ }, use) => {
@ -58,23 +59,35 @@ const test = base.extend<{ serverURL: string, serverURLRewrittenToLocalhost: str
test.skip(({ mode }) => mode !== 'default');
const kClientCertificatesDir = path.join(__dirname, '../config/testserver/client-certificates');
const kValidationSubTests: any[] = [
[[{ url: 'test', certs: [] }], 'No certs specified for url: test'],
[[{ url: 'test', certs: [{}] }]], 'None of cert, key, passphrase or pfx is specified',
[[{
url: 'test', certs: [{
const kValidationSubTests: [BrowserContextOptions, string ][] = [
[{ clientCertificates: [{ url: 'test', certs: [] }] }, 'No certs specified for url: test'],
[{ clientCertificates: [{ url: 'test', certs: [{}] }] }, 'None of cert, key, passphrase or pfx is specified'],
[{ clientCertificates: [{
url: 'test',
certs: [{
cert: 'foo',
key: 'foo',
passphrase: 'foo',
pfx: 'foo',
}]
}], 'pfx is specified together with cert, key or passphrase']
}] }, 'pfx is specified together with cert, key or passphrase'],
[{
proxy: { server: 'http://localhost:8080' },
clientCertificates: [{
url: 'test',
certs: [{
cert: 'foo',
key: 'foo',
passphrase: 'foo',
pfx: 'foo',
}]
}] }, 'Cannot specify both proxy and clientCertificates'],
];
test.describe('fetch', () => {
test('validate input', async ({ playwright }) => {
for (const [clientCertificates, expected] of kValidationSubTests)
await expect(playwright.request.newContext({ clientCertificates })).rejects.toThrow(expected);
for (const [contextOptions, expected] of kValidationSubTests)
await expect(playwright.request.newContext(contextOptions)).rejects.toThrow(expected);
});
test('should fail with no client certificates provided', async ({ playwright, serverURL }) => {
@ -183,8 +196,8 @@ test.describe('fetch', () => {
test.describe('browser', () => {
test('validate input', async ({ browser }) => {
for (const [clientCertificates, expected] of kValidationSubTests)
await expect(browser.newContext({ clientCertificates })).rejects.toThrow(expected);
for (const [contextOptions, expected] of kValidationSubTests)
await expect(browser.newContext(contextOptions)).rejects.toThrow(expected);
});
test('should keep supporting http', async ({ browser, server }) => {