const http = require('http'); const https = require('https'); const fs = require('fs'); const path = require('path'); const PORT = 3000; const CACHE_DIR = path.join(__dirname, '.cache'); const CACHE_EXPIRY = 30 * 24 * 60 * 60 * 1000; // 30 days in milliseconds const CLEAN_INTERVAL = 24 * 60 * 60 * 1000; // 1 day in milliseconds // Ensure the cache directory exists if (!fs.existsSync(CACHE_DIR)) { fs.mkdirSync(CACHE_DIR); } // Helper function to get cache file path const getCacheFilePath = (requestUrl) => { const sanitizedUrl = requestUrl.replace(/[^a-z0-9]/gi, '_').toLowerCase(); return path.join(CACHE_DIR, sanitizedUrl); }; // Function to clean up expired cache files const cleanUpCache = () => { fs.readdir(CACHE_DIR, (err, files) => { if (err) { console.error('Error reading cache directory:', err); return; } const now = Date.now(); files.forEach(file => { const filePath = path.join(CACHE_DIR, file); fs.stat(filePath, (err, stats) => { if (err) { console.error('Error getting file stats:', err); return; } if (now - stats.mtimeMs > CACHE_EXPIRY) { fs.unlink(filePath, (err) => { if (err) { console.error('Error deleting file:', err); } }); } }); }); }); }; // Schedule cache clean-up at regular intervals setInterval(cleanUpCache, CLEAN_INTERVAL); // Function to handle proxying and caching const handleRequest = (req, res) => { const targetUrl = `https://oss.x-php.com${req.url}`; const cacheFilePath = getCacheFilePath(targetUrl); // Check if the cache file exists and is still valid if (fs.existsSync(cacheFilePath)) { const stats = fs.statSync(cacheFilePath); const now = Date.now(); if (now - stats.mtimeMs < CACHE_EXPIRY) { // Serve from cache const cachedData = JSON.parse(fs.readFileSync(cacheFilePath, 'utf8')); res.writeHead(cachedData.statusCode, cachedData.headers); res.end(Buffer.from(cachedData.body, 'base64')); return; } } // Fetch from the target URL https.get(targetUrl, (proxyRes) => { let data = []; proxyRes.on('data', (chunk) => { data.push(chunk); }); proxyRes.on('end', () => { const responseData = Buffer.concat(data); // Save the response to cache const cacheData = { statusCode: proxyRes.statusCode, headers: proxyRes.headers, body: responseData.toString('base64') }; fs.writeFileSync(cacheFilePath, JSON.stringify(cacheData)); // Serve the response res.writeHead(proxyRes.statusCode, proxyRes.headers); res.end(responseData); }); }).on('error', (err) => { res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('Error fetching the resource'); }); }; // Create an HTTP server const server = http.createServer(handleRequest); server.listen(PORT, () => { console.log(`Proxy server running at http://localhost:${PORT}`); });