Skip to content

Commit

Permalink
Merge branch 'development' of github.com:balderdashy/sails into devel…
Browse files Browse the repository at this point in the history
…opment
  • Loading branch information
mikermcneil committed Aug 10, 2013
2 parents 4eb42d3 + a0a54a1 commit f06ab4f
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 23 deletions.
4 changes: 4 additions & 0 deletions bin/sails.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ sails.config = {
if(argv.verbose){
sails.config.log = {level: 'verbose'};
}
if(argv.port){
sails.config.port = argv.port;
}

require('../lib/configuration')(sails).load(function (err) {
if (err) throw new Error(err);

Expand Down
2 changes: 1 addition & 1 deletion lib/app/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module.exports = function (sails) {
configOverride = configOverride || {};
// Environment variables should override other config
configOverride.environment = process.env.NODE_ENV;
configOverride.port = process.env.PORT;
configOverride.port = process.env.PORT || configOverride.port;
sails.config = util.clone(configOverride);

async.auto({
Expand Down
9 changes: 9 additions & 0 deletions lib/configuration/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ module.exports = function (sails) {
pubsub : require('../hooks/pubsub'),
policies : require('../hooks/policies'),
csrf : require('../hooks/csrf'),
cors : require('../hooks/cors'), // IMPORTANT -- must be AFTER csrf!
i18n : require('../hooks/i18n'),
http : require('../hooks/http')
},
Expand Down Expand Up @@ -124,6 +125,14 @@ module.exports = function (sails) {
// _csrf is a parameter for views, and is also available via GET at /csrfToken
csrf: false,

// CORS header settings -- setting origin to '' means CORS is off by default
cors: {
origin: '',
credentials: true,
methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
headers: 'content-type'
},

uploadLimitDefault: '10mb',

// Port to run this app on
Expand Down
31 changes: 10 additions & 21 deletions lib/express/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,26 +122,23 @@ module.exports = function (sails) {

// Pass csrf token to templates via locals
app.use(function(req, res, next){
if (res.locals._csrf === 'undefined') {
if (res.locals._csrf === 'undefined') {
res.locals._csrf = req.session._csrf;
}
next();
});
}

var limitDefault = sails.config.uploadLimitDefault;
var needToCheckRoutes = false;
var needToCheckRoutes = false;

// pre-calculare regexp for paths
for (var key in sails.config.routes) {
var match = expressUtils.pathRegexp(key.split(' ').reverse()[0], []);
sails.config.routes[key].pathRegexp = match;
if (sails.config.routes[key].cors && typeof sails.config.routes[key].cors === 'boolean') {
sails.config.routes[key].cors = '*';
}

// Optimization: don't check routes if we don't need to
if(sails.config.routes[key].cors || sails.config.routes[key].uploadLimit || sails.config.routes[key].streamFiles) {
if(sails.config.routes[key].limit || sails.config.routes[key].streamFiles) {
needToCheckRoutes = true;
}
}
Expand All @@ -158,20 +155,12 @@ module.exports = function (sails) {
(key.split(' ').length > 1 ? req.method.toLowerCase() === key.split(' ')[0].toLowerCase() : true)) {
if (typeof route === 'object'){

// Apply cors config
if(route.cors) {
res.setHeader('Access-Control-Allow-Origin', route.cors);

// Remove CSRF token if it exists
res.locals._csrf = null;
}

if(route.streamFiles) {
var type = req.headers['content-type'];
if (type && type.toLowerCase().indexOf('multipart/form-data') !== -1) {
if (type && type.toLowerCase().indexOf('multipart/form-data') !== -1) {
sails.log.verbose('Streaming files, disabling body parer for this request');
req.bodyParserDisabled = true;
}
}
}

// Apply uploadLimit config
Expand All @@ -194,12 +183,12 @@ module.exports = function (sails) {
app.use(function(req, res, next) {

// Body parser can be disabled per-request for streaming file uploads
if(req.bodyParserDisabled) {
return next();
}
if(req.bodyParserDisabled) {
return next();
}

return bodyParser(req, res, next);
})
return bodyParser(req, res, next);
});

app.use(function handleBodyParserError (err, req, res, next) {

Expand Down
127 changes: 127 additions & 0 deletions lib/hooks/cors/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
module.exports = function(sails) {

/**
* Module dependencies.
*/

var _ = require('lodash'),
expresstUtils = require('../../../node_modules/express/lib/utils.js');
Hook = require('../../index');


/**
* Expose hook definition
*/

return {

initialize: function(cb) {

// If origin is set to '', CORS is off, since it wouldn't allow connections from anywhere.
if (sails.config.cors.origin === '') {
return cb();
}

sails.on('router:before', function () {

// Make sure there's a universal OPTIONS route that just send back a 200
sails.router.bind('options /*', sendHeaders(null, true));

// If we're setting CORS on all routes by default, set up a universal route for it here.
// CORS can still be turned off for specific routes by setting "cors:false"
if (sails.config.cors.allRoutes === true) {
sails.router.bind('/*', sendHeaders());
}

// Loop through all configured routes, looking for CORS options
_.each(sails.config.routes, function(config, path) {

if (!_.isUndefined(config.cors)) {

// If cors is set to "false", clear the CORS headers for this route
if (config.cors === false) {
sails.router.bind(path, clearHeaders);
return;
}

// If cors is set to "true", and we're not doing all routes by default, set
// the CORS headers for this route using the default origin
else if (config.cors === true && !sails.config.cors.allRoutes) {
sails.router.bind(path, setHeaders());
}

// Else if cors is set to a string, use that has the origin
else if (typeof config.cors === "string") {
sails.router.bind(path, setHeaders({origin:config.cors}));
}

// Else if cors is an object, use that as the config
else if (_.isPlainObject(config.cors)) {
sails.router.bind(path, setHeaders(config.cors));
}

// Otherwise throw a warning
else {
sails.log.warn("Invalid CORS settings for route "+path);
}

}

});

});

cb();

}

};

function sendHeaders(routeCorsConfig, respond) {

if (!routeCorsConfig) {
routeCorsConfig = {};
}

return function(req, res, next) {

// If we can set headers (i.e. it's not a socket request), do so.
if (res.setHeader) {
res.setHeader('Access-Control-Allow-Origin', routeCorsConfig.origin || sails.config.cors.origin);
res.setHeader('Access-Control-Allow-Credentials', routeCorsConfig.credentials || sails.config.cors.credentials);
res.setHeader('Access-Control-Allow-Methods', routeCorsConfig.methods || sails.config.cors.methods);
res.setHeader('Access-Control-Allow-Headers', routeCorsConfig.headers || sails.config.cors.headers);
res.locals._csrf = null;
}

if (respond) {
res.send(200);
} else {
next();
}

};

}

function clearHeaders(req, res, next) {

// Replace the CSRF token if required
if (sails.config.csrf) {
res.locals._csrf = req.session._csrf;
}

// If we can set headers (i.e. it's not a socket request), do so.
if (res.setHeader) {
res.setHeader('Access-Control-Allow-Origin', '');
res.setHeader('Access-Control-Allow-Credentials', '');
res.setHeader('Access-Control-Allow-Methods', '');
res.setHeader('Access-Control-Allow-Headers', '');
}

next();

}


};
4 changes: 3 additions & 1 deletion lib/hooks/pubsub/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ module.exports = function(sails) {
socket.join( my.room(id) );
});

this.subscribe(socket, id);
if (socket) {
this.subscribe(socket, id);
}
},


Expand Down

0 comments on commit f06ab4f

Please sign in to comment.