var logging = require("./logging"); var config = require("./config"); var crc = require("crc").crc32; var human_status = { "-2": "user error", "-1": "server error", 0: "none", 1: "cached", 2: "downloaded", 3: "checked", }; // handles HTTP responses // +request+ a http.IncomingMessage // +response+ a http.ServerResponse // +result+ an object with: // * status: see human_status, required // * redirect: redirect URL // * body: file or message, required unless redirect is present or status is < 0 // * 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 module.exports = function(request, response, result) { response.on("close", function() { logging.warn(request.id, "Connection closed"); }); response.on("finish", function() { logging.log(request.id, response.statusCode, "(" + human_status[result.status] + ")"); }); response.on("error", function(err) { logging.error(request.id, err); }); // These headers are the same for every response var headers = { "Content-Type": result.type || "text/plain", "Cache-Control": "max-age=" + config.browser_cache_time + ", public", "Response-Time": Date.now() - request.start, "X-Storage-Type": human_status[result.status], "X-Request-ID": request.id, "Access-Control-Allow-Origin": "*" }; if (result.err) { logging.error(result.err); } if (result.body) { // use Mojang's image hash if available // use crc32 as a hash function otherwise var etag = result.body && result.hash && result.hash.substr(0, 10) || crc(result.body); headers.Etag = "\"" + etag + "\""; // handle etag caching var incoming_etag = request.headers["if-none-match"]; if (incoming_etag && incoming_etag === headers.Etag) { logging.debug("Etag matches"); response.writeHead(304, headers); response.end(); return; } } if (result.redirect) { headers.Location = result.redirect; response.writeHead(307, headers); response.end(); return; } if (result.status === -2) { response.writeHead(422, headers); response.end(result.body); } else if (result.status === -1) { response.writeHead(500, headers); response.end(result.body); } else { response.writeHead(200, headers); response.end(result.body); } };