mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
chore: use happy eyeballs for client-certificates (#31859)
This commit is contained in:
parent
d3e2c6cbb2
commit
0c6ecf8df4
@ -20,7 +20,7 @@ import type https from 'https';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import tls from 'tls';
|
import tls from 'tls';
|
||||||
import stream from 'stream';
|
import stream from 'stream';
|
||||||
import { createSocket } from '../utils/happy-eyeballs';
|
import { createSocket, createTLSSocket } from '../utils/happy-eyeballs';
|
||||||
import { isUnderTest, ManualPromise } from '../utils';
|
import { isUnderTest, ManualPromise } from '../utils';
|
||||||
import type { SocksSocketClosedPayload, SocksSocketDataPayload, SocksSocketRequestedPayload } from '../common/socksProxy';
|
import type { SocksSocketClosedPayload, SocksSocketDataPayload, SocksSocketRequestedPayload } from '../common/socksProxy';
|
||||||
import { SocksProxy } from '../common/socksProxy';
|
import { SocksProxy } from '../common/socksProxy';
|
||||||
@ -42,22 +42,21 @@ class ALPNCache {
|
|||||||
const result = new ManualPromise<string>();
|
const result = new ManualPromise<string>();
|
||||||
this._cache.set(cacheKey, result);
|
this._cache.set(cacheKey, result);
|
||||||
result.then(success);
|
result.then(success);
|
||||||
const socket = tls.connect({
|
createTLSSocket({
|
||||||
host,
|
host,
|
||||||
port,
|
port,
|
||||||
servername: net.isIP(host) ? undefined : host,
|
servername: net.isIP(host) ? undefined : host,
|
||||||
ALPNProtocols: ['h2', 'http/1.1'],
|
ALPNProtocols: ['h2', 'http/1.1'],
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
});
|
}).then(socket => {
|
||||||
socket.on('secureConnect', () => {
|
socket.on('secureConnect', () => {
|
||||||
// The server may not respond with ALPN, in which case we default to http/1.1.
|
// The server may not respond with ALPN, in which case we default to http/1.1.
|
||||||
result.resolve(socket.alpnProtocol || 'http/1.1');
|
result.resolve(socket.alpnProtocol || 'http/1.1');
|
||||||
socket.end();
|
socket.end();
|
||||||
});
|
});
|
||||||
socket.on('error', error => {
|
}).catch(error => {
|
||||||
debugLogger.log('client-certificates', `ALPN error: ${error.message}`);
|
debugLogger.log('client-certificates', `ALPN error: ${error.message}`);
|
||||||
result.resolve('http/1.1');
|
result.resolve('http/1.1');
|
||||||
socket.end();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import * as https from 'https';
|
|||||||
import * as net from 'net';
|
import * as net from 'net';
|
||||||
import * as tls from 'tls';
|
import * as tls from 'tls';
|
||||||
import { ManualPromise } from './manualPromise';
|
import { ManualPromise } from './manualPromise';
|
||||||
|
import { assert } from './debug';
|
||||||
|
|
||||||
// Implementation(partial) of Happy Eyeballs 2 algorithm described in
|
// Implementation(partial) of Happy Eyeballs 2 algorithm described in
|
||||||
// https://www.rfc-editor.org/rfc/rfc8305
|
// https://www.rfc-editor.org/rfc/rfc8305
|
||||||
@ -66,7 +67,41 @@ export async function createSocket(host: string, port: number): Promise<net.Sock
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createConnectionAsync(options: http.ClientRequestArgs, oncreate: ((err: Error | null, socket?: net.Socket) => void) | undefined, useTLS: boolean) {
|
export async function createTLSSocket(options: tls.ConnectionOptions): Promise<tls.TLSSocket> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
assert(options.host, 'host is required');
|
||||||
|
if (net.isIP(options.host)) {
|
||||||
|
const socket = tls.connect(options)
|
||||||
|
socket.on('connect', () => resolve(socket));
|
||||||
|
socket.on('error', error => reject(error));
|
||||||
|
} else {
|
||||||
|
createConnectionAsync(options, (err, socket) => {
|
||||||
|
if (err)
|
||||||
|
reject(err);
|
||||||
|
if (socket)
|
||||||
|
resolve(socket);
|
||||||
|
}, true).catch(err => reject(err));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createConnectionAsync(
|
||||||
|
options: http.ClientRequestArgs,
|
||||||
|
oncreate: ((err: Error | null, socket?: tls.TLSSocket) => void) | undefined,
|
||||||
|
useTLS: true
|
||||||
|
): Promise<void>;
|
||||||
|
|
||||||
|
export async function createConnectionAsync(
|
||||||
|
options: http.ClientRequestArgs,
|
||||||
|
oncreate: ((err: Error | null, socket?: net.Socket) => void) | undefined,
|
||||||
|
useTLS: false
|
||||||
|
): Promise<void>;
|
||||||
|
|
||||||
|
export async function createConnectionAsync(
|
||||||
|
options: http.ClientRequestArgs,
|
||||||
|
oncreate: ((err: Error | null, socket?: any) => void) | undefined,
|
||||||
|
useTLS: boolean
|
||||||
|
): Promise<void> {
|
||||||
const lookup = (options as any).__testHookLookup || lookupAddresses;
|
const lookup = (options as any).__testHookLookup || lookupAddresses;
|
||||||
const hostname = clientRequestArgsToHostName(options);
|
const hostname = clientRequestArgsToHostName(options);
|
||||||
const addresses = await lookup(hostname);
|
const addresses = await lookup(hostname);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user