[Bug]: Websocket connection in renderer doesn't go through proxy even when session.setProxy used
Bojack92160 opened this issue · comments
Preflight Checklist
- I have read the Contributing Guidelines for this project.
- I agree to follow the Code of Conduct that this project adheres to.
- I have searched the issue tracker for a bug report that matches the one I want to file, without success.
Electron Version
18.3.0
What operating system are you using?
Windows
Operating System Version
Windows 10
What arch are you using?
x64
Last Known Working Electron version
don't know
Expected Behavior
I would like to make my websocket connection (as a client) go through a proxy.
For that, I create my websocket in a browser window, and use setProxy on the window.
When I use setProxy on the session of a browser window, I expect it to proxify all connections.
Actual Behavior
The websocket is well opened but does not go through the proxy.
In fact, the 'login' event is not even called.
I have tried to use webContents.session.forceReloadProxyConfig() wihtout success.
If I use loadUrl to go for example on 'https://whatismyipaddress.com/', this request go though the proxy, and the login event is called
Testcase Gist URL
No response
Additional Information
Environment versions:
node 16.15.1
ws 8.6.0
Code:
Here is my code to reproduce:
In the main process:
const { BrowserWindow, ipcMain } = require('electron');
this.win = new BrowserWindow({
width: 1000,
height: 600,
webPreferences: {
devTools: true,
nodeIntegration: true,
contextIsolation: false
}
});
this.win.webContents.on('login', (event, webContents, request, callback) => {
console.log(' WM login with user and password');
callback('username', 'password');
this.win.webContents.openDevTools();
});
this.win.webContents.session.setProxy({ proxyRules: 'http://myProxyIp:myProxyPort' });
this.win.loadUrl('./index.html');
this.win.webContents.send('openWs', ['wsUrl']); //method to open ws in render windows
ipcMain.on('error', (event, arg) => {
console.log(arg);
});
ipcMain.on('close', (event, arg) => {
console.log(arg);
});
ipcMain.on('message', (event, arg) => {
console.log(arg)
});
ipcMain.on('message', (event, arg) => {
console.log(arg)
});
The render process:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</body>
<script>
require('./renderWs.js');
</script>
</html>
renderWs.js :
const Websocket = require('ws');
const ipc = require('electron').ipcRenderer;
ipc.on('openWs', (event, args) => {
console.log(event, args);
openWS(...args);
});
async function openWS(url) {
const ws = new Websocket(url);
ws.on('open', () => {
ipc.send('open', 'open');
console.log('open');
ipc.on('send', (event, msg) => {
console.log(event, msg);
ws.send(msg);
});
});
ws.on('error', (e) => {
ipc.send('error', e);
console.log('error', e);
});
ws.on('close', (code) => {
ipc.send('close', close);
console.log('close', code);
});
ws.on('message', (data, isBinary) => {
ipc.send('message', [data, isBinary]);
console.log('message', !isBinary ? data.toString() : data);
});
}
You are using the ws
package and not the native WebSocket. So this is not a browser API but a Node.js thing (different HTTP stack from the renderer/browser). It can be proxied according to their docs https://www.npmjs.com/package/ws#how-to-connect-via-a-proxy but you shouldn't need that package at all.
thanks for the answer, this explain this behaviour