Spaces:
Sleeping
Sleeping
| const http = require('http'); | |
| const httpProxy = require('http-proxy'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const APP_URL = process.env.MAIN_URL || "http://localhost:3000"; | |
| const UPLOAD_DIR = process.env.UPLOAD_DIRECTORY || "/app/uploads"; | |
| // ------------------------------------------------------------------- | |
| // DÉTECTION DYNAMIQUE DU DOSSIER STATIC (Vérifié pour Hugging Face) | |
| // ------------------------------------------------------------------- | |
| const possiblePaths = [ | |
| path.join(__dirname, 'app', 'static'), | |
| path.join(__dirname, 'static'), | |
| '/app/app/static', | |
| '/app/static' | |
| ]; | |
| let foundPath = ''; | |
| for (const p of possiblePaths) { | |
| try { | |
| if (fs.existsSync(p) && fs.readdirSync(p).includes('terms.html')) { | |
| foundPath = p; | |
| break; | |
| } | |
| } catch (e) { | |
| // Dossier non accessible ou n'existe pas | |
| } | |
| } | |
| const STATIC_DIR = foundPath || possiblePaths[0]; | |
| // ------------------------------------------------------------------- | |
| // MVEMBA SYSTEM CONFIGURATION: PROXY v5.2.1 (Fix Double Declaration) | |
| // ------------------------------------------------------------------- | |
| const proxyOptions = { ws: true, xfwd: true, cookieDomainRewrite: "", secure: false, changeOrigin: true }; | |
| const backendProxy = httpProxy.createProxyServer({ target: 'http://127.0.0.1:4000', ...proxyOptions }); | |
| const frontendProxy = httpProxy.createProxyServer({ target: 'http://127.0.0.1:4200', ...proxyOptions }); | |
| const errorHandler = (err, req, res) => { | |
| console.error(`[ERROR] ${new Date().toISOString()} : ${err.message}`); | |
| if (!res.headersSent) { | |
| res.writeHead(500, { 'Content-Type': 'text/plain' }); | |
| res.end('MVEMBA_SYSTEM: Service temporarily unavailable.'); | |
| } | |
| }; | |
| backendProxy.on('error', errorHandler); | |
| frontendProxy.on('error', errorHandler); | |
| const setCacheHeaders = (res, ext) => { | |
| const oneDay = 24 * 60 * 60; | |
| if (['.mp4', '.webm', '.mov'].includes(ext)) { | |
| res.setHeader('Cache-Control', `public, max-age=${oneDay}`); | |
| } else { | |
| res.setHeader('Cache-Control', 'no-cache'); | |
| } | |
| }; | |
| const serveStaticFile = (res, filePath, contentType = 'text/html') => { | |
| if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) { | |
| res.writeHead(200, { 'Content-Type': contentType }); | |
| fs.createReadStream(filePath).pipe(res); | |
| } else { | |
| console.error(`[404] File not found at: ${filePath}`); | |
| res.writeHead(404); | |
| res.end('File not found'); | |
| } | |
| }; | |
| // ------------------------------------------------------------------- | |
| // HTTP SERVER | |
| // ------------------------------------------------------------------- | |
| const server = http.createServer((req, res) => { | |
| // TikTok Domain Verification | |
| if (req.url === '/tiktokPNM40yS7EF2dkzSNfJclFifdnpalsOMm.txt') { | |
| res.writeHead(200, { 'Content-Type': 'text/plain' }); | |
| res.end('tiktok-developers-site-verification=PNM40yS7EF2dkzSNfJclFifdnpalsOMm'); | |
| return; | |
| } | |
| // Static pages | |
| if (req.url === '/privacy') return serveStaticFile(res, path.join(STATIC_DIR, 'privacy.html')); | |
| if (req.url === '/terms') return serveStaticFile(res, path.join(STATIC_DIR, 'terms.html')); | |
| if (req.url === '/deletion') return serveStaticFile(res, path.join(STATIC_DIR, 'deletion.html')); | |
| req.headers['x-forwarded-proto'] = 'https'; | |
| req.headers['x-forwarded-port'] = '443'; | |
| if (req.headers.host) req.headers['x-forwarded-host'] = req.headers.host; | |
| if (req.url.startsWith('/uploads/')) { | |
| const filePath = path.join(UPLOAD_DIR, decodeURIComponent(req.url.replace('/uploads/', ''))); | |
| if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) { | |
| setCacheHeaders(res, path.extname(filePath)); | |
| fs.createReadStream(filePath).pipe(res); | |
| return; | |
| } else { | |
| res.writeHead(404); | |
| res.end('File not found'); | |
| return; | |
| } | |
| } | |
| if (req.url.startsWith('/api') || req.url.startsWith('/public') || req.url.startsWith('/webhooks') || req.url.startsWith('/v1')) { | |
| if (req.url.startsWith('/api')) req.url = req.url.replace(/^\/api/, '') || '/'; | |
| backendProxy.web(req, res); | |
| } else { | |
| frontendProxy.web(req, res); | |
| } | |
| }); | |
| server.on('upgrade', (req, socket, head) => { | |
| if (req.url.startsWith('/api') || req.url.startsWith('/socket.io')) { | |
| if (req.url.startsWith('/api')) req.url = req.url.replace(/^\/api/, '') || '/'; | |
| backendProxy.ws(req, socket, head); | |
| } else { | |
| frontendProxy.ws(req, socket, head); | |
| } | |
| }); | |
| server.listen(3000, () => { | |
| console.log('------------------------------------------------------------'); | |
| console.log('[STATUS] MVEMBA SECURE PROXY ENGINE v5.2.1 DEPLOYED'); | |
| if (foundPath) { | |
| console.log(`[SUCCESS] Static files matched at: ${STATIC_DIR}`); | |
| } else { | |
| console.log(`[WARNING] Static directory not confirmed, using: ${STATIC_DIR}`); | |
| } | |
| console.log(`[TARGET] ${APP_URL}`); | |
| console.log('------------------------------------------------------------'); | |
| }); |