crafatar/lib/response.js
2015-04-20 00:52:08 +02:00

86 lines
2.4 KiB
JavaScript

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);
}
};