Shopping List v2.0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

filesrv.js 1.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. let http = require("http");
  2. let pathlib = require("path");
  3. let fs = require("fs");
  4. module.exports = function createFileServer(webroot) {
  5. let server = http.createServer((req, res) => {
  6. console.log(req.method+" "+req.url);
  7. if (req.method != "HEAD" && req.method != "GET") {
  8. res.writeHead(405);
  9. res.end(`Unexpected method: ${req.method}`);
  10. return;
  11. }
  12. let path = pathlib.normalize(pathlib.join(webroot, req.url));
  13. if (!path.startsWith(webroot)) {
  14. res.writeHead(404);
  15. res.end(`404 Not Found: ${req.url}`);
  16. return;
  17. }
  18. (function read(path) {
  19. let rs = fs.createReadStream(path);
  20. rs.once("error", err => {
  21. if (err.code == "ENOENT") {
  22. res.writeHead(404);
  23. res.end(`404 Not Found: ${req.url}`);
  24. } else if (err.code == "EISDIR") {
  25. if (!req.url.endsWith("/")) {
  26. res.writeHead(302, {
  27. location: `${req.url}/`,
  28. });
  29. res.end(`302 Found: ${req.url}/`);
  30. } else {
  31. read(path+"/index.html");
  32. }
  33. } else {
  34. console.warn(`Failed to open ${path}`);
  35. console.trace(err);
  36. res.writeHead(500);
  37. res.end("500 Internal Server Error");
  38. }
  39. });
  40. rs.once("open", () => {
  41. let ctype = null;
  42. if (path.endsWith(".html"))
  43. ctype = "text/html";
  44. else if (path.endsWith(".js"))
  45. ctype = "application/javascript";
  46. else if (path.endsWith(".css"))
  47. ctype = "text/css";
  48. else if (path.endsWith(".svg"))
  49. ctype = "image/svg+xml";
  50. if (ctype)
  51. res.writeHead(200, { "Content-Type": ctype });
  52. else
  53. res.writeHead(200);
  54. rs.pipe(res);
  55. });
  56. })(path);
  57. });
  58. return server;
  59. }