router.ts 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * @Author: HonorLee
  3. * @Version 2.0
  4. * @LastUpdate 2019/10/11
  5. */
  6. import PATH = require('path');
  7. export default class Router{
  8. private static _midware:any = {};
  9. private static _midwareIndex:Array<string> = [];
  10. public static setMidware(rule:RegExp,func:any){
  11. const reg = rule.toString();
  12. if(!Router._midware[reg]){
  13. Router._midware[reg] = {exp:rule,handler:[]};
  14. Router._midwareIndex.push(reg);
  15. }
  16. Router._midware[reg].handler.push(func);
  17. }
  18. public static async run(requestData:RequestData){
  19. let method = 'index';
  20. let handlerFile;
  21. Object.keys(SYSTEM.MVC.ROUTER_MAP).forEach(path=>{
  22. if(requestData.path && requestData.path.indexOf(path) == 0){
  23. if(SYSTEM.MVC.ROUTER_MAP[path].constructor==String){
  24. requestData.path = `${SYSTEM.MVC.ROUTER_MAP[path]}${requestData.path.replace(path,'')}`;
  25. }else if(SYSTEM.MVC.ROUTER_MAP[path].constructor==Object){
  26. if(SYSTEM.MVC.ROUTER_MAP[path].method){
  27. if(requestData.method!=SYSTEM.MVC.ROUTER_MAP[path].method){
  28. if(requestData.res){
  29. requestData.res.statusCode = 400;
  30. requestData.res.write('Unauthorized request method!');
  31. requestData.res.end();
  32. }
  33. return
  34. }
  35. }
  36. if(SYSTEM.MVC.ROUTER_MAP[path].forward){
  37. requestData.path = `${SYSTEM.MVC.ROUTER_MAP[path].forward}${requestData.path.replace(path,'')}`;
  38. }
  39. }
  40. }
  41. })
  42. if(requestData.path == '/'){
  43. handlerFile = '/index.js'
  44. }else if(requestData.path && requestData.path.match(/\/$/g)){
  45. handlerFile = `${requestData.path}index.js`;
  46. }else if(requestData.path){
  47. try{
  48. FILE.statSync(`${SYSTEM.MVC.PATH.CONTROLLER}${requestData.path}.js`)
  49. handlerFile = `${requestData.path}.js`;
  50. }catch(e){
  51. const pathArr = requestData.path.split('/');
  52. method = pathArr.pop() || 'index';
  53. const path = pathArr.join('/');
  54. try{
  55. FILE.statSync(`${SYSTEM.MVC.PATH.CONTROLLER}${path}.js`)
  56. handlerFile = `${path}.js`;
  57. }catch(e){
  58. try{
  59. FILE.statSync(`${SYSTEM.MVC.PATH.CONTROLLER}${path}/index.js`);
  60. handlerFile = `${path}/index.js`;
  61. }catch(e){
  62. handlerFile = null;
  63. }
  64. }
  65. }
  66. }else{
  67. handlerFile = null;
  68. }
  69. if(method == '__construct') return Router._error(403,'Function __construct can\'t be called outside',requestData.res);
  70. if(!handlerFile) return Router._error(404,`No such handler [${requestData.path}]`,requestData.res);
  71. handlerFile = `${SYSTEM.MVC.PATH.CONTROLLER}${handlerFile}`;
  72. let handlerClass,handler;
  73. try {
  74. // eslint-disable-next-line @typescript-eslint/no-var-requires
  75. handlerClass = require(handlerFile);
  76. if(handlerClass.default) handlerClass = handlerClass.default;
  77. }catch(e:any){
  78. console.log(e.stack);
  79. if(e.code=='MODULE_NOT_FOUND'){
  80. Router._error(404,null,requestData.res);
  81. }else{
  82. Router._error(404,e.stack,requestData.res);
  83. }
  84. return;
  85. }
  86. try{
  87. handler = new handlerClass(requestData);
  88. // const mixHandler = handler;
  89. }catch(e:any){
  90. return Router._error(403,e.stack,requestData.res);
  91. }
  92. // if(handler instanceof CONTROLLER){
  93. // mixHandler = handler;
  94. // }else{
  95. // const baseClass = new CONTROLLER(requestData);
  96. // mixHandler = Object.assign(baseClass,handler);
  97. // }
  98. if(typeof handler[method]==='function'){
  99. let returnSometing;
  100. if(requestData.path && Router._midwareIndex.length){
  101. for(const reg of Router._midwareIndex){
  102. const match = requestData.path.match(Router._midware[reg].exp);
  103. if(match && match.index==0){
  104. for(const func of Router._midware[reg].handler){
  105. const ret = await func.call(handler,handler);
  106. if(ret==false) return;
  107. }
  108. }
  109. }
  110. }
  111. if(typeof handler['__construct']==='function'){
  112. try{
  113. returnSometing = await handler['__construct'].call(handler);
  114. }catch(e:any){
  115. LOGGER.error(`Function __construct in [${handlerFile}] called error:`);
  116. Router._error(403,e.stack,requestData.res);
  117. return;
  118. }
  119. if(returnSometing == false) return;
  120. }
  121. if(handler[method].prototype && handler[method].prototype.method && handler[method].prototype.method.toLowerCase()!=requestData.method) return handler.end('Unauthorized request method',400);
  122. try{
  123. await handler[method].call(handler,returnSometing);
  124. }catch(e:any){
  125. LOGGER.error(`Function [${method}] in [${handlerFile}] called error:`);
  126. Router._error(403,e.stack,requestData.res);
  127. }
  128. }else{
  129. Router._error(404,`No such method [${method}] in handler [${handlerFile}]`,requestData.res);
  130. }
  131. }
  132. private static _error(code:number,errMsg:string|null,res:any){
  133. if(errMsg) LOGGER.error(errMsg);
  134. res.writeHead(code, {'Content-Type': 'text/html'});
  135. res.end(`<center style="font-size:24px">- ${code} -</center>`);
  136. }
  137. // private static _encodeRequestData(req){
  138. // req._GET = Router._encodeObj(req._GET);
  139. // req._POST = Router._encodeObj(req._POST);
  140. // }
  141. // private static _encodeObj(obj){
  142. // let newObj = {};
  143. // Object.keys(obj).forEach(key=>{
  144. // if(typeof(obj[key]==='string')){
  145. // newObj[encodeURI(key)] = encodeURI(obj[key]);
  146. // }else{
  147. // newObj[encodeURI(key)] = obj[key];
  148. // }
  149. // })
  150. // return newObj;
  151. // }
  152. }
  153. // module.exports = Router;