mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(client-certificates): when server does tls renegotiation (#32155)
Certain https servers like Microsoft IIS aka. TLS servers do the TLS renegotiation after the TLS handshake. This ends up in two `'secureConnect'` events due to an upstream Node.js bug: https://github.com/nodejs/node/issues/54362 Drive-by: Move other listeners like `'close'` / `'end'` to `once()` as well. Relates https://github.com/microsoft/playwright/issues/32004
This commit is contained in:
parent
856c4509a2
commit
4daf5c2303
@ -60,7 +60,7 @@ class ALPNCache {
|
|||||||
ALPNProtocols: ['h2', 'http/1.1'],
|
ALPNProtocols: ['h2', 'http/1.1'],
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
}).then(socket => {
|
}).then(socket => {
|
||||||
socket.on('secureConnect', () => {
|
socket.once('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();
|
||||||
@ -93,8 +93,8 @@ class SocksProxyConnection {
|
|||||||
|
|
||||||
async connect() {
|
async connect() {
|
||||||
this.target = await createSocket(rewriteToLocalhostIfNeeded(this.host), this.port);
|
this.target = await createSocket(rewriteToLocalhostIfNeeded(this.host), this.port);
|
||||||
this.target.on('close', this._targetCloseEventListener);
|
this.target.once('close', this._targetCloseEventListener);
|
||||||
this.target.on('error', error => this.socksProxy._socksProxy.sendSocketError({ uid: this.uid, error: error.message }));
|
this.target.once('error', error => this.socksProxy._socksProxy.sendSocketError({ uid: this.uid, error: error.message }));
|
||||||
this.socksProxy._socksProxy.socketConnected({
|
this.socksProxy._socksProxy.socketConnected({
|
||||||
uid: this.uid,
|
uid: this.uid,
|
||||||
host: this.target.localAddress!,
|
host: this.target.localAddress!,
|
||||||
@ -138,9 +138,9 @@ class SocksProxyConnection {
|
|||||||
...dummyServerTlsOptions,
|
...dummyServerTlsOptions,
|
||||||
ALPNProtocols: alpnProtocolChosenByServer === 'h2' ? ['h2', 'http/1.1'] : ['http/1.1'],
|
ALPNProtocols: alpnProtocolChosenByServer === 'h2' ? ['h2', 'http/1.1'] : ['http/1.1'],
|
||||||
});
|
});
|
||||||
this.internal?.on('close', () => dummyServer.close());
|
this.internal?.once('close', () => dummyServer.close());
|
||||||
dummyServer.emit('connection', this.internal);
|
dummyServer.emit('connection', this.internal);
|
||||||
dummyServer.on('secureConnection', internalTLS => {
|
dummyServer.once('secureConnection', internalTLS => {
|
||||||
debugLogger.log('client-certificates', `Browser->Proxy ${this.host}:${this.port} chooses ALPN ${internalTLS.alpnProtocol}`);
|
debugLogger.log('client-certificates', `Browser->Proxy ${this.host}:${this.port} chooses ALPN ${internalTLS.alpnProtocol}`);
|
||||||
|
|
||||||
let targetTLS: tls.TLSSocket | undefined = undefined;
|
let targetTLS: tls.TLSSocket | undefined = undefined;
|
||||||
@ -162,7 +162,7 @@ class SocksProxyConnection {
|
|||||||
this.target.removeListener('close', this._targetCloseEventListener);
|
this.target.removeListener('close', this._targetCloseEventListener);
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
const session: http2.ServerHttp2Session = http2.performServerHandshake(internalTLS);
|
const session: http2.ServerHttp2Session = http2.performServerHandshake(internalTLS);
|
||||||
session.on('stream', (stream: http2.ServerHttp2Stream) => {
|
session.once('stream', (stream: http2.ServerHttp2Stream) => {
|
||||||
stream.respond({
|
stream.respond({
|
||||||
'content-type': 'text/html',
|
'content-type': 'text/html',
|
||||||
[http2.constants.HTTP2_HEADER_STATUS]: 503,
|
[http2.constants.HTTP2_HEADER_STATUS]: 503,
|
||||||
@ -171,7 +171,7 @@ class SocksProxyConnection {
|
|||||||
session.close();
|
session.close();
|
||||||
closeBothSockets();
|
closeBothSockets();
|
||||||
});
|
});
|
||||||
stream.on('error', () => closeBothSockets());
|
stream.once('error', () => closeBothSockets());
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
closeBothSockets();
|
closeBothSockets();
|
||||||
@ -208,16 +208,16 @@ class SocksProxyConnection {
|
|||||||
|
|
||||||
targetTLS = tls.connect(tlsOptions);
|
targetTLS = tls.connect(tlsOptions);
|
||||||
|
|
||||||
targetTLS.on('secureConnect', () => {
|
targetTLS.once('secureConnect', () => {
|
||||||
internalTLS.pipe(targetTLS);
|
internalTLS.pipe(targetTLS);
|
||||||
targetTLS.pipe(internalTLS);
|
targetTLS.pipe(internalTLS);
|
||||||
});
|
});
|
||||||
|
|
||||||
internalTLS.on('end', () => closeBothSockets());
|
internalTLS.once('end', () => closeBothSockets());
|
||||||
targetTLS.on('end', () => closeBothSockets());
|
targetTLS.once('end', () => closeBothSockets());
|
||||||
|
|
||||||
internalTLS.on('error', () => closeBothSockets());
|
internalTLS.once('error', () => closeBothSockets());
|
||||||
targetTLS.on('error', handleError);
|
targetTLS.once('error', handleError);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user