test: check that browsers use proxy for websocket requests (#35348)

This commit is contained in:
Dmitry Gozman 2025-03-26 21:33:53 +00:00 committed by GitHub
parent 5af22ed72e
commit 89386628db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 47 additions and 7 deletions

View File

@ -88,6 +88,10 @@ export class TestProxy {
url.host = `127.0.0.1:${port}`; url.host = `127.0.0.1:${port}`;
if (options?.prefix) if (options?.prefix)
url.pathname = url.pathname.replace(options.prefix, ''); url.pathname = url.pathname.replace(options.prefix, '');
if (url.protocol === 'ws:')
url.protocol = 'http:';
else if (url.protocol === 'wss:')
url.protocol = 'https:';
req.url = url.toString(); req.url = url.toString();
}); });
} }

View File

@ -322,3 +322,37 @@ it('should use SOCKS proxy for websocket requests', async ({ browserType, server
await browser.close(); await browser.close();
await closeProxyServer(); await closeProxyServer();
}); });
it('should use http proxy for websocket requests', async ({ browserName, browserType, server, proxyServer }) => {
proxyServer.forwardTo(server.PORT, { allowConnectRequests: true });
const browser = await browserType.launch({
proxy: { server: `localhost:${proxyServer.PORT}` }
});
server.sendOnWebSocketConnection('incoming');
server.setRoute('/target.html', async (req, res) => {
res.end('<html><title>Served by the proxy</title></html>');
});
const page = await browser.newPage();
await page.goto('http://fake-localhost-127-0-0-1.nip.io:1337/target.html');
expect(await page.title()).toBe('Served by the proxy');
const value = await page.evaluate(() => {
let cb;
const result = new Promise(f => cb = f);
const ws = new WebSocket('ws://fake-localhost-127-0-0-1.nip.io:1337/ws');
ws.addEventListener('message', data => { ws.close(); cb(data.data); });
return result;
});
expect(value).toBe('incoming');
// WebKit does not use CONNECT for websockets, but other browsers do.
if (browserName === 'webkit')
expect(proxyServer.wsUrls).toContain('ws://fake-localhost-127-0-0-1.nip.io:1337/ws');
else
expect(proxyServer.connectHosts).toContain('fake-localhost-127-0-0-1.nip.io:1337');
await browser.close();
});

View File

@ -476,19 +476,21 @@ function onupgrade(req: http.IncomingMessage, socket: net.Socket, head: Buffer)
localAddress: this.localAddress, localAddress: this.localAddress,
}); });
proxyReq.on('error', () => socket.destroy());
proxyReq.on('upgrade', async function (proxyRes, proxySocket, proxyHead) { proxyReq.on('upgrade', async function (proxyRes, proxySocket, proxyHead) {
const header = ['HTTP/1.1 101 Switching Protocols']; const header = ['HTTP/1.1 101 Switching Protocols'];
for (const [key, value] of Object.entries(proxyRes.headersDistinct)) for (const [key, value] of Object.entries(proxyRes.headersDistinct))
header.push(`${key}: ${value}`); header.push(`${key}: ${value}`);
socket.write(header.join('\r\n') + '\r\n\r\n'); socket.write(header.join('\r\n') + '\r\n\r\n');
if (proxyHead && proxyHead.length) proxySocket.unshift(proxyHead); if (proxyHead && proxyHead.length)
proxySocket.unshift(proxyHead);
try { proxySocket.pipe(socket);
await pipeline(proxySocket, socket, proxySocket); socket.pipe(proxySocket);
} catch (error) { proxySocket.on('error', () => socket.destroy());
if (error.code !== "ECONNRESET") socket.on('error', () => proxySocket.destroy());
throw error; proxySocket.on('end', () => socket.end());
} socket.on('end', () => proxySocket.end());
}); });
proxyReq.end(head); proxyReq.end(head);