const redis = require('redis'); const validUrl = require('valid-url'); const express = require('express'); const app = express(); app.use(express.json()); const port = 3000; //redis client const redisCli = redis.createClient({ host: 'redis', port: 6379 }) redisCli.on("error", console.error); //validation const outpath = ['sym', '', 'manifest.json', 'admin', 'stats', 'api', 'swagger']; const validateKey = key => !outpath.find(path=>path===key); //random key const getKey = length => { let forbidden = false; let key = ''; let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; do{ for (let i = 0; i < length; i++ ) key += characters.charAt(Math.floor(Math.random() * characters.length)); forbidden = !validateKey(key); redisCli.hget('surl;'+key, 'url', (err, obj) => { if(err) console.error(err); if(obj) forbidden = true; }); } while (forbidden); return key; } const keyLength = 4; //validate url const validateUrl = url => validUrl.isUri(url); //express server app.put('/api/v1/key', async (req, res) => { if (req.body.url === undefined){ res.status(400); res.send({status: 400, message: 'url is undefined'}); return } if (!validateUrl(req.body.url)){ res.status(400); res.send({status: 400, message: 'url is invalid'}); return } try{ let key = getKey(keyLength); await redisCli.HMSET('surl;'+key, 'url', req.body.url, 'time', Date.now()); res.status(201); res.send({status: 201, url: req.body.url, key}); }catch (e){ console.error(e); res.status(500); res.send({status: 500, message: 'server error'}); } }); app.get('/:key', (req, res) => { redisCli.HGET('surl;'+req.params.key, 'url', (err, obj) => { if(obj){ res.redirect(302, obj); }else{ res.status(404); res.send({status: 404, message: 'this short url does not exist'}); } }); }); app.listen(port);