mirror of
https://github.com/azures04/crafatar.git
synced 2026-03-21 23:41:18 +01:00
commit
df49eadea1
60
app.js
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;
|
|
||||||
@ -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"
|
"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": {
|
"dependencies": {
|
||||||
"body-parser": "~1.10.0",
|
|
||||||
"canvas": "1.1.6",
|
"canvas": "1.1.6",
|
||||||
"cookie-parser": "~1.3.3",
|
|
||||||
"coveralls": "^2.11.2",
|
"coveralls": "^2.11.2",
|
||||||
"debug": "~2.1.1",
|
|
||||||
"express": "~4.10.6",
|
|
||||||
"istanbul": "^0.3.2",
|
"istanbul": "^0.3.2",
|
||||||
"jade": "~1.8.2",
|
"jade": "~1.8.2",
|
||||||
"lwip": "0.0.6",
|
"lwip": "0.0.6",
|
||||||
"mocha": "2.1.0",
|
"mocha": "2.1.0",
|
||||||
"mocha-lcov-reporter": "0.0.1",
|
"mocha-lcov-reporter": "0.0.1",
|
||||||
"morgan": "~1.5.0",
|
|
||||||
"redis": "0.12.1",
|
"redis": "0.12.1",
|
||||||
"request": "2.51.0",
|
"request": "2.51.0",
|
||||||
"node-df": "0.1.1"
|
"node-df": "0.1.1"
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
var router = require("express").Router();
|
|
||||||
var networking = require("../modules/networking");
|
var networking = require("../modules/networking");
|
||||||
var logging = require("../modules/logging");
|
var logging = require("../modules/logging");
|
||||||
var helpers = require("../modules/helpers");
|
var helpers = require("../modules/helpers");
|
||||||
@ -13,23 +12,31 @@ var human_status = {
|
|||||||
"-1": "error"
|
"-1": "error"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* GET avatar request. */
|
// GET avatar request
|
||||||
router.get("/:uuid.:ext?", function(req, res) {
|
module.exports = 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");
|
|
||||||
var start = new Date();
|
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;
|
var etag = null;
|
||||||
|
|
||||||
// Prevent app from crashing/freezing
|
// Prevent app from crashing/freezing
|
||||||
if (size < config.min_size || size > config.max_size) {
|
if (size < config.min_size || size > config.max_size) {
|
||||||
// "Unprocessable Entity", valid request, but semantically erroneous:
|
// "Unprocessable Entity", valid request, but semantically erroneous:
|
||||||
// https://tools.ietf.org/html/rfc4918#page-78
|
// 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;
|
return;
|
||||||
} else if (!helpers.uuid_valid(uuid)) {
|
} 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +50,7 @@ router.get("/:uuid.:ext?", function(req, res) {
|
|||||||
logging.error(uuid + " " + err);
|
logging.error(uuid + " " + err);
|
||||||
}
|
}
|
||||||
etag = hash && hash.substr(0, 32) || "none";
|
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) {
|
if (image) {
|
||||||
var http_status = 200;
|
var http_status = 200;
|
||||||
if (matches) {
|
if (matches) {
|
||||||
@ -51,7 +58,7 @@ router.get("/:uuid.:ext?", function(req, res) {
|
|||||||
} else if (err) {
|
} else if (err) {
|
||||||
http_status = 503;
|
http_status = 503;
|
||||||
}
|
}
|
||||||
logging.debug("Etag: " + req.get("If-None-Match"));
|
logging.debug("Etag: " + req.headers["if-none-match"]);
|
||||||
logging.debug("matches: " + matches);
|
logging.debug("matches: " + matches);
|
||||||
logging.log("status: " + http_status);
|
logging.log("status: " + http_status);
|
||||||
sendimage(http_status, status, image);
|
sendimage(http_status, status, image);
|
||||||
@ -94,7 +101,4 @@ router.get("/:uuid.:ext?", function(req, res) {
|
|||||||
});
|
});
|
||||||
res.end(http_status == 304 ? null : image);
|
res.end(http_status == 304 ? null : image);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
@ -1,15 +1,17 @@
|
|||||||
var express = require("express");
|
|
||||||
var config = require("../modules/config");
|
var config = require("../modules/config");
|
||||||
var router = express.Router();
|
var jade = require("jade");
|
||||||
|
|
||||||
/* GET home page. */
|
// compile jade
|
||||||
router.get("/", function(req, res) {
|
var index = jade.compileFile(__dirname + "/../views/index.jade");
|
||||||
res.render("index", {
|
|
||||||
|
module.exports = function(req, res) {
|
||||||
|
var html = index({
|
||||||
title: "Crafatar",
|
title: "Crafatar",
|
||||||
domain: "https://" + req.headers.host,
|
domain: "https://" + "req.hostname",
|
||||||
config: config
|
config: config
|
||||||
});
|
});
|
||||||
});
|
res.writeHead(200, {
|
||||||
|
"Content-Length": html.length
|
||||||
|
});
|
||||||
module.exports = router;
|
res.end(html);
|
||||||
|
};
|
||||||
@ -1,4 +1,3 @@
|
|||||||
var router = require("express").Router();
|
|
||||||
var logging = require("../modules/logging");
|
var logging = require("../modules/logging");
|
||||||
var helpers = require("../modules/helpers");
|
var helpers = require("../modules/helpers");
|
||||||
var config = require("../modules/config");
|
var config = require("../modules/config");
|
||||||
@ -14,33 +13,45 @@ var human_status = {
|
|||||||
"-1": "error"
|
"-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
|
// GET render request
|
||||||
// functions once response methods are extracted
|
module.exports = function(req, res) {
|
||||||
router.get("/:type/:uuid.:ext?", function(req, res) {
|
var start = new Date();
|
||||||
var raw_type = req.params.type;
|
var raw_type = (req.url.pathname.split("/")[2] || "");
|
||||||
|
|
||||||
// Check valid type for now
|
// validate type
|
||||||
if (raw_type != "body" && raw_type != "head") {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var body = raw_type == "body";
|
var body = raw_type == "body";
|
||||||
var uuid = req.params.uuid;
|
var uuid = (req.url.pathname.split("/")[3] || "").split(".")[0];
|
||||||
var def = req.query.default;
|
var def = req.url.query.default;
|
||||||
var scale = parseInt(req.query.scale) || config.default_scale;
|
var scale = parseInt(req.url.query.scale) || config.default_scale;
|
||||||
var helm = req.query.hasOwnProperty("helm");
|
var helm = req.url.query.hasOwnProperty("helm");
|
||||||
var start = new Date();
|
|
||||||
var etag = null;
|
var etag = null;
|
||||||
|
|
||||||
if (scale < config.min_scale || scale > config.max_scale) {
|
if (scale < config.min_scale || scale > config.max_scale) {
|
||||||
// Preventing from OOM crashes.
|
res.writeHead(422, {
|
||||||
res.status(422).send("422 Invalid Scale");
|
"Content-Type": "text/plain",
|
||||||
|
"Response-Time": new Date() - start
|
||||||
|
});
|
||||||
|
res.end("422 Invalid Scale");
|
||||||
return;
|
return;
|
||||||
} else if (!helpers.uuid_valid(uuid)) {
|
} 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +65,7 @@ router.get("/:type/:uuid.:ext?", function(req, res) {
|
|||||||
logging.error(uuid + " " + err);
|
logging.error(uuid + " " + err);
|
||||||
}
|
}
|
||||||
etag = hash && hash.substr(0, 32) || "none";
|
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) {
|
if (image) {
|
||||||
var http_status = 200;
|
var http_status = 200;
|
||||||
if (matches) {
|
if (matches) {
|
||||||
@ -63,7 +74,7 @@ router.get("/:type/:uuid.:ext?", function(req, res) {
|
|||||||
http_status = 503;
|
http_status = 503;
|
||||||
}
|
}
|
||||||
logging.log("matches: " + matches);
|
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);
|
logging.log("status: " + http_status);
|
||||||
sendimage(http_status, status, image);
|
sendimage(http_status, status, image);
|
||||||
} else {
|
} else {
|
||||||
@ -119,6 +130,4 @@ router.get("/:type/:uuid.:ext?", function(req, res) {
|
|||||||
});
|
});
|
||||||
res.end(http_status == 304 ? null : image);
|
res.end(http_status == 304 ? null : image);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
@ -2,19 +2,22 @@ var networking = require("../modules/networking");
|
|||||||
var logging = require("../modules/logging");
|
var logging = require("../modules/logging");
|
||||||
var helpers = require("../modules/helpers");
|
var helpers = require("../modules/helpers");
|
||||||
var config = require("../modules/config");
|
var config = require("../modules/config");
|
||||||
var router = require("express").Router();
|
|
||||||
var skins = require("../modules/skins");
|
var skins = require("../modules/skins");
|
||||||
var lwip = require("lwip");
|
var lwip = require("lwip");
|
||||||
|
|
||||||
/* GET skin request. */
|
// GET skin request
|
||||||
router.get("/:uuid.:ext?", function(req, res) {
|
module.exports = function(req, res) {
|
||||||
var uuid = (req.params.uuid || "");
|
|
||||||
var def = req.query.default;
|
|
||||||
var start = new Date();
|
var start = new Date();
|
||||||
|
var uuid = (req.url.pathname.split("/")[2] || "").split(".")[0];
|
||||||
|
var def = req.url.query.default;
|
||||||
var etag = null;
|
var etag = null;
|
||||||
|
|
||||||
if (!helpers.uuid_valid(uuid)) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +31,7 @@ router.get("/:uuid.:ext?", function(req, res) {
|
|||||||
logging.error(uuid + " " + err);
|
logging.error(uuid + " " + err);
|
||||||
}
|
}
|
||||||
etag = hash && hash.substr(0, 32) || "none";
|
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) {
|
if (image) {
|
||||||
var http_status = 200;
|
var http_status = 200;
|
||||||
if (matches) {
|
if (matches) {
|
||||||
@ -36,7 +39,7 @@ router.get("/:uuid.:ext?", function(req, res) {
|
|||||||
} else if (err) {
|
} else if (err) {
|
||||||
http_status = 503;
|
http_status = 503;
|
||||||
}
|
}
|
||||||
logging.debug("Etag: " + req.get("If-None-Match"));
|
logging.debug("Etag: " + req.headers["if-none-match"]);
|
||||||
logging.debug("matches: " + matches);
|
logging.debug("matches: " + matches);
|
||||||
logging.log("status: " + http_status);
|
logging.log("status: " + http_status);
|
||||||
sendimage(http_status, image);
|
sendimage(http_status, image);
|
||||||
@ -81,7 +84,4 @@ router.get("/:uuid.:ext?", function(req, res) {
|
|||||||
});
|
});
|
||||||
res.end(http_status == 304 ? null : image);
|
res.end(http_status == 304 ? null : image);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
86
server.js
86
server.js
@ -1,14 +1,88 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
var config = require("./modules/config");
|
var config = require("./modules/config");
|
||||||
var debug = require("debug")("crafatar");
|
var logging = require("./modules/logging");
|
||||||
var clean = require("./modules/cleaner");
|
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() {
|
function asset_request(req, res) {
|
||||||
debug("Crafatar server listening on port " + server.address().port);
|
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
|
// cleaning worker
|
||||||
setInterval(clean.run, config.cleaning_interval * 1000);
|
setInterval(clean.run, config.cleaning_interval * 1000);
|
||||||
@ -1,8 +0,0 @@
|
|||||||
extends layout
|
|
||||||
|
|
||||||
block content
|
|
||||||
.container.errmsg
|
|
||||||
h1= message
|
|
||||||
h2= error.status
|
|
||||||
if error.stack
|
|
||||||
pre #{error.stack}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user