Comparing version 2.3.0 to 2.4.0
203
index.js
@@ -31,3 +31,4 @@ 'use strict'; | ||
var primus = this; | ||
var primus = this | ||
, key; | ||
@@ -88,3 +89,5 @@ this.auth = options.authorization || null; // Do we have an authorization handler. | ||
// | ||
for (var key in Spark) this.Spark[key] = Spark[key]; | ||
for (key in Spark) { | ||
this.Spark[key] = Spark[key]; | ||
} | ||
@@ -98,5 +101,15 @@ this.parsers(options.parser); | ||
// | ||
if ('object' === typeof options.plugin) for (var key in options.plugin) { | ||
this.use(key, options.plugin[key]); | ||
if ('string' === typeof options.plugin) { | ||
options.plugin.split(/[\s|,]+/).forEach(function register(name) { | ||
primus.use(name, name); | ||
}); | ||
return; | ||
} | ||
if ('object' === typeof options.plugin) { | ||
for (key in options.plugin) { | ||
this.use(key, options.plugin[key]); | ||
} | ||
} | ||
} | ||
@@ -248,2 +261,3 @@ | ||
// | ||
this.before('forwarded', require('./middleware/forwarded')); | ||
this.before('cors', require('./middleware/access-control')); | ||
@@ -610,4 +624,4 @@ this.before('primus.js', require('./middleware/primus')); | ||
// | ||
if (!('server' in energon || 'client' in energon)) { | ||
throw new PrimusError('The plugin in missing a client or server function', this); | ||
if (!energon.server && !energon.client) { | ||
throw new PrimusError('The plugin is missing a client or server function', this); | ||
} | ||
@@ -810,10 +824,6 @@ | ||
options = options || {}; | ||
var primus = this; | ||
/** | ||
* Clean up some stuff. | ||
* | ||
* @api private | ||
*/ | ||
function cleanup() { | ||
setTimeout(function cleanup() { | ||
// | ||
@@ -843,30 +853,74 @@ // Optionally close the server. | ||
// | ||
primus.emit('close', options); | ||
primus.asyncemit('close', options, function done(err) { | ||
if (err) { | ||
if (fn) return fn(err); | ||
throw err; | ||
} | ||
if (primus.transformer) { | ||
primus.transformer.emit('close', options); | ||
primus.transformer.removeAllListeners(); | ||
if (primus.transformer) { | ||
primus.transformer.emit('close', options); | ||
primus.transformer.removeAllListeners(); | ||
} | ||
if (primus.server) primus.server.removeAllListeners(); | ||
primus.removeAllListeners(); | ||
// | ||
// Null some potentially heavy objects to free some more memory instantly. | ||
// | ||
primus.transformers.outgoing.length = primus.transformers.incoming.length = 0; | ||
primus.transformer = primus.encoder = primus.decoder = primus.server = null; | ||
primus.sparks = primus.connected = 0; | ||
primus.connections = Object.create(null); | ||
primus.ark = Object.create(null); | ||
if (fn) fn(); | ||
}); | ||
}, +options.timeout || 0); | ||
return this; | ||
}); | ||
/** | ||
* Async emit an event. We make a really broad assumption here and that is they | ||
* have the same amount of arguments as the supplied arguments (excluding the | ||
* event name). | ||
* | ||
* @returns {Primus} | ||
* @api private | ||
*/ | ||
Primus.readable('asyncemit', function asyncemit() { | ||
var args = Array.prototype.slice.call(arguments, 0) | ||
, async = args.length - 1 | ||
, fn = args.pop() | ||
, primus = this; | ||
(function each(stack) { | ||
if (!stack.length) return fn(); | ||
var event = stack.shift(); | ||
if (event.__EE3_once) { | ||
primus.removeListener(args[0], event); | ||
} | ||
if (primus.server) primus.server.removeAllListeners(); | ||
primus.removeAllListeners(); | ||
if (event.length !== async) { | ||
event.apply(event.__EE3_context || primus, args); | ||
return each(stack); | ||
} | ||
// | ||
// Null some potentially heavy objects to free some more memory instantly. | ||
// Async operation | ||
// | ||
primus.transformers.outgoing.length = primus.transformers.incoming.length = 0; | ||
primus.transformer = primus.encoder = primus.decoder = primus.server = null; | ||
primus.sparks = primus.connected = 0; | ||
event.apply( | ||
event.__EE3_context || primus, | ||
args.concat(function done(err) { | ||
if (err) return fn(err); | ||
primus.connections = Object.create(null); | ||
primus.ark = Object.create(null); | ||
each(stack); | ||
}) | ||
); | ||
})(this.listeners(args.shift())); | ||
if (fn) fn(); | ||
} | ||
// | ||
// Force a `0` as timeout to maintain a full async callback. | ||
// | ||
setTimeout(cleanup, +options.timeout || 0); | ||
return this; | ||
@@ -940,72 +994,19 @@ }); | ||
options = options || {}; | ||
var server = require('create-server')(options, { | ||
http: function warn() { | ||
if (!options.iknowhttpsisbetter) [ | ||
'', | ||
'We\'ve detected that you\'re using a HTTP instead of a HTTPS server.', | ||
'Please beaware that real-time connections have less chance of being blocked', | ||
'by firewalls and anti-virus scanners if they are encrypted (using SSL). If', | ||
'you run your server behind a reverse and HTTPS terminating proxy ignore', | ||
'this message, if not, you\'ve been warned.', | ||
'' | ||
].forEach(function each(line) { | ||
console.log('primus: '+ line); | ||
}); | ||
} | ||
}); | ||
var port = options.port || 443 // Force HTTPS as default server. | ||
, certs = options.key && options.cert // Check HTTPS certificates. | ||
, secure = certs || 443 === port // Check for a true HTTPS | ||
, spdy = 'spdy' in options // Maybe.. We're SPDY | ||
, server; | ||
var path = require('path') | ||
, fs = require('fs'); | ||
// | ||
// We need to have SSL certs for SPDY and secure servers. | ||
// | ||
if ((secure || spdy) && !certs) { | ||
throw new Error('Missing the SSL key or certificate files in the options.'); | ||
} | ||
// | ||
// When given a `options.root` assume that our SSL certs and keys are path | ||
// references that still needs to be read. This allows a much more human | ||
// readable interface for SSL. | ||
// | ||
if (secure && options.root) { | ||
['cert', 'key', 'ca', 'pfx', 'crl'].filter(function filter(key) { | ||
return key in options; | ||
}).forEach(function parse(key) { | ||
var data = options[key]; | ||
if (Array.isArray(data)) { | ||
options[key] = data.map(function read(file) { | ||
return fs.readFileSync(path.join(options.root, file)); | ||
}); | ||
} else { | ||
options[key] = fs.readFileSync(path.join(options.root, data)); | ||
} | ||
}); | ||
} | ||
if (spdy) { | ||
server = require('spdy').createServer(options); | ||
} else if (secure) { | ||
server = require('https').createServer(options); | ||
if (+options.redirect) require('http').createServer(function handle(req, res) { | ||
res.statusCode = 404; | ||
if (req.headers.host) { | ||
res.statusCode = 301; | ||
res.setHeader('Location', 'https://'+ req.headers.host + req.url); | ||
} | ||
res.end(''); | ||
}).listen(+options.redirect); | ||
} else { | ||
server = require('http').createServer(); | ||
if (!options.iknowhttpsisbetter) [ | ||
'', | ||
'We\'ve detected that you\'re using a HTTP instead of a HTTPS server.', | ||
'Please beaware that real-time connections have less chance of being blocked', | ||
'by firewalls and anti-virus scanners if they are encrypted (using SSL). If', | ||
'you run your server behind a reverse and HTTPS terminating proxy ignore', | ||
'this message, if not, you\'ve been warned.', | ||
'' | ||
].forEach(function each(line) { | ||
console.log('primus: '+ line); | ||
}); | ||
} | ||
// | ||
// Now that we've got a server, we can setup the Primus and start listening. | ||
@@ -1016,4 +1017,2 @@ // | ||
if (fn) application.on('connection', fn); | ||
server.listen(port); | ||
return application; | ||
@@ -1020,0 +1019,0 @@ }; |
{ | ||
"name": "primus", | ||
"version": "2.3.0", | ||
"version": "2.4.0", | ||
"description": "Primus is a simple abstraction around real-time frameworks. It allows you to easily switch between different frameworks without any code changes.", | ||
"main": "index.js", | ||
"scripts": { | ||
"browserify": "browserify example/primus.js -o example/primus.browserify.js --standalone Primus", | ||
"integration": "NODE_ENV=testing ./node_modules/.bin/mocha $(find test -name '*.integration.js')", | ||
@@ -18,10 +17,31 @@ "test": "NODE_ENV=testing ./node_modules/.bin/mocha $(find test -name '*.test.js')", | ||
"keywords": [ | ||
"abstraction", | ||
"browserchannel", | ||
"engine.io", | ||
"framework", | ||
"comet", | ||
"streaming", | ||
"pubsub", | ||
"pub", | ||
"sub", | ||
"ajax", | ||
"xhr", | ||
"polling", | ||
"http", | ||
"faye", | ||
"io", | ||
"primus", | ||
"prumus", | ||
"real-time", | ||
"realtime", | ||
"socket", | ||
"socket.io", | ||
"sockets", | ||
"sockjs", | ||
"spark", | ||
"transformer", | ||
"transformers", | ||
"websocket", | ||
"ws", | ||
"engine.io", | ||
"socket.io", | ||
"transformer" | ||
"websockets", | ||
"ws" | ||
], | ||
@@ -32,6 +52,7 @@ "author": "Arnout Kazemier", | ||
"access-control": "0.0.x", | ||
"diagnostics": "0.0.2", | ||
"create-server": "0.0.x", | ||
"diagnostics": "0.0.x", | ||
"eventemitter3": "0.1.x", | ||
"forwarded-for": "0.0.x", | ||
"fusing": "0.2.x", | ||
"fusing": "0.3.x", | ||
"load": "1.0.x", | ||
@@ -42,13 +63,14 @@ "setheader": "0.0.x" | ||
"binary-pack": "0.0.x", | ||
"browserchannel": "1.2.x", | ||
"browserchannel": "2.0.x", | ||
"chai": "1.9.x", | ||
"derequire": "0.8.x", | ||
"ejson": "1.0.x", | ||
"engine.io": "1.2.x", | ||
"engine.io-client": "1.2.x", | ||
"engine.io": "1.3.x", | ||
"engine.io-client": "1.3.x", | ||
"faye-websocket": "0.7.x", | ||
"global-wrap": "1.4.x", | ||
"jsonh": "0.0.x", | ||
"mocha": "1.19.x", | ||
"mocha": "1.20.x", | ||
"pre-commit": "0.0.x", | ||
"request": "2.36.x", | ||
"request": "2.37.x", | ||
"socket.io": "0.9.x", | ||
@@ -55,0 +77,0 @@ "socket.io-client": "0.9.x", |
@@ -31,4 +31,2 @@ 'use strict'; | ||
if ('string' !== typeof data) return fn(err, data); | ||
try { data = BinaryPack.unpack(data); } | ||
@@ -47,4 +45,8 @@ catch (e) { err = e; } | ||
' catch (e) {}', | ||
BinaryPack.BrowserSource, | ||
' var exports = {};', | ||
' (function () { ', | ||
BinaryPack.BrowserSource, | ||
' }).call(exports);', | ||
' return exports.BinaryPack;', | ||
'})();' | ||
].join('\n'); |
@@ -356,2 +356,3 @@ /*globals require, define */ | ||
* @param {String} name The module to require. | ||
* @returns {Object|Undefined} The module that we required. | ||
* @api private | ||
@@ -475,3 +476,3 @@ */ | ||
* @type {Boolean} | ||
* @api private | ||
* @private | ||
*/ | ||
@@ -487,3 +488,3 @@ Primus.prototype.AVOID_WEBSOCKETS = false; | ||
* @type {Boolean} | ||
* @api private | ||
* @private | ||
*/ | ||
@@ -517,3 +518,3 @@ Primus.prototype.NETWORK_EVENTS = false; | ||
* @param {String} name The name of the plugin. | ||
* @returns {Mixed} | ||
* @returns {Object|undefined} The plugin or undefined. | ||
* @api public | ||
@@ -539,3 +540,3 @@ */ | ||
* @param {String} evt The event name. | ||
* @returns {Boolean} | ||
* @returns {Boolean} Indication of the event is reserved for internal use. | ||
* @api public | ||
@@ -552,3 +553,3 @@ */ | ||
* @type {Object} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -573,2 +574,3 @@ Primus.prototype.reserved.events = { | ||
* @param {Object} options The original options object. | ||
* @returns {Primus} | ||
* @api private | ||
@@ -630,3 +632,4 @@ */ | ||
primus.on('incoming::error', function error(e) { | ||
var connect = primus.timers.connect; | ||
var connect = primus.timers.connect | ||
, err = e; | ||
@@ -639,5 +642,22 @@ // | ||
if (primus.attempt) return primus.reconnect(); | ||
if (primus.listeners('error').length) primus.emit('error', e); | ||
// | ||
// When the error is not an Error instance we try to normalize it. | ||
// | ||
if ('string' === typeof e) { | ||
err = new Error(e); | ||
} else if (!(e instanceof Error) && 'object' === typeof e) { | ||
// | ||
// BrowserChannel and SockJS returns an object which contains some | ||
// details of the error. In order to have a proper error we "copy" the | ||
// details in an Error instance. | ||
// | ||
err = new Error(e.message || e.reason); | ||
for (var key in e) { | ||
if (e.hasOwnProperty(key)) err[key] = e[key]; | ||
} | ||
} | ||
if (primus.listeners('error').length) primus.emit('error', err); | ||
// | ||
// We received an error while connecting, this most likely the result of an | ||
@@ -880,3 +900,3 @@ // unauthorized access to the server. But this something that is only | ||
// parsed data and the second argument is the raw string that we received. | ||
// This allows you, for exampele, to do some validation on the parsed data | ||
// This allows you, for example, to do some validation on the parsed data | ||
// and then save the raw string in your database without the stringify | ||
@@ -897,2 +917,3 @@ // overhead. | ||
* @param {Function} fn Callback function. | ||
* @returns {Primus} | ||
* @api public | ||
@@ -912,2 +933,3 @@ */ | ||
* | ||
* @returns {Primus} | ||
* @api public | ||
@@ -926,3 +948,4 @@ */ | ||
return this.emit('outgoing::open'); | ||
this.emit('outgoing::open'); | ||
return this; | ||
}; | ||
@@ -934,3 +957,3 @@ | ||
* @param {Mixed} data The data that needs to be written. | ||
* @returns {Boolean} Always returns true. | ||
* @returns {Boolean} Always returns true as we don't support back pressure. | ||
* @api public | ||
@@ -949,3 +972,3 @@ */ | ||
* @param {Mixed} data The message that needs to be written. | ||
* @returns {Boolean} | ||
* @returns {Boolean} Successful write to the underlaying transport. | ||
* @api private | ||
@@ -991,2 +1014,3 @@ */ | ||
* | ||
* @returns {Primus} | ||
* @api private | ||
@@ -1023,4 +1047,6 @@ */ | ||
function ping() { | ||
primus.clearTimeout('ping').write('primus::ping::'+ (+new Date)); | ||
primus.emit('outgoing::ping'); | ||
var value = +new Date(); | ||
primus.clearTimeout('ping').write('primus::ping::'+ value); | ||
primus.emit('outgoing::ping', value); | ||
primus.timers.pong = setTimeout(pong, primus.options.pong); | ||
@@ -1030,2 +1056,3 @@ } | ||
primus.timers.ping = setTimeout(ping, primus.options.ping); | ||
return this; | ||
}; | ||
@@ -1036,2 +1063,3 @@ | ||
* | ||
* @returns {Primus} | ||
* @api private | ||
@@ -1078,2 +1106,3 @@ */ | ||
* @param {String} ..args.. The names of the timeout's we need clear. | ||
* @returns {Primus} | ||
* @api private | ||
@@ -1096,2 +1125,3 @@ */ | ||
* @param {Object} opts Options for configuring the timeout. | ||
* @returns {Primus} | ||
* @api private | ||
@@ -1163,2 +1193,3 @@ */ | ||
* | ||
* @returns {Primus} | ||
* @api private | ||
@@ -1191,3 +1222,3 @@ */ | ||
/** | ||
* Close the connection. | ||
* Close the connection completely. | ||
* | ||
@@ -1272,2 +1303,3 @@ * @param {Mixed} data last packet of data. | ||
* | ||
* @type {Function} | ||
* @param {String} url Connection URL. | ||
@@ -1404,2 +1436,3 @@ * @returns {Object} Parsed connection. | ||
* @param {Function} parser Argument parser. | ||
* @returns {Function} The wrapped function that will emit events when called. | ||
* @api public | ||
@@ -1431,2 +1464,3 @@ */ | ||
* @param {Function} fn A new message transformer. | ||
* @returns {Primus} | ||
* @api public | ||
@@ -1450,2 +1484,3 @@ */ | ||
* @param {Error} err The critical error. | ||
* @returns {Primus} | ||
* @api private | ||
@@ -1452,0 +1487,0 @@ */ |
22
spark.js
@@ -95,3 +95,3 @@ 'use strict'; | ||
Spark.readable('address', { get: function address() { | ||
return forwarded(this.remote, this.headers, this.primus.whitelist); | ||
return this.request.forwarded || forwarded(this.remote, this.headers, this.primus.whitelist); | ||
}}, true); | ||
@@ -215,2 +215,10 @@ | ||
// | ||
// We've received a ping message. | ||
// | ||
spark.on('incoming::ping', function ping(time) { | ||
spark.emit('outgoing::pong', time); | ||
spark._write('primus::pong::'+ time); | ||
}); | ||
// | ||
// The client has disconnected. | ||
@@ -277,3 +285,8 @@ // | ||
process.nextTick(function tick() { | ||
primus.emit('connection', spark); | ||
primus.asyncemit('connection', spark, function damn(err) { | ||
if (!err) return; | ||
spark.emit('error', err); | ||
spark.end(); | ||
}); | ||
}); | ||
@@ -377,3 +390,3 @@ }]); | ||
case 'ping': | ||
this._write('primus::pong::'+ value); | ||
this.emit('incoming::ping', value); | ||
break; | ||
@@ -425,4 +438,3 @@ | ||
Spark.readable('write', function write(data) { | ||
var primus = this.primus | ||
, packet; | ||
var primus = this.primus; | ||
@@ -429,0 +441,0 @@ // |
@@ -21,3 +21,7 @@ { | ||
"client": "sockjs-client-node" | ||
}, | ||
"faye": { | ||
"server": "faye-websocket", | ||
"client": "faye-websocket" | ||
} | ||
} |
@@ -48,3 +48,5 @@ 'use strict'; | ||
socket.onclose = primus.emits('end'); | ||
socket.onmessage = primus.emits('data'); | ||
socket.onmessage = primus.emits('data', function parse(evt) { | ||
return evt.data; | ||
}); | ||
}); | ||
@@ -51,0 +53,0 @@ |
'use strict'; | ||
/*globals faye*/ | ||
/*globals MozWebSocket */ | ||
@@ -16,7 +16,9 @@ /** | ||
// | ||
// Selects an available Socket.io constructor. | ||
// Selects an available WebSocket constructor. | ||
// | ||
var Factory = (function Factory() { | ||
if ('undefined' !== typeof faye && faye.Client) return faye.Client; | ||
try { return require('faye').Client; } | ||
var Factory = (function factory() { | ||
if ('undefined' !== typeof WebSocket) return WebSocket; | ||
if ('undefined' !== typeof MozWebSocket) return MozWebSocket; | ||
try { return Primus.require('faye-websocket').Client; } | ||
catch (e) {} | ||
@@ -27,15 +29,32 @@ | ||
if (!factory) return this.emit('error', new Error('No faye client factory')); | ||
if (!Factory) return primus.critical(new Error('Missing required `faye-websocket` module. Please run `npm install --save faye-websocket`')); | ||
// | ||
// Connect to the given url. | ||
// Connect to the given URL. | ||
// | ||
primus.on('outgoing::open', function open() { | ||
if (socket) socket.disconnect(); | ||
primus.on('outgoing::open', function opening() { | ||
if (socket) socket.close(); | ||
// | ||
// We need to remove the pathname here as socket.io will assume that we want | ||
// to connect to a namespace instead. | ||
// FireFox will throw an error when we try to establish a connection from | ||
// a secure page to an unsecured WebSocket connection. This is inconsistent | ||
// behaviour between different browsers. This should ideally be solved in | ||
// Primus when we connect. | ||
// | ||
socket = new Factory(primus.uri('http', true)); | ||
try { | ||
// | ||
// Only allow primus.transport object in Node.js, it will throw in | ||
// browsers with a TypeError if we supply to much arguments. | ||
// | ||
if (Factory.length === 3) { | ||
primus.socket = socket = new Factory( | ||
primus.uri({ protocol: 'ws', query: true }), // URL | ||
[], // Sub protocols | ||
primus.transport // options. | ||
); | ||
} else { | ||
primus.socket = socket = new Factory(primus.uri({ protocol: 'ws', query: true })); | ||
} | ||
} catch (e) { return primus.emit('error', e); } | ||
@@ -45,5 +64,9 @@ // | ||
// | ||
socket.subscribe(primus.pathname, primus.emits('data')); | ||
socket.bind('transport:up', primus.emits('open')); | ||
socket.bind('transport:down', primus.emits('end')); | ||
socket.binaryType = 'arraybuffer'; | ||
socket.onopen = primus.emits('open'); | ||
socket.onerror = primus.emits('error'); | ||
socket.onclose = primus.emits('end'); | ||
socket.onmessage = primus.emits('data', function parse(evt) { | ||
return evt.data; | ||
}); | ||
}); | ||
@@ -55,24 +78,24 @@ | ||
primus.on('outgoing::data', function write(message) { | ||
if (socket) socket.publish(primus.pathname, message); | ||
if (!socket || socket.readyState !== 1) return; | ||
try { socket.send(message); } | ||
catch (e) { primus.emit('incoming::error', e); } | ||
}); | ||
// | ||
// Attempt to reconnect the socket. It asumes that the `close` event is | ||
// called if it failed to disconnect. Bypass the namespaces and use | ||
// socket.socket. | ||
// Attempt to reconnect the socket. It assumes that the `outgoing::end` event is | ||
// called if it failed to disconnect. | ||
// | ||
primus.on('outgoing::reconnect', function reconnect() { | ||
if (socket) { | ||
socket.disconnect(); | ||
socket.connect(); | ||
} | ||
if (socket) primus.emit('outgoing::end'); | ||
primus.emit('outgoing::open'); | ||
}); | ||
// | ||
// We need to close the socket. Bypass the namespaces and disconnect using | ||
// socket.socket. | ||
// We need to close the socket. | ||
// | ||
primus.on('outgoing::end', function close() { | ||
if (socket) { | ||
socket.disconnect(); | ||
socket.onerror = socket.onopen = socket.onclose = socket.onmessage = null; | ||
socket.close(); | ||
socket = null; | ||
@@ -79,0 +102,0 @@ } |
'use strict'; | ||
var path = require('path') | ||
, directory = path.dirname(require.resolve('faye')) | ||
, library = path.join(directory, 'browser/faye-browser.js'); | ||
// | ||
@@ -14,7 +10,4 @@ // Expose the module as new Transformer instance. | ||
// The client-logic to connect with the a server. | ||
client: require('./client'), | ||
// The client-side library of Faye. | ||
library: require('fs').readFileSync(library, 'utf-8') | ||
// The client-logic to connect with the server. | ||
client: require('./client') | ||
}); |
'use strict'; | ||
var http = require('http') | ||
, parse = require('url').parse; | ||
/** | ||
* Minimum viable WebSocket server for Node.js that works through the primus | ||
* Minimum viable WebSocket server for Node.js that works through the Primus | ||
* interface. | ||
@@ -11,38 +14,51 @@ * | ||
module.exports = function server() { | ||
var faye = require('faye') | ||
, primus = this.primus | ||
var Faye = require('faye-websocket') | ||
, Spark = this.Spark; | ||
this.service = new faye.NodeAdapter({ | ||
mount: primus.pathname | ||
, timeout: 45 | ||
}); | ||
// | ||
// We've received a new connection, create a new Spark. The Spark will | ||
// automatically announce it self as a new connection once it's created (after | ||
// the next tick). | ||
// Listen to upgrade requests. | ||
// | ||
this.service.on('connection', function connection(socket) { | ||
var spark = new Spark( | ||
socket.handshake.headers // HTTP request headers. | ||
, socket.handshake.address // IP address. | ||
, socket.handshake.query // Optional query string. | ||
, socket.id // Unique connection id | ||
); | ||
this.on('upgrade', function upgrade(req, socket, head) { | ||
if (!Faye.isWebSocket(req)) return socket.destroy(); | ||
spark.on('outgoing::end', function end() { | ||
socket.disconnect(); | ||
}).on('outgoing::data', function write(data) { | ||
socket.send(data); | ||
var websocket = new Faye(req, socket, head); | ||
// | ||
// The WebSocket handshake is complete only when the `open` event is fired. | ||
// | ||
websocket.on('open', function open() { | ||
var spark = new Spark( | ||
req.headers // HTTP request headers. | ||
, req // IP address location. | ||
, parse(req.url).query // Optional query string. | ||
, null // We don't have an unique id. | ||
, req // Reference to the HTTP req. | ||
); | ||
spark.on('outgoing::end', function end() { | ||
if (websocket) websocket.close(); | ||
}).on('outgoing::data', function write(data) { | ||
if ('string' === typeof data) return websocket.send(data); | ||
websocket.send(data, { binary: true }); | ||
}); | ||
websocket.on('error', spark.emits('error')); | ||
websocket.on('message', spark.emits('data', function parse(evt) { | ||
return evt.data; | ||
})); | ||
websocket.on('close', spark.emits('end', function close() { | ||
websocket.removeAllListeners(); | ||
websocket = null; | ||
})); | ||
}); | ||
socket.on('disconnect', spark.emits('end')); | ||
socket.on('message', spark.emits('data')); | ||
}); | ||
// | ||
// Listen to upgrade requests. | ||
// Listen to non-upgrade requests. | ||
// | ||
this.service.attach(this); | ||
this.on('request', function request(req, res) { | ||
res.writeHead(426, { 'content-type': 'text/plain' }); | ||
res.end(http.STATUS_CODES[426]); | ||
}); | ||
}; |
@@ -34,3 +34,3 @@ 'use strict'; | ||
// | ||
// Listen to upgrade requests | ||
// Listen to upgrade requests. | ||
// | ||
@@ -63,7 +63,12 @@ this.on('upgrade', function upgrade(req, socket, head) { | ||
}); | ||
}).on('request', function request(req, res) { | ||
res.writeHead(400, {'content-type': 'text/plain'}); | ||
res.end(http.STATUS_CODES[400]); | ||
}); | ||
// | ||
// Listen to non-upgrade requests. | ||
// | ||
this.on('request', function request(req, res) { | ||
res.writeHead(426, { 'content-type': 'text/plain' }); | ||
res.end(http.STATUS_CODES[426]); | ||
}); | ||
this.on('close', function close() { | ||
@@ -70,0 +75,0 @@ service.close(); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
380392
55
9218
2041
12
6
8
18
+ Addedcreate-server@0.0.x
+ Addedcolor@0.7.3(transitive)
+ Addedcolor-convert@0.5.3(transitive)
+ Addedcolor-name@1.0.1(transitive)
+ Addedcolor-string@0.2.4(transitive)
+ Addedconnected@0.0.2(transitive)
+ Addedcreate-server@0.0.7(transitive)
+ Addeddiagnostics@0.0.4(transitive)
+ Addedfusing@0.3.2(transitive)
- Removedcolor@0.6.0(transitive)
- Removedcolor-convert@0.2.1(transitive)
- Removedcolor-string@0.1.3(transitive)
- Removeddiagnostics@0.0.2(transitive)
- Removedfusing@0.2.3(transitive)
- Removedpretty-hrtime@0.2.2(transitive)
Updateddiagnostics@0.0.x
Updatedfusing@0.3.x