From 6b33982a5500599058fc38a944cf04a0a0c99ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=92=8B=E5=B0=8F=E9=99=8C?= Date: Fri, 27 Sep 2024 23:09:57 +0800 Subject: [PATCH] 111 --- index.js | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/index.js b/index.js index 24197cb..01894cb 100644 --- a/index.js +++ b/index.js @@ -37,8 +37,6 @@ const server = http.createServer(async (req, res) => { const parsedUrl = url.parse(req.url, true); const reqPath = parsedUrl.pathname; const sign = parsedUrl.query.sign || ''; - - // 只要reqPath的文件名,不要路径 const reqName = parsedUrl.pathname.split('/').pop(); const cacheMetaFile = path.join(cacheDir, `${reqName.replace(/\//g, '_')}.meta`); const cacheContentFile = path.join(cacheDir, `${reqName.replace(/\//g, '_')}.content`); @@ -63,7 +61,6 @@ const server = http.createServer(async (req, res) => { fs.writeFileSync(cacheMetaFile, JSON.stringify(data)); } - // 如果 cacheContentFile 存在 直接调用它 if (fs.existsSync(cacheContentFile)) { serveFromCache(cacheMetaFile, cacheContentFile, res); return; @@ -120,31 +117,36 @@ const fetchApiData = (reqPath, sign) => { const fetchAndServe = (data, tempCacheContentFile, cacheContentFile, res) => { https.get(data.realUrl, { timeout: requestTimeout * 10 }, (realRes) => { - - // 创建临时缓存文件流 const cacheStream = fs.createWriteStream(tempCacheContentFile, { flags: 'w' }); - // 通过 data.path 判断是否是视频.mp4 const isVideo = data.path.includes('.mp4'); + data.headers['content-length'] = realRes.headers['content-length']; res.writeHead(realRes.statusCode, { ...data.headers, - 'Content-Type': isVideo ? 'video/mp4' : 'application/octet-stream', '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(), - 'ETag': data.uniqid || '' }); realRes.pipe(cacheStream); realRes.pipe(res); realRes.on('end', () => { - // 下载完成后,将临时文件重命名为最终缓存文件 - fs.renameSync(tempCacheContentFile, cacheContentFile); cacheStream.end(); + if (fs.existsSync(tempCacheContentFile)) { + try { + fs.renameSync(tempCacheContentFile, cacheContentFile); + } catch (err) { + console.error(`Error renaming file: ${err}`); + } + } }); realRes.on('error', (e) => { @@ -152,33 +154,41 @@ const fetchAndServe = (data, tempCacheContentFile, cacheContentFile, res) => { res.writeHead(502, { 'Content-Type': 'text/plain' }); res.end(`Bad Gateway: ${data.realUrl}`); } - fs.unlinkSync(tempCacheContentFile); // 删除临时文件 + if (fs.existsSync(tempCacheContentFile)) { + fs.unlinkSync(tempCacheContentFile); + } }); }).on('error', (e) => { if (!res.headersSent) { res.writeHead(502, { 'Content-Type': 'text/plain' }); res.end(`Bad Gateway: ${data.realUrl}`); } - fs.unlinkSync(tempCacheContentFile); // 删除临时文件 + if (fs.existsSync(tempCacheContentFile)) { + fs.unlinkSync(tempCacheContentFile); + } }); }; const serveFromCache = (cacheMetaFile, cacheContentFile, res) => { const cacheData = JSON.parse(fs.readFileSync(cacheMetaFile, 'utf8')); const readStream = fs.createReadStream(cacheContentFile); - // 判断是否是视频 const isVideo = cacheData.path.includes('.mp4'); + + cacheData.headers['content-length'] = fs.statSync(cacheContentFile).size; + readStream.on('open', () => { res.writeHead(200, { ...cacheData.headers, - 'Content-Type': isVideo ? 'video/mp4' : 'application/octet-stream', '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(), - 'ETag': cacheData.uniqid || '' }); readStream.pipe(res); }); @@ -203,7 +213,6 @@ process.on('SIGINT', () => { process.exit(0); }); - // Force shutdown after 10 seconds if not closed setTimeout(() => { console.error('Forcing shutdown...'); process.exit(1);