From d5ccb72caff4d957b25574218ef161e0632e27fa Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 19:55:28 +0100 Subject: [PATCH 01/13] remove pretty much unused debug module --- package.json | 1 - server.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 26fc719..d7268fb 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ "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", diff --git a/server.js b/server.js index d501c5b..d49e1b6 100644 --- a/server.js +++ b/server.js @@ -1,13 +1,13 @@ #!/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"); app.set("port", process.env.PORT || 3000); var server = app.listen(app.get("port"), function() { - debug("Crafatar server listening on port " + server.address().port); + logging.debug("Crafatar server listening on port " + server.address().port); }); // cleaning worker From d10c94698f350b5143c457dcb14e91ee09ca8c7f Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 21:15:26 +0100 Subject: [PATCH 02/13] rewrite server.js --- server.js | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/server.js b/server.js index d49e1b6..6dc6ccc 100644 --- a/server.js +++ b/server.js @@ -2,13 +2,70 @@ var config = require("./modules/config"); 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() { - logging.debug("Crafatar server listening on port " + server.address().port); -}); +function asset_request(req, res) { + var filename = __dirname + "/public/" + req.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; + // we need to use url.parse and give the result to url.parse because nodejs + var prequest = url.parse(req.url, querystring); + + console.log("Request: " + prequest.pathname); + console.log("Params: " + JSON.stringify(prequest.query)); + + switch (prequest.pathname) { + case "/": + routes.index(prequest, res); + break; + case "/avatars": + routes.avatars(prequest, res); + break; + case "/skins": + routes.skins(prequest, res); + break; + case "/renders": + routes.renders(prequest, res); + break; + default: + asset_request(prequest, res); + } +} + +http.createServer(requestHandler).listen(process.env.PORT || 3000); // cleaning worker setInterval(clean.run, config.cleaning_interval * 1000); \ No newline at end of file From 3ac98c88cfbaa362f3adf101309ffbae9533b67f Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 21:28:12 +0100 Subject: [PATCH 03/13] remove expressjs from index --- routes/index.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/routes/index.js b/routes/index.js index c0b0304..cd7b7b4 100644 --- a/routes/index.js +++ b/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; \ No newline at end of file + res.writeHead(200, { + "Content-Length": html.length + }); + res.end(html); +}; \ No newline at end of file From 958b1ea907478f3843d02edbeaea2a33ba3293ca Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 21:55:38 +0100 Subject: [PATCH 04/13] remove expressjs from avatars --- routes/avatars.js | 29 ++++++++++++++--------------- server.js | 31 +++++++++++++++++-------------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/routes/avatars.js b/routes/avatars.js index 3d50b32..74e2a08 100644 --- a/routes/avatars.js +++ b/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,12 +12,13 @@ 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) { + logging.debug(req.url.pathname); + var uuid = (req.url.pathname.split("/")[2] || ""); + var size = parseInt(req.url.query.size) || config.default_size; + var def = req.url.query.default; + var helm = req.url.query.hasOwnProperty("helm"); var start = new Date(); var etag = null; @@ -26,10 +26,12 @@ router.get("/:uuid.:ext?", function(req, res) { 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); + res.end("Invalid size"); return; } else if (!helpers.uuid_valid(uuid)) { - res.status(422).send("422 Invalid UUID"); + res.writeHead(422); + res.end("Invalid UUID"); return; } @@ -43,7 +45,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 +53,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 +96,4 @@ router.get("/:uuid.:ext?", function(req, res) { }); res.end(http_status == 304 ? null : image); } -}); - - -module.exports = router; \ No newline at end of file +}; \ No newline at end of file diff --git a/server.js b/server.js index 6dc6ccc..d9653a8 100644 --- a/server.js +++ b/server.js @@ -15,7 +15,7 @@ var routes = { }; function asset_request(req, res) { - var filename = __dirname + "/public/" + req.pathname; + var filename = __dirname + "/public/" + req.url.pathname; fs.exists(filename, function(exists) { if (exists) { fs.readFile(filename, function(err, contents) { @@ -41,27 +41,30 @@ function asset_request(req, res) { 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 - var prequest = url.parse(req.url, querystring); + request.url = url.parse(req.url, querystring); + request.url.query = request.url.query || {}; - console.log("Request: " + prequest.pathname); - console.log("Params: " + JSON.stringify(prequest.query)); + var local_path = request.url.pathname.split("/")[1]; + console.log("Request: " + request.url.pathname + " (" + local_path + ")"); + console.log(request.headers); - switch (prequest.pathname) { - case "/": - routes.index(prequest, res); + switch (local_path) { + case "": + routes.index(request, res); break; - case "/avatars": - routes.avatars(prequest, res); + case "avatars": + routes.avatars(request, res); break; - case "/skins": - routes.skins(prequest, res); + case "skins": + routes.skins(request, res); break; - case "/renders": - routes.renders(prequest, res); + case "renders": + routes.renders(request, res); break; default: - asset_request(prequest, res); + asset_request(request, res); } } From 81cd71bf6ed20f982b81da1566395ed8fd285dd0 Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 22:02:06 +0100 Subject: [PATCH 05/13] fix 422 response in avatars --- routes/avatars.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/routes/avatars.js b/routes/avatars.js index 74e2a08..e6740af 100644 --- a/routes/avatars.js +++ b/routes/avatars.js @@ -14,23 +14,28 @@ var human_status = { // GET avatar request module.exports = function(req, res) { - logging.debug(req.url.pathname); + var start = new Date(); var uuid = (req.url.pathname.split("/")[2] || ""); var size = parseInt(req.url.query.size) || config.default_size; var def = req.url.query.default; var helm = req.url.query.hasOwnProperty("helm"); - var start = new Date(); 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.writeHead(422); + res.writeHead(422, { + "Content-Type": "text/plain", + "Response-Time": new Date() - start + }); res.end("Invalid size"); return; } else if (!helpers.uuid_valid(uuid)) { - res.writeHead(422); + res.writeHead(422, { + "Content-Type": "text/plain", + "Response-Time": new Date() - start + }); res.end("Invalid UUID"); return; } From 0a8f2e133ed84a3d715d9823d6f21e54e5ad48c4 Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 22:04:21 +0100 Subject: [PATCH 06/13] allow .png extension for avatars --- routes/avatars.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/avatars.js b/routes/avatars.js index e6740af..c3d0cec 100644 --- a/routes/avatars.js +++ b/routes/avatars.js @@ -15,7 +15,7 @@ var human_status = { // GET avatar request module.exports = function(req, res) { var start = new Date(); - var uuid = (req.url.pathname.split("/")[2] || ""); + 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"); From 846b738226a08f3d90379605e9d60196baf4c969 Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 22:16:35 +0100 Subject: [PATCH 07/13] better error handling + logging in server.js --- server.js | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/server.js b/server.js index d9653a8..dc0b721 100644 --- a/server.js +++ b/server.js @@ -47,24 +47,32 @@ function requestHandler(req, res) { request.url.query = request.url.query || {}; var local_path = request.url.pathname.split("/")[1]; - console.log("Request: " + request.url.pathname + " (" + local_path + ")"); - console.log(request.headers); + console.log(request.method + " " + request.url.pathname); - 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); + 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"); } } From 0a4011abc1f0ff5b1d27431e24386e7680512206 Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 22:25:09 +0100 Subject: [PATCH 08/13] allow only GET + HEAD requests --- server.js | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/server.js b/server.js index dc0b721..ac43201 100644 --- a/server.js +++ b/server.js @@ -48,31 +48,37 @@ function requestHandler(req, res) { var local_path = request.url.pathname.split("/")[1]; console.log(request.method + " " + request.url.pathname); - - 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); + 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"); } - } catch(e) { - var error = JSON.stringify(req.headers) + "\n" + e.stack; - logging.error("Error: " + error); - res.writeHead(500, { + } else { + res.writeHead(405, { "Content-Type": "text/plain" }); - res.end(config.debug_enabled ? error : "Internal server error"); + res.end("Method not allowed"); } } From 0009535fc012394ba238902584a2db0e66ba3b3d Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 22:26:29 +0100 Subject: [PATCH 09/13] upper case HTTP status messages --- routes/avatars.js | 2 +- server.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/routes/avatars.js b/routes/avatars.js index c3d0cec..c597eba 100644 --- a/routes/avatars.js +++ b/routes/avatars.js @@ -29,7 +29,7 @@ module.exports = function(req, res) { "Content-Type": "text/plain", "Response-Time": new Date() - start }); - res.end("Invalid size"); + res.end("Invalid Size"); return; } else if (!helpers.uuid_valid(uuid)) { res.writeHead(422, { diff --git a/server.js b/server.js index ac43201..63b3dd8 100644 --- a/server.js +++ b/server.js @@ -21,7 +21,7 @@ function asset_request(req, res) { fs.readFile(filename, function(err, contents) { if (err) { res.writeHead(500, {"Content-type" : "text/plain"}); - res.end("Internal server error"); + res.end("Internal Server Error"); } else { res.writeHead(200, { "Content-type" : mime.lookup(filename), @@ -34,7 +34,7 @@ function asset_request(req, res) { res.writeHead(404, { "Content-type" : "text/plain" }); - res.end("Not found"); + res.end("Not Found"); } }); } @@ -72,13 +72,13 @@ function requestHandler(req, res) { res.writeHead(500, { "Content-Type": "text/plain" }); - res.end(config.debug_enabled ? error : "Internal server error"); + res.end(config.debug_enabled ? error : "Internal Server Error"); } } else { res.writeHead(405, { "Content-Type": "text/plain" }); - res.end("Method not allowed"); + res.end("Method Not Allowed"); } } From 2f4951311da3aed3da308bd9079c30f0f117eba8 Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 22:58:38 +0100 Subject: [PATCH 10/13] remove expressjs from skins --- routes/skins.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/routes/skins.js b/routes/skins.js index 0767a2e..0a09918 100644 --- a/routes/skins.js +++ b/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; \ No newline at end of file +}; \ No newline at end of file From 7ff1ae1b2532534f6cfc1063e6868c97027b956c Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 23:06:28 +0100 Subject: [PATCH 11/13] remove expressjs from renders --- routes/renders.js | 51 ++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/routes/renders.js b/routes/renders.js index d391859..80ca4aa 100644 --- a/routes/renders.js +++ b/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; \ No newline at end of file +}; \ No newline at end of file From 86aea3527d1ff418210adfd211b128fb6c3cb748 Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 23:19:16 +0100 Subject: [PATCH 12/13] remove app.js --- app.js | 60 ---------------------------------------------------- package.json | 4 ---- 2 files changed, 64 deletions(-) delete mode 100644 app.js diff --git a/app.js b/app.js deleted file mode 100644 index 64f3fbc..0000000 --- a/app.js +++ /dev/null @@ -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; \ No newline at end of file diff --git a/package.json b/package.json index d7268fb..18e3c5c 100644 --- a/package.json +++ b/package.json @@ -25,17 +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", - "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" From fecdc4de8122880347a16510b5170caba18c3b26 Mon Sep 17 00:00:00 2001 From: jomo Date: Fri, 2 Jan 2015 23:20:55 +0100 Subject: [PATCH 13/13] remove obsolete error.jade --- views/error.jade | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 views/error.jade diff --git a/views/error.jade b/views/error.jade deleted file mode 100644 index 00716a4..0000000 --- a/views/error.jade +++ /dev/null @@ -1,8 +0,0 @@ -extends layout - -block content - .container.errmsg - h1= message - h2= error.status - if error.stack - pre #{error.stack}