Browse Source

some fix && feature

HonorLee 5 years ago
parent
commit
2f1906bc1f
7 changed files with 197 additions and 58 deletions
  1. 17 0
      rule.js
  2. 9 4
      system/core.js
  3. 5 5
      system/lib/core/handler.js
  4. 6 6
      system/lib/core/module.js
  5. 57 21
      system/lib/core/router.js
  6. 102 21
      system/lib/core/session.js
  7. 1 1
      system/lib/core/static.js

+ 17 - 0
rule.js

@@ -0,0 +1,17 @@
+/*
+ * @Author: HonorLee
+ * @Version 1.0
+ * @LastUpdate 2018/6/20
+ * @License MIT
+*/
+
+module.exports = {
+    '/':{
+        permission:[],
+        onerror:'R:/'
+    },
+    '/index':{
+        permission:[],
+        onerror:'A:Unauthorized'
+    },
+}

+ 9 - 4
system/core.js

@@ -24,7 +24,7 @@ global.Core.Path = {
     Upload      : ROOTPATH + '/' + Config.Asset.upload_path
 };
 
-//Global Extension Require 
+//Global Extension Require
 global.serverUID    = (Math.ceil(Math.random()*61439+4096)).toString(16).toUpperCase();
 global.Moment       = require('moment-range').extendMoment(require('moment'));
 global.URL          = require('url');
@@ -50,7 +50,7 @@ CoreLibFiles.forEach(function(filename){
     let coreClass;
     try {
         coreClass = require(Core.Path.CoreLib + '/' + filename);
-        
+
     }catch(e){
         console.log('[Core] Core library file ['+filename+'] load error!');
         console.log(e);
@@ -89,7 +89,7 @@ if(Config && Config.Database.Mysql.on){
             });
         }
     });
-    
+
 }
 
 //If Mongodb on,load Mongodb Extension
@@ -152,4 +152,9 @@ for(let i in HandlerFiles){
     let path = HandlerFiles[i]['path'];
     CACHE.Handlers.push(path.replace(Core.Path.Handler,''));
 }
-CACHE.HandlersString = CACHE.Handlers.join('|');
+CACHE.HandlersString = CACHE.Handlers.join('|');
+
+global.RouterRule = null;
+try{
+    global.RouterRule = require(ROOTPATH+'/rule.js');
+}catch(e){}

+ 5 - 5
system/lib/core/handler.js

@@ -34,7 +34,7 @@ module.exports = function(req,res){
                 mimeType = arguments[2];
                 break;
         }
-        if(status) this.Response.status(status);
+        if(status) this.Response.statusCode = status;
         if(mimeType) this.Response.setHeader('Content-Type', `${mimeType}; charset=UTF-8`);
         this.Response.write(endContent);
         this.Response.end();
@@ -63,7 +63,7 @@ module.exports = function(req,res){
      * [responseAPI description]
      * @param  {[type]} statusCode [description]
      * @param  {[type]} somthing   [description]
-     */ 
+     */
     this.endAPI = this.responseAPI = function(statusCode,somthing){
         let endContent = {statusCode:statusCode,data:null};
         if(typeof somthing == 'string' || typeof somthing == 'number' || typeof somthing == 'object'){
@@ -93,9 +93,9 @@ module.exports = function(req,res){
         let cookie,originCookie;
         if(this.Response.hasHeader('Set-Cookie')){
             originCookie = this.Response.getHeader('Set-Cookie');
-        }else{
-            originCookie = [];
         }
+        if(!originCookie) originCookie = [];
+        if(typeof originCookie == 'string') originCookie = [originCookie];
         cookie = `${key}=${value}`;
         if(path) cookie += ';path=' + path;
         if(expire){
@@ -116,4 +116,4 @@ module.exports = function(req,res){
         if(!originCookieValue) return false;
         this.setCookie(key,originCookieValue,expire,path);
     }
-}
+}

+ 6 - 6
system/lib/core/module.js

@@ -1,11 +1,11 @@
-/**
- * @Author  HonorLee (dev@honorlee.me)
- * @Version 1.0 (2018-05-27)
+/*
+ * @Author: HonorLee
+ * @Version 1.0
+ * @LastUpdate 2018/6/21
  * @License MIT
- */
+*/
 'use strict'
 global.M = function(moduleName){
-    console.log(this)
     if(!moduleName){
         LOGGER.error('Module name is empty!');
         return null;
@@ -20,4 +20,4 @@ global.M = function(moduleName){
         return null;
     }
     return Module;
-};
+};

+ 57 - 21
system/lib/core/router.js

@@ -1,8 +1,9 @@
-/**
- * @Author  HonorLee (dev@honorlee.me)
- * @Version 1.0 (2018-05-04)
+/*
+ * @Author: HonorLee
+ * @Version 1.0
+ * @LastUpdate 2018/6/19
  * @License MIT
- */
+*/
 'use strict'
 CACHE.router = {};
 
@@ -34,40 +35,75 @@ var Router ={
         methodMark[handlerFile] = 'index';
         //
         if(path!='/index'){
-            method = pathArr.pop();
-            handlerFile = pathArr.join('/') + '/index.js';
-            expArr.push(handlerFile);
-            methodMark[handlerFile] = method;
-            //
-            handlerFile = pathArr.join('/') + '.js';
-            expArr.push(handlerFile);
-            methodMark[handlerFile] = method;
+            if(pathArr.length==2){
+                method = pathArr[1];
+                handlerFile = '/index.js';
+                expArr.push(handlerFile);
+                methodMark[handlerFile] = method;
+            }else{
+                method = pathArr.pop();
+                handlerFile = pathArr.join('/') + '/index.js';
+                expArr.push(handlerFile);
+                methodMark[handlerFile] = method;
+                //
+                handlerFile = pathArr.join('/') + '.js';
+                expArr.push(handlerFile);
+                methodMark[handlerFile] = method;
+            }
         }
-        
+
         match = new RegExp(expArr.join('|')).exec(CACHE.HandlersString);
         if(!match) return Router._error('No such handler ['+handlerFile+']',res);
 
         method = methodMark[match];
         handlerFile = Core.Path.Handler + match;
-
+        if(method=='') method = 'index';
         if(method=='__construct') return Router._error('__construct can\'t be called outside in ['+handlerFile+']',res);
-        
         let handler;
         try {
             handler = require(handlerFile);
         }catch(e){
-            Router._error(e.stack,res);
+            LOGGER.debug(e.stack,res);
         }
         if(typeof handler === 'function') handler = new handler();
         let baseClass = new HANDLER(req,res);
         let newHandlerClass = Object.assign(baseClass,handler);
 
         if(!CACHE.router[handlerFile]){ CACHE.router[handlerFile] = true;}
-
-        if(newHandlerClass.hasOwnProperty(method) && typeof newHandlerClass[method]==='function'){
+        if(newHandlerClass.COOKIE && newHandlerClass.COOKIE['session']){
+            new SESSION.instance(newHandlerClass.COOKIE['session'],function(sessionid,session){
+                newHandlerClass.session = session;
+                Router.runHandler(path,handlerFile,newHandlerClass,method,res);
+            });
+        }else{
+            new SESSION.instance(null,function(sessionid,session){
+                newHandlerClass.session = session;
+                newHandlerClass.setCookie('session',sessionid,'forever','/');
+                Router.runHandler(path,handlerFile,newHandlerClass,method,res);
+            });
+        }
+    },
+    runHandler:function(path,handlerFile,handler,method,res){
+        if(RouterRule && RouterRule[path] && RouterRule[path]['permission'].length){
+            let status = handler.session.get('status');
+            if(!new RegExp(status).exec(RouterRule[path]['permission'])){
+                let control = (RouterRule[path]['onerror']).split(':');
+                let way = control[0];
+                let output = control[1];
+                if(way=='R'){
+                    if(!output) output = '/';
+                    return handler.endRedirect(output);
+                }
+                if(way=='A'){
+                    if(!output) output = 'Unauthorized';
+                    return handler.endAPI(-1,output);
+                }
+            }
+        }
+        if(handler.hasOwnProperty(method) && typeof handler[method]==='function'){
             let noBypass = true;
-            if(newHandlerClass.hasOwnProperty('__construct') && typeof newHandlerClass['__construct']==='function') noBypass = newHandlerClass['__construct']();
-            if(noBypass || noBypass===undefined) newHandlerClass[method]();
+            if(handler.hasOwnProperty('__construct') && typeof handler['__construct']==='function') noBypass = handler['__construct']();
+            if(noBypass || noBypass===undefined) handler[method]();
         }else{
             Router._error('Handler ['+handlerFile+'] no such method "'+method+'"',res);
         }
@@ -84,7 +120,7 @@ module.exports = function(req,res){
     let URLParse  = URL.parse(URI,true);
     let URLArr    = URLParse.pathname.split('/');
     let enterURI  = String(URLArr[1])==''?'index':String(URLArr[1]);
-    let isAsset   = enterURI == Config.Asset.asset_path;
+    let isAsset   = (enterURI == Config.Asset.asset_path || URI=='/favicon.ico');
 
     req._GET = URLParse.query;
     if(isAsset){

+ 102 - 21
system/lib/core/session.js

@@ -1,8 +1,9 @@
-/**
- * @Author  HonorLee (dev@honorlee.me)
- * @Version 1.0 (2018-05-04)
+/*
+ * @Author: HonorLee
+ * @Version 1.0
+ * @LastUpdate 2018/6/19
  * @License MIT
- */
+*/
 'use strict'
 var Session = {
     set:function(key,value,callback){
@@ -10,18 +11,41 @@ var Session = {
         if(!key || value==null) return callback.call(this,'Session key or value is empty',null);
         let _this = this;
         let session = {};
-        
+
         session.id = MD5(new Date().getTime()+''+Math.floor(Math.random()*9000+1000));
         session.data = {};
         session.data[key] = value;
         session.expire = Config.SessionExpire*60;
         session.expireTime = new Date().getTime()+session.expire*1000;
+        session.autoRenewExpire = Config.SessionExpire*60;
 
         Manager.set(session,function(err){
             if(err) return callback.call(_this,'Session set err;',null);
             callback.call(_this,null,session);
         });
     },
+    setExpireTime:function(sessionid,expire,autoRenewExpire,callback){
+        let _this = this;
+        callback = Manager.buildCallback(callback);
+        if(!sessionid) return callback.call(this,'Session id is empty',null);
+        if(!expire) return callback.call(this,'Session expire must bigger than 0',null);
+        Session.get(sessionid,function(err,data){
+            if(err || !data) return callback.call(this,'Session is gone',null);
+            let session = data;
+            session.expire = expire*60;
+            autoRenewExpire = autoRenewExpire*1;
+            if(autoRenewExpire>0) session.autoRenewExpire = autoRenewExpire*60;
+            Manager.set(session,function(err){
+                if(err){
+                    LOGGER.error(err);
+                    callback.call(_this,'Session set expire error',null);
+                }else{
+                    callback.call(_this,null,session);
+                }
+            })
+        });
+
+    },
     update:function(sessionid,key,value,callback){
         callback = Manager.buildCallback(callback);
         if(!sessionid || !key || value==null) return callback.call(this,'Session id,key or value is empty',null);
@@ -35,7 +59,7 @@ var Session = {
             }
 
             if(err || result == null || Config.Session.AutoRefresh){
-                session.expire = Config.SessionExpire*60;
+                session.expire = session.autoRenewExpire;
                 session.expireTime = new Date().getTime()+session.expire*1000;
             }
 
@@ -66,47 +90,64 @@ var Session = {
     clear:function(sessionid){
         if(!sessionid) return;
         Manager.clear(sessionid);
+    },
+    instance:function(sessionID,callback){
+        return new Instance(sessionID,callback);
     }
 };
 module.exports = Session;
 
 var Manager = {
     get:function(sessionid,callback){
-        if(Config.Database.Memcache.on && Memcache){
+        let session;
+        if(Config.Session.StoreType.toLowerCase()=='memcache' && Config.Database.Memcache.on && Memcache){
             Memcache.get('session_'+sessionid,function(err,result){
                 if(err) return callback(err);
+                session = result;
                 callback(null,result);
+                if(session && Config.Session.AutoRefresh){
+                    session.expire = session.autoRenewExpire;
+                    session.expireTime = new Date().getTime()+session.expire*1000;
+                    Manager.set(session,null);
+                }
             });
         }else{
-            let sessionData = null;
             try{
-                sessionData = JSON.parse(FILE.readFileSync(Core.Path.Session + '/' + sessionid,'UTF-8'));
+                session = JSON.parse(FILE.readFileSync(Core.Path.Session + '/' + sessionid,'UTF-8'));
             }catch(e){}
-            if(sessionData && sessionData.expireTime){
-                if(new Date().getTime()>sessionData.expireTime){
-                    sessionData = null;
-                    Manager.clear(sessionid);
+            if(session && session.expireTime){
+                if(new Date().getTime()>session.expireTime){
+                    if(Config.Session.AutoRefresh){
+                        session.expire = session.autoRenewExpire;
+                        session.expireTime = new Date().getTime()+session.expire*1000;
+                        Manager.set(session,null);
+                    }else{
+                        session = null;
+                        Manager.clear(sessionid);
+                    }
                 }
             }
-            callback(null,sessionData);
+            if(callback) callback(null,session);
         }
+
     },
     set:function(session,callback){
-        if(Config.Database.Memcache.on && Memcache){
+        if(Config.Session.StoreType.toLowerCase()=='memcache' && Config.Database.Memcache.on && Memcache){
             Memcache.set('session_'+session.id,session,session.expire,function(err){
                 if(err){
                     Logger.error(err);
-                    return callback(err);
+                    if(callback) callback(err);
+                    return;
                 }
-                callback();
+                if(callback) callback();
             });
         }else{
             FILE.writeFileSync(Core.Path.Session + '/' + session.id,JSON.stringify(session),'UTF-8');
-            callback();
+            if(callback) callback();
         }
     },
     clear:function(sessionid){
-        if(Config.Database.Memcache.on && Memcache){
+        if(Config.Session.StoreType.toLowerCase()=='memcache' && Config.Database.Memcache.on && Memcache){
             Memcache.del('session_'+sessionid);
         }else{
             try{
@@ -116,6 +157,46 @@ var Manager = {
     },
     buildCallback:function(callback){
         if(callback && typeof callback=='function') return callback;
-        callback = function(){}
+        return function(){};
+    }
+}
+
+var Instance = function(sessionID,callback){
+    var _data;
+    var _sessionID = sessionID;
+    var _this = this;
+    this.sessionID = _sessionID;
+    this.get = function(key){
+        return _data[key];
+    }
+    this.set = function(key,value){
+        _data[key] = value;
+        Session.update(_sessionID,key,value);
+    }
+    this.setExpireTime = function(expire,autoRenewExpire){
+        Session.setExpireTime(_sessionID,expire,autoRenewExpire);
+    }
+    if(sessionID){
+        Session.get(sessionID,function(err,session){
+            if(err || !session){
+                Session.set('status',0,function(err,new_session){
+                    _data = new_session.data;
+                    _this.sessionID = new_session.id;
+                    if(callback) callback(new_session.id,_this);
+                });
+            }else{
+                _data = session.data;
+                _this.sessionID = session.id;
+                if(callback) callback(session.id,_this);
+            }
+        });
+    }else{
+        Session.set('status',0,function(err,new_session){
+            _data = new_session.data;
+            _sessionID = new_session.id;
+            _this.sessionID = new_session.id;
+            if(callback) callback(new_session.id,_this);
+        });
     }
-}
+    return this;
+}

+ 1 - 1
system/lib/core/static.js

@@ -13,7 +13,7 @@ var Static = {
             res.end();
             return;  
         }
-        if(ext.match(/png|jpg|jpeg|gif/)){
+        if(ext.match(/png|jpg|jpeg|gif|ico/)){
             IMAGE.load(URL.parse(assetFile,true).pathname,ext,req,res);
         }else if(FILE.existsSync(assetFile)){
             var data;