avatars.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. var networking = require('../modules/networking');
  2. var logging = require('../modules/logging');
  3. var helpers = require('../modules/helpers');
  4. var router = require('express').Router();
  5. var config = require('../modules/config');
  6. var skins = require('../modules/skins');
  7. var human_status = {
  8. 0: "none",
  9. 1: "cached",
  10. 2: "downloaded",
  11. 3: "checked",
  12. "-1": "error"
  13. };
  14. router.get('/skins/:uuid.:ext?', function(req, res) {
  15. var uuid = req.params.uuid;
  16. var start = new Date();
  17. if (!helpers.uuid_valid(uuid)) {
  18. res.status(422).send("422 Invalid UUID");
  19. return;
  20. }
  21. // strip dashes
  22. uuid = uuid.replace(/-/g, "");
  23. try {
  24. helpers.get_image_hash(uuid, function(err, status, hash) {
  25. if (hash) {
  26. res.writeHead(301, {
  27. 'Location': "http://textures.minecraft.net/texture/" + hash,
  28. 'Cache-Control': 'max-age=' + config.browser_cache_time + ', public',
  29. 'Response-Time': new Date() - start,
  30. 'X-Storage-Type': human_status[status],
  31. 'Access-Control-Allow-Origin': "*",
  32. 'Origin': 'https://crafatar.com'
  33. });
  34. res.end();
  35. } else if (!err) {
  36. res.writeHead(404, {
  37. 'Cache-Control': 'max-age=' + config.browser_cache_time + ', public',
  38. 'Response-Time': new Date() - start,
  39. 'X-Storage-Type': human_status[status],
  40. 'Access-Control-Allow-Origin': "*"
  41. });
  42. res.end("404 Not found");
  43. } else {
  44. res.status(500).send("500 Internal server error");
  45. }
  46. });
  47. } catch(e) {
  48. logging.error("Error!");
  49. logging.error(e);
  50. res.status(500).send("500 Internal server error");
  51. }
  52. });
  53. /* GET avatar request. */
  54. router.get('/avatars/:uuid.:ext?', function(req, res) {
  55. var uuid = req.params.uuid;
  56. var size = req.query.size || config.default_size;
  57. var def = req.query.default;
  58. var helm = req.query.hasOwnProperty('helm');
  59. var start = new Date();
  60. // Prevent app from crashing/freezing
  61. if (size < config.min_size || size > config.max_size) {
  62. // "Unprocessable Entity", valid request, but semantically erroneous:
  63. // https://tools.ietf.org/html/rfc4918#page-78
  64. res.status(422).send("422 Invalid size");
  65. return;
  66. } else if (!helpers.uuid_valid(uuid)) {
  67. res.status(422).send("422 Invalid UUID");
  68. return;
  69. }
  70. // strip dashes
  71. uuid = uuid.replace(/-/g, "");
  72. try {
  73. helpers.get_avatar(uuid, helm, size, function(err, status, image) {
  74. logging.log(uuid + " - " + human_status[status]);
  75. if (err) {
  76. logging.error(err);
  77. }
  78. if (image) {
  79. sendimage(err ? 503 : 200, status, image);
  80. } else {
  81. handle_default(404, status);
  82. }
  83. });
  84. } catch(e) {
  85. logging.error("Error!");
  86. logging.error(e);
  87. handle_default(500, status);
  88. }
  89. function handle_default(http_status, img_status) {
  90. if (def && def != "steve" && def != "alex") {
  91. res.writeHead(301, {
  92. 'Cache-Control': 'max-age=' + config.browser_cache_time + ', public',
  93. 'Response-Time': new Date() - start,
  94. 'X-Storage-Type': human_status[img_status],
  95. 'Location': def,
  96. 'Access-Control-Allow-Origin': "*"
  97. });
  98. res.end();
  99. } else {
  100. def = def || skins.default_skin(uuid);
  101. skins.resize_img("public/images/" + def + ".png", size, function(err, image) {
  102. sendimage(http_status, img_status, image);
  103. });
  104. }
  105. }
  106. function sendimage(http_status, img_status, image) {
  107. res.writeHead(http_status, {
  108. 'Content-Type': 'image/png',
  109. 'Cache-Control': 'max-age=' + config.browser_cache_time + ', public',
  110. 'Response-Time': new Date() - start,
  111. 'X-Storage-Type': human_status[img_status],
  112. 'Access-Control-Allow-Origin': "*"
  113. });
  114. res.end(image);
  115. }
  116. });
  117. module.exports = router;