Advertise byte ranges on downloads, and record the live checks
Stalwart honors a single byte range on its download endpoint but sends no Accept-Ranges, and Chrome's PDF viewer only reads a file in pieces when the first response says it can. The proxy now says so itself. Checked live on 0.16.22: ContactCard/changes reports creates, updates and destroys exactly, which the contacts store's sync relies on, and a range the server cannot serve gets the whole file with 200, never 416. The mock now answers ranges the same way and sends no Accept-Ranges.
This commit is contained in:
@@ -139,20 +139,23 @@ export const server = createServer(async (req, res) => {
|
||||
const b = blobs.get(blobId ?? "");
|
||||
if (!b) { res.writeHead(404); return res.end(); }
|
||||
const type = url.searchParams.get("accept") ?? b.type;
|
||||
// One byte range, the way a PDF viewer or a video element asks for one.
|
||||
/*
|
||||
* One byte range, answered as Stalwart answers it (0.16.22, checked live
|
||||
* on 2026-09-16): a 206 for a single range it can serve, and the whole
|
||||
* file with a 200 for anything else -- several ranges, or one past the
|
||||
* end. It never sends Accept-Ranges.
|
||||
*/
|
||||
const m = /^bytes=(\d*)-(\d*)$/.exec(String(req.headers.range ?? ""));
|
||||
if (m && (m[1] || m[2])) {
|
||||
const size = b.data.length;
|
||||
const start = m[1] ? Number(m[1]) : Math.max(0, size - Number(m[2]));
|
||||
const end = m[1] && m[2] ? Math.min(Number(m[2]), size - 1) : size - 1;
|
||||
if (start >= size || start > end) {
|
||||
res.writeHead(416, { "content-range": `bytes */${size}` });
|
||||
return res.end();
|
||||
if (start < size && start <= end) {
|
||||
res.writeHead(206, { "content-type": type, "content-length": end - start + 1, "content-range": `bytes ${start}-${end}/${size}` });
|
||||
return res.end(b.data.subarray(start, end + 1));
|
||||
}
|
||||
res.writeHead(206, { "content-type": type, "content-length": end - start + 1, "content-range": `bytes ${start}-${end}/${size}`, "accept-ranges": "bytes" });
|
||||
return res.end(b.data.subarray(start, end + 1));
|
||||
}
|
||||
res.writeHead(200, { "content-type": type, "content-length": b.data.length, "accept-ranges": "bytes" });
|
||||
res.writeHead(200, { "content-type": type, "content-length": b.data.length });
|
||||
return res.end(b.data);
|
||||
}
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user