url.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. var fs = require('fs');
  2. function Url(url) {
  3. this.url = url;
  4. if (this.url.indexOf('?') >= 0)
  5. this.url = this.url.substr(0, this.url.indexOf('?'));
  6. while (this.url.length && this.url[0] === '/') {
  7. this.url = this.url.substr(1);
  8. }
  9. var urlParts = this.url.split("/");
  10. this.urlParts = [];
  11. for (var i =0, nbParts = urlParts.length; i < nbParts; i++) {
  12. if (urlParts[i])
  13. this.urlParts.push(urlParts[i]);
  14. }
  15. var stop = url.indexOf("?");
  16. if (stop === -1) {
  17. stop = url.length;
  18. }
  19. this.path = url.substr(0, stop);
  20. var queryTokens = url.substr(stop +1).split("&");
  21. this.queryTokens = {};
  22. for (var i =0, nbTokens = queryTokens.length; i < nbTokens; i++) {
  23. var token = queryTokens[i].split("=");
  24. if (token[0] !== "") {
  25. if (!this.queryTokens[token[0]]) {
  26. this.queryTokens[token[0]] = [];
  27. }
  28. this.queryTokens[token[0]].push(token[1] || true);
  29. }
  30. }
  31. this.serve = null;
  32. this.template = null;
  33. if (!tryLoadTemplate.apply(this))
  34. tryLoadPublic.apply(this);
  35. }
  36. function tryLoadPublic() {
  37. try{
  38. if (!this.urlParts.length) {
  39. this.serve = {
  40. filename: "public/index.html"
  41. ,stat: fs.statSync("public/index.html")
  42. };
  43. } else if (this.urlParts.length == 1) {
  44. this.serve = {
  45. filename: "public/" +this.urlParts[0]
  46. ,stat: fs.statSync("public/" +this.urlParts[0])
  47. };
  48. }
  49. return true;
  50. } catch (e) {
  51. // Not a public/ file
  52. }
  53. return false;
  54. }
  55. function tryLoadTemplateFile(fileName) {
  56. try{
  57. fs.statSync(fileName);
  58. } catch (e) {
  59. // Not a template file
  60. return null;
  61. }
  62. return require(fileName);
  63. }
  64. function tryLoadTemplate() {
  65. var template;
  66. if (!this.urlParts[0]) {
  67. template = tryLoadTemplateFile(__dirname +'/../template/index.js');
  68. } else if (this.urlParts[0][0] !== '_') {
  69. template = tryLoadTemplateFile(__dirname +'/../template/' +this.urlParts[0] +'.js');
  70. }
  71. if (!template || (template.match && !template.match(this)) || (!template.match && this.urlParts[0].length > 1)) {
  72. return false;
  73. }
  74. this.template = template;
  75. return true;
  76. }
  77. Url.prototype.isPublic = function() {
  78. return this.serve !== null;
  79. };
  80. Url.prototype.isTemplate = function() {
  81. return !!this.template;
  82. };
  83. Url.prototype.getReadStream = function() {
  84. return fs.createReadStream(this.serve.filename);
  85. };
  86. Url.prototype.match = function(arr) {
  87. if (arr.length !== this.urlParts.length)
  88. return false;
  89. for (var i=0, arrLen = arr.length; i < arrLen; i++)
  90. if (arr[i] !== this.urlParts[i] && arr[i] !== '?')
  91. return false;
  92. return true;
  93. }
  94. module.exports = { Url: Url };