server.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #!/usr/bin/env node
  2. var logging = require("./logging");
  3. var querystring = require("querystring");
  4. var config = require("./config");
  5. var http = require("http");
  6. var mime = require("mime");
  7. var path = require("path");
  8. var url = require("url");
  9. var fs = require("fs");
  10. var server = null;
  11. var routes = {
  12. index: require("./routes/index"),
  13. avatars: require("./routes/avatars"),
  14. skins: require("./routes/skins"),
  15. renders: require("./routes/renders"),
  16. capes: require("./routes/capes")
  17. };
  18. function asset_request(req, res) {
  19. var filename = path.join(__dirname, "public", req.url.path_list.join("/"));
  20. fs.exists(filename, function(exists) {
  21. if (exists) {
  22. res.writeHead(200, { "Content-type": mime.lookup(filename) });
  23. fs.createReadStream(filename).pipe(res);
  24. } else {
  25. res.writeHead(404, {
  26. "Content-type": "text/plain"
  27. });
  28. res.end("Not Found");
  29. }
  30. });
  31. }
  32. function requestHandler(req, res) {
  33. var request = req;
  34. request.url = url.parse(req.url, true);
  35. request.url.query = request.url.query || {};
  36. // remove trailing and double slashes + other junk
  37. var path_list = request.url.pathname.split("/");
  38. for (var i = 0; i < path_list.length; i++) {
  39. // URL decode
  40. path_list[i] = querystring.unescape(path_list[i]);
  41. }
  42. request.url.path_list = path_list;
  43. // generate 12 character random string
  44. request.id = Math.random().toString(36).substring(2, 14);
  45. var local_path = request.url.path_list[1];
  46. logging.log(request.id + request.method, request.url.href);
  47. if (request.method === "GET" || request.method === "HEAD") {
  48. try {
  49. switch (local_path) {
  50. case "":
  51. routes.index(request, res);
  52. break;
  53. case "avatars":
  54. routes.avatars(request, res);
  55. break;
  56. case "skins":
  57. routes.skins(request, res);
  58. break;
  59. case "renders":
  60. routes.renders(request, res);
  61. break;
  62. case "capes":
  63. routes.capes(request, res);
  64. break;
  65. default:
  66. asset_request(request, res);
  67. }
  68. } catch(e) {
  69. var error = JSON.stringify(req.headers) + "\n" + e.stack;
  70. logging.error(request.id + "Error:", error);
  71. res.writeHead(500, {
  72. "Content-Type": "text/plain"
  73. });
  74. res.end(config.debug_enabled ? error : "Internal Server Error");
  75. }
  76. } else {
  77. res.writeHead(405, {
  78. "Content-Type": "text/plain"
  79. });
  80. res.end("Method Not Allowed");
  81. }
  82. }
  83. var exp = {};
  84. exp.boot = function(callback) {
  85. var port = process.env.PORT || 3000;
  86. var bind_ip = process.env.BIND || "0.0.0.0";
  87. logging.log("Server running on http://" + bind_ip + ":" + port + "/");
  88. server = http.createServer(requestHandler).listen(port, bind_ip, function() {
  89. if (callback) {
  90. callback();
  91. }
  92. });
  93. };
  94. exp.close = function(callback) {
  95. server.close(function() {
  96. callback();
  97. });
  98. };
  99. module.exports = exp;
  100. if (require.main === module) {
  101. logging.error("Please use 'npm start' or 'lib/www.js'");
  102. process.exit(1);
  103. }