diff options
| author | tjpcc <tjp@ctrl-c.club> | 2023-09-28 08:08:48 -0600 |
|---|---|---|
| committer | tjpcc <tjp@ctrl-c.club> | 2023-10-09 08:47:37 -0600 |
| commit | 6e1c25af361dde4c063eccbf769e966df4b65f23 (patch) | |
| tree | d28044cf2db246555deda8db395f2f0a7e786590 /gopher.go | |
| parent | b4f45f7c654e87bda6d5e7effb6ac5b5feb29ce0 (diff) | |
config file refactor
Diffstat (limited to 'gopher.go')
| -rw-r--r-- | gopher.go | 119 |
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 +} |
