浏览代码

use response.js for all responses

results in:
1) less duplicated code
2) default response headers being used at all times
3) *all* requests being logged properly

- adds documentation for result.code
- allows using result.code to override HTTP 500
- uses response.js for too-busy, server error, method not allowed
jomo 8 年之前
父节点
当前提交
f1f3ba6709
共有 3 个文件被更改,包括 31 次插入28 次删除
  1. 3 2
      lib/response.js
  2. 7 7
      lib/routes/avatars.js
  3. 21 19
      lib/server.js

+ 3 - 2
lib/response.js

@@ -25,6 +25,7 @@ var silent_errors = ["ETIMEDOUT", "ESOCKETTIMEDOUT", "ECONNRESET", "EHOSTUNREACH
 //  * type:     a valid Content-Type for the body, defaults to "text/plain"
 //  * hash:     image hash, required when body is an image
 //  * err:      a possible Error
+//  * code:     override HTTP response code when status is < 0
 module.exports = function(request, response, result) {
   // These headers are the same for every response
   var headers = {
@@ -32,7 +33,7 @@ module.exports = function(request, response, result) {
     "Cache-Control": "max-age=" + config.caching.browser,
     "Response-Time": Date.now() - request.start,
     "X-Request-ID": request.id,
-    "Access-Control-Allow-Origin": "*"
+    "Access-Control-Allow-Origin": "*",
   };
 
   response.on("close", function() {
@@ -87,7 +88,7 @@ module.exports = function(request, response, result) {
   } else if (result.status === -1) {
     // 500 responses shouldn't be cached
     headers["Cache-Control"] = "private, max-age=0, no-cache";
-    response.writeHead(500, headers);
+    response.writeHead(result.code || 500, headers);
   } else {
     if (result.body) {
       headers.Etag = etag;

+ 7 - 7
lib/routes/avatars.js

@@ -23,13 +23,13 @@ function handle_default(img_status, userId, size, def, req, err, callback) {
       callback({
         status: img_status,
         redirect: newUrl,
-        err: err
+        err: err,
       });
     } else {
       callback({
         status: img_status,
         redirect: def,
-        err: err
+        err: err,
       });
     }
   } else {
@@ -44,7 +44,7 @@ function handle_default(img_status, userId, size, def, req, err, callback) {
         body: image,
         type: "image/png",
         hash: def,
-        err: resize_err || err
+        err: resize_err || err,
       });
     });
   }
@@ -62,7 +62,7 @@ module.exports = function(req, callback) {
     callback({
       status: -2,
       body: "Invalid Path",
-      code: 404
+      code: 404,
     });
     return;
   }
@@ -73,13 +73,13 @@ module.exports = function(req, callback) {
     // https://tools.ietf.org/html/rfc4918#page-78
     callback({
       status: -2,
-      body: "Invalid Size"
+      body: "Invalid Size",
     });
     return;
   } else if (!helpers.id_valid(userId)) {
     callback({
       status: -2,
-      body: "Invalid UserID"
+      body: "Invalid UserID",
     });
     return;
   }
@@ -101,7 +101,7 @@ module.exports = function(req, callback) {
           body: image,
           type: "image/png",
           err: err,
-          hash: hash
+          hash: hash,
         });
       } else {
         handle_default(status, userId, size, def, req, err, callback);

+ 21 - 19
lib/server.js

@@ -16,7 +16,7 @@ var routes = {
   avatars: require("./routes/avatars"),
   skins: require("./routes/skins"),
   renders: require("./routes/renders"),
-  capes: require("./routes/capes")
+  capes: require("./routes/capes"),
 };
 
 // serves assets from lib/public
@@ -28,7 +28,7 @@ function asset_request(req, callback) {
         callback({
           body: data,
           type: mime.lookup(filename),
-          err: err
+          err: err,
         });
       });
     } else {
@@ -70,60 +70,62 @@ function requestHandler(req, res) {
 
   toobusy.maxLag(200);
   if (toobusy() && !process.env.TRAVIS) {
-    res.writeHead(503, {
-      "Content-Type": "text/plain"
+    response(req, res, {
+      status: -1,
+      body: "Server is over capacity :/",
+      err: "Too busy",
+      code: 503,
     });
-    res.end("Server is over capacity :/");
-    logging.error("Too busy:", req.id, 503, Date.now() - req.start + "ms", "(error)");
     return;
   }
 
   if (req.method === "GET" || req.method === "HEAD") {
     try {
       switch (local_path) {
-        case "":
+      case "":
         routes.index(req, function(result) {
           response(req, res, result);
         });
         break;
-        case "avatars":
+      case "avatars":
         routes.avatars(req, function(result) {
           response(req, res, result);
         });
         break;
-        case "skins":
+      case "skins":
         routes.skins(req, function(result) {
           response(req, res, result);
         });
         break;
-        case "renders":
+      case "renders":
         routes.renders(req, function(result) {
           response(req, res, result);
         });
         break;
-        case "capes":
+      case "capes":
         routes.capes(req, function(result) {
           response(req, res, result);
         });
         break;
-        default:
+      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"
+      response(req, res, {
+        status: -1,
+        body: config.server.debug_enabled ? error : "Internal Server Error",
+        err: error,
       });
-      res.end(config.server.debug_enabled ? error : "Internal Server Error");
     }
   } else {
-    res.writeHead(405, {
-      "Content-Type": "text/plain"
+    response(req, res, {
+      status: -2,
+      body: "Method Not Allowed",
+      code: 405,
     });
-    res.end("Method Not Allowed");
   }
 }