Skip to content

Commit aaf56be

Browse files
committed
Updated cors mechanism.
1 parent 389d895 commit aaf56be

5 files changed

Lines changed: 96 additions & 104 deletions

File tree

index.js

Lines changed: 90 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ function Framework() {
428428

429429
this.id = null;
430430
this.version = 1970;
431-
this.version_header = '1.9.7-1';
431+
this.version_header = '1.9.7-2';
432432

433433
var version = process.version.toString().replace('v', '').replace(/\./g, '');
434434
if (version[0] !== '0' || version[1] !== '0')
@@ -491,6 +491,9 @@ function Framework() {
491491
'default-maximum-file-descriptors': 0,
492492
'default-timezone': '',
493493

494+
// Seconds (2 minutes)
495+
'default-cors-maxage': 120,
496+
494497
// in milliseconds
495498
'default-request-timeout': 5000,
496499

@@ -1090,51 +1093,67 @@ Framework.prototype.restful = function(url, flags, onQuery, onGet, onSave, onDel
10901093
* @param {Boolean} credentials
10911094
* @return {Framework}
10921095
*/
1093-
Framework.prototype.cors = function(url, origin, methods, credentials, headers) {
1096+
Framework.prototype.cors = function(url, flags, credentials) {
10941097

10951098
var self = this;
10961099
var route = {};
10971100
var tmp;
10981101

1099-
if (typeof(credentials) === STRING || credentials instanceof Array) {
1100-
tmp = headers;
1101-
headers = credentials;
1102-
credentials = tmp;
1103-
}
1102+
var origins = [];
1103+
var methods = [];
1104+
var headers = [];
1105+
var age;
1106+
1107+
if (flags instanceof Array) {
1108+
for (var i = 0, length = flags.length; i < length; i++) {
1109+
var flag = flags[i];
1110+
var type = typeof(flag);
1111+
1112+
if (type === STRING)
1113+
flag = flag.toLowerCase();
1114+
else if (type === NUMBER) {
1115+
age = flag;
1116+
continue;
1117+
}
11041118

1105-
if (typeof(origin) === STRING)
1106-
origin = origin.split(',').trim();
1107-
if (typeof(methods) === STRING)
1108-
methods = methods.split(',').trim();
1109-
if (typeof(headers) === STRING)
1110-
headers = headers.split(',').trim();
1119+
if (flag === true || flag.startsWith('credential')) {
1120+
credentials = true;
1121+
continue;
1122+
}
1123+
1124+
if (flag.startsWith('http://') || flag.startsWith('https://')) {
1125+
origins.push(flag);
1126+
continue;
1127+
}
11111128

1112-
if (!headers)
1113-
headers = ['*'];
1114-
if (!origin)
1115-
origin = ['*'];
1116-
if (!methods)
1117-
methods = ['*'];
1129+
switch (flag) {
1130+
case 'post':
1131+
case 'put':
1132+
case 'delete':
1133+
case 'options':
1134+
case 'patch':
1135+
case 'head':
1136+
case 'get':
1137+
methods.push(flag.toUpperCase());
1138+
break;
1139+
default:
1140+
headers.push(flag);
1141+
break;
1142+
}
1143+
}
1144+
}
11181145

11191146
route.isASTERIX = url.lastIndexOf('*') !== -1;
11201147

11211148
if (route.isASTERIX)
11221149
url = url.replace('*', '');
11231150

1124-
for (var i = 0, length = origin.length; i < length; i++)
1125-
origin[i] = origin[i].toLowerCase();
1126-
1127-
for (var i = 0, length = headers.length; i < length; i++)
1128-
headers[i] = headers[i].toLowerCase();
1129-
1130-
for (var i = 0, length = methods.length; i < length; i++)
1131-
methods[i] = methods[i].toUpperCase();
1132-
11331151
route.url = framework_internal.routeSplitCreate(framework_internal.encodeUnicodeURL(url.trim()));
1134-
route.origin = origin.indexOf('*') === -1 ? origin : null;
1135-
route.methods = methods.indexOf('*') === -1 ? methods : ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATH', 'HEAD', 'OPTIONS'];
1136-
route.headers = headers.indexOf('*') === -1 ? headers : null;
1152+
route.origins = origins.length ? origins : null;
1153+
route.methods = methods.length ? methods : null;
1154+
route.headers = headers.length ? headers : null;
11371155
route.credentials = credentials;
1156+
route.age = age || framework.config['default-cors-maxage'];
11381157

11391158
self.routes.cors.push(route);
11401159
self._length_cors = self.routes.cors.length;
@@ -6434,125 +6453,97 @@ Framework.prototype._cors = function(req, res, fn, arg) {
64346453

64356454
var self = this;
64366455
var cors;
6437-
var is = false;
6456+
var isAllowed = false;
6457+
var stop = false;
64386458

64396459
for (var i = 0; i < self._length_cors; i++) {
64406460
cors = self.routes.cors[i];
64416461
if (!framework_internal.routeCompare(req.path, cors.url, false, cors.isASTERIX))
64426462
continue;
6443-
is = true;
6463+
isAllowed = true;
64446464
break;
64456465
}
64466466

6447-
if (!is) {
6448-
fn = null;
6449-
self.emit('request-end', req, res);
6450-
self._request_stats(false, false);
6451-
self.stats.request.blocked++;
6452-
res.writeHead(404);
6453-
res.end();
6454-
return;
6455-
}
6467+
if (!isAllowed)
6468+
stop = true;
64566469

6457-
is = false;
6470+
isAllowed = false;
64586471

6459-
// compare
6460-
var isAllowed = false;
64616472
var headers = req.headers;
64626473

6463-
if (cors.headers) {
6464-
6474+
if (!stop && cors.headers) {
6475+
isAllowed = false;
64656476
for (var i = 0, length = cors.headers.length; i < length; i++) {
64666477
if (headers[cors.headers[i]]) {
64676478
isAllowed = true;
64686479
break;
64696480
}
64706481
}
6471-
6472-
if (!isAllowed) {
6473-
fn = null;
6474-
self.emit('request-end', req, res);
6475-
self._request_stats(false, false);
6476-
self.stats.request.blocked++;
6477-
res.writeHead(404);
6478-
res.end();
6479-
return;
6480-
}
6481-
6482-
isAllowed = false;
6482+
if (!isAllowed)
6483+
stop = true;
64836484
}
64846485

6485-
if (cors.methods) {
6486-
6486+
if (!stop && cors.methods) {
6487+
isAllowed = false;
64876488
var current = headers['access-control-request-method'] || req.method;
64886489
if (current !== 'OPTIONS') {
64896490
for (var i = 0, length = cors.methods.length; i < length; i++) {
64906491
if (current.indexOf(cors.methods[i]) !== -1)
64916492
isAllowed = true;
64926493
}
64936494

6494-
if (!isAllowed) {
6495-
fn = null;
6496-
self.emit('request-end', req, res);
6497-
self._request_stats(false, false);
6498-
self.stats.request.blocked++;
6499-
res.writeHead(404);
6500-
res.end();
6501-
return;
6502-
}
6495+
if (!isAllowed)
6496+
stop = true;
65036497
}
6504-
6505-
isAllowed = false;
65066498
}
65076499

65086500
var origin = headers['origin'].toLowerCase();
6509-
6510-
if (cors.origin) {
6511-
for (var i = 0, length = cors.origin.length; i < length; i++) {
6512-
if (cors.origin[i].indexOf(origin) !== -1) {
6501+
if (!stop && cors.origins) {
6502+
isAllowed = false;
6503+
for (var i = 0, length = cors.origins.length; i < length; i++) {
6504+
if (cors.origins[i].indexOf(origin) !== -1) {
65136505
isAllowed = true;
65146506
break;
65156507
}
65166508
}
6517-
6518-
if (!isAllowed) {
6519-
fn = null;
6520-
self.emit('request-end', req, res);
6521-
self._request_stats(false, false);
6522-
self.stats.request.blocked++;
6523-
res.writeHead(404);
6524-
res.end();
6525-
return;
6526-
}
6509+
if (!isAllowed)
6510+
stop = true;
65276511
}
65286512

65296513
var tmp;
65306514
var name;
65316515
var isOPTIONS = req.method === 'OPTIONS';
65326516

6533-
res.setHeader('Access-Control-Allow-Origin', cors.origin ? cors.origin : cors.credentials ? origin : '*');
6517+
res.setHeader('Access-Control-Allow-Origin', cors.origins ? cors.origins : cors.credentials ? isAllowed ? origin : cors.origins ? cors.origins : origin : '*');
65346518

65356519
if (cors.credentials)
65366520
res.setHeader('Access-Control-Allow-Credentials', 'true');
65376521

65386522
name = 'Access-Control-Allow-Methods';
65396523

6540-
if (cors.methods) {
6524+
if (cors.methods)
65416525
res.setHeader(name, cors.methods.join(', '));
6542-
} else if (isOPTIONS) {
6543-
tmp = headers['access-control-request-method'];
6544-
if (tmp)
6545-
res.setHeader(name, tmp);
6546-
}
6526+
else
6527+
res.setHeader(name, '*');
65476528

65486529
name = 'Access-Control-Allow-Headers';
65496530

6550-
if (cors.headers) {
6531+
if (cors.headers)
65516532
res.setHeader(name, cors.headers.join(', '));
6552-
} else if (isOPTIONS) {
6553-
tmp = headers['access-control-request-headers'];
6554-
if (tmp)
6555-
res.setHeader(name, tmp);
6533+
else
6534+
res.setHeader(name, '*');
6535+
6536+
if (cors.age)
6537+
res.setHeader('Access-Control-Max-Age', cors.age);
6538+
6539+
if (stop) {
6540+
fn = null;
6541+
self.emit('request-end', req, res);
6542+
self._request_stats(false, false);
6543+
self.stats.request.blocked++;
6544+
res.writeHead(404);
6545+
res.end();
6546+
return;
65566547
}
65576548

65586549
if (!isOPTIONS)
@@ -8065,6 +8056,7 @@ Framework.prototype._configure = function(arr, rewrite) {
80658056
var value = str.substring(index + 1).trim();
80668057

80678058
switch (name) {
8059+
case 'default-cors-maxage':
80688060
case 'default-request-length':
80698061
case 'default-websocket-request-length':
80708062
case 'default-request-timeout':

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"name": "Сковорода Никита Андреевич",
6464
"email": "chalkerx@gmail.com"
6565
}],
66-
"version": "1.9.7-1",
66+
"version": "1.9.7-2",
6767
"homepage": "http://www.totaljs.com",
6868
"bugs": {
6969
"url": "https://github.com/totaljs/framework/issues",

test/controllers/default.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,10 @@ exports.install = function() {
142142
// maximumSize
143143
framework.websocket('/', socket);
144144
framework.route('/theme-green/', view_theme);
145-
framework.cors('/api/*', '*');
146-
framework.cors('/cors/origin-all/', '*');
145+
framework.cors('/api/*');
146+
framework.cors('/cors/origin-all/');
147147
framework.cors('/cors/origin-not/', ['http://www.petersirka.eu', 'http://www.858project.com']);
148-
framework.cors('/cors/headers/', '*', 'post,put,delete,options', true);
148+
framework.cors('/cors/headers/', ['post', 'put', 'delete', 'options'], true);
149149
};
150150

151151
function plain_options() {

test/test-framework-debug.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ var framework = require('../index');
44
var fs = require('fs');
55
var url = 'http://127.0.0.1:8001/';
66
var errorStatus = 0;
7-
var max = 1;
7+
var max = 100;
88

99
// INSTALL('module', 'https://www.totaljs.com/framework/include.js', { test: true });
1010

test/test-framework-release.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ var framework = require('../index');
44
var fs = require('fs');
55
var url = 'http://127.0.0.1:8001/';
66
var errorStatus = 0;
7-
var max = 1;
7+
var max = 100;
88

99
// INSTALL('module', 'https://www.totaljs.com/framework/include.js', { test: true });
1010

0 commit comments

Comments
 (0)