test: added tests for WebSocket over Socks proxy (#7235)
This commit is contained in:
parent
e6bf0a07fe
commit
4c6deaa449
|
|
@ -265,7 +265,7 @@ expect(userId).toBeTruthy();
|
||||||
|
|
||||||
// Assert value for input element
|
// Assert value for input element
|
||||||
await page.waitForSelector('#search');
|
await page.waitForSelector('#search');
|
||||||
const value = await page.$eval('#search', el => el.value);
|
const value = await page.inputValue('#search');
|
||||||
expect(value === 'query').toBeTruthy();
|
expect(value === 'query').toBeTruthy();
|
||||||
|
|
||||||
// Assert computed style
|
// Assert computed style
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,9 @@ export class FFNetworkManager {
|
||||||
ipAddress: event.remoteIPAddress,
|
ipAddress: event.remoteIPAddress,
|
||||||
port: event.remotePort,
|
port: event.remotePort,
|
||||||
});
|
});
|
||||||
} else {response._serverAddrFinished();}
|
} else {
|
||||||
|
response._serverAddrFinished();
|
||||||
|
}
|
||||||
response._securityDetailsFinished({
|
response._securityDetailsFinished({
|
||||||
protocol: event?.securityDetails?.protocol,
|
protocol: event?.securityDetails?.protocol,
|
||||||
subjectName: event?.securityDetails?.subjectName,
|
subjectName: event?.securityDetails?.subjectName,
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ type ServerFixtures = {
|
||||||
asset: (p: string) => string;
|
asset: (p: string) => string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ServersInternal = ServerFixtures & { socksServer: any };
|
type ServersInternal = ServerFixtures & { socksServer: socks.SocksServer };
|
||||||
const serverFixtures: Fixtures<ServerFixtures, ServerOptions & { __servers: ServersInternal }> = {
|
const serverFixtures: Fixtures<ServerFixtures, ServerOptions & { __servers: ServersInternal }> = {
|
||||||
loopback: [ undefined, { scope: 'worker' } ],
|
loopback: [ undefined, { scope: 'worker' } ],
|
||||||
__servers: [ async ({ loopback }, run, workerInfo) => {
|
__servers: [ async ({ loopback }, run, workerInfo) => {
|
||||||
|
|
@ -151,8 +151,8 @@ const serverFixtures: Fixtures<ServerFixtures, ServerOptions & { __servers: Serv
|
||||||
httpsServer.enableHTTPCache(cachedPath);
|
httpsServer.enableHTTPCache(cachedPath);
|
||||||
|
|
||||||
const socksServer = socks.createServer((info, accept, deny) => {
|
const socksServer = socks.createServer((info, accept, deny) => {
|
||||||
let socket;
|
const socket = accept(true);
|
||||||
if ((socket = accept(true))) {
|
if (socket) {
|
||||||
// Catch and ignore ECONNRESET errors.
|
// Catch and ignore ECONNRESET errors.
|
||||||
socket.on('error', () => {});
|
socket.on('error', () => {});
|
||||||
const body = '<html><title>Served by the SOCKS proxy</title></html>';
|
const body = '<html><title>Served by the SOCKS proxy</title></html>';
|
||||||
|
|
|
||||||
26
tests/index.d.ts
vendored
Normal file
26
tests/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
declare module 'socksv5' {
|
||||||
|
import type net from 'net';
|
||||||
|
|
||||||
|
class Auth { }
|
||||||
|
|
||||||
|
class SocksServer {
|
||||||
|
listen: net.Server['listen'];
|
||||||
|
useAuth(auth: Auth): void;
|
||||||
|
close: net.Server['close'];
|
||||||
|
}
|
||||||
|
|
||||||
|
type Info = {
|
||||||
|
srcAddr: string;
|
||||||
|
srcPort: number;
|
||||||
|
dstAddr: string;
|
||||||
|
dstPort: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function acceptHandler(intercept: true): net.Socket | undefined;
|
||||||
|
function acceptHandler(intercept: false): undefined;
|
||||||
|
export function createServer(cb: (info: Info, accept: typeof acceptHandler, deny: () => void) => void): SocksServer;
|
||||||
|
|
||||||
|
export const auth: {
|
||||||
|
None: () => Auth
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { playwrightTest as it, expect } from './config/browserTest';
|
import { playwrightTest as it, expect } from './config/browserTest';
|
||||||
|
import socks from 'socksv5';
|
||||||
import net from 'net';
|
import net from 'net';
|
||||||
|
|
||||||
it('should throw for bad server value', async ({browserType, browserOptions}) => {
|
it('should throw for bad server value', async ({browserType, browserOptions}) => {
|
||||||
|
|
@ -203,3 +204,60 @@ it('should use proxy', async ({ browserType, browserOptions }) => {
|
||||||
// This connect request should have emulated user agent.
|
// This connect request should have emulated user agent.
|
||||||
expect(requestText).toContain('MyUserAgent');
|
expect(requestText).toContain('MyUserAgent');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function setupSocksForwardingServer(port: number, forwardPort: number){
|
||||||
|
const socksServer = socks.createServer((info, accept, deny) => {
|
||||||
|
if (!['127.0.0.1', 'fake-localhost-127-0-0-1.nip.io'].includes(info.dstAddr) || info.dstPort !== 1337) {
|
||||||
|
deny();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const socket = accept(true);
|
||||||
|
if (socket) {
|
||||||
|
const dstSock = new net.Socket();
|
||||||
|
socket.pipe(dstSock).pipe(socket);
|
||||||
|
socket.on('close', () => dstSock.end());
|
||||||
|
socket.on('end', () => dstSock.end());
|
||||||
|
dstSock.setKeepAlive(false);
|
||||||
|
dstSock.connect(forwardPort, '127.0.0.1');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await new Promise(resolve => socksServer.listen(port, 'localhost', resolve));
|
||||||
|
socksServer.useAuth(socks.auth.None());
|
||||||
|
return {
|
||||||
|
closeProxyServer: () => socksServer.close(),
|
||||||
|
proxyServerAddr: `socks5://localhost:${port}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should use SOCKS proxy for websocket requests', async ({browserName, platform, browserType, browserOptions, server}, testInfo) => {
|
||||||
|
it.fixme(browserName === 'webkit' && platform === 'darwin');
|
||||||
|
const {proxyServerAddr, closeProxyServer} = await setupSocksForwardingServer(testInfo.workerIndex + 2048 + 2, server.PORT);
|
||||||
|
const browser = await browserType.launch({
|
||||||
|
...browserOptions,
|
||||||
|
proxy: {
|
||||||
|
server: proxyServerAddr,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
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();
|
||||||
|
|
||||||
|
// Hosts get resolved by the client
|
||||||
|
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');
|
||||||
|
|
||||||
|
await browser.close();
|
||||||
|
closeProxyServer();
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,5 @@
|
||||||
"strictBindCallApply": true,
|
"strictBindCallApply": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
},
|
},
|
||||||
"include": ["**/*.spec.js", "**/*.ts"]
|
"include": ["**/*.spec.js", "**/*.ts", "index.d.ts"]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue