Skip to content

Commit 4cf5c9a

Browse files
Apollon77joeferner
authored andcommitted
* update badges and add Node.js compatibility note to Readme
* adjust testing to new WebSocket versions * Adjust logic to still also get underlaying socket errors for WebSockets
1 parent 00c3ef6 commit 4cf5c9a

File tree

3 files changed

+51
-35
lines changed

3 files changed

+51
-35
lines changed

README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22

33
HTTP Man In The Middle (MITM) Proxy written in node.js. Supports capturing and modifying the request and response data.
44

5+
[![NPM version](http://img.shields.io/npm/v/http-mitm-proxy.svg)](https://www.npmjs.com/package/http-mitm-proxy)
56
[![](https://david-dm.org/joeferner/node-http-mitm-proxy.svg)](https://david-dm.org/joeferner/node-http-mitm-proxy)
6-
[![Build Status](https://travis-ci.org/joeferner/node-http-mitm-proxy.svg?branch=master)](https://travis-ci.org/joeferner/node-http-mitm-proxy)
7-
7+
[![Downloads](https://img.shields.io/npm/dm/http-mitm-proxy.svg)](https://www.npmjs.com/package/http-mitm-proxy)
8+
![Test Status](https://github.com/joeferner/node-http-mitm-proxy/workflows/Tests/badge.svg)
89

910
# Install
1011

1112
`npm install --save http-mitm-proxy`
1213

14+
## Node.js Compatibility
15+
The library should work starting Node.js 8.x, but testing is only expected for currently supported LTS versions of Node.js starting Node.js 12.x . use on your own risk with non LTS Node.js versions.
16+
1317
## Typescript
1418
type definitions are now included in this project, no extra steps required.
1519

lib/proxy.js

+18-12
Original file line numberDiff line numberDiff line change
@@ -628,9 +628,10 @@ Proxy.prototype._onWebSocketServerConnect = function(isSSL, ws, upgradeReq) {
628628
ctx.clientToProxyWebSocket.on('ping', self._onWebSocketFrame.bind(self, ctx, 'ping', false));
629629
ctx.clientToProxyWebSocket.on('pong', self._onWebSocketFrame.bind(self, ctx, 'pong', false));
630630
ctx.clientToProxyWebSocket.on('error', self._onWebSocketError.bind(self, ctx));
631+
ctx.clientToProxyWebSocket._socket.on('error', self._onWebSocketError.bind(self, ctx));
631632
ctx.clientToProxyWebSocket.on('close', self._onWebSocketClose.bind(self, ctx, false));
632633
ctx.clientToProxyWebSocket._socket.pause();
633-
634+
634635
var url;
635636
if (upgradeReq.url == '' || /^\//.test(upgradeReq.url)) {
636637
var hostPort = Proxy.parseHostAndPort(upgradeReq);
@@ -665,6 +666,7 @@ Proxy.prototype._onWebSocketServerConnect = function(isSSL, ws, upgradeReq) {
665666
ctx.proxyToServerWebSocket.on('error', self._onWebSocketError.bind(self, ctx));
666667
ctx.proxyToServerWebSocket.on('close', self._onWebSocketClose.bind(self, ctx, true));
667668
ctx.proxyToServerWebSocket.on('open', function() {
669+
ctx.proxyToServerWebSocket._socket.on('error', self._onWebSocketError.bind(self, ctx));
668670
if (ctx.clientToProxyWebSocket.readyState === WebSocket.OPEN) {
669671
ctx.clientToProxyWebSocket._socket.resume();
670672
}
@@ -816,7 +818,7 @@ Proxy.prototype._onHttpServerRequest = function(isSSL, clientToProxyRequest, pro
816818
}
817819
if (self.responseContentPotentiallyModified || ctx.responseContentPotentiallyModified) {
818820
ctx.serverToProxyResponse.headers['transfer-encoding'] = 'chunked';
819-
delete ctx.serverToProxyResponse.headers['content-length'];
821+
delete ctx.serverToProxyResponse.headers['content-length'];
820822
}
821823
if (self.keepAlive) {
822824
if (ctx.clientToProxyRequest.headers['proxy-connection']) {
@@ -991,14 +993,14 @@ Proxy.prototype._onWebSocketClose = function(ctx, closedByServer, code, message)
991993
}
992994
if (ctx.clientToProxyWebSocket.readyState !== ctx.proxyToServerWebSocket.readyState) {
993995
try {
994-
if (ctx.clientToProxyWebSocket.readyState === WebSocket.CLOSED && ctx.proxyToServerWebSocket.readyState === WebSocket.OPEN) {
995-
ctx.proxyToServerWebSocket.close(code, message);
996+
if (ctx.clientToProxyWebSocket.readyState === WebSocket.CLOSED && ctx.proxyToServerWebSocket.readyState === WebSocket.OPEN) {
997+
code === 1005 ? ctx.proxyToServerWebSocket.close() : ctx.proxyToServerWebSocket.close(code, message);
996998
} else if (ctx.proxyToServerWebSocket.readyState === WebSocket.CLOSED && ctx.clientToProxyWebSocket.readyState === WebSocket.OPEN) {
997-
ctx.clientToProxyWebSocket.close(code, message);
999+
code === 1005 ? ctx.proxyToServerWebSocket.close() : ctx.clientToProxyWebSocket.close(code, message);
9981000
}
999-
} catch (err) {
1000-
return self._onWebSocketError(ctx, err);
1001-
}
1001+
} catch (err) {
1002+
return self._onWebSocketError(ctx, err);
1003+
}
10021004
}
10031005
});
10041006
}
@@ -1014,10 +1016,14 @@ Proxy.prototype._onWebSocketError = function(ctx, err) {
10141016
});
10151017
}
10161018
if (ctx.proxyToServerWebSocket && ctx.clientToProxyWebSocket.readyState !== ctx.proxyToServerWebSocket.readyState) {
1017-
if (ctx.clientToProxyWebSocket.readyState === WebSocket.CLOSED && ctx.proxyToServerWebSocket.readyState === WebSocket.OPEN) {
1018-
ctx.proxyToServerWebSocket.close();
1019-
} else if (ctx.proxyToServerWebSocket.readyState === WebSocket.CLOSED && ctx.clientToProxyWebSocket.readyState === WebSocket.OPEN) {
1020-
ctx.clientToProxyWebSocket.close();
1019+
try {
1020+
if (ctx.clientToProxyWebSocket.readyState === WebSocket.CLOSED && ctx.proxyToServerWebSocket.readyState === WebSocket.OPEN) {
1021+
ctx.proxyToServerWebSocket.close();
1022+
} else if (ctx.proxyToServerWebSocket.readyState === WebSocket.CLOSED && ctx.clientToProxyWebSocket.readyState === WebSocket.OPEN) {
1023+
ctx.clientToProxyWebSocket.close();
1024+
}
1025+
} catch (err) {
1026+
// ignore
10211027
}
10221028
}
10231029
};

test/01_proxy.js

+27-21
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ var getHttp = function (url, cb) {
2727
};
2828

2929
var proxyHttp = function (url, keepAlive, cb) {
30-
request({
31-
url: url,
32-
proxy: 'http://127.0.0.1:' + testProxyPort,
30+
request({
31+
url: url,
32+
proxy: 'http://127.0.0.1:' + testProxyPort,
3333
ca: fs.readFileSync(__dirname + '/../.http-mitm-proxy/certs/ca.pem'),
3434
agentOptions: {
3535
keepAlive: keepAlive
@@ -65,7 +65,7 @@ describe('proxy', function () {
6565
];
6666
var wss = null;
6767

68-
before(function () {
68+
before(function (done) {
6969
testFiles.forEach(function (val) {
7070
testHashes[val] = crypto.createHash('sha256').update(fs.readFileSync(__dirname + '/www/' + val, 'utf8'), 'utf8').digest().toString();
7171
});
@@ -74,20 +74,22 @@ describe('proxy', function () {
7474
fileStaticA.serve(req, res);
7575
}).resume();
7676
});
77-
srvA.listen(testPortA, testHost);
78-
srvB = http.createServer(function (req, res) {
79-
req.addListener('end', function () {
80-
fileStaticB.serve(req, res);
81-
}).resume();
82-
});
83-
srvB.listen(testPortB, testHost);
84-
wss = new WebSocket.Server({
85-
port: testWSPort,
86-
});
87-
wss.on('connection', function (ws) {
88-
// just reply with the same message
89-
ws.on('message', function (message) {
90-
ws.send(message);
77+
srvA.listen(testPortA, testHost, () => {
78+
srvB = http.createServer(function (req, res) {
79+
req.addListener('end', function () {
80+
fileStaticB.serve(req, res);
81+
}).resume();
82+
});
83+
srvB.listen(testPortB, testHost, () => {
84+
wss = new WebSocket.Server({
85+
port: testWSPort,
86+
}, done);
87+
wss.on('connection', function (ws) {
88+
// just reply with the same message
89+
ws.on('message', function (message) {
90+
ws.send(message);
91+
});
92+
});
9193
});
9294
});
9395
});
@@ -371,8 +373,10 @@ describe('proxy', function () {
371373
});
372374

373375
it('send + receive message through proxy', function (done) {
374-
var ws = new WebSocket('ws://localhost:' + testProxyPort, {
375-
host: 'localhost:' + testWSPort,
376+
var ws = new WebSocket('ws://localhost:' + testProxyPort, {
377+
headers: {
378+
Host: 'localhost:' + testWSPort
379+
}
376380
});
377381
var testMessage = 'does websocket proxying work?';
378382
ws.on('open', function () {
@@ -417,7 +421,9 @@ describe('proxy', function () {
417421
});
418422

419423
var ws = new WebSocket('ws://localhost:' + testProxyPort, {
420-
host: 'localhost:' + testWSPort,
424+
headers: {
425+
host: 'localhost:' + testWSPort
426+
}
421427
});
422428
var testMessage = 'does rewriting messages work?';
423429
var rewrittenMessage = 'rewriting messages does work!';

0 commit comments

Comments
 (0)