/* * @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 pathArr = path.split('/'); let method = 'index'; let match = false; if(path=='/') path = '/index'; let expArr = [],methodMark = {}; let handlerFile; // handlerFile = path + '/index.js'; expArr.push(handlerFile); methodMark[handlerFile] = 'index'; // handlerFile = path + '.js'; expArr.push(handlerFile); methodMark[handlerFile] = 'index'; // if(path!='/index'){ 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){ 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.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(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; };