renders.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. var logging = require("../modules/logging");
  2. var helpers = require("../modules/helpers");
  3. var config = require("../modules/config");
  4. var skins = require("../modules/skins");
  5. var renders = require("../modules/renders");
  6. var fs = require("fs");
  7. var human_status = {
  8. 0: "none",
  9. 1: "cached",
  10. 2: "downloaded",
  11. 3: "checked",
  12. "-1": "error"
  13. };
  14. // valid types: head, body
  15. // helmet is query param
  16. // TODO: The Type logic should be two separate GET functions once response methods are extracted
  17. // GET render request
  18. module.exports = function(req, res) {
  19. var start = new Date();
  20. var raw_type = (req.url.path_list[2] || "");
  21. // validate type
  22. if (raw_type != "body" && raw_type != "head") {
  23. res.writeHead(422, {
  24. "Content-Type": "text/plain",
  25. "Response-Time": new Date() - start
  26. });
  27. res.end("Invalid Render Type");
  28. return;
  29. }
  30. var body = raw_type == "body";
  31. var uuid = (req.url.path_list[3] || "").split(".")[0];
  32. var def = req.url.query.default;
  33. var scale = parseInt(req.url.query.scale) || config.default_scale;
  34. var helm = req.url.query.hasOwnProperty("helm");
  35. var etag = null;
  36. if (scale < config.min_scale || scale > config.max_scale) {
  37. res.writeHead(422, {
  38. "Content-Type": "text/plain",
  39. "Response-Time": new Date() - start
  40. });
  41. res.end("422 Invalid Scale");
  42. return;
  43. } else if (!helpers.uuid_valid(uuid)) {
  44. res.writeHead(422, {
  45. "Content-Type": "text/plain",
  46. "Response-Time": new Date() - start
  47. });
  48. res.end("422 Invalid UUID");
  49. return;
  50. }
  51. // strip dashes
  52. uuid = uuid.replace(/-/g, "");
  53. try {
  54. helpers.get_render(uuid, scale, helm, body, function(err, status, hash, image) {
  55. logging.log(uuid + " - " + human_status[status]);
  56. if (err) {
  57. logging.error(uuid + " " + err);
  58. }
  59. etag = hash && hash.substr(0, 32) || "none";
  60. var matches = req.headers["if-none-match"] == '"' + etag + '"';
  61. if (image) {
  62. var http_status = 200;
  63. if (matches) {
  64. http_status = 304;
  65. } else if (err) {
  66. http_status = 503;
  67. }
  68. logging.debug(uuid + " etag: " + req.headers["if-none-match"]);
  69. logging.debug(uuid + " matches: " + matches);
  70. sendimage(http_status, status, image, uuid);
  71. } else {
  72. logging.log(uuid + " image not found, using default.");
  73. handle_default(404, status, uuid);
  74. }
  75. });
  76. } catch(e) {
  77. logging.error(uuid + " error: " + e);
  78. handle_default(500, status, uuid);
  79. }
  80. // default alex/steve images can be rendered, but
  81. // custom images will not be
  82. function handle_default(http_status, img_status, uuid) {
  83. if (def && def != "steve" && def != "alex") {
  84. logging.log(uuid + " status: 301");
  85. res.writeHead(301, {
  86. "Cache-Control": "max-age=" + config.browser_cache_time + ", public",
  87. "Response-Time": new Date() - start,
  88. "X-Storage-Type": human_status[img_status],
  89. "Access-Control-Allow-Origin": "*",
  90. "Location": def
  91. });
  92. res.end();
  93. } else {
  94. def = def || skins.default_skin(uuid);
  95. fs.readFile("public/images/" + def + "_skin.png", function (err, buf) {
  96. if (err) {
  97. // errored while loading the default image, continuing with null image
  98. logging.error(uuid + "error loading default render image: " + err);
  99. }
  100. // we render the default skins, but not custom images
  101. renders.draw_model(uuid, buf, scale, helm, body, function(err, def_img) {
  102. if (err) {
  103. logging.log(uuid + "error while rendering default image: " + err);
  104. }
  105. sendimage(http_status, img_status, def_img, uuid);
  106. });
  107. });
  108. }
  109. }
  110. function sendimage(http_status, img_status, image, uuid) {
  111. logging.log(uuid + " status: " + http_status);
  112. res.writeHead(http_status, {
  113. "Content-Type": "image/png",
  114. "Cache-Control": "max-age=" + config.browser_cache_time + ", public",
  115. "Response-Time": new Date() - start,
  116. "X-Storage-Type": human_status[img_status],
  117. "Access-Control-Allow-Origin": "*",
  118. "Etag": '"' + etag + '"'
  119. });
  120. res.end(http_status == 304 ? null : image);
  121. }
  122. };