123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- #!/usr/bin/env node
- var logging = require("./logging");
- var querystring = require("querystring");
- var response = require("./response");
- var config = require("./config");
- var http = require("http");
- var mime = require("mime");
- var path = require("path");
- var url = require("url");
- var fs = require("fs");
- var server = null;
- var routes = {
- index: require("./routes/index"),
- avatars: require("./routes/avatars"),
- skins: require("./routes/skins"),
- renders: require("./routes/renders"),
- capes: require("./routes/capes")
- };
- // serves assets from lib/public
- function asset_request(req, callback) {
- var filename = path.join(__dirname, "public", req.url.path_list.join("/"));
- fs.exists(filename, function(exists) {
- if (exists) {
- fs.readFile(filename, function(err, data) {
- callback({
- body: data,
- type: mime.lookup(filename),
- err: err
- });
- });
- } else {
- callback({});
- }
- });
- }
- // generates a 12 character random string
- function request_id() {
- return Math.random().toString(36).substring(2, 14);
- }
- // splits a URL path into an Array
- // the path is resolved and decoded
- function path_list(pathname) {
- // remove double and trailing slashes
- pathname = pathname.replace(/\/\/+/g, "/").replace(/(.)\/$/, "$1");
- var list = pathname.split("/");
- list.shift();
- for (var i = 0; i < list.length; i++) {
- // URL decode
- list[i] = querystring.unescape(list[i]);
- }
- return list;
- }
- function requestHandler(req, res) {
- req.url = url.parse(req.url, true);
- req.url.query = req.url.query || {};
- req.url.path_list = path_list(req.url.pathname);
- req.id = request_id();
- req.start = Date.now();
- var local_path = req.url.path_list[0];
- logging.log(req.id, req.method, req.url.href);
- if (req.method === "GET" || req.method === "HEAD") {
- try {
- switch (local_path) {
- case "":
- routes.index(req, function(result) {
- response(req, res, result);
- });
- break;
- case "avatars":
- routes.avatars(req, function(result) {
- response(req, res, result);
- });
- break;
- case "skins":
- routes.skins(req, function(result) {
- response(req, res, result);
- });
- break;
- case "renders":
- routes.renders(req, function(result) {
- response(req, res, result);
- });
- break;
- case "capes":
- routes.capes(req, function(result) {
- response(req, res, result);
- });
- break;
- default:
- asset_request(req, function(result) {
- response(req, res, result);
- });
- }
- } catch(e) {
- var error = JSON.stringify(req.headers) + "\n" + e.stack;
- logging.error(req.id + "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");
- }
- }
- var exp = {};
- exp.boot = function(callback) {
- var port = process.env.PORT || 3000;
- var bind_ip = process.env.BIND || "0.0.0.0";
- logging.log("Server running on http://" + bind_ip + ":" + port + "/");
- server = http.createServer(requestHandler).listen(port, bind_ip, function() {
- if (callback) {
- callback();
- }
- });
- };
- exp.close = function(callback) {
- server.close(function() {
- callback();
- });
- };
- module.exports = exp;
- if (require.main === module) {
- logging.error("Please use 'npm start' or 'www.js'");
- process.exit(1);
- }
|