chore: deflate large web socket messages (#26720)

This commit is contained in:
Pavel Feldman 2023-08-25 16:13:46 -07:00 committed by GitHub
parent feac31dbdc
commit bc1f6272d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 3 deletions

View file

@ -28,6 +28,7 @@ import type { AndroidDevice } from '../server/android/android';
import type { SocksProxy } from '../common/socksProxy'; import type { SocksProxy } from '../common/socksProxy';
import { debugLogger } from '../common/debugLogger'; import { debugLogger } from '../common/debugLogger';
import { createHttpServer } from '../utils'; import { createHttpServer } from '../utils';
import { perMessageDeflate } from '../server/transport';
let lastConnectionId = 0; let lastConnectionId = 0;
const kConnectionSymbol = Symbol('kConnection'); const kConnectionSymbol = Symbol('kConnection');
@ -82,7 +83,11 @@ export class PlaywrightServer {
}); });
debugLogger.log('server', 'Listening at ' + wsEndpoint); debugLogger.log('server', 'Listening at ' + wsEndpoint);
this._wsServer = new wsServer({ server, path: this._options.path }); this._wsServer = new wsServer({
server,
path: this._options.path,
perMessageDeflate,
});
const browserSemaphore = new Semaphore(this._options.maxConnections); const browserSemaphore = new Semaphore(this._options.maxConnections);
const controllerSemaphore = new Semaphore(1); const controllerSemaphore = new Semaphore(1);
const reuseBrowserSemaphore = new Semaphore(1); const reuseBrowserSemaphore = new Semaphore(1);
@ -92,6 +97,7 @@ export class PlaywrightServer {
}); });
} }
this._wsServer.on('connection', (ws, request) => { this._wsServer.on('connection', (ws, request) => {
debugLogger.log('server', 'Connected client ws.extension=' + ws.extensions);
const url = new URL('http://localhost' + (request.url || '')); const url = new URL('http://localhost' + (request.url || ''));
const browserHeader = request.headers['x-playwright-browser']; const browserHeader = request.headers['x-playwright-browser'];
const browserName = url.searchParams.get('browser') || (Array.isArray(browserHeader) ? browserHeader[0] : browserHeader) || null; const browserName = url.searchParams.get('browser') || (Array.isArray(browserHeader) ? browserHeader[0] : browserHeader) || null;

View file

@ -23,6 +23,16 @@ import { makeWaitForNextTask } from '../utils';
import { httpHappyEyeballsAgent, httpsHappyEyeballsAgent } from '../utils/happy-eyeballs'; import { httpHappyEyeballsAgent, httpsHappyEyeballsAgent } from '../utils/happy-eyeballs';
import type { HeadersArray } from './types'; import type { HeadersArray } from './types';
export const perMessageDeflate = {
zlibDeflateOptions: {
level: 3,
},
zlibInflateOptions: {
chunkSize: 10 * 1024
},
threshold: 10 * 1024,
};
export type ProtocolRequest = { export type ProtocolRequest = {
id: number; id: number;
method: string; method: string;
@ -117,13 +127,13 @@ export class WebSocketTransport implements ConnectionTransport {
this.wsEndpoint = url; this.wsEndpoint = url;
this._logUrl = logUrl; this._logUrl = logUrl;
this._ws = new ws(url, [], { this._ws = new ws(url, [], {
perMessageDeflate: false,
maxPayload: 256 * 1024 * 1024, // 256Mb, maxPayload: 256 * 1024 * 1024, // 256Mb,
// Prevent internal http client error when passing negative timeout. // Prevent internal http client error when passing negative timeout.
handshakeTimeout: Math.max(progress?.timeUntilDeadline() ?? 30_000, 1), handshakeTimeout: Math.max(progress?.timeUntilDeadline() ?? 30_000, 1),
headers, headers,
followRedirects, followRedirects,
agent: (/^(https|wss):\/\//.test(url)) ? httpsHappyEyeballsAgent : httpHappyEyeballsAgent agent: (/^(https|wss):\/\//.test(url)) ? httpsHappyEyeballsAgent : httpHappyEyeballsAgent,
perMessageDeflate,
}); });
this._ws.on('upgrade', response => { this._ws.on('upgrade', response => {
for (let i = 0; i < response.rawHeaders.length; i += 2) { for (let i = 0; i < response.rawHeaders.length; i += 2) {