diff --git a/src/createServer.js b/src/createServer.js index 1cf1dda..6324144 100644 --- a/src/createServer.js +++ b/src/createServer.js @@ -1,8 +1,102 @@ 'use strict'; +const http = require('http'); +const fs = require('fs/promises'); +const path = require('path'); + +function readBody(req) { + return new Promise((resolve, reject) => { + let body = ''; + + req.on('data', (chunk) => { + body += chunk.toString(); + + if (body.length > 1e6) { + req.destroy(); + reject(new Error('Body too large')); + } + }); + + req.on('end', () => resolve(body)); + req.on('error', reject); + }); +} + +function parseExpense(req, body) { + const type = req.headers['content-type'] || ''; + + if (type.includes('application/json')) { + const data = JSON.parse(body || '{}'); + + return { + date: data.date || '', + title: data.title || '', + amount: data.amount || '', + }; + } + + const params = new URLSearchParams(body); + + return { + date: params.get('date') || '', + title: params.get('title') || '', + amount: params.get('amount') || '', + }; +} + +function isValidExpense(expense) { + return expense.date && expense.title && expense.amount; +} + function createServer() { - /* Write your code here */ - // Return instance of http.Server class + return http.createServer(async (req, res) => { + if (req.method === 'GET' && req.url === '/') { + const htmlPath = path.join(__dirname, '..', 'index.html'); + + const html = await fs.readFile(htmlPath, 'utf-8'); + + res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); + res.end(html); + + return; + } + + if ( + req.method === 'POST' && + (req.url === '/add-expense' || req.url === '/submit-expense') + ) { + try { + const body = await readBody(req); + const expense = parseExpense(req, body); + + if (!isValidExpense(expense)) { + res.writeHead(400, { 'Content-Type': 'text/plain' }); + res.end('Bad request'); + + return; + } + + const dbDir = path.join(__dirname, '..', 'db'); + const filePath = path.join(dbDir, 'expense.json'); + + await fs.mkdir(dbDir, { recursive: true }); + await fs.writeFile(filePath, JSON.stringify(expense, null, 2), 'utf-8'); + + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify(expense)); + + return; + } catch { + res.writeHead(500); + res.end(); + + return; + } + } + + res.writeHead(404, { 'Content-Type': 'text/plain' }); + res.end('Not found'); + }); } module.exports = { diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..547518e --- /dev/null +++ b/src/index.html @@ -0,0 +1,17 @@ + + +
+ +