From e48179a1f992eef4551474f69778508fe92d3ce3 Mon Sep 17 00:00:00 2001 From: ProgrammerIn-wonderland <3838shah@gmail.com> Date: Wed, 27 Aug 2025 18:01:19 -0400 Subject: [PATCH] fix: improve support for unbounded range headers --- .../src/routers/filesystem_api/read.js | 26 ++++++++++++++++--- .../src/routers/filesystem_api/token-read.js | 26 ++++++++++++++++--- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/backend/src/routers/filesystem_api/read.js b/src/backend/src/routers/filesystem_api/read.js index eab0537b5..022570fd7 100644 --- a/src/backend/src/routers/filesystem_api/read.js +++ b/src/backend/src/routers/filesystem_api/read.js @@ -94,10 +94,28 @@ module.exports = eggspress('/read', { const rangeInfo = parseRangeHeader(req.headers["range"]); if (rangeInfo) { const { start, end, isMultipart } = rangeInfo; - const contentRange = end !== null - ? `bytes ${start}-${end}/*` - : `bytes ${start}-*/*`; - res.set("Content-Range", contentRange); + + // For open-ended ranges, we need to calculate the actual end byte + let actualEnd = end; + let fileSize = null; + + try { + fileSize = await req.values.fsNode.get('size'); + if (end === null) { + actualEnd = fileSize - 1; // File size is 1-based, end byte is 0-based + } + } catch (e) { + // If we can't get file size, we'll let the storage layer handle it + // and not set Content-Range header + actualEnd = null; + fileSize = null; + } + + if (actualEnd !== null) { + const totalSize = fileSize !== null ? fileSize : '*'; + const contentRange = `bytes ${start}-${actualEnd}/${totalSize}`; + res.set("Content-Range", contentRange); + } // If this was a multipart request, modify the range header to only include the first range if (isMultipart) { diff --git a/src/backend/src/routers/filesystem_api/token-read.js b/src/backend/src/routers/filesystem_api/token-read.js index ef168258b..b7b4b5ab7 100644 --- a/src/backend/src/routers/filesystem_api/token-read.js +++ b/src/backend/src/routers/filesystem_api/token-read.js @@ -113,10 +113,28 @@ module.exports = eggspress('/token-read', { const rangeInfo = parseRangeHeader(req.headers["range"]); if (rangeInfo) { const { start, end, isMultipart } = rangeInfo; - const contentRange = end !== null - ? `bytes ${start}-${end}/*` - : `bytes ${start}-*/*`; - res.set("Content-Range", contentRange); + + // For open-ended ranges, we need to calculate the actual end byte + let actualEnd = end; + let fileSize = null; + + try { + fileSize = await req.values.fsNode.get('size'); + if (end === null) { + actualEnd = fileSize - 1; // File size is 1-based, end byte is 0-based + } + } catch (e) { + // If we can't get file size, we'll let the storage layer handle it + // and not set Content-Range header + actualEnd = null; + fileSize = null; + } + + if (actualEnd !== null) { + const totalSize = fileSize !== null ? fileSize : '*'; + const contentRange = `bytes ${start}-${actualEnd}/${totalSize}`; + res.set("Content-Range", contentRange); + } // If this was a multipart request, modify the range header to only include the first range if (isMultipart) {