Reputation: 43673
I need to log WebSocket traffic, so I am about to write a Chrome Extension that would inject some JavaScript code that should do a trick.
WebSocket = new Proxy(WebSocket, {
construct: (target, args) => {
console.log('new WebSocket instance');
return new target(...args);
}
})
What method do I need to override to log messages sent and received?
How can I modify such messages sent/received? A simple working code would be greatly appreciated.
Upvotes: 0
Views: 241
Reputation: 370759
Rather than a Proxy, I'd construct and return a plain WebSocket, with your own custom methods attached as needed:
const origWebSocket = window.WebSocket;
window.WebSocket = function(url) {
const socket = new origWebSocket(url);
socket.send = (msg) => {
console.log('intercepted send:', msg);
origWebSocket.prototype.send.call(socket, msg);
};
socket.addEventListener('message', (event) => {
console.log('intercepted receive:', event.data);
});
return socket;
};
// patching done
const socket = new WebSocket('wss://echo.websocket.org');
socket.onopen = () => {
socket.send('hi');
};
To also modify an incoming message, you can patch the onmessage
property of the instance (and the addEventListener
property too, if needed) so that, when a message is received, it goes through your custom function first before the user's callback runs:
const origWebSocket = window.WebSocket;
const origOnMessage = Object.getOwnPropertyDescriptor(WebSocket.prototype, 'onmessage').set;
window.WebSocket = function(url) {
const socket = new origWebSocket(url);
Object.defineProperty(socket, 'onmessage', {
set(cb) {
origOnMessage.call(socket, (e) => {
// Have to use defineProperty because `data` is a getter on the prototype
Object.defineProperty(e, 'data', { value: e.data + ' modified' });
cb(e);
});
}
});
socket.send = (msg) => {
console.log('intercepted send:', msg);
origWebSocket.prototype.send.call(socket, msg);
};
socket.addEventListener('message', (event) => {
console.log('intercepted receive:', event.data);
event.data = 'foobar';
});
return socket;
};
// patching done
const socket = new WebSocket('wss://echo.websocket.org');
socket.onopen = () => {
socket.send('hi');
};
socket.onmessage = e => console.log('consumer sees message:', e.data);
Upvotes: 1