diff --git a/desktop/src/main/stream.ts b/desktop/src/main/stream.ts index 1c8223c87c..262e4dc055 100644 --- a/desktop/src/main/stream.ts +++ b/desktop/src/main/stream.ts @@ -106,7 +106,12 @@ const handleRead = async (path: string) => { res.headers.set("Content-Length", `${fileSize}`); // Add the file's last modified time (as epoch milliseconds). - const mtimeMs = stat.mtimeMs; + // + // [Note: Use integral epoch milliseconds] + // + // The `mtimeMs` returned by Node.js is a double, with sub-millisecond + // precision. Ente clients expect integral milliseconds, so truncate. + const mtimeMs = Math.trunc(stat.mtimeMs); res.headers.set("X-Last-Modified-Ms", `${mtimeMs}`); } return res; @@ -132,6 +137,17 @@ const handleReadZip = async (zipPath: string, entryName: string) => { // Close the zip handle when the underlying stream closes. stream.on("end", () => void zip.close()); + // While it is documented that entry.time is the modification time, + // the units are not mentioned. By seeing the source code, we can + // verify that it is indeed epoch milliseconds. See `parseZipTime` + // in the node-stream-zip source, + // https://github.com/antelle/node-stream-zip/blob/master/node_stream_zip.js + // + // See also: [Note: Use integral epoch milliseconds]. In this case I didn't + // actually find an example of submillisecond precision, just being + // preemptively careful and this Math.trunc might not necessarily be needed. + const modifiedMs = Math.trunc(entry.time); + return new Response(webReadableStream, { headers: { // We don't know the exact type, but it doesn't really matter, just @@ -139,12 +155,7 @@ const handleReadZip = async (zipPath: string, entryName: string) => { // doesn't tinker with it thinking of it as text. "Content-Type": "application/octet-stream", "Content-Length": `${entry.size}`, - // While it is documented that entry.time is the modification time, - // the units are not mentioned. By seeing the source code, we can - // verify that it is indeed epoch milliseconds. See `parseZipTime` - // in the node-stream-zip source, - // https://github.com/antelle/node-stream-zip/blob/master/node_stream_zip.js - "X-Last-Modified-Ms": `${entry.time}`, + "X-Last-Modified-Ms": `${modifiedMs}`, }, }); };