From 9f3b1354544e6e473ceb111915fdc234dd178a26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=92=8B=E5=B0=8F=E9=99=8C?= Date: Tue, 15 Oct 2024 18:54:26 +0800 Subject: [PATCH] 1111 --- index.js | 327 +-------------------------------------------------- obfuscate.js | 20 ++++ package.json | 5 + source.js | 326 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 352 insertions(+), 326 deletions(-) create mode 100644 obfuscate.js create mode 100644 package.json create mode 100644 source.js diff --git a/index.js b/index.js index 3544c98..4fd9849 100644 --- a/index.js +++ b/index.js @@ -1,326 +1 @@ -const http = require('http'); -const https = require('https'); -const url = require('url'); -const querystring = require('querystring'); -const fs = require('fs'); -const pathModule = require('path'); -const crypto = require('crypto'); - -const requestTimeout = 10000; // 10 seconds -const cacheDir = pathModule.join(__dirname, '.cache'); -const args = process.argv.slice(2); -const pathIndex = {}; - -// 增加访问计数器 -const viewsInfo = { - // 请求次数 - request: 0, - // 缓存命中次数 - cacheHit: 0, - // API调用次数 - apiCall: 0, - // 缓存调用次数 - cacheCall: 0, -}; - -// 默认端口号和 API 地址 -let port = 9001; -let apiEndpoint = 'https://oss.x-php.com/alist/link'; - -// 解析命令行参数 -args.forEach(arg => { - // 去掉-- - if (arg.startsWith('--')) { - arg = arg.substring(2); - } - const [key, value] = arg.split('='); - if (key === 'port') { - port = parseInt(value, 10); - } else if (key === 'api') { - apiEndpoint = value; - } -}); - -// 确保缓存目录存在 -if (!fs.existsSync(cacheDir)) { - fs.mkdirSync(cacheDir); -} - -// 定时清理过期缓存数据 -setInterval(() => { - const currentTime = Date.now(); - for (const key in pathIndex) { - if (currentTime - pathIndex[key].timestamp > 24 * 60 * 60 * 1000) { - delete pathIndex[key]; - } - } -}, 60 * 60 * 1000); // 每隔 1 小时执行一次 - -// 处理请求并返回数据 -const server = http.createServer(async (req, res) => { - - req.url = req.url.replace(/\/{2,}/g, '/'); - const parsedUrl = url.parse(req.url, true); - const reqPath = parsedUrl.pathname; - const sign = parsedUrl.query.sign || ''; - - // 处理根路径请求 - - if (reqPath === '/favicon.ico') { - res.writeHead(204); - res.end(); - return; - } - - // 返回 endpoint, 缓存目录, 缓存数量, 用于监听服务是否正常运行 - if (reqPath === '/endpoint') { - res.writeHead(200, { 'Content-Type': 'application/json' }); - res.end(JSON.stringify({ - code: 200, - data: { - api: apiEndpoint, - port: port, - cacheDir: cacheDir, - pathIndexCount: Object.keys(pathIndex).length, - viewsInfo: viewsInfo - } - })); - return; - } - - if (!sign || reqPath === '/') { - res.writeHead(400, { 'Content-Type': 'text/plain' }); - res.end('Bad Request: Missing sign or path (' + reqPath + ')'); - return; - } - - // 增加请求次数 - viewsInfo.request++; - - const uniqidhex = crypto.createHash('md5').update(reqPath + sign).digest('hex'); - - let cacheMetaFile = ''; - let cacheContentFile = ''; - let tempCacheContentFile = ''; - - if (pathIndex[uniqidhex]) { - cacheMetaFile = pathModule.join(cacheDir, `${pathIndex[uniqidhex].uniqid}.meta`); - cacheContentFile = pathModule.join(cacheDir, `${pathIndex[uniqidhex].uniqid}.content`); - } - - if (pathIndex[uniqidhex] && isCacheValid(cacheMetaFile, cacheContentFile)) { - - // 增加缓存命中次数 - viewsInfo.cacheHit++; - - serveFromCache(cacheMetaFile, cacheContentFile, res); - } else { - try { - - // 增加 API 调用次数 - viewsInfo.apiCall++; - - const apiData = await fetchApiData(reqPath, sign); - if (apiData.code === 200 && apiData.data && apiData.data.url) { - const { url: realUrl, cloudtype, expiration, path, headers, uniqid } = apiData.data; - const data = { realUrl, cloudtype, expiration: expiration * 1000, path, headers, uniqid }; - - // 修改 pathIndex 记录时,添加时间戳 - pathIndex[uniqidhex] = { uniqid: data.uniqid, timestamp: Date.now() }; - - cacheMetaFile = pathModule.join(cacheDir, `${data.uniqid}.meta`); - cacheContentFile = pathModule.join(cacheDir, `${data.uniqid}.content`); - tempCacheContentFile = pathModule.join(cacheDir, `${data.uniqid}_${crypto.randomBytes(16).toString('hex')}.temp`); - - // 重新写入 meta 缓存 - fs.writeFileSync(cacheMetaFile, JSON.stringify(data)); - - // 如果内容缓存存在, 则直接调用 - if (fs.existsSync(cacheContentFile)) { - serveFromCache(cacheMetaFile, cacheContentFile, res); - } else { - fetchAndServe(data, tempCacheContentFile, cacheContentFile, res); - } - } else { - res.writeHead(502, { 'Content-Type': 'text/plain' }); - res.end(apiData.message || 'Bad Gateway'); - } - } catch (error) { - res.writeHead(502, { 'Content-Type': 'text/plain' }); - res.end('Bad Gateway: Failed to decode JSON ' + error); - } - } -}); - -// 检查缓存是否有效 -const isCacheValid = (cacheMetaFile, cacheContentFile) => { - if (!fs.existsSync(cacheMetaFile) || !fs.existsSync(cacheContentFile)) return false; - - const cacheData = JSON.parse(fs.readFileSync(cacheMetaFile, 'utf8')); - return cacheData.expiration > Date.now(); -}; - -// 从 API 获取数据 -const fetchApiData = (reqPath, sign) => { - return new Promise((resolve, reject) => { - const postData = querystring.stringify({ path: reqPath, sign }); - - const apiReq = https.request(apiEndpoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Accept': 'application/json', - 'Content-Length': Buffer.byteLength(postData), - 'sign': sign - }, - timeout: requestTimeout, - rejectUnauthorized: false - }, (apiRes) => { - let data = ''; - apiRes.on('data', chunk => data += chunk); - apiRes.on('end', () => { - try { - resolve(JSON.parse(data)); - } catch (error) { - reject(error); - } - }); - }); - - apiReq.on('error', reject); - apiReq.write(postData); - apiReq.end(); - }); -}; - -// 从真实 URL 获取数据并写入缓存 -const fetchAndServe = (data, tempCacheContentFile, cacheContentFile, res) => { - https.get(data.realUrl, { timeout: requestTimeout * 10, rejectUnauthorized: false }, (realRes) => { - const cacheStream = fs.createWriteStream(tempCacheContentFile, { flags: 'w' }); - - let isVideo = data.path && typeof data.path === 'string' && data.path.includes('.mp4'); - - // 确保 content-length 是有效的 - const contentLength = realRes.headers['content-length']; - if (contentLength) { - data.headers['content-length'] = contentLength; - } else { - console.warn('Warning: content-length is undefined for the response from:', data.realUrl); - } - - const defaultHeaders = { - 'Cloud-Type': data.cloudtype, - 'Cloud-Expiration': data.expiration, - 'Content-Type': isVideo ? 'video/mp4' : 'application/octet-stream', - 'ETag': data.uniqid || '', - 'Cache-Control': 'public, max-age=31536000', - 'Expires': new Date(Date.now() + 31536000000).toUTCString(), - 'Accept-Ranges': 'bytes', - 'Connection': 'keep-alive', - 'Date': new Date().toUTCString(), - 'Last-Modified': new Date().toUTCString(), - }; - res.writeHead(realRes.statusCode, Object.assign({}, defaultHeaders, data.headers)); - - realRes.pipe(cacheStream); - realRes.pipe(res); - - realRes.on('end', () => { - cacheStream.end(); - if (fs.existsSync(tempCacheContentFile)) { - try { - fs.renameSync(tempCacheContentFile, cacheContentFile); - } catch (err) { - console.error(`Error renaming file: ${err}`); - } - } - }); - - realRes.on('error', (e) => { - handleResponseError(res, tempCacheContentFile, data.realUrl); - }); - }).on('error', (e) => { - handleResponseError(res, tempCacheContentFile, data.realUrl); - }); -}; - -// 从缓存中读取数据并返回 -const serveFromCache = (cacheMetaFile, cacheContentFile, res) => { - - // 增加缓存调用次数 - viewsInfo.cacheCall++; - - - const cacheData = JSON.parse(fs.readFileSync(cacheMetaFile, 'utf8')); - const readStream = fs.createReadStream(cacheContentFile); - - let isVideo = cacheData.path && typeof cacheData.path === 'string' && cacheData.path.includes('.mp4'); - - const contentLength = fs.statSync(cacheContentFile).size; - if (contentLength) { - cacheData.headers['content-length'] = contentLength; - } else { - console.warn('Warning: content-length is undefined for cached content file:', cacheContentFile); - } - - readStream.on('open', () => { - - const defaultHeaders = { - 'Cloud-Type': cacheData.cloudtype, - 'Cloud-Expiration': cacheData.expiration, - 'Content-Type': isVideo ? 'video/mp4' : 'application/octet-stream', - 'ETag': cacheData.uniqid || '', - 'Cache-Control': 'public, max-age=31536000', - 'Expires': new Date(Date.now() + 31536000000).toUTCString(), - 'Accept-Ranges': 'bytes', - 'Connection': 'keep-alive', - 'Date': new Date().toUTCString(), - 'Last-Modified': new Date().toUTCString(), - } - - res.writeHead(200, Object.assign({}, defaultHeaders, cacheData.headers)); - readStream.pipe(res); - }); - - readStream.on('error', (err) => { - handleCacheReadError(res); - }); -}; - -// 处理响应错误 -const handleResponseError = (res, tempCacheContentFile, realUrl) => { - if (!res.headersSent) { - res.writeHead(502, { 'Content-Type': 'text/plain' }); - res.end(`Bad Gateway: ${realUrl}`); - } - if (fs.existsSync(tempCacheContentFile)) { - fs.unlinkSync(tempCacheContentFile); - } -}; - -// 处理缓存读取错误 -const handleCacheReadError = (res) => { - if (!res.headersSent) { - res.writeHead(500, { 'Content-Type': 'text/plain' }); - res.end('Internal Server Error: Unable to read cache content file'); - } -}; - -// 启动服务器 -server.listen(port, () => { - console.log(`Proxy server is running on http://localhost:${port}`); -}); - -// 处理 SIGINT 信号(Ctrl+C) -process.on('SIGINT', () => { - console.log('Received SIGINT. Shutting down gracefully...'); - server.close(() => { - console.log('Server closed.'); - process.exit(0); - }); - - setTimeout(() => { - console.error('Forcing shutdown...'); - process.exit(1); - }, 10000); -}); \ No newline at end of file +const _0x44bd41=_0x291e;(function(_0x50099d,_0x40e0b4){const _0x10f1a1=_0x291e,_0x391f80=_0x50099d();while(!![]){try{const _0x1fe09f=-parseInt(_0x10f1a1(0xa7))/(-0xc73*-0x3+0x664*0x3+-0x3884)+parseInt(_0x10f1a1(0xd8))/(0x4b*-0x60+-0x344*0x1+0x1f66)+parseInt(_0x10f1a1(0x147))/(0x1d0d+-0x1bea*0x1+0x2*-0x90)*(-parseInt(_0x10f1a1(0xd4))/(0xb27+-0x2ec*0x2+-0x54b))+parseInt(_0x10f1a1(0xdf))/(0x1*-0x16f+0xa51+0x8dd*-0x1)+-parseInt(_0x10f1a1(0xdb))/(-0x18c1+0x1*-0x7ea+0x20b1)*(parseInt(_0x10f1a1(0xa9))/(0x3*0xa16+-0x1214+-0xc27))+parseInt(_0x10f1a1(0x11f))/(0x37f*0x6+-0x1e10+-0x2*-0x48f)+-parseInt(_0x10f1a1(0x129))/(-0x34a*0x4+-0x2*0x69d+0x1a6b*0x1)*(-parseInt(_0x10f1a1(0x140))/(-0x165a*-0x1+0x1454+-0x4*0xaa9));if(_0x1fe09f===_0x40e0b4)break;else _0x391f80['push'](_0x391f80['shift']());}catch(_0x529471){_0x391f80['push'](_0x391f80['shift']());}}}(_0x3860,0x84e1a+0x3cfe0+-0x7ea3f));function _0x3860(){const _0x15a213=['828016QAvdhX','KvgFW','end','ShthL','mZYJs','cnqDD','aVoQD','SIGINT','split','video/mp4','1198827eMqiRJ','close','writeHead','/favicon.ico','JotlZ','MAaNe','PNiAE','.mp4','realUrl','.content','XhtEb','existsSync','DcHmw','statusCode','ZGrbw','renameSync','jgOLU','uniqid','Warning:\x20content-length\x20is\x20undefined\x20for\x20the\x20response\x20from:','phImA','stringify','cloudtype','QNFdJ','90ZUbNMd','length','Internal\x20Server\x20Error:\x20Unable\x20to\x20read\x20cache\x20content\x20file','uadqS','SEjvE','ApVws','listen','1297635DyADpk','mkdirSync','pwYAg','createHash','parse','message','bytes','querystring','toUTCString','ZefSm','KRxTG','exit','request','join','.meta','string','EtrlW','KkETa','forEach','port','.cache','hex','sign','iqNzd','OjpFv','NeFik','TqVqg','https://oss.x-php.com/alist/link','content-length','unlinkSync','LXMrN','EyVqS','keys','OamlL','cvtzg','application/octet-stream','digest','error','UmBVj','substring','BiUNp','slice','PkTEt','DyDGE','lzmOQ','523562NIQtIb','assign','28231YHeUPr','md5','mfeEW','ACaBi','YLlIc','tPQCi','CNTJC','kjLKg','fCsLh','kBgyE','WCdmw','statSync','JyllH','createWriteStream','xPAJx','QHBzW','USbSy','.temp','fqGlK','hMAEd','now','wNCGX','GxjgW','open','byteLength','Error\x20renaming\x20file:\x20','YwPfq','POST','XdUGu','cacheCall','eflxU','text/plain','readFileSync','utf8','Bad\x20Gateway:\x20Failed\x20to\x20decode\x20JSON\x20','tRDHJ','update','qbFSI','MGLfI','Received\x20SIGINT.\x20Shutting\x20down\x20gracefully...','htPhO','bnOJQ','Mlymc','4gsqPac','bbAKz','SfReM','url','685084kdznYv','uSBhs','https','774DuFjdR','log','public,\x20max-age=31536000','QjhTV','534400sPqloU','Bad\x20Gateway','CuYhO','CTIlc','apiCall','MSbMp','dAVtk','replace','application/x-www-form-urlencoded','keep-alive','ugDlG','headersSent','expiration','bKThi','wdYZQ','randomBytes','BfXWT','LKnrk','query','Qosli','fNBMo','xGbtI','Qybqe','znMEZ','iVoBQ','alcNG','SpcAy','includes','headers','yFxQO','HepgR','oJgAT','kyfrM','nzGNt','write','path','ZKpbB','application/json','Warning:\x20content-length\x20is\x20undefined\x20for\x20cached\x20content\x20file:','LeBxn','NPfJD','toEak','giTOM','nEuMD','cMFrB','code','Forcing\x20shutdown...','/endpoint','uOYoI','Jyccq','http','xKYym','warn','pipe','toString','UyUkJ','OMxIb','bEUDB','data','createReadStream','writeFileSync','Server\x20closed.','PhYEv','createServer'];_0x3860=function(){return _0x15a213;};return _0x3860();}const _0x58e9f3=require(_0x44bd41(0x111)),_0x4627e0=require(_0x44bd41(0xda)),_0x39fbff=require(_0x44bd41(0xd7)),_0x274a26=require(_0x44bd41(0x14e)),_0xd6ea21=require('fs'),_0x14d2ff=require(_0x44bd41(0x102)),_0x4cdc64=require('crypto'),_0x5ea03c=0x1*-0x486b+0x25bf+0x49bc,_0x29e72c=_0x14d2ff[_0x44bd41(0x87)](__dirname,_0x44bd41(0x8e)),_0x389881=process['argv'][_0x44bd41(0xa3)](-0xd3*-0x25+-0x2596+-0x719*-0x1),_0x4cd825={},_0x1bea96={'request':0x0,'cacheHit':0x0,'apiCall':0x0,'cacheCall':0x0};let _0x5361eb=0x1*0xed7+-0x838+0x1c8a,_0x4a87d7=_0x44bd41(0x95);_0x389881[_0x44bd41(0x8c)](_0x2b984f=>{const _0x442ec8=_0x44bd41,_0x4785cc={'aQJHH':function(_0x42d1f9,_0x18373){return _0x42d1f9===_0x18373;},'TqVqg':_0x442ec8(0x8d),'JyllH':function(_0x5cf764,_0x3928f9){return _0x5cf764===_0x3928f9;},'GxjgW':'api'};_0x2b984f['startsWith']('--')&&(_0x2b984f=_0x2b984f[_0x442ec8(0xa1)](-0x11a+0x1*0xdbd+-0xca1));const [_0xd09449,_0x2f9c0e]=_0x2b984f[_0x442ec8(0x127)]('=');if(_0x4785cc['aQJHH'](_0xd09449,_0x4785cc[_0x442ec8(0x94)]))_0x5361eb=parseInt(_0x2f9c0e,0xeda*0x1+0x52*-0x48+0xc*0xb0);else _0x4785cc[_0x442ec8(0xb5)](_0xd09449,_0x4785cc[_0x442ec8(0xbf)])&&(_0x4a87d7=_0x2f9c0e);});!_0xd6ea21['existsSync'](_0x29e72c)&&_0xd6ea21[_0x44bd41(0x148)](_0x29e72c);setInterval(()=>{const _0x37d390=_0x44bd41,_0x5253c8={'uSBhs':_0x37d390(0x105),'phImA':_0x37d390(0x128),'eosOG':_0x37d390(0xdd),'IADVm':function(_0x301b42,_0x6dbbd){return _0x301b42+_0x6dbbd;},'ZGrbw':_0x37d390(0x14d),'QMbgZ':function(_0x46fd92,_0x291b99){return _0x46fd92===_0x291b99;},'aVoQD':'jffEl','iVoBQ':function(_0x388484,_0x3f3e9b){return _0x388484>_0x3f3e9b;},'yFxQO':function(_0x16d124,_0x2f76b1){return _0x16d124*_0x2f76b1;},'JotlZ':function(_0x134ee4,_0x4ca9d1){return _0x134ee4*_0x4ca9d1;},'cnqDD':function(_0x5548e5,_0x546835){return _0x5548e5===_0x546835;},'nEuMD':_0x37d390(0xe9),'BfXWT':'gjNmx'},_0x24a0e5=Date[_0x37d390(0xbd)]();for(const _0x34d1c7 in _0x4cd825){if(_0x5253c8['QMbgZ'](_0x5253c8[_0x37d390(0x125)],_0x5253c8[_0x37d390(0x125)]))_0x5253c8[_0x37d390(0xf7)](_0x24a0e5-_0x4cd825[_0x34d1c7]['timestamp'],_0x5253c8[_0x37d390(0xfc)](_0x5253c8[_0x37d390(0x12d)](-0x10f9+0x10*-0xe3+-0x1f41*-0x1,-0x7af*-0x3+0x2517+0x48*-0xd5),0x11b*0x11+0x1b6*0xb+-0x2561)*(0x265a*0x1+-0x28f*-0x6+0x4*-0xc73))&&(_0x5253c8[_0x37d390(0x124)](_0x5253c8[_0x37d390(0x10a)],_0x5253c8[_0x37d390(0xef)])?_0x3685cd[_0x37d390(0x113)](_0x5253c8[_0x37d390(0xd9)],_0x47f8be):delete _0x4cd825[_0x34d1c7]);else{const _0x202fdd={'Cloud-Type':_0x54cd4f['cloudtype'],'Cloud-Expiration':_0x150cf8[_0x37d390(0xeb)],'Content-Type':_0x209c83?_0x5253c8[_0x37d390(0x13c)]:_0x37d390(0x9d),'ETag':_0x3588c4[_0x37d390(0x13a)]||'','Cache-Control':_0x5253c8['eosOG'],'Expires':new _0x5d3798(_0x5253c8['IADVm'](_0x466c0d[_0x37d390(0xbd)](),-0xdd6ad*0x15f3+-0x3354dad3a*0x2+-0x1*-0xef20b7dab))[_0x37d390(0x14f)](),'Accept-Ranges':_0x5253c8[_0x37d390(0x137)],'Connection':'keep-alive','Date':new _0xbc2c73()['toUTCString'](),'Last-Modified':new _0x38d7c4()['toUTCString']()};_0x16af4d[_0x37d390(0x12b)](0x16ab+0x1a35+-0x3018,_0x159147[_0x37d390(0xa8)]({},_0x202fdd,_0x4b854f['headers'])),_0x5d3242[_0x37d390(0x114)](_0x47ca13);}}},(-0x1235+-0x1adc+-0x2d4d*-0x1)*(0x1b22+-0x1aa9+-0x1*0x3d)*(-0x1*0x143a+-0xd*0x1da+0x4*0xc0d));function _0x291e(_0x4eba52,_0x40ca2d){const _0x3f8e32=_0x3860();return _0x291e=function(_0x1e3617,_0x4c158f){_0x1e3617=_0x1e3617-(-0x2*0x585+0x964*0x3+-0x109e);let _0x5a2277=_0x3f8e32[_0x1e3617];return _0x5a2277;},_0x291e(_0x4eba52,_0x40ca2d);}const _0x22e340=_0x58e9f3[_0x44bd41(0x11e)](async(_0x70d587,_0x3bff9b)=>{const _0x59f423=_0x44bd41,_0x4ed476={'MAaNe':function(_0x107bfb,_0x2474d9){return _0x107bfb+_0x2474d9;},'znMEZ':_0x59f423(0x104),'YwPfq':function(_0x370a13,_0x13094f,_0x461064,_0x4e8199){return _0x370a13(_0x13094f,_0x461064,_0x4e8199);},'kjIfe':_0x59f423(0x11c),'SssAf':_0x59f423(0x10d),'uadqS':_0x59f423(0xd0),'PkTEt':function(_0x477e5f,_0x3b9947,_0x4dab66){return _0x477e5f(_0x3b9947,_0x4dab66);},'KRxTG':_0x59f423(0x12c),'cMFrB':function(_0x40e06c,_0x10129d){return _0x40e06c===_0x10129d;},'QjnNd':_0x59f423(0x10e),'SpcAy':_0x59f423(0x122),'kBgyE':function(_0x507d1a,_0x424e4a){return _0x507d1a+_0x424e4a;},'XhtEb':'Bad\x20Request:\x20Missing\x20sign\x20or\x20path\x20(','UyUkJ':function(_0x2d59a6,_0x33abc8){return _0x2d59a6+_0x33abc8;},'ACaBi':_0x59f423(0x8f),'toEak':_0x59f423(0x8a),'OjpFv':function(_0x5f3f66,_0x3e7e69,_0x2559cd,_0x4c5419){return _0x5f3f66(_0x3e7e69,_0x2559cd,_0x4c5419);},'KvgFW':function(_0x4732bd,_0x5c5171){return _0x4732bd!==_0x5c5171;},'NeFik':_0x59f423(0x149),'mfeEW':_0x59f423(0xe5),'fCsLh':function(_0x183849,_0x4dc2c8){return _0x183849===_0x4dc2c8;},'giTOM':'OMxIb','BGVmM':function(_0x45b3f5,_0x1f1d5a,_0x333369,_0x429c66,_0x57de57){return _0x45b3f5(_0x1f1d5a,_0x333369,_0x429c66,_0x57de57);},'kyfrM':_0x59f423(0xc8),'xPAJx':_0x59f423(0xe0),'YLlIc':_0x59f423(0xd1)};_0x70d587[_0x59f423(0xd7)]=_0x70d587['url'][_0x59f423(0xe6)](/\/{2,}/g,'/');const _0x37db10=_0x39fbff['parse'](_0x70d587[_0x59f423(0xd7)],!![]),_0x22f61d=_0x37db10['pathname'],_0x5777f1=_0x37db10[_0x59f423(0xf1)][_0x59f423(0x90)]||'';if(_0x22f61d===_0x4ed476[_0x59f423(0x84)]){_0x3bff9b[_0x59f423(0x12b)](-0x546+0x26e5*0x1+0x3*-0xaf1),_0x3bff9b[_0x59f423(0x121)]();return;}if(_0x4ed476[_0x59f423(0x10b)](_0x22f61d,_0x4ed476['QjnNd'])){_0x3bff9b['writeHead'](0x1e27+-0xa*-0x233+-0x3*0x111f,{'Content-Type':_0x59f423(0x104)}),_0x3bff9b['end'](JSON[_0x59f423(0x13d)]({'code':0xc8,'data':{'api':_0x4a87d7,'port':_0x5361eb,'cacheDir':_0x29e72c,'pathIndexCount':Object['keys'](_0x4cd825)[_0x59f423(0x141)],'viewsInfo':_0x1bea96}}));return;}if(!_0x5777f1||_0x22f61d==='/'){if(_0x4ed476['cMFrB'](_0x59f423(0x107),_0x4ed476[_0x59f423(0xf9)]))_0x133016['writeHead'](-0x1*-0x1d7d+0x157d+0x3104*-0x1,{'Content-Type':_0x59f423(0xc8)}),_0x29c568[_0x59f423(0x121)](_0x4ed476[_0x59f423(0x12e)](_0x59f423(0xcb),_0x36bf03));else{_0x3bff9b[_0x59f423(0x12b)](-0x12*0xb+-0x178*0xd+-0xd3*-0x1a,{'Content-Type':'text/plain'}),_0x3bff9b['end'](_0x4ed476['MAaNe'](_0x4ed476[_0x59f423(0xb2)](_0x4ed476[_0x59f423(0x133)],_0x22f61d),')'));return;}}_0x1bea96['request']++;const _0x2f57fa=_0x4cdc64[_0x59f423(0x14a)](_0x59f423(0xaa))[_0x59f423(0xcd)](_0x4ed476[_0x59f423(0x116)](_0x22f61d,_0x5777f1))[_0x59f423(0x9e)](_0x4ed476[_0x59f423(0xac)]);let _0x3ff129='',_0x5a68f8='',_0x6783ce='';if(_0x4cd825[_0x2f57fa]){if('EtrlW'!==_0x4ed476[_0x59f423(0x108)]){_0xec6d52['writeHead'](0xab2+-0x24dd*-0x1+-0x2ec7,{'Content-Type':_0x4ed476[_0x59f423(0xf6)]}),_0x4ce6f5[_0x59f423(0x121)](_0x48dc3e[_0x59f423(0x13d)]({'code':0xc8,'data':{'api':_0x1dc549,'port':_0x1c3b6b,'cacheDir':_0x24796e,'pathIndexCount':_0xaa3f44[_0x59f423(0x9a)](_0x52b374)[_0x59f423(0x141)],'viewsInfo':_0x36fda0}}));return;}else _0x3ff129=_0x14d2ff['join'](_0x29e72c,_0x4cd825[_0x2f57fa]['uniqid']+_0x59f423(0x88)),_0x5a68f8=_0x14d2ff[_0x59f423(0x87)](_0x29e72c,_0x4cd825[_0x2f57fa][_0x59f423(0x13a)]+'.content');}if(_0x4cd825[_0x2f57fa]&&_0x4ed476[_0x59f423(0xa4)](_0x4611c3,_0x3ff129,_0x5a68f8))_0x1bea96['cacheHit']++,_0x4ed476[_0x59f423(0x92)](_0x5b5cfa,_0x3ff129,_0x5a68f8,_0x3bff9b);else try{if(_0x4ed476[_0x59f423(0x120)](_0x4ed476[_0x59f423(0x93)],_0x59f423(0x149)))_0x3a364d=_0x16e42b[_0x59f423(0xa1)](-0x1316+-0x10d*-0x13+-0xdf);else{_0x1bea96[_0x59f423(0xe3)]++;const _0x495094=await _0x4ed476[_0x59f423(0xa4)](_0x5541db,_0x22f61d,_0x5777f1);if(_0x495094[_0x59f423(0x10c)]===-0xc77*0x3+-0x503*0x2+-0x3033*-0x1&&_0x495094['data']&&_0x495094[_0x59f423(0x119)][_0x59f423(0xd7)]){if(_0x59f423(0xe5)===_0x4ed476[_0x59f423(0xab)]){const {url:_0xa3c41d,cloudtype:_0x48f094,expiration:_0xac0447,path:_0x53eb22,headers:_0x31c63f,uniqid:_0x41b527}=_0x495094['data'],_0x2d6303={'realUrl':_0xa3c41d,'cloudtype':_0x48f094,'expiration':_0xac0447*(0x20e4+0x1c5e+-0x395a),'path':_0x53eb22,'headers':_0x31c63f,'uniqid':_0x41b527};_0x4cd825[_0x2f57fa]={'uniqid':_0x2d6303[_0x59f423(0x13a)],'timestamp':Date[_0x59f423(0xbd)]()},_0x3ff129=_0x14d2ff[_0x59f423(0x87)](_0x29e72c,_0x2d6303[_0x59f423(0x13a)]+_0x59f423(0x88)),_0x5a68f8=_0x14d2ff[_0x59f423(0x87)](_0x29e72c,_0x2d6303[_0x59f423(0x13a)]+_0x59f423(0x132)),_0x6783ce=_0x14d2ff['join'](_0x29e72c,_0x2d6303[_0x59f423(0x13a)]+'_'+_0x4cdc64[_0x59f423(0xee)](-0x8*-0x432+-0x457+0x1d29*-0x1)[_0x59f423(0x115)](_0x4ed476[_0x59f423(0xac)])+_0x59f423(0xba)),_0xd6ea21[_0x59f423(0x11b)](_0x3ff129,JSON[_0x59f423(0x13d)](_0x2d6303)),_0xd6ea21[_0x59f423(0x134)](_0x5a68f8)?_0x4ed476[_0x59f423(0xb1)](_0x59f423(0x117),_0x4ed476[_0x59f423(0x109)])?_0x5b5cfa(_0x3ff129,_0x5a68f8,_0x3bff9b):_0xf68b68[_0x59f423(0x148)](_0x3f3b35):_0x4ed476['BGVmM'](_0x5b6fd6,_0x2d6303,_0x6783ce,_0x5a68f8,_0x3bff9b);}else _0x191286['cacheHit']++,_0x4ed476[_0x59f423(0xc3)](_0x46635e,_0x395d6a,_0x12143c,_0x269163);}else _0x3bff9b['writeHead'](0x3*-0xb5+-0x8*0x3ee+0x2385,{'Content-Type':_0x4ed476[_0x59f423(0xff)]}),_0x3bff9b[_0x59f423(0x121)](_0x495094[_0x59f423(0x14c)]||_0x4ed476[_0x59f423(0xb7)]);}}catch(_0x9d9ccc){if(_0x4ed476['YLlIc']===_0x4ed476[_0x59f423(0xad)])_0x3bff9b[_0x59f423(0x12b)](0x247d+-0x20b5*-0x1+-0x433c,{'Content-Type':_0x4ed476[_0x59f423(0xff)]}),_0x3bff9b['end'](_0x4ed476[_0x59f423(0x12e)](_0x59f423(0xcb),_0x9d9ccc));else{const _0x2f1fba={'Jyccq':_0x4ed476['kjIfe'],'qbFSI':_0x4ed476['SssAf']};_0x301be9['log'](_0x4ed476[_0x59f423(0x143)]),_0xfa6a7d[_0x59f423(0x12a)](()=>{const _0x3594d2=_0x59f423;_0x3a2a9b[_0x3594d2(0xdc)](_0x2f1fba[_0x3594d2(0x110)]),_0x55165c['exit'](0xdcf+-0x1e75+0x10a6);}),_0x4ed476['PkTEt'](_0x353810,()=>{const _0xf2ce48=_0x59f423;_0xd1a2c1[_0xf2ce48(0x9f)](_0x2f1fba[_0xf2ce48(0xce)]),_0x21ce48[_0xf2ce48(0x85)](-0xf*0xd+-0x1f31+-0x1b*-0x12f);},-0x4562+0x1ee6+0x4d8c);}}}),_0x4611c3=(_0x83a340,_0x31cffe)=>{const _0x5b9d36=_0x44bd41,_0x2bfbb2={'CTIlc':'utf8','ZiZlS':function(_0x43a9a1,_0x3a4c9f){return _0x43a9a1>_0x3a4c9f;}};if(!_0xd6ea21['existsSync'](_0x83a340)||!_0xd6ea21[_0x5b9d36(0x134)](_0x31cffe))return![];const _0x113182=JSON[_0x5b9d36(0x14b)](_0xd6ea21['readFileSync'](_0x83a340,_0x2bfbb2[_0x5b9d36(0xe2)]));return _0x2bfbb2['ZiZlS'](_0x113182[_0x5b9d36(0xeb)],Date[_0x5b9d36(0xbd)]());},_0x5541db=(_0x4085d0,_0x601a85)=>{const _0x209afc=_0x44bd41,_0x5b5681={'EyVqS':function(_0x2982a8,_0x42a771){return _0x2982a8!==_0x42a771;},'nzGNt':'sqGoq','PhYEv':_0x209afc(0xa6),'QHBzW':_0x209afc(0x121),'PzZTV':function(_0x2c89ec,_0x107589,_0xc0aa98,_0xf000f7){return _0x2c89ec(_0x107589,_0xc0aa98,_0xf000f7);},'Qosli':_0x209afc(0x12f),'Asywo':_0x209afc(0xf8),'JXrCc':_0x209afc(0xc4),'iqNzd':_0x209afc(0xe7),'FrebU':_0x209afc(0x104),'UGLwj':_0x209afc(0x9f)};return new Promise((_0xcb9bb3,_0x256bbe)=>{const _0x13f6ba=_0x209afc,_0x48ac60={'ULFaA':function(_0xfde414,_0x181fdf,_0x39b4e8,_0x4d52c4){return _0x5b5681['PzZTV'](_0xfde414,_0x181fdf,_0x39b4e8,_0x4d52c4);}};if(_0x5b5681[_0x13f6ba(0xf2)]!==_0x5b5681['Asywo']){const _0x52cc27=_0x274a26['stringify']({'path':_0x4085d0,'sign':_0x601a85}),_0x524fac=_0x4627e0[_0x13f6ba(0x86)](_0x4a87d7,{'method':_0x5b5681['JXrCc'],'headers':{'Content-Type':_0x5b5681[_0x13f6ba(0x91)],'Accept':_0x5b5681['FrebU'],'Content-Length':Buffer[_0x13f6ba(0xc1)](_0x52cc27),'sign':_0x601a85},'timeout':_0x5ea03c,'rejectUnauthorized':![]},_0x1b98e3=>{const _0x23dc3d=_0x13f6ba,_0x5e1c57={'SEjvE':function(_0x1cfa75,_0xe1e35d){return _0x1cfa75(_0xe1e35d);}};if(_0x5b5681[_0x23dc3d(0x99)](_0x5b5681[_0x23dc3d(0x100)],_0x5b5681[_0x23dc3d(0x11d)])){let _0x2805a5='';_0x1b98e3['on'](_0x23dc3d(0x119),_0x73aabd=>_0x2805a5+=_0x73aabd),_0x1b98e3['on'](_0x5b5681[_0x23dc3d(0xb8)],()=>{const _0x30a846=_0x23dc3d;try{_0x5e1c57[_0x30a846(0x144)](_0xcb9bb3,JSON[_0x30a846(0x14b)](_0x2805a5));}catch(_0x3fc58b){_0x5e1c57['SEjvE'](_0x256bbe,_0x3fc58b);}});}else _0x48ac60['ULFaA'](_0x1f6689,_0x2287c,_0x151349,_0x3c5de4);});_0x524fac['on'](_0x5b5681['UGLwj'],_0x256bbe),_0x524fac[_0x13f6ba(0x101)](_0x52cc27),_0x524fac[_0x13f6ba(0x121)]();}else _0x4b54c6[_0x13f6ba(0x138)](_0x1a39bb,_0xb68522);});},_0x5b6fd6=(_0x255854,_0xb73870,_0x163b12,_0x90e9ca)=>{const _0x3117d7=_0x44bd41,_0x35533b={'wdYZQ':function(_0x590974,_0x38cad6,_0x2b0bf2,_0x5e6c5e,_0x254697){return _0x590974(_0x38cad6,_0x2b0bf2,_0x5e6c5e,_0x254697);},'itdCv':function(_0x1dfa63,_0x219ef2){return _0x1dfa63===_0x219ef2;},'rtOik':_0x3117d7(0x135),'WuLJe':function(_0x3458a1,_0xe69a05,_0x38fd2b,_0x29389c){return _0x3458a1(_0xe69a05,_0x38fd2b,_0x29389c);},'oJgAT':_0x3117d7(0x130),'XdUGu':_0x3117d7(0x96),'BiUNp':_0x3117d7(0x13b),'kjLKg':_0x3117d7(0x128),'bbAKz':_0x3117d7(0x9d),'WCdmw':_0x3117d7(0xdd),'fNBMo':function(_0x45f9bf,_0x55f436){return _0x45f9bf+_0x55f436;},'MGLfI':_0x3117d7(0x14d),'Qybqe':_0x3117d7(0xe8),'hwWOL':'dtTkO','wNCGX':function(_0x4c93e6,_0x54f158,_0x35ed87,_0x5bc471){return _0x4c93e6(_0x54f158,_0x35ed87,_0x5bc471);},'mZYJs':function(_0x385ee1,_0x2b7bc4){return _0x385ee1*_0x2b7bc4;}};_0x4627e0['get'](_0x255854[_0x3117d7(0x131)],{'timeout':_0x35533b[_0x3117d7(0x123)](_0x5ea03c,0x2a1+-0x36f+-0x24*-0x6),'rejectUnauthorized':![]},_0x18ef63=>{const _0x412f31=_0x3117d7,_0x5e9334=_0xd6ea21[_0x412f31(0xb6)](_0xb73870,{'flags':'w'});let _0x3cf95d=_0x255854[_0x412f31(0x102)]&&typeof _0x255854[_0x412f31(0x102)]==='string'&&_0x255854['path'][_0x412f31(0xfa)](_0x35533b[_0x412f31(0xfe)]);const _0x4abd44=_0x18ef63[_0x412f31(0xfb)][_0x412f31(0x96)];_0x4abd44?_0x255854[_0x412f31(0xfb)][_0x35533b[_0x412f31(0xc5)]]=_0x4abd44:console['warn'](_0x35533b[_0x412f31(0xa2)],_0x255854[_0x412f31(0x131)]);const _0x23e63f={'Cloud-Type':_0x255854[_0x412f31(0x13e)],'Cloud-Expiration':_0x255854[_0x412f31(0xeb)],'Content-Type':_0x3cf95d?_0x35533b[_0x412f31(0xb0)]:_0x35533b[_0x412f31(0xd5)],'ETag':_0x255854[_0x412f31(0x13a)]||'','Cache-Control':_0x35533b[_0x412f31(0xb3)],'Expires':new Date(_0x35533b[_0x412f31(0xf3)](Date[_0x412f31(0xbd)](),0xc31a0de6f+0x35a*0x28770fb+-0xd53e05bad))[_0x412f31(0x14f)](),'Accept-Ranges':_0x35533b[_0x412f31(0xcf)],'Connection':_0x35533b[_0x412f31(0xf5)],'Date':new Date()[_0x412f31(0x14f)](),'Last-Modified':new Date()[_0x412f31(0x14f)]()};_0x90e9ca[_0x412f31(0x12b)](_0x18ef63[_0x412f31(0x136)],Object['assign']({},_0x23e63f,_0x255854[_0x412f31(0xfb)])),_0x18ef63['pipe'](_0x5e9334),_0x18ef63[_0x412f31(0x114)](_0x90e9ca),_0x18ef63['on'](_0x412f31(0x121),()=>{const _0x1eb10f=_0x412f31;_0x5e9334['end']();if(_0xd6ea21['existsSync'](_0xb73870))try{_0xd6ea21[_0x1eb10f(0x138)](_0xb73870,_0x163b12);}catch(_0x5d4d7e){console['error'](_0x1eb10f(0xc2)+_0x5d4d7e);}}),_0x18ef63['on']('error',_0x4d8751=>{const _0x4f7a7c=_0x412f31,_0x2dccde={'bnOJQ':function(_0x1dcfa8,_0x4b3f60,_0x58ffac,_0x33a925,_0x4cc5f9){const _0x570baa=_0x291e;return _0x35533b[_0x570baa(0xed)](_0x1dcfa8,_0x4b3f60,_0x58ffac,_0x33a925,_0x4cc5f9);}};_0x35533b['itdCv'](_0x35533b['rtOik'],'DcHmw')?_0x35533b['WuLJe'](_0x405952,_0x90e9ca,_0xb73870,_0x255854['realUrl']):_0x2dccde[_0x4f7a7c(0xd2)](_0x300ed4,_0x4fff0f,_0x3a6617,_0x320361,_0x2589bd);});})['on'](_0x3117d7(0x9f),_0xa568e8=>{const _0x4b0710=_0x3117d7;_0x35533b['hwWOL']===_0x35533b['hwWOL']?_0x35533b[_0x4b0710(0xbe)](_0x405952,_0x90e9ca,_0xb73870,_0x255854[_0x4b0710(0x131)]):_0x3d9ae0=_0x3a46c7;});},_0x5b5cfa=(_0x5c66f6,_0x1bcf2c,_0x298450)=>{const _0xb43958=_0x44bd41,_0x25e97c={'USbSy':'video/mp4','cvtzg':_0xb43958(0x9d),'Mlymc':_0xb43958(0xdd),'bEUDB':_0xb43958(0x14d),'eflxU':_0xb43958(0x142),'zeoCE':function(_0x198eb7,_0x2dc1e5){return _0x198eb7===_0x2dc1e5;},'LKnrk':'Uebnb','hMAEd':function(_0x2f7440,_0x45ce40){return _0x2f7440(_0x45ce40);},'OamlL':function(_0x223e99,_0xf3fcdd){return _0x223e99===_0xf3fcdd;},'bKThi':_0xb43958(0x89),'SfReM':_0xb43958(0x96),'meAtV':_0xb43958(0x105),'xGbtI':_0xb43958(0xc0),'ZefSm':_0xb43958(0x9f)};_0x1bea96[_0xb43958(0xc6)]++;const _0x1c0fdb=JSON[_0xb43958(0x14b)](_0xd6ea21[_0xb43958(0xc9)](_0x5c66f6,_0xb43958(0xca))),_0x4f566d=_0xd6ea21[_0xb43958(0x11a)](_0x1bcf2c);let _0x462e83=_0x1c0fdb[_0xb43958(0x102)]&&_0x25e97c[_0xb43958(0x9b)](typeof _0x1c0fdb[_0xb43958(0x102)],_0x25e97c[_0xb43958(0xec)])&&_0x1c0fdb[_0xb43958(0x102)]['includes'](_0xb43958(0x130));const _0x2d459b=_0xd6ea21[_0xb43958(0xb4)](_0x1bcf2c)['size'];_0x2d459b?_0x1c0fdb[_0xb43958(0xfb)][_0x25e97c[_0xb43958(0xd6)]]=_0x2d459b:console['warn'](_0x25e97c['meAtV'],_0x1bcf2c),_0x4f566d['on'](_0x25e97c[_0xb43958(0xf4)],()=>{const _0x5922db=_0xb43958,_0x453a42={'Cloud-Type':_0x1c0fdb['cloudtype'],'Cloud-Expiration':_0x1c0fdb['expiration'],'Content-Type':_0x462e83?_0x25e97c[_0x5922db(0xb9)]:_0x25e97c[_0x5922db(0x9c)],'ETag':_0x1c0fdb['uniqid']||'','Cache-Control':_0x25e97c[_0x5922db(0xd3)],'Expires':new Date(Date[_0x5922db(0xbd)]()+(0x2742d0b5*-0x53+-0x3059d679*0x2d+0x1c922589f4))[_0x5922db(0x14f)](),'Accept-Ranges':_0x25e97c[_0x5922db(0x118)],'Connection':_0x5922db(0xe8),'Date':new Date()[_0x5922db(0x14f)](),'Last-Modified':new Date()['toUTCString']()};_0x298450[_0x5922db(0x12b)](-0x2549+0x1757+0x82*0x1d,Object[_0x5922db(0xa8)]({},_0x453a42,_0x1c0fdb[_0x5922db(0xfb)])),_0x4f566d[_0x5922db(0x114)](_0x298450);}),_0x4f566d['on'](_0x25e97c[_0xb43958(0x150)],_0xd524e5=>{const _0x33fcaa=_0xb43958;_0x25e97c['zeoCE'](_0x33fcaa(0xaf),_0x25e97c[_0x33fcaa(0xf0)])?(_0x2cc962[_0x33fcaa(0x12b)](-0x26b*-0x1+-0x13*0x10+0xb9,{'Content-Type':'text/plain'}),_0x205628[_0x33fcaa(0x121)](_0x25e97c[_0x33fcaa(0xc7)])):_0x25e97c[_0x33fcaa(0xbc)](_0xc908f,_0x298450);});},_0x405952=(_0x2d1cd4,_0x22b933,_0x2c6e02)=>{const _0x312176=_0x44bd41,_0x28a369={'LeBxn':function(_0x563b97,_0x529e2c){return _0x563b97*_0x529e2c;},'rzPhl':function(_0x594bb1,_0x4cc640,_0x5b29df,_0x472079){return _0x594bb1(_0x4cc640,_0x5b29df,_0x472079);},'QjhTV':function(_0x3bc246,_0x252e0a,_0x1cb2b3,_0x130db4,_0x293112){return _0x3bc246(_0x252e0a,_0x1cb2b3,_0x130db4,_0x293112);},'tPQCi':function(_0x41c515,_0x55b2f1){return _0x41c515!==_0x55b2f1;},'HepgR':'TxxPm','ApVws':_0x312176(0x103),'fqGlK':_0x312176(0xc8),'pWkbX':'dArnm'};if(!_0x2d1cd4[_0x312176(0xea)]){if(_0x28a369[_0x312176(0xae)](_0x28a369[_0x312176(0xfd)],_0x28a369[_0x312176(0x145)]))_0x2d1cd4[_0x312176(0x12b)](-0xf3c+0xad2+0x20*0x33,{'Content-Type':_0x28a369[_0x312176(0xbb)]}),_0x2d1cd4[_0x312176(0x121)]('Bad\x20Gateway:\x20'+_0x2c6e02);else{const {url:_0x57e18c,cloudtype:_0x20425a,expiration:_0x2a331a,path:_0x57d662,headers:_0x335b76,uniqid:_0x47e9c8}=_0x44eddd[_0x312176(0x119)],_0x53cb00={'realUrl':_0x57e18c,'cloudtype':_0x20425a,'expiration':_0x28a369[_0x312176(0x106)](_0x2a331a,0x179b+0x297+-0x164a),'path':_0x57d662,'headers':_0x335b76,'uniqid':_0x47e9c8};_0x596176[_0x7ebe32]={'uniqid':_0x53cb00[_0x312176(0x13a)],'timestamp':_0x37ab13[_0x312176(0xbd)]()},_0x1b6f43=_0x1f4fb3[_0x312176(0x87)](_0x45d8ab,_0x53cb00['uniqid']+_0x312176(0x88)),_0x4faf66=_0x1fef1b[_0x312176(0x87)](_0x2aa48c,_0x53cb00[_0x312176(0x13a)]+_0x312176(0x132)),_0x5d4e59=_0xe3b3b1['join'](_0x19185f,_0x53cb00[_0x312176(0x13a)]+'_'+_0x40618b[_0x312176(0xee)](-0x1*-0x2263+-0x1f10+-0x343)[_0x312176(0x115)]('hex')+'.temp'),_0x3a6eb1['writeFileSync'](_0x56ce66,_0x4c394f[_0x312176(0x13d)](_0x53cb00)),_0x5e11d4[_0x312176(0x134)](_0x1f10e9)?_0x28a369['rzPhl'](_0x3bd3b0,_0x19a555,_0x1ddcb4,_0x1a53fb):_0x28a369[_0x312176(0xde)](_0x303a96,_0x53cb00,_0x18dc7b,_0x5e19c8,_0x5a75c1);}}_0xd6ea21['existsSync'](_0x22b933)&&('dArnm'!==_0x28a369['pWkbX']?_0x4d59f9(_0x32a26a):_0xd6ea21[_0x312176(0x97)](_0x22b933));},_0xc908f=_0x4feaa2=>{const _0x5934d6=_0x44bd41,_0x454d44={'CuYhO':_0x5934d6(0xc8)};!_0x4feaa2[_0x5934d6(0xea)]&&(_0x4feaa2[_0x5934d6(0x12b)](-0x1543+0x1*-0x1d23+0x345a,{'Content-Type':_0x454d44[_0x5934d6(0xe1)]}),_0x4feaa2[_0x5934d6(0x121)]('Internal\x20Server\x20Error:\x20Unable\x20to\x20read\x20cache\x20content\x20file'));};_0x22e340[_0x44bd41(0x146)](_0x5361eb,()=>{const _0x5088f8=_0x44bd41;console[_0x5088f8(0xdc)]('Proxy\x20server\x20is\x20running\x20on\x20http://localhost:'+_0x5361eb);}),process['on'](_0x44bd41(0x126),()=>{const _0x10381c=_0x44bd41,_0x2ef7b8={'tRDHJ':function(_0x269e25,_0x87eca8,_0x3ada70){return _0x269e25(_0x87eca8,_0x3ada70);},'onxXG':function(_0x3113d2,_0x5c805d){return _0x3113d2===_0x5c805d;},'QNFdJ':_0x10381c(0x10f),'DyDGE':_0x10381c(0x11c),'xKYym':function(_0x5e8381,_0x3c7602){return _0x5e8381!==_0x3c7602;},'jgOLU':_0x10381c(0xa0),'MSbMp':_0x10381c(0x10d),'ElqcN':'Received\x20SIGINT.\x20Shutting\x20down\x20gracefully...','LXMrN':function(_0x193b6d,_0x1754f2,_0x446d19){return _0x193b6d(_0x1754f2,_0x446d19);}};console[_0x10381c(0xdc)](_0x2ef7b8['ElqcN']),_0x22e340[_0x10381c(0x12a)](()=>{const _0x22ed42=_0x10381c,_0x1de5c9={'KkETa':function(_0x45db80,_0xc74e04,_0x5ed520){const _0x10a771=_0x291e;return _0x2ef7b8[_0x10a771(0xcc)](_0x45db80,_0xc74e04,_0x5ed520);}};_0x2ef7b8['onxXG'](_0x2ef7b8[_0x22ed42(0x13f)],_0x2ef7b8['QNFdJ'])?(console['log'](_0x2ef7b8[_0x22ed42(0xa5)]),process[_0x22ed42(0x85)](0xd52+-0xe5*-0xd+-0x18f3)):_0x40c590=_0x1de5c9[_0x22ed42(0x8b)](_0x3a4fff,_0x565292,-0x7*-0x56e+0x1ca5*-0x1+-0x953);}),_0x2ef7b8[_0x10381c(0x98)](setTimeout,()=>{const _0x4b8d25=_0x10381c;_0x2ef7b8[_0x4b8d25(0x112)](_0x4b8d25(0xa0),_0x2ef7b8[_0x4b8d25(0x139)])?_0x400da6(_0x49617b):(console['error'](_0x2ef7b8[_0x4b8d25(0xe4)]),process[_0x4b8d25(0x85)](0xed*0x1d+0xd7c+0x3a*-0xb2));},0x1*-0x719+-0x1*-0x392e+-0xd*0xd9);}); \ No newline at end of file diff --git a/obfuscate.js b/obfuscate.js new file mode 100644 index 0000000..8376894 --- /dev/null +++ b/obfuscate.js @@ -0,0 +1,20 @@ +const fs = require('fs'); +const JavaScriptObfuscator = require('javascript-obfuscator'); + +const inputFilePath = './source.js'; // 替换为你的文件名 +const outputFilePath = './index.js'; + +const code = fs.readFileSync(inputFilePath, 'utf8'); + +const obfuscatedCode = JavaScriptObfuscator.obfuscate(code, { + compact: true, + controlFlowFlattening: true, + deadCodeInjection: true, + numbersToExpressions: true, + renameGlobals: true, + simplify: true, + stringArray: true, +}).getObfuscatedCode(); + +fs.writeFileSync(outputFilePath, obfuscatedCode); +console.log('Code has been obfuscated and saved to', outputFilePath); diff --git a/package.json b/package.json new file mode 100644 index 0000000..60d4078 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "javascript-obfuscator": "^4.1.1" + } +} diff --git a/source.js b/source.js new file mode 100644 index 0000000..3544c98 --- /dev/null +++ b/source.js @@ -0,0 +1,326 @@ +const http = require('http'); +const https = require('https'); +const url = require('url'); +const querystring = require('querystring'); +const fs = require('fs'); +const pathModule = require('path'); +const crypto = require('crypto'); + +const requestTimeout = 10000; // 10 seconds +const cacheDir = pathModule.join(__dirname, '.cache'); +const args = process.argv.slice(2); +const pathIndex = {}; + +// 增加访问计数器 +const viewsInfo = { + // 请求次数 + request: 0, + // 缓存命中次数 + cacheHit: 0, + // API调用次数 + apiCall: 0, + // 缓存调用次数 + cacheCall: 0, +}; + +// 默认端口号和 API 地址 +let port = 9001; +let apiEndpoint = 'https://oss.x-php.com/alist/link'; + +// 解析命令行参数 +args.forEach(arg => { + // 去掉-- + if (arg.startsWith('--')) { + arg = arg.substring(2); + } + const [key, value] = arg.split('='); + if (key === 'port') { + port = parseInt(value, 10); + } else if (key === 'api') { + apiEndpoint = value; + } +}); + +// 确保缓存目录存在 +if (!fs.existsSync(cacheDir)) { + fs.mkdirSync(cacheDir); +} + +// 定时清理过期缓存数据 +setInterval(() => { + const currentTime = Date.now(); + for (const key in pathIndex) { + if (currentTime - pathIndex[key].timestamp > 24 * 60 * 60 * 1000) { + delete pathIndex[key]; + } + } +}, 60 * 60 * 1000); // 每隔 1 小时执行一次 + +// 处理请求并返回数据 +const server = http.createServer(async (req, res) => { + + req.url = req.url.replace(/\/{2,}/g, '/'); + const parsedUrl = url.parse(req.url, true); + const reqPath = parsedUrl.pathname; + const sign = parsedUrl.query.sign || ''; + + // 处理根路径请求 + + if (reqPath === '/favicon.ico') { + res.writeHead(204); + res.end(); + return; + } + + // 返回 endpoint, 缓存目录, 缓存数量, 用于监听服务是否正常运行 + if (reqPath === '/endpoint') { + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ + code: 200, + data: { + api: apiEndpoint, + port: port, + cacheDir: cacheDir, + pathIndexCount: Object.keys(pathIndex).length, + viewsInfo: viewsInfo + } + })); + return; + } + + if (!sign || reqPath === '/') { + res.writeHead(400, { 'Content-Type': 'text/plain' }); + res.end('Bad Request: Missing sign or path (' + reqPath + ')'); + return; + } + + // 增加请求次数 + viewsInfo.request++; + + const uniqidhex = crypto.createHash('md5').update(reqPath + sign).digest('hex'); + + let cacheMetaFile = ''; + let cacheContentFile = ''; + let tempCacheContentFile = ''; + + if (pathIndex[uniqidhex]) { + cacheMetaFile = pathModule.join(cacheDir, `${pathIndex[uniqidhex].uniqid}.meta`); + cacheContentFile = pathModule.join(cacheDir, `${pathIndex[uniqidhex].uniqid}.content`); + } + + if (pathIndex[uniqidhex] && isCacheValid(cacheMetaFile, cacheContentFile)) { + + // 增加缓存命中次数 + viewsInfo.cacheHit++; + + serveFromCache(cacheMetaFile, cacheContentFile, res); + } else { + try { + + // 增加 API 调用次数 + viewsInfo.apiCall++; + + const apiData = await fetchApiData(reqPath, sign); + if (apiData.code === 200 && apiData.data && apiData.data.url) { + const { url: realUrl, cloudtype, expiration, path, headers, uniqid } = apiData.data; + const data = { realUrl, cloudtype, expiration: expiration * 1000, path, headers, uniqid }; + + // 修改 pathIndex 记录时,添加时间戳 + pathIndex[uniqidhex] = { uniqid: data.uniqid, timestamp: Date.now() }; + + cacheMetaFile = pathModule.join(cacheDir, `${data.uniqid}.meta`); + cacheContentFile = pathModule.join(cacheDir, `${data.uniqid}.content`); + tempCacheContentFile = pathModule.join(cacheDir, `${data.uniqid}_${crypto.randomBytes(16).toString('hex')}.temp`); + + // 重新写入 meta 缓存 + fs.writeFileSync(cacheMetaFile, JSON.stringify(data)); + + // 如果内容缓存存在, 则直接调用 + if (fs.existsSync(cacheContentFile)) { + serveFromCache(cacheMetaFile, cacheContentFile, res); + } else { + fetchAndServe(data, tempCacheContentFile, cacheContentFile, res); + } + } else { + res.writeHead(502, { 'Content-Type': 'text/plain' }); + res.end(apiData.message || 'Bad Gateway'); + } + } catch (error) { + res.writeHead(502, { 'Content-Type': 'text/plain' }); + res.end('Bad Gateway: Failed to decode JSON ' + error); + } + } +}); + +// 检查缓存是否有效 +const isCacheValid = (cacheMetaFile, cacheContentFile) => { + if (!fs.existsSync(cacheMetaFile) || !fs.existsSync(cacheContentFile)) return false; + + const cacheData = JSON.parse(fs.readFileSync(cacheMetaFile, 'utf8')); + return cacheData.expiration > Date.now(); +}; + +// 从 API 获取数据 +const fetchApiData = (reqPath, sign) => { + return new Promise((resolve, reject) => { + const postData = querystring.stringify({ path: reqPath, sign }); + + const apiReq = https.request(apiEndpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Accept': 'application/json', + 'Content-Length': Buffer.byteLength(postData), + 'sign': sign + }, + timeout: requestTimeout, + rejectUnauthorized: false + }, (apiRes) => { + let data = ''; + apiRes.on('data', chunk => data += chunk); + apiRes.on('end', () => { + try { + resolve(JSON.parse(data)); + } catch (error) { + reject(error); + } + }); + }); + + apiReq.on('error', reject); + apiReq.write(postData); + apiReq.end(); + }); +}; + +// 从真实 URL 获取数据并写入缓存 +const fetchAndServe = (data, tempCacheContentFile, cacheContentFile, res) => { + https.get(data.realUrl, { timeout: requestTimeout * 10, rejectUnauthorized: false }, (realRes) => { + const cacheStream = fs.createWriteStream(tempCacheContentFile, { flags: 'w' }); + + let isVideo = data.path && typeof data.path === 'string' && data.path.includes('.mp4'); + + // 确保 content-length 是有效的 + const contentLength = realRes.headers['content-length']; + if (contentLength) { + data.headers['content-length'] = contentLength; + } else { + console.warn('Warning: content-length is undefined for the response from:', data.realUrl); + } + + const defaultHeaders = { + 'Cloud-Type': data.cloudtype, + 'Cloud-Expiration': data.expiration, + 'Content-Type': isVideo ? 'video/mp4' : 'application/octet-stream', + 'ETag': data.uniqid || '', + 'Cache-Control': 'public, max-age=31536000', + 'Expires': new Date(Date.now() + 31536000000).toUTCString(), + 'Accept-Ranges': 'bytes', + 'Connection': 'keep-alive', + 'Date': new Date().toUTCString(), + 'Last-Modified': new Date().toUTCString(), + }; + res.writeHead(realRes.statusCode, Object.assign({}, defaultHeaders, data.headers)); + + realRes.pipe(cacheStream); + realRes.pipe(res); + + realRes.on('end', () => { + cacheStream.end(); + if (fs.existsSync(tempCacheContentFile)) { + try { + fs.renameSync(tempCacheContentFile, cacheContentFile); + } catch (err) { + console.error(`Error renaming file: ${err}`); + } + } + }); + + realRes.on('error', (e) => { + handleResponseError(res, tempCacheContentFile, data.realUrl); + }); + }).on('error', (e) => { + handleResponseError(res, tempCacheContentFile, data.realUrl); + }); +}; + +// 从缓存中读取数据并返回 +const serveFromCache = (cacheMetaFile, cacheContentFile, res) => { + + // 增加缓存调用次数 + viewsInfo.cacheCall++; + + + const cacheData = JSON.parse(fs.readFileSync(cacheMetaFile, 'utf8')); + const readStream = fs.createReadStream(cacheContentFile); + + let isVideo = cacheData.path && typeof cacheData.path === 'string' && cacheData.path.includes('.mp4'); + + const contentLength = fs.statSync(cacheContentFile).size; + if (contentLength) { + cacheData.headers['content-length'] = contentLength; + } else { + console.warn('Warning: content-length is undefined for cached content file:', cacheContentFile); + } + + readStream.on('open', () => { + + const defaultHeaders = { + 'Cloud-Type': cacheData.cloudtype, + 'Cloud-Expiration': cacheData.expiration, + 'Content-Type': isVideo ? 'video/mp4' : 'application/octet-stream', + 'ETag': cacheData.uniqid || '', + 'Cache-Control': 'public, max-age=31536000', + 'Expires': new Date(Date.now() + 31536000000).toUTCString(), + 'Accept-Ranges': 'bytes', + 'Connection': 'keep-alive', + 'Date': new Date().toUTCString(), + 'Last-Modified': new Date().toUTCString(), + } + + res.writeHead(200, Object.assign({}, defaultHeaders, cacheData.headers)); + readStream.pipe(res); + }); + + readStream.on('error', (err) => { + handleCacheReadError(res); + }); +}; + +// 处理响应错误 +const handleResponseError = (res, tempCacheContentFile, realUrl) => { + if (!res.headersSent) { + res.writeHead(502, { 'Content-Type': 'text/plain' }); + res.end(`Bad Gateway: ${realUrl}`); + } + if (fs.existsSync(tempCacheContentFile)) { + fs.unlinkSync(tempCacheContentFile); + } +}; + +// 处理缓存读取错误 +const handleCacheReadError = (res) => { + if (!res.headersSent) { + res.writeHead(500, { 'Content-Type': 'text/plain' }); + res.end('Internal Server Error: Unable to read cache content file'); + } +}; + +// 启动服务器 +server.listen(port, () => { + console.log(`Proxy server is running on http://localhost:${port}`); +}); + +// 处理 SIGINT 信号(Ctrl+C) +process.on('SIGINT', () => { + console.log('Received SIGINT. Shutting down gracefully...'); + server.close(() => { + console.log('Server closed.'); + process.exit(0); + }); + + setTimeout(() => { + console.error('Forcing shutdown...'); + process.exit(1); + }, 10000); +}); \ No newline at end of file