@@ -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' :
0 commit comments