Реализуйте простой HTTP-сервер на Node.js, который возвращает уникальные одноразовые ссылки (вида /once/abc123
) и сам удаляет их после одного использования или по истечении 60 секунд — в зависимости от того, что наступит раньше.
При повторном доступе к использованной или истекшей ссылке сервер должен возвращать 410 Gone
.
Поведение:
GET-запрос на /create создаёт новую одноразовую ссылку, возвращает её клиенту.
При первом запросе к этой ссылке (/once/<id>) возвращается "✅ Valid link" и она становится недействительной.
Если никто не обратился к ссылке за 60 секунд — она автоматически удаляется, и возвращается "410 Gone" при попытке перейти.
Решение задачи
const http = require('http');
const crypto = require('crypto');
const PORT = 3000;
const links = {}; // { id: { createdAt: timestamp, used: bool } }
function generateId() {
return crypto.randomBytes(6).toString('hex');
}
function cleanupLinks() {
const now =Date.now ();
for (const id in links) {
if (now - links[id].createdAt > 60000 || links[id].used) {
delete links[id];
}
}
}
setInterval(cleanupLinks, 5000); // чистим каждые 5 сек
const server = http.createServer((req, res) => {
const url = new URL(req.url, `http://${req.headers.host }`);
if (url.pathname === '/create') {
const id = generateId();
links[id] = { createdAt:Date.now (), used: false };
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(`/once/${id}`);
return;
}
const match = url.pathname.match(/^\/once\/([a-z0-9]+)$/);
if (match) {
const id = match[1];
const record = links[id];
if (!record || record.used || (Date.now () - record.createdAt > 60000)) {
res.writeHead(410, { 'Content-Type': 'text/plain' });
res.end('🔒 410 Gone: Link expired or used');
} else {
links[id].used = true;
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('✅ Valid link');
}
return;
}
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('404 Not Found');
});
server.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});