mirror of
https://github.com/avwo/whistle.git
synced 2026-10-29 07:06:36 +08:00
feat: Handle websocket
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user