Skip to content

Commit a74cd85

Browse files
committed
socket.io stuff
1 parent 4a4607d commit a74cd85

File tree

3 files changed

+80
-13
lines changed

3 files changed

+80
-13
lines changed

lib/caronte/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function createRightProxy(type) {
5656
var evnt = ev + pass.name.toLowerCase();
5757

5858
options.ee.emit(evnt + 'begin', req, res);
59-
var val = pass(req, res, options);
59+
var val = pass(req, res, options, head);
6060
options.ee.emit(evnt + 'end');
6161

6262
return val;

lib/caronte/passes/ws.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,22 @@ function checkMethodAndHeader (req, res, options) {
2828
}
2929

3030
if (req.headers.upgrade.toLowerCase() !== 'websocket') {
31-
req.end(); return true;
31+
res.destroy(); return true;
3232
}
3333
},
3434

35+
/**
36+
* Setup socket
37+
*
38+
*/
39+
40+
function setupSocket(req, res) {
41+
res.setTimeout(0);
42+
res.setNoDelay(true);
43+
44+
res.setKeepAlive(true, 0);
45+
},
46+
3547
/**
3648
* Sets `x-forwarded-*` headers if specified in config.
3749
*
@@ -58,8 +70,8 @@ function XHeaders(req, res, options) {
5870
*
5971
*
6072
*/
61-
function stream(req, res, options, instance) {
62-
req.pipe(new WebsocketStream(options, instance)).pipe(res);
73+
function stream(req, res, options, head) {
74+
req.pipe(new WebsocketStream(options, head)).pipe(res);
6375
}
6476

6577
] // <--

lib/caronte/streams/websocket.js

+64-9
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ module.exports = WebsocketStream;
88
function WebsocketStream(options, res) {
99
Duplex.call(this);
1010

11-
this.options = options;
12-
this.res = res;
11+
this.options = options;
12+
this.res = res;
13+
this.handshakeDone = false;
1314

1415
var self = this;
1516

@@ -28,9 +29,13 @@ WebsocketStream.prototype.onPipe = function(req) {
2829
common.setupOutgoing(self.options.ssl || {}, self.options, req)
2930
);
3031

31-
this.proxyReq.once('response', function(proxyRes) {
32-
self.onResponse(proxyRes);
32+
this.proxyReq.once('socket', function(proxySocket) {
33+
self.onSocket(proxySocket);
3334
});
35+
this.proxyReq.on('upgrade', function(proxyRes, proxySocket, proxyHead) {
36+
self.onUpgrade(proxyRes, proxySocket, proxyHead);
37+
});
38+
3439
this.proxyReq.on('error', function(e) {
3540
self.onError(e);
3641
});
@@ -40,8 +45,25 @@ WebsocketStream.prototype.onFinish = function() {
4045
this.proxyReq.end();
4146
};
4247

43-
WebsocketStream.prototype.onResponse = function(proxyRes) {
44-
this.proxyRes = proxyRes;
48+
WebsocketStream.prototype.onSocket = function(proxySocket) {
49+
50+
51+
};
52+
53+
WebsocketStream.prototype.onUpgrade = function(proxyRes, proxySocket, proxyHead) {
54+
this.handshake = {
55+
headers : proxyRes.headers,
56+
statusCode : proxyRes.statusCode
57+
};
58+
59+
this.proxyRes = proxyRes;
60+
this.proxySocket = proxySocket;
61+
this.proxyHead = proxyHead;
62+
63+
proxySocket.setTimeout(0);
64+
proxySocket.setNoDelay(true);
65+
66+
proxySocket.setKeepAlive(true, 0);
4567

4668

4769
};
@@ -52,9 +74,42 @@ WebsocketStream.prototype.onError = function(e) {
5274

5375

5476
WebsocketStream.prototype._write = function(chunk, encoding, callback) {
55-
77+
this.proxySocket.write(chunk, encoding, callback);
5678
};
5779

5880
WebsocketStream.prototype._read = function(size) {
59-
60-
};
81+
var chunk = (this.proxySocket ? this.proxySocket.read(size) : '') || '';
82+
83+
if(chunk && !this.handshakeDone) {
84+
var headers = '';
85+
86+
if (this.handshake.statusCode && this.handshake.statusCode == 101) {
87+
headers = [
88+
'HTTP/1.1 101 Switching Protocols',
89+
'Upgrade: websocket',
90+
'Connection: Upgrade',
91+
'Sec-WebSocket-Accept: ' + this.handshake.headers['sec-websocket-accept']
92+
];
93+
94+
headers = headers.concat('', '').join('\r\n');
95+
}
96+
97+
/*
98+
* Socket.IO specific code
99+
*/
100+
101+
var sdata = chunk.toString();
102+
sdata = sdata.substr(0, sdata.search(CRLF + CRLF));
103+
chunk = data.slice(Buffer.byteLength(sdata), data.length);
104+
105+
if (self.source.https && !self.target.https) { sdata = sdata.replace('ws:', 'wss:'); }
106+
107+
this.push(headers + sdata);
108+
this.push(data);
109+
110+
this.handshakeDone = true;
111+
return;
112+
}
113+
114+
this.push(chunk);
115+
};

0 commit comments

Comments
 (0)