76 lines
2.4 KiB
JavaScript
76 lines
2.4 KiB
JavaScript
const http = require('http');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const ROOT = __dirname;
|
|
const DATA_FILE = path.join(ROOT, 'data.json');
|
|
const PORT = Number(process.env.PORT) || 8080;
|
|
|
|
const TYPES = {
|
|
'.html': 'text/html; charset=utf-8',
|
|
'.js': 'text/javascript; charset=utf-8',
|
|
'.json': 'application/json; charset=utf-8',
|
|
'.css': 'text/css; charset=utf-8',
|
|
'.svg': 'image/svg+xml',
|
|
};
|
|
|
|
function send(res, status, body, type = 'text/plain; charset=utf-8') {
|
|
res.writeHead(status, { 'Content-Type': type });
|
|
res.end(body);
|
|
}
|
|
|
|
function readBody(req) {
|
|
return new Promise((resolve, reject) => {
|
|
let body = '';
|
|
req.on('data', (chunk) => {
|
|
body += chunk;
|
|
if (body.length > 2_000_000) {
|
|
req.destroy();
|
|
reject(new Error('Request body too large'));
|
|
}
|
|
});
|
|
req.on('end', () => resolve(body));
|
|
req.on('error', reject);
|
|
});
|
|
}
|
|
|
|
const server = http.createServer(async (req, res) => {
|
|
try {
|
|
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
|
|
if (req.method === 'POST' && url.pathname === '/api/data') {
|
|
const body = await readBody(req);
|
|
const data = JSON.parse(body);
|
|
|
|
if (!data || typeof data !== 'object' || !data.surcharges || !Array.isArray(data.history)) {
|
|
return send(res, 400, JSON.stringify({ error: 'Invalid data format' }), 'application/json; charset=utf-8');
|
|
}
|
|
|
|
fs.writeFileSync(DATA_FILE, JSON.stringify(data, null, 2) + '\n');
|
|
return send(res, 200, JSON.stringify({ ok: true }), 'application/json; charset=utf-8');
|
|
}
|
|
|
|
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
return send(res, 405, 'Method not allowed');
|
|
}
|
|
|
|
const requestPath = url.pathname === '/' ? '/index.html' : url.pathname;
|
|
const filePath = path.normalize(path.join(ROOT, requestPath));
|
|
|
|
if (!filePath.startsWith(ROOT)) return send(res, 403, 'Forbidden');
|
|
if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) return send(res, 404, 'Not found');
|
|
|
|
const type = TYPES[path.extname(filePath)] || 'application/octet-stream';
|
|
res.writeHead(200, { 'Content-Type': type });
|
|
if (req.method === 'HEAD') return res.end();
|
|
fs.createReadStream(filePath).pipe(res);
|
|
} catch (err) {
|
|
console.error(err);
|
|
send(res, 500, JSON.stringify({ error: err.message }), 'application/json; charset=utf-8');
|
|
}
|
|
});
|
|
|
|
server.listen(PORT, () => {
|
|
console.log(`AZ INTEC Index läuft auf http://localhost:${PORT}`);
|
|
});
|