Advertisement
dev017

servidor js

Jun 7th, 2025 (edited)
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 4.65 KB | Cybersecurity | 0 0
  1. const http = require('http');
  2. const fs = require('fs').promises;
  3. const path = require('path');
  4. const url = require('url');
  5. const querystring = require('querystring');
  6. const { performance } = require('perf_hooks');
  7.  
  8. const HOST = 'localhost';
  9. const PORT = 8080;
  10. const STATIC_DIR = path.join(__dirname, 'public');
  11. const MIME_TYPES = {
  12.   '.html': 'text/html; charset=utf-8',
  13.   '.js': 'application/javascript',
  14.   '.css': 'text/css',
  15.   '.json': 'application/json',
  16.   '.png': 'image/png',
  17.   '.jpg': 'image/jpeg',
  18.   '.gif': 'image/gif',
  19.   '.svg': 'image/svg+xml'
  20. };
  21.  
  22. const cache = new Map();
  23. const requestQueue = [];
  24. let activeRequests = 0;
  25. const MAX_CONCURRENT = 100;
  26. const CACHE_TTL = 3600000;
  27.  
  28. const logger = {
  29.   log: (req, status, time) => {
  30.     const timestamp = new Date().toISOString();
  31.     const { method, url } = req;
  32.     console.log(`${timestamp} ${method} ${url} ${status} ${time.toFixed(2)}ms`);
  33.   },
  34.   error: (err) => console.error(`[${new Date().toISOString()}] ERROR: ${err.stack}`)
  35. };
  36.  
  37. const rateLimit = new Map();
  38. const RATE_LIMIT = 100;
  39. const RATE_WINDOW = 60000;
  40.  
  41. const checkRateLimit = (ip) => {
  42.   const now = Date.now();
  43.   const record = rateLimit.get(ip) || { count: 0, start: now };
  44.  
  45.   if (now - record.start > RATE_WINDOW) {
  46.     record.count = 0;
  47.     record.start = now;
  48.   }
  49.  
  50.   record.count++;
  51.   rateLimit.set(ip, record);
  52.  
  53.   return record.count <= RATE_LIMIT;
  54. };
  55.  
  56. const handleStaticFile = async (pathname, res) => {
  57.   const filePath = path.join(STATIC_DIR, pathname === '/' ? 'index.html' : pathname);
  58.  
  59.   if (cache.has(filePath)) {
  60.     const { content, mime, timestamp } = cache.get(filePath);
  61.     if (Date.now() - timestamp < CACHE_TTL) {
  62.       res.writeHead(200, {
  63.         'Content-Type': mime,
  64.         'Cache-Control': 'public, max-age=3600'
  65.       });
  66.       res.end(content);
  67.       return true;
  68.     }
  69.     cache.delete(filePath);
  70.   }
  71.  
  72.   try {
  73.     const content = await fs.readFile(filePath);
  74.     const ext = path.extname(filePath).toLowerCase();
  75.     const mime = MIME_TYPES[ext] || 'application/octet-stream';
  76.    
  77.     cache.set(filePath, {
  78.       content,
  79.       mime,
  80.       timestamp: Date.now()
  81.     });
  82.  
  83.     res.writeHead(200, {
  84.       'Content-Type': mime,
  85.       'Cache-Control': 'public, max-age=3600'
  86.     });
  87.     res.end(content);
  88.     return true;
  89.   } catch (err) {
  90.     return false;
  91.   }
  92. };
  93.  
  94. const handleApiRequest = async (req, res, pathname, query) => {
  95.   if (pathname.startsWith('/api/')) {
  96.     res.writeHead(200, { 'Content-Type': 'application/json' });
  97.     res.end(JSON.stringify({
  98.       status: 'ok',
  99.       path: pathname,
  100.       query,
  101.       timestamp: Date.now()
  102.     }));
  103.     return true;
  104.   }
  105.   return false;
  106. };
  107.  
  108. const queueRequest = (req, res) => {
  109.   return new Promise((resolve) => {
  110.     requestQueue.push({ req, res, resolve });
  111.     processQueue();
  112.   });
  113. };
  114.  
  115. const processQueue = () => {
  116.   if (activeRequests >= MAX_CONCURRENT || !requestQueue.length) return;
  117.  
  118.   activeRequests++;
  119.   const { req, res, resolve } = requestQueue.shift();
  120.  
  121.   handleRequest(req, res).finally(() => {
  122.     activeRequests--;
  123.     resolve();
  124.     processQueue();
  125.   });
  126. };
  127.  
  128. const handleRequest = async (req, res) => {
  129.   const startTime = performance.now();
  130.   const { pathname, query } = url.parse(req.url, true);
  131.   const ip = req.socket.remoteAddress;
  132.  
  133.   try {
  134.     if (!checkRateLimit(ip)) {
  135.       res.writeHead(429, { 'Content-Type': 'text/plain' });
  136.       res.end('Rate limit exceeded');
  137.       logger.log(req, 429, performance.now() - startTime);
  138.       return;
  139.     }
  140.  
  141.     res.setHeader('X-Powered-By', 'Node.js');
  142.     res.setHeader('X-Content-Type-Options', 'nosniff');
  143.     res.setHeader('X-Frame-Options', 'DENY');
  144.  
  145.     if (await handleApiRequest(req, res, pathname, query)) {
  146.       logger.log(req, 200, performance.now() - startTime);
  147.       return;
  148.     }
  149.  
  150.     if (await handleStaticFile(pathname, res)) {
  151.       logger.log(req, 200, performance.now() - startTime);
  152.       return;
  153.     }
  154.  
  155.     res.writeHead(404, { 'Content-Type': 'text/plain' });
  156.     res.end('Not Found');
  157.     logger.log(req, 404, performance.now() - startTime);
  158.   } catch (err) {
  159.     res.writeHead(500, { 'Content-Type': 'text/plain' });
  160.     res.end('Internal Server Error');
  161.     logger.error(err);
  162.     logger.log(req, 500, performance.now() - startTime);
  163.   }
  164. };
  165.  
  166. const server = http.createServer((req, res) => {
  167.   queueRequest(req, res);
  168. });
  169.  
  170. server.on('error', logger.error);
  171.  
  172. server.listen(PORT, HOST, () => {
  173.   console.log(`Server running at http://${HOST}:${PORT}`);
  174. });
  175.  
  176. process.on('SIGTERM', () => {
  177.   server.close(() => {
  178.     console.log('Server terminated');
  179.     process.exit(0);
  180.   });
  181. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement