MCPcopy
hub / github.com/microsoft/playwright / WSServer

Class WSServer

packages/utils/wsServer.ts:52–184  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

50};
51
52export class WSServer {
53 private _wsServer: WebSocketServer | undefined;
54 server: http.Server | undefined;
55 private _delegate: WSServerDelegate;
56 // Allowed Host headers for HTTP requests. null disables the check (server bound to a public address).
57 private _allowedHosts: Set<string> | null = null;
58
59 constructor(delegate: WSServerDelegate) {
60 this._delegate = delegate;
61 }
62
63 async listen(port: number = 0, hostname: string | undefined, path: string): Promise<string> {
64 debugLogger.log('server', `Server started at ${new Date()}`);
65
66 // Default to loopback so the WebSocket RPC is not exposed to the network unless
67 // the caller explicitly opts in by passing a host (e.g. '0.0.0.0').
68 hostname ??= 'localhost';
69
70 const server = createHttpServer((request, response) => this._onRequest(request, response));
71 server.on('error', error => debugLogger.log('server', String(error)));
72 this.server = server;
73
74 const wsEndpoint = await new Promise<string>((resolve, reject) => {
75 server.listen(port, hostname, () => {
76 const address = server.address();
77 if (!address) {
78 reject(new Error('Could not bind server socket'));
79 return;
80 }
81 if (typeof address === 'string') {
82 resolve(`${address}${path}`);
83 return;
84 }
85 // Advertise the bound IP literal in the wsEndpoint so the client connects to
86 // the same address family the server bound to. Otherwise the client and
87 // server resolvers can disagree on what 'localhost' means (see #40605).
88 this._allowedHosts = computeAllowedHosts(hostname, address.address);
89 resolve(`ws://${urlHostFromAddress(address)}:${address.port}${path}`);
90 }).on('error', reject);
91 });
92
93 debugLogger.log('server', 'Listening at ' + wsEndpoint);
94
95 this._wsServer = new wsServer({
96 noServer: true,
97 perMessageDeflate,
98 });
99
100 this._wsServer.on('headers', headers => this._delegate.onHeaders(headers));
101
102 server.on('upgrade', (request, socket, head) => {
103 const pathname = new URL('http://localhost' + request.url!).pathname;
104 if (pathname !== path) {
105 socket.write(`HTTP/${request.httpVersion} 400 Bad Request\r\n\r\n`);
106 socket.destroy();
107 return;
108 }
109 if (this._allowedHosts && !this._isAllowedOrigin(request.headers.origin)) {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…