Bläddra i källkod

Merge pull request #56 from Jake0oo0/no-express

Remove express.js
jomo 10 år sedan
förälder
incheckning
df49eadea1
8 ändrade filer med 153 tillägg och 137 borttagningar
  1. 0 60
      app.js
  2. 0 5
      package.json
  3. 19 15
      routes/avatars.js
  4. 12 10
      routes/index.js
  5. 30 21
      routes/renders.js
  6. 12 12
      routes/skins.js
  7. 80 6
      server.js
  8. 0 8
      views/error.jade

+ 0 - 60
app.js

@@ -1,60 +0,0 @@
-var express = require("express");
-var path = require("path");
-var logger = require("morgan");
-var cookieParser = require("cookie-parser");
-var bodyParser = require("body-parser");
-
-var routes = require("./routes/index");
-var avatars = require("./routes/avatars");
-var skins = require("./routes/skins");
-var renders = require("./routes/renders");
-
-var app = express();
-
-// view engine setup
-app.set("views", path.join(__dirname, "views"));
-app.set("view engine", "jade");
-
-app.use(logger("dev"));
-app.use(bodyParser.json());
-app.use(bodyParser.urlencoded({ extended: false }));
-app.use(cookieParser());
-app.use(express.static(path.join(__dirname, "public")));
-
-app.use("/", routes);
-app.use("/avatars", avatars);
-app.use("/skins", skins);
-app.use("/renders", renders);
-
-// catch 404 and forward to error handler
-app.use(function(req, res, next) {
-  var err = new Error("Not Found");
-  err.status = 404;
-  next(err);
-});
-
-// error handlers
-
-// development error handler
-// will print stacktrace
-if (app.get("env") === "development") {
-  app.use(function(err, req, res, next) {
-    res.status(err.status || 500);
-    res.render("error", {
-      message: err.message,
-      error: err
-    });
-  });
-}
-
-// production error handler
-// no stacktraces leaked to user
-app.use(function(err, req, res, next) {
-  res.status(err.status || 500);
-  res.render("error", {
-    message: err.message,
-    error: {}
-  });
-});
-
-module.exports = app;

+ 0 - 5
package.json

@@ -25,18 +25,13 @@
     "test": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
   },
   "dependencies": {
-    "body-parser": "~1.10.0",
     "canvas": "1.1.6",
-    "cookie-parser": "~1.3.3",
     "coveralls": "^2.11.2",
-    "debug": "~2.1.1",
-    "express": "~4.10.6",
     "istanbul": "^0.3.2",
     "jade": "~1.8.2",
     "lwip": "0.0.6",
     "mocha": "2.1.0",
     "mocha-lcov-reporter": "0.0.1",
-    "morgan": "~1.5.0",
     "redis": "0.12.1",
     "request": "2.51.0",
     "node-df": "0.1.1"

+ 19 - 15
routes/avatars.js

@@ -1,4 +1,3 @@
-var router = require("express").Router();
 var networking = require("../modules/networking");
 var logging = require("../modules/logging");
 var helpers = require("../modules/helpers");
@@ -13,23 +12,31 @@ var human_status = {
   "-1": "error"
 };
 
-/* GET avatar request. */
-router.get("/:uuid.:ext?", function(req, res) {
-  var uuid = (req.params.uuid || "");
-  var size = parseInt(req.query.size) || config.default_size;
-  var def = req.query.default;
-  var helm = req.query.hasOwnProperty("helm");
+// GET avatar request
+module.exports = function(req, res) {
   var start = new Date();
+  var uuid = (req.url.pathname.split("/")[2] || "").split(".")[0];
+  var size = parseInt(req.url.query.size) || config.default_size;
+  var def = req.url.query.default;
+  var helm = req.url.query.hasOwnProperty("helm");
   var etag = null;
 
   // Prevent app from crashing/freezing
   if (size < config.min_size || size > config.max_size) {
     // "Unprocessable Entity", valid request, but semantically erroneous:
     // https://tools.ietf.org/html/rfc4918#page-78
-    res.status(422).send("422 Invalid size");
+    res.writeHead(422, {
+      "Content-Type": "text/plain",
+      "Response-Time": new Date() - start
+    });
+    res.end("Invalid Size");
     return;
   } else if (!helpers.uuid_valid(uuid)) {
-    res.status(422).send("422 Invalid UUID");
+    res.writeHead(422, {
+      "Content-Type": "text/plain",
+      "Response-Time": new Date() - start
+    });
+    res.end("Invalid UUID");
     return;
   }
 
@@ -43,7 +50,7 @@ router.get("/:uuid.:ext?", function(req, res) {
         logging.error(uuid + " " + err);
       }
       etag = hash && hash.substr(0, 32) || "none";
-      var matches = req.get("If-None-Match") == '"' + etag + '"';
+      var matches = req.headers["if-none-match"] == '"' + etag + '"';
       if (image) {
         var http_status = 200;
         if (matches) {
@@ -51,7 +58,7 @@ router.get("/:uuid.:ext?", function(req, res) {
         } else if (err) {
           http_status = 503;
         }
-        logging.debug("Etag: " + req.get("If-None-Match"));
+        logging.debug("Etag: " + req.headers["if-none-match"]);
         logging.debug("matches: " + matches);
         logging.log("status: " + http_status);
         sendimage(http_status, status, image);
@@ -94,7 +101,4 @@ router.get("/:uuid.:ext?", function(req, res) {
     });
     res.end(http_status == 304 ? null : image);
   }
-});
-
-
-module.exports = router;
+};

+ 12 - 10
routes/index.js

@@ -1,15 +1,17 @@
-var express = require("express");
 var config = require("../modules/config");
-var router = express.Router();
+var jade = require("jade");
 
-/* GET home page. */
-router.get("/", function(req, res) {
-  res.render("index", {
+// compile jade
+var index = jade.compileFile(__dirname + "/../views/index.jade");
+
+module.exports = function(req, res) {
+  var html = index({
     title: "Crafatar",
-    domain: "https://" + req.headers.host,
+    domain: "https://" + "req.hostname",
     config: config
   });
-});
-
-
-module.exports = router;
+  res.writeHead(200, {
+    "Content-Length": html.length
+  });
+  res.end(html);
+};

+ 30 - 21
routes/renders.js

@@ -1,4 +1,3 @@
-var router = require("express").Router();
 var logging = require("../modules/logging");
 var helpers = require("../modules/helpers");
 var config = require("../modules/config");
@@ -14,33 +13,45 @@ var human_status = {
   "-1": "error"
 };
 
-// valid types: head, body. helmet is query param
+// valid types: head, body
+// helmet is query param
+// TODO: The Type logic should be two separate GET functions once response methods are extracted
 
-// The Type logic should be two separate GET
-// functions once response methods are extracted
-router.get("/:type/:uuid.:ext?", function(req, res) {
-  var raw_type = req.params.type;
+// GET render request
+module.exports = function(req, res) {
+  var start = new Date();
+  var raw_type = (req.url.pathname.split("/")[2] || "");
 
-  // Check valid type for now
+  // validate type
   if (raw_type != "body" && raw_type != "head") {
-    res.status(404).send("404 Invalid Render Type");
+    res.writeHead(422, {
+      "Content-Type": "text/plain",
+      "Response-Time": new Date() - start
+    });
+    res.end("Invalid Render Type");
     return;
   }
 
   var body = raw_type == "body";
-  var uuid = req.params.uuid;
-  var def = req.query.default;
-  var scale = parseInt(req.query.scale) || config.default_scale;
-  var helm = req.query.hasOwnProperty("helm");
-  var start = new Date();
+  var uuid = (req.url.pathname.split("/")[3] || "").split(".")[0];
+  var def = req.url.query.default;
+  var scale = parseInt(req.url.query.scale) || config.default_scale;
+  var helm = req.url.query.hasOwnProperty("helm");
   var etag = null;
 
   if (scale < config.min_scale || scale > config.max_scale) {
-    // Preventing from OOM crashes.
-    res.status(422).send("422 Invalid Scale");
+    res.writeHead(422, {
+      "Content-Type": "text/plain",
+      "Response-Time": new Date() - start
+    });
+    res.end("422 Invalid Scale");
     return;
   } else if (!helpers.uuid_valid(uuid)) {
-    res.status(422).send("422 Invalid UUID");
+    res.writeHead(422, {
+      "Content-Type": "text/plain",
+      "Response-Time": new Date() - start
+    });
+    res.end("422 Invalid UUID");
     return;
   }
 
@@ -54,7 +65,7 @@ router.get("/:type/:uuid.:ext?", function(req, res) {
         logging.error(uuid + " " + err);
       }
       etag = hash && hash.substr(0, 32) || "none";
-      var matches = req.get("If-None-Match") == '"' + etag + '"';
+      var matches = req.headers["if-none-match"] == '"' + etag + '"';
       if (image) {
         var http_status = 200;
         if (matches) {
@@ -63,7 +74,7 @@ router.get("/:type/:uuid.:ext?", function(req, res) {
           http_status = 503;
         }
         logging.log("matches: " + matches);
-        logging.log("Etag: " + req.get("If-None-Match"));
+        logging.log("Etag: " + req.headers["if-none-match"]);
         logging.log("status: " + http_status);
         sendimage(http_status, status, image);
       } else {
@@ -119,6 +130,4 @@ router.get("/:type/:uuid.:ext?", function(req, res) {
     });
     res.end(http_status == 304 ? null : image);
   }
-});
-
-module.exports = router;
+};

+ 12 - 12
routes/skins.js

@@ -2,19 +2,22 @@ var networking = require("../modules/networking");
 var logging = require("../modules/logging");
 var helpers = require("../modules/helpers");
 var config = require("../modules/config");
-var router = require("express").Router();
 var skins = require("../modules/skins");
 var lwip = require("lwip");
 
-/* GET skin request. */
-router.get("/:uuid.:ext?", function(req, res) {
-  var uuid = (req.params.uuid || "");
-  var def = req.query.default;
+// GET skin request
+module.exports = function(req, res) {
   var start = new Date();
+  var uuid = (req.url.pathname.split("/")[2] || "").split(".")[0];
+  var def = req.url.query.default;
   var etag = null;
 
   if (!helpers.uuid_valid(uuid)) {
-    res.status(422).send("422 Invalid UUID");
+    res.writeHead(422, {
+      "Content-Type": "text/plain",
+      "Response-Time": new Date() - start
+    });
+    res.end("Invalid UUID");
     return;
   }
 
@@ -28,7 +31,7 @@ router.get("/:uuid.:ext?", function(req, res) {
         logging.error(uuid + " " + err);
       }
       etag = hash && hash.substr(0, 32) || "none";
-      var matches = req.get("If-None-Match") == '"' + etag + '"';
+      var matches = req.headers["if-none-match"] == '"' + etag + '"';
       if (image) {
         var http_status = 200;
         if (matches) {
@@ -36,7 +39,7 @@ router.get("/:uuid.:ext?", function(req, res) {
         } else if (err) {
           http_status = 503;
         }
-        logging.debug("Etag: " + req.get("If-None-Match"));
+        logging.debug("Etag: " + req.headers["if-none-match"]);
         logging.debug("matches: " + matches);
         logging.log("status: " + http_status);
         sendimage(http_status, image);
@@ -81,7 +84,4 @@ router.get("/:uuid.:ext?", function(req, res) {
     });
     res.end(http_status == 304 ? null : image);
   }
-});
-
-
-module.exports = router;
+};

+ 80 - 6
server.js

@@ -1,14 +1,88 @@
 #!/usr/bin/env node
 var config = require("./modules/config");
-var debug = require("debug")("crafatar");
+var logging = require("./modules/logging");
 var clean = require("./modules/cleaner");
-var app = require("./app");
+var http = require("http");
+var mime = require("mime");
+var url = require("url");
+var fs = require("fs");
 
-app.set("port", process.env.PORT || 3000);
+var routes = {
+  index: require("./routes/index"),
+  avatars: require("./routes/avatars"),
+  skins: require("./routes/skins"),
+  renders: require("./routes/renders")
+};
 
-var server = app.listen(app.get("port"), function() {
-  debug("Crafatar server listening on port " + server.address().port);
-});
+function asset_request(req, res) {
+  var filename = __dirname + "/public/" + req.url.pathname;
+  fs.exists(filename, function(exists) {
+    if (exists) {
+      fs.readFile(filename, function(err, contents) {
+        if (err) {
+          res.writeHead(500, {"Content-type" : "text/plain"});
+          res.end("Internal Server Error");
+        } else {
+          res.writeHead(200, {
+            "Content-type" : mime.lookup(filename),
+            "Content-Length": contents.length
+          });
+          res.end(contents);
+        }
+      });
+    } else {
+      res.writeHead(404, {
+        "Content-type" : "text/plain"
+      });
+      res.end("Not Found");
+    }
+  });
+}
+
+function requestHandler(req, res) {
+  var querystring = url.parse(req.url).query;
+  var request = req;
+  // we need to use url.parse and give the result to url.parse because nodejs
+  request.url = url.parse(req.url, querystring);
+  request.url.query = request.url.query || {};
+
+  var local_path = request.url.pathname.split("/")[1];
+  console.log(request.method + " " + request.url.pathname);
+  if (request.method == "GET" || request.method == "HEAD") {
+    try {
+      switch (local_path) {
+        case "":
+          routes.index(request, res);
+          break;
+        case "avatars":
+          routes.avatars(request, res);
+          break;
+        case "skins":
+          routes.skins(request, res);
+          break;
+        case "renders":
+          routes.renders(request, res);
+          break;
+        default:
+          asset_request(request, res);
+      }
+    } catch(e) {
+      var error = JSON.stringify(req.headers) + "\n" + e.stack;
+      logging.error("Error: " + error);
+      res.writeHead(500, {
+        "Content-Type": "text/plain"
+      });
+      res.end(config.debug_enabled ? error : "Internal Server Error");
+    }
+  } else {
+    res.writeHead(405, {
+      "Content-Type": "text/plain"
+    });
+    res.end("Method Not Allowed");
+  }
+}
+
+http.createServer(requestHandler).listen(process.env.PORT || 3000);
 
 // cleaning worker
 setInterval(clean.run, config.cleaning_interval * 1000);

+ 0 - 8
views/error.jade

@@ -1,8 +0,0 @@
-extends layout
-
-block content
-  .container.errmsg
-    h1= message
-    h2= error.status
-    if error.stack
-      pre #{error.stack}