Last active
September 18, 2025 09:11
-
-
Save cj-praveen/cb659b27e86e8c12e27a4067b83182e6 to your computer and use it in GitHub Desktop.
A read-only file server
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
| #!/usr/bin/env bun | |
| import { stat, readdir } from "fs/promises"; | |
| import { join } from "path"; | |
| const root = process.cwd(); | |
| async function html(target, baseDir) { | |
| const entries = await readdir(target); | |
| return new Response( | |
| `<!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>${target}</title> | |
| </head> | |
| <body> | |
| <h1>${target}</h1> | |
| <hr> | |
| <pre>${ | |
| entries | |
| .map(entry => `<a href="${join(baseDir, entry)}" target="_self">${entry}</a>`) | |
| .join("<br>")} | |
| </pre> | |
| <hr> | |
| </body> | |
| </html>`, | |
| { | |
| headers: { | |
| "Content-Type": "text/html" | |
| } | |
| } | |
| ); | |
| } | |
| const server = Bun.serve({ | |
| hostname: "0.0.0.0", | |
| port: 5050, | |
| async fetch(req) { | |
| const url = new URL(req.url); | |
| if (url.pathname === "/") | |
| return html(root, "/"); | |
| else { | |
| const path = decodeURI(url.pathname); | |
| const abs_path = join(root, path); | |
| const range = req.headers.get("range"); | |
| try { | |
| const info = await stat(abs_path); | |
| if (info.isFile()) { | |
| const file = Bun.file(abs_path); | |
| if (range) { | |
| const [startStr, endStr] = range.replace(/bytes=/, "").split("-"); | |
| const start = parseInt(startStr, 10); | |
| const end = endStr ? parseInt(endStr, 10) : size - 1; | |
| const chunkSize = (end - start) + 1; | |
| const slice = file.slice(start, end + 1); | |
| return new Response(slice, { | |
| status: 206, | |
| headers: { | |
| "Content-Range": `bytes ${start}-${end}/${info.size}`, | |
| "Accept-Ranges": "bytes", | |
| "Content-Length": chunkSize.toString(), | |
| "Content-Type": file.type, | |
| }, | |
| }); | |
| } | |
| return new Response(file, { | |
| headers: { | |
| "Content-Type": file.type || "application/octet-stream" | |
| } | |
| }); | |
| } | |
| else if (info.isDirectory()) | |
| return html(abs_path, path); | |
| } catch(err) { | |
| return new Response(err, { status: 500 }); | |
| } | |
| } | |
| return new Response("File not found!", { status: 404 }); | |
| } | |
| }); | |
| console.log("Press Ctrl+C to quit!"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment