Last active
February 2, 2023 05:04
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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