Created
July 6, 2023 19:22
-
-
Save izelnakri/fe3f27fe5b3a7e79208883c04525bfbd to your computer and use it in GitHub Desktop.
No-dependency HTTP Server in node.js
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
import fs from "node:fs"; | |
import http from "node:http"; | |
import path from "node:path"; | |
import process from "node:process"; | |
const PORT = 8000; | |
const STATIC_PATH = path.join(process.cwd(), "./static"); | |
const NOT_FOUND_HTML_PATH = path.join(STATIC_PATH, "./404.html"); | |
const MIDDLEWARE_HANDLER = async (req, res) => { | |
const filePath = (url.endsWith("/") ? [STATIC_PATH, url, "index.html"] : [STATIC_PATH, url]).join(''); | |
const statusCode = await fileExists(filePath) ? 200 : 404; | |
console.log(`${req.method} ${req.url} ${statusCode}`); | |
}; | |
const NOT_FOUND_HTML_HANDLER = async (req, res) => { | |
res.writeHead(404, { | |
"Content-Type": MIME_TYPES.html | |
}); | |
fs.createReadStream(NOT_FOUND_HTML_PATH).pipe(res); | |
}; | |
const MIME_TYPES = { | |
default: "application/octet-stream", | |
html: "text/html; charset=UTF-8", | |
js: "application/javascript", | |
css: "text/css", | |
png: "image/png", | |
jpg: "image/jpg", | |
gif: "image/gif", | |
ico: "image/x-icon", | |
svg: "image/svg+xml", | |
}; | |
async function fileExists(pathString) { | |
return await fs.promises.access(pathString).then(() => true, () => false) | |
} | |
function createHTTPServer(port, handler) { | |
return new Promise((resolve, reject) => { | |
let server = http.createServer(handler) | |
.once('error', reject) | |
.on('listening', () => resolve(server)) | |
.listen(port); | |
}); | |
} | |
await createHTTPServer(PORT, async ({ url, headers, method }, res) => { | |
const filePath = (url.endsWith("/") ? [STATIC_PATH, url, "index.html"] : [STATIC_PATH, url]).join(''); | |
const statusCode = await fileExists(filePath) ? 200 : 404; | |
const contentType = | |
headers.accept?.includes('text/html') | |
? MIME_TYPES.html | |
: MIME_TYPES[path.extname(filePath).substring(1).toLowerCase()] || MIME_TYPES.default; | |
res.writeHead(statusCode, { "Content-Type": contentType }); | |
fs.createReadStream(statusCode === 200 ? filePath : NOT_FOUND_HTML_PATH) | |
.pipe(res); | |
console.log(`${method} ${url} ${statusCode}`); | |
}); | |
console.log(`Server running at http://127.0.0.1:${PORT}/`); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment