/* * @Author: HonorLee * @Version 1.0 * @LastUpdate 2018/6/19 * @License MIT */ 'use strict' CACHE.router = {}; var Router ={ goAsset:function(path,req,res){ let assetFile = Core.Path.Asset+path; FILE.stat(assetFile,function(err,status){ if(err || !status.isFile()){ Router._error('No such file ['+path+']',res); }else{ STATIC.load(assetFile,req,res); } }); }, goHandler:function(path,req,res){ let method = 'index'; let handlerFile; if(path=='/'){ handlerFile = '/index.js' }else if(path.lastIndexOf('/')==(path.length-1)){ handlerFile = `${path}index.js`; }else{ if(FILE.existsSync(Core.Path.Handler + `${path}.js`)){ handlerFile = `${path}.js`; }else{ let pathArr = path.split('/'); method = pathArr.pop(); path = pathArr.join('/'); if(FILE.existsSync(Core.Path.Handler + `${path}.js`)){ handlerFile = `${path}.js`; }else if(FILE.existsSync(Core.Path.Handler + `${path}/index.js`)){ handlerFile = `${path}/index.js`; } } } if(!handlerFile) return Router._error('No such handler ['+path+']',res); handlerFile = Core.Path.Handler + handlerFile; if(method=='__construct') return Router._error('__construct can\'t be called outside in ['+handlerFile+']',res); let handler; try { handler = require(handlerFile); }catch(e){ 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(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((RouterRule[path]['method'] && RouterRule[path]['method'].length && new RegExp(method).exec(RouterRule[path]['method'])) || (!RouterRule[path]['method'] || RouterRule[path]['method'].length==0)){ 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); } return; } } } if(handler.hasOwnProperty(method) && typeof handler[method]==='function'){ let noBypass = true; 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); } }, _error:function(log,res){ LOGGER.error(log); res.writeHead(404, {'Content-Type': 'text/html'}); res.end('404'); } }; module.exports = function(req,res){ let URI = req.url; 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 || URI=='/favicon.ico'); req._GET = URLParse.query; if(isAsset){ let assetPath = URLArr.join('/').replace('/'+Config.Asset.asset_path,''); Router.goAsset(assetPath,req,res); return; } req._Cookie = {}; req.headers.cookie && req.headers.cookie.split(';').forEach(function(Cookie){ let parts = Cookie.split('='); let key = parts[0].trim(); let value = (parts[1]||'').trim(); if(parts.length>2){ parts = parts.shift(); value = parts.join('=').trim(); } req._Cookie[key] = value; }); Router.goHandler(URLParse.pathname,req,res); return this; };