summaryrefslogtreecommitdiff
path: root/gopher.go
diff options
context:
space:
mode:
authortjpcc <tjp@ctrl-c.club>2023-09-28 08:08:48 -0600
committertjpcc <tjp@ctrl-c.club>2023-10-09 08:47:37 -0600
commit6e1c25af361dde4c063eccbf769e966df4b65f23 (patch)
treed28044cf2db246555deda8db395f2f0a7e786590 /gopher.go
parentb4f45f7c654e87bda6d5e7effb6ac5b5feb29ce0 (diff)
config file refactor
Diffstat (limited to 'gopher.go')
-rw-r--r--gopher.go119
1 files changed, 119 insertions, 0 deletions
diff --git a/gopher.go b/gopher.go
new file mode 100644
index 0000000..5e36266
--- /dev/null
+++ b/gopher.go
@@ -0,0 +1,119 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "strings"
+
+ sr "tildegit.org/tjp/sliderule"
+ "tildegit.org/tjp/sliderule/contrib/cgi"
+ "tildegit.org/tjp/sliderule/contrib/fs"
+ "tildegit.org/tjp/sliderule/gopher"
+ "tildegit.org/tjp/sliderule/gopher/gophermap"
+ "tildegit.org/tjp/sliderule/logging"
+ "tildegit.org/tjp/syw"
+)
+
+func buildGopherServer(server Server, config *Configuration) (sr.Server, error) {
+ addr := fmt.Sprintf("%s:%d", server.IP.String(), server.Port)
+
+ _, info, _, errlog := Loggers(config)
+ _ = info.Log("msg", "building gopher server", "addr", addr)
+
+ return gopher.NewServer(
+ context.Background(),
+ server.Hostnames[0],
+ "tcp",
+ addr,
+ logging.LogRequests(info)(routes(server)),
+ errlog,
+ )
+}
+
+func addGopherRoute(router *sr.Router, route RouteDirective) {
+ switch route.Type {
+ case "static":
+ addGopherStaticRoute(router, route)
+ case "cgi":
+ addGopherCGIRoute(router, route)
+ case "git":
+ addGopherGitRoute(router, route)
+ }
+}
+
+func addGopherStaticRoute(router *sr.Router, route RouteDirective) {
+ dirmaps := []string{}
+ if route.Modifiers.DirDefault != "" {
+ dirmaps = append(dirmaps, route.Modifiers.DirDefault)
+ }
+ settings := &gophermap.FileSystemSettings{
+ ParseExtended: route.Modifiers.ExtendedGophermap,
+ Exec: route.Modifiers.Exec,
+ ListUsers: false,
+ DirMaps: dirmaps,
+ }
+
+ buildAndAddRoute(router, route, func(route RouteDirective) sr.Handler {
+ handlers := []sr.Handler{}
+
+ if route.Modifiers.Exec {
+ handlers = append(handlers, cgi.ExecGopherMaps(route.FsPath, route.URLPath, settings))
+ }
+
+ handlers = append(handlers, fs.GopherFileHandler(route.FsPath, route.URLPath, settings))
+
+ if route.Modifiers.DirDefault != "" {
+ handlers = append(handlers, fs.GopherDirectoryDefault(route.FsPath, route.URLPath, settings))
+ }
+
+ if route.Modifiers.DirList {
+ handlers = append(handlers, fs.GopherDirectoryListing(route.FsPath, route.URLPath, settings))
+ }
+
+ if len(handlers) == 1 {
+ return handlers[0]
+ }
+ return sr.FallthroughHandler(handlers...)
+ })
+}
+
+func addGopherCGIRoute(router *sr.Router, route RouteDirective) {
+ dirmaps := []string{}
+ if route.Modifiers.DirDefault != "" {
+ dirmaps = append(dirmaps, route.Modifiers.DirDefault)
+ }
+ settings := &gophermap.FileSystemSettings{
+ ParseExtended: route.Modifiers.ExtendedGophermap,
+ Exec: true,
+ ListUsers: false,
+ DirMaps: dirmaps,
+ }
+
+ buildAndAddRoute(router, route, func(route RouteDirective) sr.Handler {
+ return cgi.GopherCGIDirectory(route.FsPath, route.URLPath, settings)
+ })
+}
+
+func addGopherGitRoute(router *sr.Router, route RouteDirective) {
+ buildAndAddRoute(router, route, func(route RouteDirective) sr.Handler {
+ return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response {
+ subrouter := syw.GopherRouter(route.FsPath, nil)
+
+ reqclone := cloneRequest(request)
+ reqclone.Path = strings.TrimPrefix(reqclone.Path, route.URLPath)
+
+ handler, params := subrouter.Match(reqclone)
+ if handler == nil {
+ return nil
+ }
+ return handler.Handle(context.WithValue(ctx, sr.RouteParamsKey, params), request)
+ })
+ })
+}
+
+func cloneRequest(request *sr.Request) *sr.Request {
+ r := *request
+ u := *request.URL
+ r.URL = &u
+ return &r
+}