diff --git a/packages/playwright-core/src/server/browser.ts b/packages/playwright-core/src/server/browser.ts index f369632f4a..e5390889bf 100644 --- a/packages/playwright-core/src/server/browser.ts +++ b/packages/playwright-core/src/server/browser.ts @@ -85,13 +85,13 @@ export abstract class Browser extends SdkObject { async newContext(metadata: CallMetadata, options: channels.BrowserNewContextParams): Promise { validateBrowserContextOptions(options, this.options); - let clientCertificateProxy: ClientCertificatesProxy | undefined; + let socksServer: ClientCertificatesProxy | undefined; if (shouldUseMitmSocksProxy(options)) { - clientCertificateProxy = new ClientCertificatesProxy(options); - options.proxy = { server: await clientCertificateProxy.listen() }; + socksServer = new ClientCertificatesProxy(options); + options.proxy = { server: await socksServer.listen() }; } const context = await this.doCreateNewContext(options); - context._socksServer = clientCertificateProxy; + context._socksServer = socksServer; if (options.storageState) await context.setStorageState(metadata, options.storageState); return context; diff --git a/packages/playwright-core/src/server/socksClientCertificatesInterceptor.ts b/packages/playwright-core/src/server/socksClientCertificatesInterceptor.ts index 390d1573a0..a05165b549 100644 --- a/packages/playwright-core/src/server/socksClientCertificatesInterceptor.ts +++ b/packages/playwright-core/src/server/socksClientCertificatesInterceptor.ts @@ -21,7 +21,7 @@ import fs from 'fs'; import tls from 'tls'; import stream from 'stream'; import { createSocket } from '../utils/happy-eyeballs'; -import { assert, isUnderTest, urlMatches } from '../utils'; +import { assert, globToRegex, isUnderTest } from '../utils'; import type { SocksSocketClosedPayload, SocksSocketDataPayload, SocksSocketRequestedPayload } from '../common/socksProxy'; import { SocksProxy } from '../common/socksProxy'; import type * as channels from '@protocol/channels'; @@ -168,11 +168,21 @@ export class ClientCertificatesProxy { } } +const kClientCertificatesGlobRegex = Symbol('kClientCertificatesGlobRegex'); + export function clientCertificatesToTLSOptions( clientCertificates: channels.BrowserNewContextOptions['clientCertificates'], requestURL: string ): Pick | undefined { - const matchingCerts = clientCertificates?.filter(c => urlMatches(undefined, requestURL, c.url)); + const matchingCerts = clientCertificates?.filter(c => { + let regex: RegExp | undefined = (c as any)[kClientCertificatesGlobRegex]; + if (!regex) { + regex = globToRegex(c.url); + (c as any)[kClientCertificatesGlobRegex] = regex; + } + regex.lastIndex = 0; + return regex.test(requestURL); + }); if (!matchingCerts || !matchingCerts.length) return; const requestOptions = {