Extract and modernize the webserver's range file serving code

The `handler` method contained this code in an inline function, which
made the `handler` method big and harder to read. Moreover, this code
relied on variables from the outer scope, which made it harder to reason
about because the inputs and outputs weren't easily visible.

This commit fixes the problems by extracting the range file serving code
into a dedicated private method, and modernizing it to use e.g. `const`/
`let` instead of `var` and using template strings.
This commit is contained in:
Tim van der Meij 2024-02-11 13:49:42 +01:00
parent 56d9930a7b
commit 336fcffd28
No known key found for this signature in database
GPG Key ID: 8C3FD2925A5F2762

View File

@ -182,8 +182,10 @@ class WebServer {
if (verbose) { if (verbose) {
console.log(url + ": range " + start + " - " + end); console.log(url + ": range " + start + " - " + end);
} }
serveRequestedFileRange( self.#serveFileRange(
res,
filePath, filePath,
fileSize,
start, start,
isNaN(end) ? fileSize : end + 1 isNaN(end) ? fileSize : end + 1
); );
@ -285,33 +287,6 @@ class WebServer {
res.end("</body></html>"); res.end("</body></html>");
}); });
} }
function serveRequestedFileRange(reqFilePath, start, end) {
var stream = fs.createReadStream(reqFilePath, {
flags: "rs",
start,
end: end - 1,
});
stream.on("error", function (error) {
res.writeHead(500);
res.end();
});
var ext = path.extname(reqFilePath).toLowerCase();
var contentType = mimeTypes[ext] || defaultMimeType;
res.setHeader("Accept-Ranges", "bytes");
res.setHeader("Content-Type", contentType);
res.setHeader("Content-Length", end - start);
res.setHeader(
"Content-Range",
"bytes " + start + "-" + (end - 1) + "/" + fileSize
);
res.writeHead(206);
stream.pipe(res);
}
} }
#serveFile(response, filePath, fileSize) { #serveFile(response, filePath, fileSize) {
@ -337,6 +312,31 @@ class WebServer {
response.writeHead(200); response.writeHead(200);
stream.pipe(response); stream.pipe(response);
} }
#serveFileRange(response, filePath, fileSize, start, end) {
const stream = fs.createReadStream(filePath, {
flags: "rs",
start,
end: end - 1,
});
stream.on("error", error => {
response.writeHead(500);
response.end();
});
const extension = path.extname(filePath).toLowerCase();
const contentType = mimeTypes[extension] || defaultMimeType;
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Content-Type", contentType);
response.setHeader("Content-Length", end - start);
response.setHeader(
"Content-Range",
`bytes ${start}-${end - 1}/${fileSize}`
);
response.writeHead(206);
stream.pipe(response);
}
} }
// This supports the "Cross-origin" test in test/unit/api_spec.js // This supports the "Cross-origin" test in test/unit/api_spec.js