New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

primus

Package Overview
Dependencies
Maintainers
5
Versions
109
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

primus - npm Package Compare versions

Comparing version 2.3.0 to 2.4.0

middleware/forwarded.js

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 @@ */

@@ -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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc