app.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import express from 'ultimate-express';
  2. import { LRUCache } from 'lru-cache';
  3. import cluster, { isWorker } from 'node:cluster';
  4. import { maxQuery, maxRows } from './config.js';
  5. import fjs from 'fast-json-stringify';
  6. const { DATABASE } = process.env;
  7. const db = DATABASE ? await import(`./database/${DATABASE}.js`) : null;
  8. const jsonSerializer = fjs({
  9. type: 'object',
  10. properties: {
  11. message: {
  12. type: 'string',
  13. format: 'unsafe',
  14. }
  15. }
  16. });
  17. const generateRandomNumber = () => Math.floor(Math.random() * maxRows) + 1;
  18. const parseQueries = (i) => Math.min(parseInt(i) || 1, maxQuery);
  19. const escapeHTMLRules = { '&': '&#38;', '<': '&#60;', '>': '&#62;', '"': '&#34;', "'": '&#39;', '/': '&#47;' };
  20. const unsafeHTMLMatcher = /[&<>"'\/]/g;
  21. const escapeHTMLCode = (text) => unsafeHTMLMatcher.test(text) ? text.replace(unsafeHTMLMatcher, function (m) { return escapeHTMLRules[m] || m; }) : text;
  22. const cache = new LRUCache({
  23. max: maxRows
  24. });
  25. const app = express();
  26. app.set("etag", false);
  27. app.set("x-powered-by", false);
  28. app.get('/plaintext', (req, res) => {
  29. res.setHeader('Server', 'UltimateExpress');
  30. res.setHeader('Content-Type', 'text/plain');
  31. res.end('Hello, World!');
  32. });
  33. app.get('/json', (req, res) => {
  34. res.setHeader('Server', 'UltimateExpress');
  35. res.setHeader('Content-Type', 'application/json');
  36. res.end(jsonSerializer({ message: "Hello, World!" }));
  37. });
  38. if (db) {
  39. app.get('/db', async (req, res) => {
  40. res.setHeader('Server', 'UltimateExpress');
  41. try {
  42. const world = await db.find(generateRandomNumber());
  43. res.json(world);
  44. } catch (error) {
  45. throw error;
  46. }
  47. });
  48. app.get('/queries', async (req, res) => {
  49. res.setHeader('Server', 'UltimateExpress');
  50. try {
  51. const queries = parseQueries(req.query.queries);
  52. const worldPromises = new Array(queries);
  53. for (let i = 0; i < queries; i++) {
  54. worldPromises[i] = db.find(generateRandomNumber());
  55. }
  56. const worlds = await Promise.all(worldPromises);
  57. res.json(worlds);
  58. } catch (error) {
  59. throw error;
  60. }
  61. })
  62. app.get('/updates', async (req, res) => {
  63. res.setHeader('Server', 'UltimateExpress');
  64. try {
  65. const queries = parseQueries(req.query.queries);
  66. const worldPromises = new Array(queries);
  67. for (let i = 0; i < queries; i++) {
  68. worldPromises[i] = db.find(generateRandomNumber());
  69. }
  70. const worlds = await Promise.all(worldPromises);
  71. for (let i = 0; i < queries; i++) {
  72. worlds[i].randomNumber = generateRandomNumber();
  73. }
  74. await db.bulkUpdate(worlds);
  75. res.json(worlds);
  76. } catch (error) {
  77. throw error;
  78. }
  79. })
  80. app.get('/fortunes', async (req, res) => {
  81. res.setHeader('Server', 'UltimateExpress');
  82. try {
  83. const fortunes = await db.fortunes()
  84. fortunes.push({ id: 0, message: 'Additional fortune added at request time.' });
  85. fortunes.sort((a, b) => (a.message < b.message) ? -1 : 1);
  86. const n = fortunes.length
  87. let i = 0, html = ''
  88. for (; i < n; i++) html += `<tr><td>${fortunes[i].id}</td><td>${escapeHTMLCode(fortunes[i].message)}</td></tr>`
  89. res
  90. .header('Content-Type', 'text/html; charset=utf-8')
  91. .end(`<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>${html}</table></body></html>`);
  92. } catch (error) {
  93. throw error;
  94. }
  95. })
  96. let isCachePopulated = false
  97. app.get('/cached-worlds', async (req, res) => {
  98. res.setHeader('Server', 'UltimateExpress');
  99. try {
  100. if (!isCachePopulated) {
  101. const worlds = await db.getAllWorlds();
  102. for (let i = 0; i < worlds.length; i++) {
  103. cache.set(worlds[i].id, worlds[i]);
  104. }
  105. isCachePopulated = true;
  106. }
  107. const count = parseQueries(req.query.count);
  108. const worlds = new Array(count);
  109. for (let i = 0; i < count; i++) {
  110. worlds[i] = cache.get(generateRandomNumber());
  111. }
  112. res.json(worlds);
  113. } catch (error) {
  114. throw error;
  115. }
  116. });
  117. }
  118. app.listen(8080, () => {
  119. console.log(`${isWorker ? `${cluster.worker.id}: ` : ''}Successfully bound to http://0.0.0.0:8080`);
  120. });