From 22c73a4f75f9e1614687be7a0740e4afd0471b40 Mon Sep 17 00:00:00 2001 From: Roddy <107297718+dhd2333@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:52:46 -0400 Subject: [PATCH 1/3] Update fileTools.js --- functions/file/fileTools.js | 46 ++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/functions/file/fileTools.js b/functions/file/fileTools.js index 1f8a5ead..d55dc6cf 100644 --- a/functions/file/fileTools.js +++ b/functions/file/fileTools.js @@ -35,6 +35,8 @@ export function setCommonHeaders(headers, encodedFileName, fileType, Referer, ur headers.set('Content-Disposition', `inline; filename="${encodedFileName}"; filename*=UTF-8''${encodedFileName}`); headers.set('Access-Control-Allow-Origin', '*'); headers.set('Accept-Ranges', 'bytes'); + + headers.append('Vary', 'Range'); if (fileType) { headers.set('Content-Type', fileType); @@ -77,19 +79,46 @@ export function handleHeadRequest(headers, etag = null) { }); } -export async function getFileContent(request, targetUrl, max_retries = 2) { +export async function getFileContent(request: Request, targetUrl: string, max_retries = 2) { let retries = 0; while (retries <= max_retries) { try { - const response = await fetch(targetUrl, { - method: request.method, - headers: request.headers, - body: request.body, + // 复制请求头,确保 Range / If-None-Match 等关键头透传 + const fwdHeaders = new Headers(request.headers); + + // Range 兜底:有些运行时需要手动 set 一下 + const range = request.headers.get("Range"); + if (range) fwdHeaders.set("Range", range); + + const upstreamReq = new Request(targetUrl, { + method: request.method === "HEAD" ? "HEAD" : "GET", // 只允许 GET/HEAD + headers: fwdHeaders, + redirect: "follow", }); + + const response = await fetch(upstreamReq); + if (response.ok || response.status === 304) { - return response; + // 加关键头,避免缓存 200 全文件覆盖 Range + const headers = new Headers(response.headers); + headers.set("Vary", "Range"); + + // 如果是 Range 请求但上游返回 200,这里可以兜底转 206 + if (range && response.status === 200) { + headers.set("Accept-Ranges", "bytes"); + return new Response(response.body, { + status: 206, + headers, + }); + } + + return new Response(response.body, { + status: response.status, + statusText: response.statusText, + headers, + }); } else if (response.status === 404) { - return new Response('Error: Image Not Found', { status: 404 }); + return new Response("Error: Image Not Found", { status: 404 }); } else { retries++; } @@ -100,6 +129,7 @@ export async function getFileContent(request, targetUrl, max_retries = 2) { return null; } + export function isTgChannel(imgRecord) { return imgRecord.metadata?.Channel === 'Telegram' || imgRecord.metadata?.Channel === 'TelegramNew'; } @@ -208,4 +238,4 @@ export async function returnWhiteListImg(url) { }, }); } -} \ No newline at end of file +} From 53d88f19fba1196ca1f367c2e839b59153871afc Mon Sep 17 00:00:00 2001 From: Roddy <107297718+dhd2333@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:54:09 -0400 Subject: [PATCH 2/3] Update fileTools.js --- functions/file/fileTools.js | 38 ++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/functions/file/fileTools.js b/functions/file/fileTools.js index d55dc6cf..52ddff01 100644 --- a/functions/file/fileTools.js +++ b/functions/file/fileTools.js @@ -79,50 +79,54 @@ export function handleHeadRequest(headers, etag = null) { }); } -export async function getFileContent(request: Request, targetUrl: string, max_retries = 2) { +export async function getFileContent(request, targetUrl, max_retries = 2) { let retries = 0; while (retries <= max_retries) { try { - // 复制请求头,确保 Range / If-None-Match 等关键头透传 + // 复制请求头,确保 Range / If-None-Match 等关键头被透传 const fwdHeaders = new Headers(request.headers); - // Range 兜底:有些运行时需要手动 set 一下 + // 显式兜底:有些运行时需要手动 set 一下 const range = request.headers.get("Range"); if (range) fwdHeaders.set("Range", range); + // 只允许 GET/HEAD 转发 + const method = request.method === "HEAD" ? "HEAD" : "GET"; + const upstreamReq = new Request(targetUrl, { - method: request.method === "HEAD" ? "HEAD" : "GET", // 只允许 GET/HEAD + method, headers: fwdHeaders, redirect: "follow", }); - const response = await fetch(upstreamReq); + const upstreamRes = await fetch(upstreamReq); - if (response.ok || response.status === 304) { - // 加关键头,避免缓存 200 全文件覆盖 Range - const headers = new Headers(response.headers); - headers.set("Vary", "Range"); + if (upstreamRes.ok || upstreamRes.status === 304) { + const headers = new Headers(upstreamRes.headers); - // 如果是 Range 请求但上游返回 200,这里可以兜底转 206 - if (range && response.status === 200) { + // 关键:让缓存区分是否带 Range + headers.append("Vary", "Range"); + + // 如果是 Range 请求但上游仍返回 200,这里兜底改成 206 + if (range && upstreamRes.status === 200) { headers.set("Accept-Ranges", "bytes"); - return new Response(response.body, { + return new Response(upstreamRes.body, { status: 206, headers, }); } - return new Response(response.body, { - status: response.status, - statusText: response.statusText, + return new Response(upstreamRes.body, { + status: upstreamRes.status, + statusText: upstreamRes.statusText, headers, }); - } else if (response.status === 404) { + } else if (upstreamRes.status === 404) { return new Response("Error: Image Not Found", { status: 404 }); } else { retries++; } - } catch (error) { + } catch (_err) { retries++; } } From bec0b965269daae77cf3b16e63675ed44a93d870 Mon Sep 17 00:00:00 2001 From: Roddy <107297718+dhd2333@users.noreply.github.com> Date: Thu, 28 Aug 2025 16:24:31 -0400 Subject: [PATCH 3/3] Update [[path]].js --- functions/file/[[path]].js | 39 +++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/functions/file/[[path]].js b/functions/file/[[path]].js index da2fe8aa..d350d67a 100644 --- a/functions/file/[[path]].js +++ b/functions/file/[[path]].js @@ -175,7 +175,9 @@ async function handleTelegramChunkedFile(context, imgRecord, encodedFileName, fi const headers = new Headers(); setCommonHeaders(headers, encodedFileName, fileType, Referer, url); headers.set('Content-Length', totalSize.toString()); - + + headers.append('Vary', 'Range'); + // 添加ETag支持 const etag = `"${metadata.TimeStamp || Date.now()}-${totalSize}"`; headers.set('ETag', etag); @@ -268,20 +270,27 @@ async function handleTelegramChunkedFile(context, imgRecord, encodedFileName, fi } }); - // 设置Range相关头部 - if (isRangeRequest) { - setRangeHeaders(headers, rangeStart, rangeEnd, totalSize); - - return new Response(stream, { - status: 206, // Partial Content - headers, - }); - } else { - return new Response(stream, { - status: 200, - headers, - }); - } +// 设置Range相关头部 +if (isRangeRequest) { +setRangeHeaders(headers, rangeStart, rangeEnd, totalSize); + + // 明确告诉浏览器/CF:支持分段请求 + headers.set('Accept-Ranges', 'bytes'); + + return new Response(stream, { + status: 206, // Partial Content + headers, + }); +} else { + // 关键:避免首个 200 整段被缓存,导致后续 Range 请求直接命中 200 + headers.set('Cache-Control', 'no-store'); // 或 'max-age=0, must-revalidate' + + return new Response(stream, { + status: 200, + headers, + }); +} + } catch (error) { return new Response(`Error: Failed to reconstruct chunked file - ${error.message}`, { status: 500 });