var fs = require("fs"); var pathlib = require("path"); var mimes = { txt: "text/plain", css: "text/css", html: "text/html", js: "application/javascript", json: "application/json", xml: "application/xml", zip: "application/zip", pdf: "application/pdf", png: "image/png", jpeg: "image/jpeg", jpg: "image/jpeg", gif: "image/gif", svg: "image/svg", } function mimetype(path) { var unknown = "application/octet-stream"; var ext = pathlib.extname(path); if (ext) return mimes[ext.substr(1)] || unknown; else return unknown; } function sendfile(path, app, pathname, res) { fs.open(path, "r", (err, fd) => { if (err) { app.notice(err); res.writeHead(404); res.end(app.template(app.res404, { pathname: pathname })); return; } res.writeHead(200, { "Content-Type": mimetype(path) }); var rs = fs.createReadStream(null, { fd: fd }); rs.on("error", err => { app.warning(err); }); rs.on("data", d => res.write(d)); rs.on("end", () => res.end()); }); } module.exports = function(root, before) { return function(req, res, app) { var pn = req.urlobj.pathname; // Send a file function send(path) { sendfile(path, app, pn, res); } // Prevent leaking information if (pn.indexOf("../") !== -1 || pn.indexOf("/..") !== -1 || pn === "..") { res.writeHead(403); res.end(app.template(app.res403, { pathname: pn })); return; } // Join the web root with the request's path name var path = pathlib.join(root, pn.replace(before, "")); fs.stat(path, (err, stat) => { // If there's an error stat'ing, just error if (err) { app.notice(err); res.writeHead(404); res.end(app.template(app.res404, { pathname: pn })); return; } // If it's a directory, we want the index.html file if (stat.isDirectory()) path = pathlib.join(path, "index.html"); // Send the file send(path); }); } }