feat: Handle websocket

This commit is contained in:
avwo
2017-07-26 10:08:51 +08:00
parent 517c15d143
commit ba2434ea55
3 changed files with 41 additions and 53 deletions
+17 -2
View File
@@ -1,7 +1,22 @@
var ws = require('ws');
var util = require('util');
var http = require('http');
var https = require('https');
function WebSocket() {
return ws();
function WebSocket(address, protocols, options) {
var httpReq = http.request;
var httpsReq = https.request;
http.request = function(opts) {
httpReq.apply(this, arguments);
};
https.request = function(opts) {
httpsReq.apply(this, arguments);
};
ws.apply(this, arguments);
http.request = httpReq;
https.request = httpsReq;
}
util.inherits(WebSocket, ws);
module.exports = WebSocket;
+21 -48
View File
@@ -6,7 +6,6 @@ var WebSocketServer = require('ws').Server;
* MIT Licensed
*/
var http = require('http');
var crypto = require('crypto');
var WebSocket = require('./ws/WebSocket');
var Extensions = require('./ws/Extensions');
@@ -40,7 +39,7 @@ WebSocketServer.prototype.handleUpgrade = function(req, socket, upgradeHead, cb)
* which may or may not be bound to a sepcific WebSocket instance.
*/
function handleHybiUpgrade(req, socket, upgradeHead, cb) {
function handleHybiUpgrade(req, socket, upgradeHead) {
// handle premature socket errors
var errorHandler = function() {
try { socket.destroy(); } catch (e) {}
@@ -63,11 +62,6 @@ function handleHybiUpgrade(req, socket, upgradeHead, cb) {
// verify protocol
var protocols = req.headers['sec-websocket-protocol'];
// verify client
var origin = version < 13 ?
req.headers['sec-websocket-origin'] :
req.headers['origin'];
// handle extensions offer
var extensionsOffer = Extensions.parse(req.headers['sec-websocket-extensions']);
@@ -108,20 +102,6 @@ function handleHybiUpgrade(req, socket, upgradeHead, cb) {
headers.push('Sec-WebSocket-Extensions: ' + Extensions.format(serverExtensions));
}
// allows external modification/inspection of handshake headers
self.emit('headers', headers);
socket.setTimeout(0);
socket.setNoDelay(true);
try {
socket.write(headers.concat('', '').join('\r\n'));
}
catch (e) {
// if the upgrade write fails, shut the connection down hard
try { socket.destroy(); } catch (e) {}
return;
}
var client = new WebSocket([req, socket, upgradeHead], {
protocolVersion: version,
protocol: protocol,
@@ -138,10 +118,26 @@ function handleHybiUpgrade(req, socket, upgradeHead, cb) {
}
});
}
// signal upgrade complete
socket.removeListener('error', errorHandler);
cb(client);
var completeHandShake = function() {
// allows external modification/inspection of handshake headers
self.emit('headers', headers);
socket.setTimeout(0);
socket.setNoDelay(true);
try {
socket.write(headers.concat('', '').join('\r\n'));
}
catch (e) {
// if the upgrade write fails, shut the connection down hard
try { socket.destroy(); } catch (e) {}
}
// signal upgrade complete
socket.removeListener('error', errorHandler);
};
if (typeof this.options.onConnect === 'function') {
this.options.onConnect(client, completeHandShake);
} else {
completeHandShake();
}
};
// optionally call external protocol selection handler before
@@ -171,29 +167,6 @@ function handleHybiUpgrade(req, socket, upgradeHead, cb) {
}
};
// optionally call external client verification handler
if (typeof this.options.verifyClient == 'function') {
var info = {
origin: origin,
secure: typeof req.connection.authorized !== 'undefined' || typeof req.connection.encrypted !== 'undefined',
req: req
};
if (this.options.verifyClient.length == 2) {
this.options.verifyClient(info, function(result, code, name) {
if (typeof code === 'undefined') code = 401;
if (typeof name === 'undefined') name = http.STATUS_CODES[code];
if (!result) abortConnection(socket, code, name);
else completeHybiUpgrade1();
});
return;
}
else if (!this.options.verifyClient(info)) {
abortConnection(socket, 401, 'Unauthorized');
return;
}
}
completeHybiUpgrade1();
}