httpServ.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. const http = require("http")
  2. ,https = require("https")
  3. ,clientSession = require("client-sessions")
  4. ,Url = require("./url.js").Url
  5. ,config = require("../config.js")
  6. ,sessionManager = require("./session.js").SessionManager
  7. ,AccountController = require("./controller/accountController.js").AccountController
  8. ,ApiController = require("./controller/apiController.js").ApiController
  9. ,MultiChatManager = require("./multichatManager.js").MultiChatManager
  10. ,AccountManager = require("./models/accounts.js").accountManager
  11. ,Slack = require("./slack.js").Slack
  12. ,slackManager = require("./slackManager.js").SlackManager
  13. ,FaviconWriter = require("./faviconWriter.js").FaviconWriter;
  14. function Server() {
  15. var ctx = this;
  16. this.httpServ = http.createServer(function(req, res) {
  17. res.ended = false;
  18. res.on('end', () => {
  19. res.ended = true;
  20. });
  21. ctx.onRequest(req, res);
  22. });
  23. this.httpServ.listen(config.port, ctx.onListen);
  24. }
  25. Server.parseCookies = function(req) {
  26. var cookies = req.headers.cookie
  27. ,cookieObj = null;
  28. if (cookies) {
  29. cookieObj = {};
  30. cookies = cookies.split(";");
  31. for (var cookieIndex =0, nbCookies =cookies.length; cookieIndex < nbCookies; cookieIndex++) {
  32. var cookieParts = cookies[cookieIndex].indexOf("=")
  33. ,cookieKey = null
  34. ,cookieValue = null;
  35. if (cookieParts === -1) {
  36. cookieKey = cookies[cookieIndex].trim();
  37. } else {
  38. cookieKey = cookies[cookieIndex].substr(0, cookieParts).trim();
  39. cookieValue = cookies[cookieIndex].substr(cookieParts +1).trim();
  40. }
  41. cookieObj[cookieKey] = cookieValue;
  42. }
  43. }
  44. return cookieObj;
  45. };
  46. Server.stringifyCookies = function(cookies) {
  47. var cookieString = "";
  48. for (var cookieKey in cookies) {
  49. cookieString += cookieString;
  50. if (cookies[cookieString] !== null) {
  51. cookieString += "=";
  52. }
  53. cookieString += "; ";
  54. }
  55. return cookieString;
  56. };
  57. Server.prototype.onListen = function() {
  58. console.log("onListen");
  59. };
  60. Server.prototype.execTemplate = function(template, req, res) {
  61. var resp = template.exec(req, res, this);
  62. if (resp && resp.body) {
  63. if (resp.status)
  64. res.writeHeader(resp.status);
  65. res.end(resp.body);
  66. }
  67. // else something is running asynchronously, let template close request later..
  68. };
  69. Server.prototype.execRequest = function(req, res) {
  70. if (req.urlObj.isTemplate() && req.urlObj.template.needLogin === false) {
  71. return this.execTemplate(req.urlObj.template, req, res);
  72. } else if (req.urlObj.isPublic()) {
  73. if (!config.isDebug)
  74. res.setHeader('Cache-Control', 'private, max-age=' +15 * 60);
  75. res.setHeader('Content-Length', req.urlObj.serve.stat.size);
  76. res.writeHeader("200");
  77. req.urlObj.getReadStream().pipe(res, { end: true });
  78. sessionManager.saveSession(req.session);
  79. return; // async pipe will close when finished
  80. } else if (!req.account) {
  81. res.writeHeader("302", { Location: "login" });
  82. res.end();
  83. } else if (req.urlObj.isTemplate()) {
  84. return this.execTemplate(req.urlObj.template, req, res);
  85. } else if (req.urlObj.match(["favicon.png"])) {
  86. if (!config.isDebug)
  87. res.setHeader('Cache-Control', 'private, max-age=' +15 * 60);
  88. var unreadHi = (req.urlObj.queryTokens.h && req.urlObj.queryTokens.h[0]) ? parseInt(req.urlObj.queryTokens.h[0], 10) : 0
  89. ,unread = (req.urlObj.queryTokens.m && req.urlObj.queryTokens.m[0]) ? parseInt(req.urlObj.queryTokens.m[0], 10) : 0;
  90. FaviconWriter.write(unreadHi, unread, (buf) => {
  91. res.writeHeader("200");
  92. res.end(buf);
  93. });
  94. sessionManager.saveSession(req.session);
  95. return;
  96. } else {
  97. // Api / dynamic content
  98. var apiSuccess = false;
  99. res.chatContext = new MultiChatManager();
  100. var services = req.account.getServices();
  101. for (var serviceId in services) {
  102. switch (services[serviceId].type) {
  103. case "Slack":
  104. res.chatContext.push(slackManager.lazyGet(serviceId, services[serviceId].oauthParam, req.reqT));
  105. break;
  106. default:
  107. console.error("Unknown service type for ", services[serviceId], " with account #" +req.account.id);
  108. }
  109. }
  110. if (req.urlObj.urlParts[0] === "account") {
  111. AccountController.onRequest(req, res, this);
  112. } else if (req.urlObj.urlParts[0] === "api") {
  113. ApiController.onRequest(req, res, this);
  114. } else {
  115. this.execTemplate(require('./template/_404.js'), req, res);
  116. }
  117. }
  118. };
  119. Server.prototype.onRequest = function(req, res) {
  120. req.reqT = Date.now();
  121. req.cookies = Server.parseCookies(req);
  122. req.session = sessionManager.forRequest(req);
  123. req.urlObj = new Url(req.url);
  124. req.account = null;
  125. if (req.session) {
  126. var self = this;
  127. AccountManager.fromId(req.session.accountId, (acc) => {
  128. req.account = acc;
  129. self.execRequest(req, res);
  130. });
  131. } else {
  132. this.execRequest(req, res);
  133. }
  134. };
  135. module.exports.HttpServ = Server;