Comparing version 2.1.4 to 2.1.5
146
index.js
@@ -238,2 +238,3 @@ 'use strict'; | ||
this.before('spec', require('./middleware/spec')); | ||
this.before('no-cache', require('./middleware/no-cache')); | ||
this.before('authorization', require('./middleware/authorization')); | ||
@@ -705,7 +706,6 @@ | ||
options = options || {}; | ||
var primus = this | ||
, clean = false; | ||
var primus = this; | ||
/** | ||
* Clean up connections that are left open. | ||
* Clean up some stuff. | ||
* | ||
@@ -715,5 +715,10 @@ * @api private | ||
function cleanup() { | ||
if (clean) return; | ||
clean = true; | ||
// | ||
// Optionally close the server. | ||
// | ||
if (options.close !== false && primus.server) primus.server.close(); | ||
// | ||
// Optionally close connections that are left open. | ||
// | ||
if (options.end !== false) { | ||
@@ -730,14 +735,8 @@ primus.forEach(function shutdown(spark) { | ||
primus.emit('close', options); | ||
primus.transformer.emit('close', options); | ||
if (fn && options.close === false) fn(); | ||
} | ||
if (primus.transformer) { | ||
primus.transformer.emit('close', options); | ||
primus.transformer.removeAllListeners(); | ||
} | ||
/** | ||
* Clean up the server after it has been closed. | ||
* | ||
* @api private | ||
*/ | ||
function closed() { | ||
if (primus.transformer) primus.transformer.removeAllListeners(); | ||
if (primus.server) primus.server.removeAllListeners(); | ||
@@ -747,11 +746,4 @@ primus.removeAllListeners(); | ||
// | ||
// The server has closed, but we didn't run any cleanups. Run them now | ||
// before we kill the `primus.connections` object which will render the | ||
// clean up process useless as there wouldn't be anything to iterate over. | ||
// Null some potentially heavy objects to free some more memory instantly. | ||
// | ||
if (!clean) cleanup(); | ||
// | ||
// Null some potentially heavy objects to free some more memory instantly | ||
// | ||
primus.transformers.outgoing.length = primus.transformers.incoming.length = 0; | ||
@@ -767,13 +759,7 @@ primus.transformer = primus.encoder = primus.decoder = primus.server = null; | ||
if (options.close !== false) { | ||
if (primus.server) primus.server.close(closed); | ||
else setTimeout(closed, 0); | ||
} | ||
// | ||
// Force a `0` as timeout to maintain a full async callback. | ||
// | ||
setTimeout(cleanup, +options.timeout || 0); | ||
if (+options.timeout) { | ||
setTimeout(cleanup, +options.timeout); | ||
} else { | ||
cleanup(); | ||
} | ||
return this; | ||
@@ -833,2 +819,96 @@ }); | ||
/** | ||
* Create a new Primus server. | ||
* | ||
* @param {Function} fn Request listener. | ||
* @param {Object} options Configuration. | ||
* @returns {Pipe} | ||
* @api public | ||
*/ | ||
Primus.createServer = function createServer(fn, options) { | ||
if ('object' === typeof fn) { | ||
options = fn; | ||
fn = null; | ||
} | ||
options = options || {}; | ||
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 real-time connections have less chance of being blocked by firewalls', | ||
'and anti-virus scanners if they are encrypted. 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. | ||
// | ||
var application = new Primus(server, options); | ||
if (fn) application.on('connection', fn); | ||
server.listen(port); | ||
return application; | ||
}; | ||
// | ||
@@ -835,0 +915,0 @@ // Expose the constructors of our Spark and Transformer so it can be extended by |
@@ -38,3 +38,3 @@ 'use strict'; | ||
return false; | ||
return true; | ||
} | ||
@@ -41,0 +41,0 @@ |
@@ -27,3 +27,3 @@ 'use strict'; | ||
return false; | ||
return true; | ||
} | ||
@@ -30,0 +30,0 @@ |
{ | ||
"name": "primus", | ||
"version": "2.1.4", | ||
"version": "2.1.5", | ||
"description": "Primus is a simple abstraction around real-time frameworks. It allows you to easily switch between different frameworks without any code changes.", | ||
@@ -29,7 +29,8 @@ "main": "index.js", | ||
"dependencies": { | ||
"load": "1.0.x", | ||
"fusing": "0.1.x", | ||
"access-control": "0.0.x", | ||
"eventemitter3": "0.1.x", | ||
"forwarded-for": "0.0.x", | ||
"access-control": "0.0.x" | ||
"fusing": "0.1.x", | ||
"load": "1.0.x", | ||
"setheader": "0.0.x" | ||
}, | ||
@@ -51,5 +52,5 @@ "devDependencies": { | ||
"sockjs": "0.3.x", | ||
"sockjs-client-node": "0.0.x", | ||
"sockjs-client-node": "0.1.x", | ||
"ws": "0.4.x" | ||
} | ||
} |
@@ -44,20 +44,22 @@ /*globals require, define */ | ||
if (1 === length) { | ||
if (fn.__EE3_once) this.removeListener(event, fn); | ||
switch (len) { | ||
case 1: | ||
fn.call(fn.context || this); | ||
fn.call(fn.__EE3_context || this); | ||
break; | ||
case 2: | ||
fn.call(fn.context || this, a1); | ||
fn.call(fn.__EE3_context || this, a1); | ||
break; | ||
case 3: | ||
fn.call(fn.context || this, a1, a2); | ||
fn.call(fn.__EE3_context || this, a1, a2); | ||
break; | ||
case 4: | ||
fn.call(fn.context || this, a1, a2, a3); | ||
fn.call(fn.__EE3_context || this, a1, a2, a3); | ||
break; | ||
case 5: | ||
fn.call(fn.context || this, a1, a2, a3, a4); | ||
fn.call(fn.__EE3_context || this, a1, a2, a3, a4); | ||
break; | ||
case 6: | ||
fn.call(fn.context || this, a1, a2, a3, a4, a5); | ||
fn.call(fn.__EE3_context || this, a1, a2, a3, a4, a5); | ||
break; | ||
@@ -70,6 +72,4 @@ | ||
fn.apply(fn.context || this, args); | ||
fn.apply(fn.__EE3_context || this, args); | ||
} | ||
if (fn.once) this.removeListener(event, fn); | ||
} else { | ||
@@ -81,4 +81,4 @@ for (i = 1, args = new Array(len -1); i < len; i++) { | ||
for (i = 0; i < length; fn = listeners[++i]) { | ||
fn.apply(fn.context || this, args); | ||
if (fn.once) this.removeListener(event, fn); | ||
if (fn.__EE3_once) this.removeListener(event, fn); | ||
fn.apply(fn.__EE3_context || this, args); | ||
} | ||
@@ -102,3 +102,3 @@ } | ||
fn.context = context; | ||
fn.__EE3_context = context; | ||
this._events[event].push(fn); | ||
@@ -118,3 +118,3 @@ | ||
EventEmitter.prototype.once = function once(event, fn, context) { | ||
fn.once = true; | ||
fn.__EE3_once = true; | ||
return this.on(event, fn, context); | ||
@@ -137,3 +137,3 @@ }; | ||
for (var i = 0, length = listeners.length; i < length; i++) { | ||
if (fn && listeners[i] !== fn && listeners[i].fn !== fn) { | ||
if (fn && listeners[i] !== fn) { | ||
events.push(listeners[i]); | ||
@@ -593,2 +593,4 @@ } | ||
primus.latency = +new Date() - start; | ||
primus.emit('open'); | ||
@@ -604,4 +606,2 @@ primus.clearTimeout('ping', 'pong').heartbeat(); | ||
} | ||
primus.latency = +new Date() - start; | ||
}); | ||
@@ -1201,21 +1201,36 @@ | ||
/** | ||
* Transform a query string object back in to string equiv. | ||
* | ||
* @param {Object} obj The query string object. | ||
* @returns {String} | ||
* @api private | ||
*/ | ||
Primus.prototype.querystringify = function querystringify(obj) { | ||
var pairs = []; | ||
for (var key in obj) { | ||
if (obj.hasOwnProperty(key)) { | ||
pairs.push(key +'='+ obj[key]); | ||
} | ||
} | ||
return pairs.join('&'); | ||
}; | ||
/** | ||
* Generates a connection URI. | ||
* | ||
* @param {String} protocol The protocol that should used to crate the URI. | ||
* @param {Boolean} querystring Do we need to include a query string. | ||
* @returns {String|options} The URL. | ||
* @api private | ||
*/ | ||
Primus.prototype.uri = function uri(options, querystring) { | ||
Primus.prototype.uri = function uri(options) { | ||
var url = this.url | ||
, server = []; | ||
, server = [] | ||
, qsa = false; | ||
// | ||
// Backwards compatible with Primus 1.4.0 | ||
// @TODO Remove me for Primus 2.0 | ||
// Query strings are only allowed when we've received clearance for it. | ||
// | ||
if ('string' === typeof options) { | ||
options = { protocol: options }; | ||
if (querystring) options.query = querystring; | ||
} | ||
if (options.query) qsa = true; | ||
@@ -1225,3 +1240,3 @@ options = options || {}; | ||
options.query = url.search && 'query' in options ? (url.search.charAt(0) === '?' ? url.search.slice(1) : url.search) : false; | ||
options.secure = 'secure' in options ? options.secure : url.protocol === 'https:'; | ||
options.secure = 'secure' in options ? options.secure : (url.protocol === 'https:' || url.protocol === 'wss:'); | ||
options.auth = 'auth' in options ? options.auth : url.auth; | ||
@@ -1238,2 +1253,19 @@ options.pathname = 'pathname' in options ? options.pathname : this.pathname.slice(1); | ||
// | ||
// `url.host` might be undefined (e.g. when using zombie) so we use the | ||
// hostname and port defined above. | ||
// | ||
var host = (443 != options.port && 80 != options.port) | ||
? options.host +':'+ options.port | ||
: options.host; | ||
// | ||
// We need to make sure that we create a unique connection URL every time to | ||
// prevent bfcache back forward cache of becoming an issue. We're doing this | ||
// by forcing an cache busting query string in to the URL. | ||
// | ||
var querystring = this.querystring(options.query || ''); | ||
querystring._primuscb = +new Date(); | ||
options.query = this.querystringify(querystring); | ||
// | ||
// Automatically suffix the protocol so we can supply `ws` and `http` and it gets | ||
@@ -1244,4 +1276,4 @@ // transformed correctly. | ||
if (options.auth) server.push(options.auth +'@'+ url.host); | ||
else server.push(url.host); | ||
if (options.auth) server.push(options.auth +'@'+ host); | ||
else server.push(host); | ||
@@ -1258,3 +1290,4 @@ // | ||
// | ||
if (options.query) server.push('?'+ options.query); | ||
if (qsa) server.push('?'+ options.query); | ||
else delete options.query; | ||
@@ -1261,0 +1294,0 @@ if (options.object) return options; |
@@ -97,4 +97,5 @@ 'use strict'; | ||
Transformer.readable('forEach', function forEach(type, req, res, next) { | ||
var layers = this.primus.layers | ||
, primus = this.primus; | ||
var transformer = this | ||
, layers = transformer.primus.layers | ||
, primus = transformer.primus; | ||
@@ -111,3 +112,3 @@ req.uri = req.uri || url(req.url, true); | ||
next(); | ||
return this; | ||
return transformer; | ||
} | ||
@@ -125,3 +126,14 @@ | ||
if (layer.length === 2) { | ||
if (layer.fn.call(primus, req, res) === false) return; | ||
var answered = layer.fn.call(primus, req, res); | ||
// | ||
// @TODO remove the warning and the unneeded code. | ||
// | ||
if (answered === false) { | ||
answered = true; | ||
if (!layer.warned) transformer.deprecate(layer); | ||
} | ||
if (answered) return; | ||
return iterate(index); | ||
@@ -137,6 +149,29 @@ } | ||
return this; | ||
return transformer; | ||
}); | ||
/** | ||
* Issue a deprecation warning. | ||
* | ||
* @param {String} data The object we're trying to deprecate. | ||
* @api private | ||
*/ | ||
Transformer.readable('deprecate', function deprecate(data) { | ||
var name = data.name; | ||
[ | ||
'', | ||
'We\'ve detected that your middleware layer ('+ name +') is returning `false`', | ||
'which will be deprecated in future releases. If this middleware has already', | ||
'answered the request it should return `true`.', | ||
'' | ||
].forEach(function each(line) { | ||
console.error('primus: '+ line); | ||
}); | ||
data.warned = true; | ||
return data; | ||
}); | ||
/** | ||
* Start listening for incoming requests and check if we need to forward them to | ||
@@ -143,0 +178,0 @@ * the transformers. |
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
354203
51
8929
1813
6
14
8
+ Addedsetheader@0.0.x