var ytdl = require('ytdl-core'); var http = require('http'); var https = require('https'); var fs = require('fs'); var cache = new Map(); async function getUrl(id) { console.debug('getUrl', id); var info = await ytdl.getInfo(id); //console.debug(info); var format = ytdl.chooseFormat(info.formats, {quality: ['22', '18', '17']}); return new URL(format.url); } async function handle(req, res) { console.log(new Date().toISOString(), req.socket.remoteAddress, req.method, req.url, req.headers['range'] || '', `"${req.headers['user-agent']}"`); if (req.method != "GET") { res.writeHead(403); res.end(); return; } if (['/', '/favicon.ico'].includes(req.url)) { res.writeHead(404); res.end(); return; } var id = req.url.match(/[a-zA-Z0-9-_]{11}/)?.[0]; if (!id) { res.writeHead(400); res.end(); return; } if (req.headers['user-agent'].startsWith("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/") && req.headers['user-agent'].endsWith(" Safari/537.36") && req.headers['accept-encoding'] == "identity") { res.writeHead(302, { "Location": `https://www.youtube.com/watch?v=${id}` }); res.end(); return; } var url = await cache.get(id); if (!url) { url = getUrl(id); cache.set(id, url); url = await url; setTimeout(cache.delete.bind(cache), Number(url.searchParams.get('expire') * 1000) - Date.now(), id); } /*res.writeHead(302, { "Location": url.toString() }); res.end();*/ var subres = await new Promise(function repeat(resolve, reject) { var headers = {}; if (req.headers['range']) headers['range'] = req.headers['range']; var subreq = https.get(url, {headers}, subres => { if (subres.headers['location']) { url = subres.headers['location']; cache.set(id, url); subreq.end(); repeat(resolve, reject); } else { resolve(subres); } }); subreq.on("error", reject); }); console.log(subres.statusCode); res.writeHead(subres.statusCode, subres.headers); subres.pipe(res); } https.createServer({ cert: fs.readFileSync("/etc/letsencrypt/live/questify.link/fullchain.pem"), key: fs.readFileSync("/etc/letsencrypt/live/questify.link/privkey.pem") }, function (req, res) { handle(req, res).catch(error => { res.writeHead(500); res.end(error.stack); console.error(error.stack); }); }).listen(443, "45.15.142.149"); /*http.createServer((req, res) => { res.writeHead(301, { Location: `https://${req.headers['host']}${req.url}` }); }).listen(80, "45.15.142.149");*/