static.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. const http = require("http");
  2. const httpServer = require("../src/httpServer");
  3. const jsl = require("svjsl");
  4. const settings = require("../settings");
  5. const fs = require("fs-extra");
  6. const debug = require("../src/verboseLogging");
  7. jsl.unused(http);
  8. const meta = {
  9. "name": "Static",
  10. "desc": "Serves static content like scripts, stylesheets and images",
  11. "unlisted": true,
  12. "noLog": true,
  13. "skipRateLimitCheck": true,
  14. };
  15. /**
  16. * Calls this endpoint
  17. * @param {http.IncomingMessage} req The HTTP server request
  18. * @param {http.ServerResponse} res The HTTP server response
  19. * @param {Array<String>} url URL path array gotten from the URL parser module
  20. * @param {Object} params URL query params gotten from the URL parser module
  21. * @param {String} format The file format to respond with
  22. */
  23. const call = (req, res, url, params, format) => {
  24. jsl.unused([req, params, format]);
  25. let filePath, mimeType, statusCode;
  26. let requestedFile = !jsl.isEmpty(url[1]) ? url[1] : null;
  27. let allowEncoding = true;
  28. let allowRobotIndexing = false; // allow indexing by robots like Googlebot
  29. switch(requestedFile)
  30. {
  31. case "index.css":
  32. filePath = `${settings.documentation.compiledPath}index_injected.css`;
  33. statusCode = 200;
  34. mimeType = "text/css";
  35. break;
  36. case "index.js":
  37. filePath = `${settings.documentation.compiledPath}index_injected.js`;
  38. statusCode = 200;
  39. mimeType = "application/javascript";
  40. break;
  41. case "cascadia-code.ttf":
  42. filePath = `${settings.documentation.dirPath}${settings.documentation.codeFontFileName}`;
  43. statusCode = 200;
  44. allowEncoding = false;
  45. mimeType = "application/x-font-ttf";
  46. break;
  47. case "errorPage.css":
  48. filePath = `${settings.documentation.compiledPath}errorPage_injected.css`;
  49. statusCode = 200;
  50. mimeType = "text/css";
  51. break;
  52. case "errorPage.js":
  53. filePath = `${settings.documentation.compiledPath}errorPage_injected.js`;
  54. statusCode = 200;
  55. mimeType = "application/javascript";
  56. break;
  57. case "rust-icon":
  58. filePath = `${settings.documentation.dirPath}static/external/rust.svg`;
  59. statusCode = 200;
  60. allowEncoding = false;
  61. mimeType = "image/svg+xml";
  62. break;
  63. case "python-icon":
  64. filePath = `${settings.documentation.dirPath}static/external/python.svg`;
  65. statusCode = 200;
  66. allowEncoding = false;
  67. mimeType = "image/svg+xml";
  68. break;
  69. case "nodejs-icon":
  70. filePath = `${settings.documentation.dirPath}static/external/nodejs.svg`;
  71. statusCode = 200;
  72. allowEncoding = false;
  73. mimeType = "image/svg+xml";
  74. break;
  75. case "golang-icon":
  76. filePath = `${settings.documentation.dirPath}static/external/golang.svg`;
  77. statusCode = 200;
  78. allowEncoding = false;
  79. mimeType = "image/svg+xml";
  80. break;
  81. case "dart-icon":
  82. filePath = `${settings.documentation.dirPath}static/external/dart.svg`;
  83. statusCode = 200;
  84. allowEncoding = false;
  85. mimeType = "image/svg+xml";
  86. break;
  87. case "csharp-icon":
  88. filePath = `${settings.documentation.dirPath}static/external/csharp.svg`;
  89. statusCode = 200;
  90. allowEncoding = false;
  91. mimeType = "image/svg+xml";
  92. break;
  93. case "kotlin-icon":
  94. filePath = `${settings.documentation.dirPath}static/external/kotlin.svg`;
  95. statusCode = 200;
  96. allowEncoding = false;
  97. mimeType = "image/svg+xml";
  98. break;
  99. case "java-icon":
  100. filePath = `${settings.documentation.dirPath}static/external/java.svg`;
  101. statusCode = 200;
  102. allowEncoding = false;
  103. mimeType = "image/svg+xml";
  104. break;
  105. case "android-icon":
  106. filePath = `${settings.documentation.dirPath}static/external/android.svg`;
  107. statusCode = 200;
  108. allowEncoding = false;
  109. mimeType = "image/svg+xml";
  110. break;
  111. case "typescript-icon":
  112. filePath = `${settings.documentation.dirPath}static/external/typescript.svg`;
  113. statusCode = 200;
  114. allowEncoding = false;
  115. mimeType = "image/svg+xml";
  116. break;
  117. case "odin-icon":
  118. filePath = `${settings.documentation.dirPath}static/external/odin.svg`;
  119. statusCode = 200;
  120. allowEncoding = false;
  121. mimeType = "image/svg+xml";
  122. break;
  123. default:
  124. requestedFile = "fallback_err_404";
  125. filePath = settings.documentation.error404path;
  126. statusCode = 404;
  127. allowEncoding = false;
  128. mimeType = "text/html";
  129. break;
  130. }
  131. let selectedEncoding = null;
  132. if(allowEncoding)
  133. selectedEncoding = httpServer.getAcceptedEncoding(req);
  134. let fileExtension = "";
  135. if(selectedEncoding != null)
  136. fileExtension = `.${httpServer.getFileExtensionFromEncoding(selectedEncoding)}`;
  137. filePath = `${filePath}${fileExtension}`;
  138. fs.exists(filePath, exists => {
  139. if(exists)
  140. {
  141. if(selectedEncoding == null || selectedEncoding == "identity")
  142. selectedEncoding = "identity"; // identity = no encoding (see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding)
  143. debug("Static", `Serving static content "${requestedFile}" with encoding "${selectedEncoding}"`);
  144. res.setHeader("Content-Encoding", selectedEncoding);
  145. res.setHeader("Cache-Control", "max-age=86400");
  146. if(!allowRobotIndexing)
  147. res.setHeader("X-Robots-Tag", "noindex, noimageindex");
  148. return httpServer.pipeFile(res, filePath, mimeType, statusCode);
  149. }
  150. else
  151. {
  152. debug("Static", `Serving static content "${requestedFile}" without encoding`);
  153. return httpServer.pipeFile(res, filePath, mimeType, statusCode);
  154. }
  155. });
  156. };
  157. module.exports = { call, meta };