Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: pass request object to message interceptors #5

Merged
merged 1 commit into from
Jul 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,21 +395,21 @@ proxyServer.listen(8015);

};
```
* **wsInterceptClientMsg**: Is a handler which is called when a websocket message is intercepted on its way to the server from the client. It takes two arguments: `data` - is a websocket message and flags (fin, mask, compress, binary). If falsy value is returned then nothing will be sended to the client.
* **wsInterceptClientMsg**: Is a handler which is called when a websocket message is intercepted on its way to the server from the client. It takes two arguments: `data` - is a websocket message and `options` in which exists field `req` - websocket request object and `flags` (fin, mask, compress, binary). If falsy value is returned then nothing will be sended to the client.
```
const proxy = new HttpProxy({
...
wsInterceptClientMsg: (data, flags) {
wsInterceptClientMsg: (data, options) {
return typeof data === 'string ? data.toUpperCase() : data;
}
...
})
```
* **wsInterceptServerMsg**: Is a handler which is called when a websocket message is intercepted on its way to the client from the server. It takes two arguments: `data` - is a websocket message and flags (fin, mask, compress, binary). If falsy value is returned then nothing will be sended to the target server.
* **wsInterceptServerMsg**: Is a handler which is called when a websocket message is intercepted on its way to the client from the server. It takes two arguments: `data` - is a websocket message and `options` in which exist fields `req` - websocket request object and `flags` (fin, mask, compress, binary). If falsy value is returned then nothing will be sended to the target server.
```
const proxy = new HttpProxy({
...
wsInterceptServerMsg: (data, flags) {
wsInterceptServerMsg: (data, options) {
return typeof data === 'string ? data.toUpperCase() : data;
}
...
Expand Down
3 changes: 2 additions & 1 deletion lib/http-proxy/passes/ws-incoming.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ module.exports = {
//
socket.write(createHttpHeader('HTTP/1.1 101 Switching Protocols', proxyRes.headers));

const wsInterceptor = WsInterceptor.create({socket, options, proxyReq, proxyRes, proxySocket});
const wsInterceptor = WsInterceptor.create({socket, options, req, proxyReq, proxyRes, proxySocket});

wsInterceptor.startDataTransfer();

server.emit('open', proxySocket);
Expand Down
43 changes: 22 additions & 21 deletions lib/http-proxy/ws/interceptor.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,15 @@ const acceptExtensions = ({extensions, isServer}) => {
return {[extensionName]: perMessageDeflate};
};

const getMsgHandler = ({interceptor, dataSender, binary}) => {
return (data, flags) => {
if (typeof interceptor !== 'function') {
dataSender({data});
return;
}

const modifiedData = interceptor(data, flags);

// if interceptor does not return data then nothing will be sended to the server
if (modifiedData) {
dataSender({data: modifiedData, binary});
}
}
};

module.exports = class Interceptor {
static create(opts = {}) {
return new this(opts);
}

constructor({socket, options, proxyReq, proxyRes, proxySocket}) {
constructor({socket, options, req, proxyReq, proxyRes, proxySocket}) {
this._socket = socket;
this._options = options;
this._req = req;
this._proxyReq = proxyReq;
this._proxyRes = proxyRes;
this._proxySocket = proxySocket;
Expand Down Expand Up @@ -74,6 +59,22 @@ module.exports = class Interceptor {
};
}

_getMsgHandler({interceptor, dataSender, binary}) {
return (data, flags) => {
if (typeof interceptor !== 'function') {
dataSender({data});
return;
}

const modifiedData = interceptor(data, {req: this._req, flags});

// if interceptor does not return data then nothing will be sended to the server
if (modifiedData) {
dataSender({data: modifiedData, binary});
}
}
}

_interceptClientMessages() {
const receiver = new Receiver(this._clientExtensions);
const sender = new Sender(this._proxySocket, this._serverExtensions);
Expand All @@ -83,8 +84,8 @@ module.exports = class Interceptor {
const options = {mask: true};
const dataSender = this._getDataSender({sender, event: 'wsClientMsg', options});

receiver.ontext = getMsgHandler({interceptor: this._options.wsInterceptClientMsg, dataSender, binary: false});
receiver.onbinary = getMsgHandler({interceptor: this._options.wsInterceptClientMsg, dataSender, binary: true});
receiver.ontext = this._getMsgHandler({interceptor: this._options.wsInterceptClientMsg, dataSender, binary: false});
receiver.onbinary = this._getMsgHandler({interceptor: this._options.wsInterceptClientMsg, dataSender, binary: true});
receiver.onclose = (code, msg, {masked: mask}) => this._isSocketOpened && sender.close(code, msg, mask);

this._socket.on('data', (data) => receiver.add(data));
Expand All @@ -98,8 +99,8 @@ module.exports = class Interceptor {
const options = {mask: false};
const dataSender = this._getDataSender({sender, event: 'wsServerMsg', options});

receiver.ontext = getMsgHandler({interceptor: this._options.wsInterceptServerMsg, dataSender, binary: false});
receiver.onbinary = getMsgHandler({interceptor: this._options.wsInterceptServerMsg, dataSender, binary: true});
receiver.ontext = this._getMsgHandler({interceptor: this._options.wsInterceptServerMsg, dataSender, binary: false});
receiver.onbinary = this._getMsgHandler({interceptor: this._options.wsInterceptServerMsg, dataSender, binary: true});
receiver.onclose = (code, msg, {masked: mask}) => this._isSocketOpened && sender.close(code, msg, mask);

this._proxySocket.on('data', (data) => receiver.add(data));
Expand Down