var fs = require('fs-extra'); var http = require('http'); var path = require('path'); var swig = require('swig'); var templates = {}; var bot, sql, cfg, lib; module.exports = Websrv; function Websrv(tbot, tsql, tcfg, tlib) { this.bot = bot = tbot; this.sql = sql = tsql; this.cfg = cfg = tcfg; this.lib = lib = tlib; http.createServer((req, res) => { if(cfg.wlip.hasOwnProperty(req.connection.remoteAddress)) { var filePath = '.' + req.url; var url = req.url.split("/")[1]; if(filePath == './') filePath = './index.html'; var extname = String(path.extname(filePath)).toLowerCase(); var contentType = 'text/html'; var mimeTypes = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.png': 'image/png', '.jpg': 'image/jpg', '.gif': 'image/gif', '.mp3': 'audio/mpeg', '.mp4': 'video/mp4', '.webm': 'video/webm', '.css': 'text/css', '.ogg': 'audio/ogg' }; if(filePath == "./index.html") { // mainpage var tpl = swig.compile(templates.index); var data = { items: [] }; sql.query("select `id`,`mime` from `f0ck`.`items` order by `id` desc", (err, rows, fields) => { rows.forEach((e,i,a) => { data.items.push({ "id": e.id, "mime": e.mime }); }); res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(tpl(data), 'utf-8'); }); } else if(Number.isInteger(parseInt(url))) { // itempage var query = "select * from `f0ck`.`items` where `id` = ? limit 1; " // get item + "select `id` from `f0ck`.`items` where `id` = (select min(`id`) from `f0ck`.`items` where `id` > ?); " // get previous item + "select `id` from `f0ck`.`items` where `id` = (select max(`id`) from `f0ck`.`items` where `id` < ?)"; // get next item sql.query(query, [url, url, url], (err, rows, fields) => { var tpl = swig.compile(templates.item); var data = { id: '', username: '', item: '', src: '', dest: '', mime: '', size: '', userchannel: '', usernetwork: '', next: null, prev: null }; if(rows[0].length) { var e = rows[0][0]; switch(e.mime) { case "image/png": case "image/jpeg": case "image/gif": data.item = 'image'; break; case "video/webm": case "video/mp4": data.item = 'video'; break; case "audio/mpeg": case "audio/ogg": data.item = 'audio'; break; } data.id = e.id; data.username = e.username; data.src = e.src; data.dest = e.dest; data.mime = e.mime; data.size = lib.formatSize(e.size); data.userchannel = e.userchannel; data.usernetwork = e.usernetwork; if(rows[1].length) data.next = rows[1][0].id; if(rows[2].length) data.prev = rows[2][0].id; } res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(tpl(data), 'utf-8'); }); } else if(filePath == "./random") { sql.query("select `id` from `f0ck`.`items` order by rand() limit 1", (err, rows, fields) => { res.writeHead(301, { 'Cache-Control': 'no-cache, public', 'Location': '/' + rows[0].id }); res.end(); }); } else if(filePath == "./how") { var tpl = swig.compile(templates.how); res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(tpl(), 'utf-8'); } else if(filePath == "./contact") { var tpl = swig.compile(templates.contact); res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(tpl(), 'utf-8'); } else if(filePath == "./scripts") { var tpl = swig.compile(templates.scripts); res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(tpl(), 'utf-8'); } else if(filePath.match(/^\.\/(b|s|t)\/.*/)) { // file contentType = mimeTypes[extname]; switch(contentType) { case "video/webm": case "video/mp4": case "audio/mpeg": case "audio/ogg": var start = 0; var end = 0; var range = req.headers['range']; var stat = fs.statSync(filePath); if(range != null) { start = parseInt(range.slice(range.indexOf('bytes=')+6, range.indexOf('-'))); end = parseInt(range.slice(range.indexOf('-')+1, range.length)); } if(isNaN(end) || end == 0) end = stat.size-1; if(start > end) return; res.writeHead(206, { 'Connection':'close', 'Content-Type':contentType, 'Content-Length':end - start, 'Content-Range':'bytes '+start+'-'+end+'/'+stat.size, 'Transfer-Encoding':'chunked' }); var stream = fs.createReadStream(filePath, { flags: 'r', start: start, end: end}); stream.pipe(res); break; default: fs.readFile(filePath, (error, content) => { if(error) { if(error.code == 'ENOENT') { res.writeHead(200, { 'Content-Type': contentType }); res.end('404 - f0ck you', 'utf-8'); } else { res.writeHead(500); res.end('Sorry, check with the site admin for error: '+error.code+' ..\n'); res.end(); } } else { res.writeHead(200, { 'Content-Type': contentType, 'Content-Length': content.length, 'Cache-Control': 'max-age=2592000, public' }); res.end(content, 'utf-8'); } }); break; } fs.readFile(filePath, (error, content) => { if(error) { if(error.code == 'ENOENT') { res.writeHead(200, { 'Content-Type': contentType }); res.end('404 - f0ck you', 'utf-8'); } else { res.writeHead(500); res.end('Sorry, check with the site admin for error: '+error.code+' ..\n'); res.end(); } } }); } else { // errorpage res.writeHead(404); res.end('404 - f0ck you', 'utf-8'); } } else { res.writeHead(403); res.end('403 - forbidden'); } }).listen(cfg.webserver.port); } Websrv.prototype.getTpls = () => { templates = { "index": fs.readFileSync("./s/index.tpl.html", "utf-8"), "item": fs.readFileSync("./s/item.tpl.html", "utf-8"), "how": fs.readFileSync("./s/how.tpl.html", "utf-8"), "contact": fs.readFileSync("./s/contact.tpl.html", "utf-8"), "scripts": fs.readFileSync("./s/scripts.tpl.html", "utf-8") }; };