Skip to content

Commit efa17ef

Browse files
committed
[fix] use routing table mhen proxying WebSockets.
closes issue #72
1 parent baf0b9e commit efa17ef

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

lib/node-http-proxy.js

+14
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,20 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options
583583
CRLF = '\r\n',
584584
outgoing;
585585

586+
options = options || {};
587+
options.host = options.host || this.target.host;
588+
options.port = options.port || this.target.port; //
589+
590+
if (this.proxyTable && !options.host) {
591+
location = this.proxyTable.getProxyLocation(req);
592+
593+
if (!location) {
594+
res.writeHead(404);
595+
return res.end();
596+
}
597+
options.port = location.port;
598+
options.host = location.host;
599+
}
586600
//
587601
// WebSocket requests must have the `GET` method and
588602
// the `upgrade:websocket` header

test/helpers.js

+40
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ TestRunner.prototype.assertResponseCode = function (proxyPort, statusCode, creat
121121
return test;
122122
};
123123

124+
//
125+
// WebSocketTest
126+
//
127+
124128
TestRunner.prototype.webSocketTest = function (options) {
125129
var self = this;
126130

@@ -154,6 +158,42 @@ TestRunner.prototype.webSocketTest = function (options) {
154158
});
155159
}
156160

161+
//
162+
// WebSocketTestWithTable
163+
//
164+
165+
TestRunner.prototype.webSocketTestWithTable = function (options) {
166+
var self = this;
167+
168+
this.startTargetServer(options.ports.target, 'hello websocket', function (err, target) {
169+
var socket = options.io.listen(target);
170+
171+
if (options.onListen) {
172+
options.onListen(socket);
173+
}
174+
175+
self.startProxyServerWithTable(
176+
options.ports.proxy,
177+
{router: options.router},
178+
function (err, proxy) {
179+
if (options.onServer) { options.onServer(proxy) }
180+
181+
//
182+
// Setup the web socket against our proxy
183+
//
184+
var uri = options.wsprotocol + '://' + options.host + ':' + options.ports.proxy;
185+
var ws = new websocket.WebSocket(uri + '/socket.io/websocket/', 'borf', {
186+
origin: options.protocol + '://' + options.host
187+
});
188+
189+
if (options.onWsupgrade) { ws.on('wsupgrade', options.onWsupgrade) }
190+
if (options.onMessage) { ws.on('message', options.onMessage) }
191+
if (options.onOpen) { ws.on('open', function () { options.onOpen(ws) }) }
192+
}
193+
);
194+
});
195+
}
196+
157197
//
158198
// Creates the reverse proxy server
159199
//

test/web-socket-proxy-test.js

+45
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,50 @@ var protocol = argv.https ? 'https' : 'http',
4848
runner = new helpers.TestRunner(protocol);
4949

5050
vows.describe('node-http-proxy/websocket/' + wsprotocol).addBatch({
51+
"when using proxy table":{
52+
"with no latency" : {
53+
"when an inbound message is sent from a WebSocket client": {
54+
topic: function () {
55+
var that = this
56+
headers = {};
57+
58+
runner.webSocketTestWithTable({
59+
io: io,
60+
host: 'localhost',
61+
wsprotocol: wsprotocol,
62+
protocol: protocol,
63+
router: {'localhost':'localhost:8230'},
64+
ports: {
65+
target: 8230,
66+
proxy: 8231
67+
},
68+
onListen: function (socket) {
69+
socket.on('connection', function (client) {
70+
client.on('message', function (msg) {
71+
that.callback(null, msg, headers);
72+
});
73+
});
74+
},
75+
onWsupgrade: function (req, res) {
76+
headers.request = req;
77+
headers.response = res.headers;
78+
},
79+
onOpen: function (ws) {
80+
ws.send(utils.encode('from client'));
81+
}
82+
});
83+
},
84+
"the target server should receive the message": function (err, msg, headers) {
85+
assert.equal(msg, 'from client');
86+
},
87+
"the origin and sec-websocket-origin headers should match": function (err, msg, headers) {
88+
assert.isString(headers.response['sec-websocket-location']);
89+
assert.isTrue(headers.response['sec-websocket-location'].indexOf(wsprotocol) !== -1);
90+
assert.equal(headers.request.Origin, headers.response['sec-websocket-origin']);
91+
}
92+
}
93+
}
94+
},
5195
"When using server created by httpProxy.createServer()": {
5296
"with no latency" : {
5397
"when an inbound message is sent from a WebSocket client": {
@@ -114,6 +158,7 @@ vows.describe('node-http-proxy/websocket/' + wsprotocol).addBatch({
114158
});
115159
},
116160
"should raise the `websocket:incoming` event": function (ign, data) {
161+
console.log(ign,data,utils.decode(data))
117162
assert.equal(utils.decode(data.toString().replace('\u0000', '')), 'from client');
118163
},
119164
},

0 commit comments

Comments
 (0)