Move handlers to classes instead of functions

This commit is contained in:
MatthiasSaihttam 2021-08-28 19:39:40 -04:00
parent aa0d8ddefe
commit 4c5985e0ff
5 changed files with 37 additions and 19 deletions

View File

@ -1,11 +1,11 @@
import * as path from "path";
import tls from "tls";
import fs from "fs";
import geminiText from "./handlers/gemini.js";
import DefaultHandler from "./handlers/default.js";
export default class GeminiServer {
constructor(options) {
this.defaultHandler = options.defaultHandler || geminiText;
this.DefaultHandler = options.DefaultHandler || DefaultHandler;
this.certificates = {};
if (options.hasOwnProperty("host")) {
@ -64,8 +64,11 @@ export default class GeminiServer {
throw new Error(`Path ${p} passed to registerPath not normalized. (Remove trailing /'s and ..'s)`);
}
if (typeof handler !== "function") {
handler = this.defaultHandler(handler);
if (typeof handler === "string") {
handler = new this.DefaultHandler(handler);
}
if (!(handler instanceof DefaultHandler)) {
throw new Error("Handler must be an instance of DefaultHandler or a subclass.");
}
this.pathRegistry.push({
@ -83,7 +86,9 @@ export default class GeminiServer {
const isSubPath = !path.posix.relative(p.path, url.pathname).startsWith("..");
if (path.posix.resolve(url.pathname) === p.path) {
const res = p.handler({ path: url })
console.log(p.handler);
// console.log(p.handler instance);
const res = p.handler.handle(url);
socket.write(res);
socket.end();
return;

View File

@ -1,5 +1,5 @@
import GeminiServer from "./GeminiServer.js";
import staticFiles from "./handlers/static.js";
import StaticHandler from "./handlers/static.js";
// import {, staticFileHandler} from "./main.js";
@ -29,15 +29,15 @@ server.registerPath("localhost/", "### Hello, world");
//Anything before the first slash is a domain name and is used in SNI matching if you passed the `host` option
server.registerPath("MacBookGamma.local/", "### Hello from my Mac!");
//Otherwise, you have a function, a handler
//Otherwise, you can subclass DefaultHandler, which has a .handle method, that takes a url
//request has everything you would expect, .servername, .path,
//You have to provide the entire responce inc. content type
server.registerPath("localhost/allFiles", request => "20 text/txt\r\nHello, World\r\n");
//You have to provide the entire response inc. content type
// server.registerPath("localhost/allFiles", request => "20 text/txt\r\nHello, World\r\n");
// We provide some convenient handlers for static, CGI, and reverse proxy
//if the passed file is a single file, it's a file. If it's a directory, all sub-files are auto-included
server.registerPath("localhost/static", staticFiles("/file/root" /*, {options}*/));
server.registerPath("localhost/static", new StaticHandler("/tmp/files " /*, {options}*/));
//The file passed to CGI handler must exist and be executable at run time
//You know what, CGIHandler hashes the file

9
handlers/default.js Normal file
View File

@ -0,0 +1,9 @@
export default class DefaultHandler {
constructor(text) {
this.text = text;
}
handle(url) {
return "20 text/gemini\r\n" + this.text;
}
}

View File

@ -1,5 +0,0 @@
export default function geminiText (text) {
return function (request) {
return "20 text/gemini\r\n" + text;
}
}

View File

@ -1,14 +1,23 @@
import * as path from "path"
import * as fs from "fs";
import DefaultHandler from "./default.js";
// This is not the handler. This is a function that takes a filePath
// and returns a handler
export default function staticFiles (basePath) {
export default class StaticHandler extends DefaultHandler {
constructor(basePath) {
super();
this.basePath = basePath;
}
// This is the handler
return function (request) {
handle (url) {
//Concat and normalize the passed URL as being relative to the base path
const toServe = path.join(basePath, request)
const toServe = path.join(this.basePath, url.pathname);
//If the resulting path is a parent, relative to basePath, disallow that
if (path.relative(basePath, toServe).startsWith("..")) {
if (path.relative(this.basePath, toServe).startsWith("..")) {
return "50"
}