Skip to content

Instantly share code, notes, and snippets.

@aymericbeaumet
Last active February 2, 2023 05:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aymericbeaumet/c73a3c91ddbcd4b9d5ca1ddb34b10081 to your computer and use it in GitHub Desktop.
Save aymericbeaumet/c73a3c91ddbcd4b9d5ca1ddb34b10081 to your computer and use it in GitHub Desktop.
Basic implementation of https://expressjs.com/en/4x/api.html#express.static, does not support any option.
const express = require("express"); // https://expressjs.com/en/4x/api.html
const fs = require("fs"); // https://nodejs.org/api/fs.html
const path = require("path"); // https://nodejs.org/api/path.html
/*
* This function exists for convenience only. It allows to create a new
* middleware with the given parameters (here we only expect a single one: the
* root directory). It mimics the genuine express.static function signature
* (modulo the options argument).
*/
function staticMiddlewareFactory(root) {
// A middleware is a function with an arity of 3 (see: https://expressjs.com/en/guide/writing-middleware.html)
return function staticMiddleware(req, res, next) {
// Strip the leading slash(es) so that it is considered as a relative path.
// Note that when the middleware is mounted at a specific path, req.url is
// relative to req.baseUrl. So it always behaves as expected.
const relativePath = req.url.replace(/^\/*/, "");
// Compute the absolute path relative to the current working directory
// (process.cwd()), the root directory, and the path extracted from the url.
const absolutePath = path.resolve(process.cwd(), root, relativePath);
// Try to read the file and send it to the client.
fs.readFile(absolutePath, (error, data) => {
// If the file is a directory (EISDIR error code) or is not found (ENOENT
// error code), just continue to the next route without triggering an
// error. Otherwise pass the error to the next() function to abort the
// request.
if (error) {
return ["EISDIR", "ENOENT"].includes(error.code) ? next() : next(error);
}
res.set("content-type", "text/plain"); // TODO: set a proper content-type infered from the file extension
return res.send(data);
});
};
}
express() // Initialize the express server, here we leverage the chained notation
.use(staticMiddlewareFactory(__dirname)) // Load the middleware, with the root being the directory of this file (see: https://nodejs.org/docs/latest/api/modules.html#modules_dirname)
.get("/hello", (req, res) => res.send("hello world")) // Make sure the middleware forwards the requests it cannot fulfill to the next middleware/handler
.listen(3000, "0.0.0.0"); // Start the server
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment