From af5764273b29b2e34ead0b54bfefe3ca912fedd1 Mon Sep 17 00:00:00 2001 From: Tim van der Meij Date: Sun, 11 Feb 2024 16:46:01 +0100 Subject: [PATCH] Extract and modernize the webserver's directory listing 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 directory listing code into a dedicated private method, and modernizing it to use e.g. `const`/ `let` instead of `var` and using template strings. --- test/webserver.mjs | 144 ++++++++++++++++++++++----------------------- 1 file changed, 71 insertions(+), 73 deletions(-) diff --git a/test/webserver.mjs b/test/webserver.mjs index 57c913d66a9772..f9094f0fb5c161 100644 --- a/test/webserver.mjs +++ b/test/webserver.mjs @@ -162,7 +162,7 @@ class WebServer { return; } if (isDir) { - serveDirectoryIndex(filePath); + self.#serveDirectoryIndex(res, pathPart, queryPart, filePath); return; } @@ -196,97 +196,95 @@ class WebServer { } self.#serveFile(res, filePath, fileSize); } + } - function escapeHTML(untrusted) { + #serveDirectoryIndex(response, pathPart, queryPart, directory) { + const escapeHTML = untrusted => // Escape untrusted input so that it can safely be used in a HTML response // in HTML and in HTML attributes. - return untrusted + untrusted .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """) .replaceAll("'", "'"); - } - function serveDirectoryIndex(dir) { - res.setHeader("Content-Type", "text/html"); - res.writeHead(200); + response.setHeader("Content-Type", "text/html"); + response.writeHead(200); - if (queryPart === "frame") { - res.end( - "" + - '', - "utf8" - ); + if (queryPart === "frame") { + response.end( + ` + + + + + `, + "utf8" + ); + return; + } + + const all = queryPart === "all"; + fs.readdir(directory, function (error, files) { + if (error) { + response.end(); return; } - var all = queryPart === "all"; - fs.readdir(dir, function (err, files) { - if (err) { - res.end(); - return; - } - res.write( - '' + - "

PDFs of " + - pathPart + - "

\n" - ); - if (pathPart !== "/") { - res.write('..
\n'); + response.write( + ` + + + + +

Index of ${pathPart}

+ ` + ); + if (pathPart !== "/") { + response.write('..
'); + } + files.forEach(file => { + let stat; + const item = pathPart + file; + let href = ""; + let label = ""; + let extraAttributes = ""; + try { + stat = fs.statSync(path.join(directory, file)); + } catch (ex) { + href = encodeURI(item); + label = `${file} (${ex})`; + extraAttributes = ' style="color:red"'; } - files.forEach(function (file) { - var stat; - var item = pathPart + file; - var href = ""; - var label = ""; - var extraAttributes = ""; - try { - stat = fs.statSync(path.join(dir, file)); - } catch (e) { + if (stat) { + if (stat.isDirectory()) { href = encodeURI(item); - label = file + " (" + e + ")"; - extraAttributes = ' style="color:red"'; - } - if (stat) { - if (stat.isDirectory()) { - href = encodeURI(item); - label = file; - } else if (path.extname(file).toLowerCase() === ".pdf") { - href = "/web/viewer.html?file=" + encodeURIComponent(item); - label = file; - extraAttributes = ' target="pdf"'; - } else if (all) { - href = encodeURI(item); - label = file; - } - } - if (label) { - res.write( - '" + - escapeHTML(label) + - "
\n" - ); + label = file; + } else if (path.extname(file).toLowerCase() === ".pdf") { + href = `/web/viewer.html?file=${encodeURIComponent(item)}`; + label = file; + extraAttributes = ' target="pdf"'; + } else if (all) { + href = encodeURI(item); + label = file; } - }); - if (files.length === 0) { - res.write("

no files found

\n"); } - if (!all && queryPart !== "side") { - res.write( - "

(only PDF files are shown, " + - 'show all)

\n' + if (label) { + response.write( + `${escapeHTML(label)}
` ); } - res.end(""); }); - } + if (files.length === 0) { + response.write("

No files found

"); + } + if (!all && queryPart !== "side") { + response.write( + '

(only PDF files are shown, show all)

' + ); + } + response.end(""); + }); } #serveFile(response, filePath, fileSize) {