const http = require('node:http'); const fs = require('node:fs'); const path = require('node:path'); const crypto = require('node:crypto'); const PORT = process.env.PORT || 3000; const DATA_DIR = path.join(__dirname, 'data'); const MAX_SIZE_BYTES = 10 * 1024 * 1024; // 10MB if (!fs.existsSync(DATA_DIR)) fs.mkdirSync(DATA_DIR); const sendJSON = (res, status, data) => { res.writeHead(status, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(data)); }; const server = http.createServer((req, res) => { const { method, url } = req; // Serve Frontend if (method === 'GET' && (url === '/' || url.startsWith('/view'))) { res.writeHead(200, { 'Content-Type': 'text/html' }); fs.createReadStream(path.join(__dirname, 'index.html')).pipe(res); return; } // CREATE Secret (Public POST) if (method === 'POST' && url === '/api/secret') { const contentLength = parseInt(req.headers['content-length'], 10); if (contentLength > MAX_SIZE_BYTES) { res.writeHead(413); return res.end('Too large'); } const id = crypto.randomUUID(); // Unique and Random URL component const filePath = path.join(DATA_DIR, id); const writeStream = fs.createWriteStream(filePath); req.pipe(writeStream); req.on('end', () => sendJSON(res, 201, { id })); writeStream.on('error', () => { res.writeHead(500); res.end(); }); return; } // READ & BURN Secret if (method === 'GET' && url.startsWith('/api/secret/')) { const id = url.split('/').pop(); if (!/^[a-z0-9-]+$/i.test(id)) { res.writeHead(400); return res.end(); } const filePath = path.join(DATA_DIR, id); if (!fs.existsSync(filePath)) { res.writeHead(404); return res.end('Burned or Not Found'); } const readStream = fs.createReadStream(filePath); res.writeHead(200, { 'Content-Type': 'application/octet-stream' }); readStream.pipe(res); // Delete immediately after stream ends readStream.on('end', () => { fs.unlink(filePath, (err) => { if (err) console.error("Burn failed", err); }); }); return; } res.writeHead(404); res.end(); }); server.listen(PORT, () => console.log(`Public Burn Server: http://localhost:${PORT}`));