From 2cdc569840f36dad139132c37de1b62e21a971b7 Mon Sep 17 00:00:00 2001 From: tjp Date: Tue, 14 Nov 2023 18:58:06 -0700 Subject: initial support for nex protocol --- nex.go | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ parse.go | 26 +++++++++++++++++++++ routes.go | 2 ++ servers.go | 6 +++++ 4 files changed, 113 insertions(+) create mode 100644 nex.go diff --git a/nex.go b/nex.go new file mode 100644 index 0000000..bd9bdce --- /dev/null +++ b/nex.go @@ -0,0 +1,79 @@ +package main + +import ( + "context" + "fmt" + + "github.com/go-kit/log/level" + + sr "tildegit.org/tjp/sliderule" + "tildegit.org/tjp/sliderule/contrib/cgi" + "tildegit.org/tjp/sliderule/contrib/fs" + "tildegit.org/tjp/sliderule/logging" + "tildegit.org/tjp/sliderule/nex" +) + +func buildNexServer(server Server, config *Configuration) (sr.Server, error) { + addr := fmt.Sprintf("%s:%d", server.IP.String(), server.Port) + + baselog := BaseLogger(config) + info := level.Info(baselog) + errlog := level.Error(baselog) + + if server.TLS != nil { + return nex.NewTLSServer( + context.Background(), + server.Hostnames[0], + "tcp", + addr, + logging.LogRequests(info)(routes(server)), + errlog, + server.TLS, + ) + } else { + return nex.NewServer( + context.Background(), + server.Hostnames[0], + "tcp", + addr, + logging.LogRequests(info)(routes(server)), + errlog, + ) + } +} + +func addNexRoute(router *sr.Router, route RouteDirective) { + switch route.Type { + case "static": + addNexStaticRoute(router, route) + case "cgi": + buildAndAddRoute(router, route, func(route RouteDirective) sr.Handler { + return cgi.NexCGIDirectory(route.FsPath, route.URLPath, route.Modifiers.ExecCmd) + }) + } +} + +func addNexStaticRoute(router *sr.Router, route RouteDirective) { + buildAndAddRoute(router, route, func(route RouteDirective) sr.Handler { + handlers := []sr.Handler{} + + if route.Modifiers.Exec { + handlers = append(handlers, cgi.NexCGIDirectory(route.FsPath, route.URLPath, route.Modifiers.ExecCmd)) + } + + handlers = append(handlers, fs.NexFileHandler(route.FsPath, route.URLPath)) + + if route.Modifiers.DirDefault != "" { + handlers = append( + handlers, + fs.NexDirectoryDefault(route.FsPath, route.URLPath, route.Modifiers.DirDefault), + ) + } + + if route.Modifiers.DirList { + handlers = append(handlers, fs.NexDirectoryListing(route.FsPath, route.URLPath, nil)) + } + + return sr.FallthroughHandler(handlers...) + }) +} diff --git a/parse.go b/parse.go index 89ce244..d0bf7a3 100644 --- a/parse.go +++ b/parse.go @@ -115,6 +115,12 @@ func Parse(input io.ReadCloser) (*Configuration, error) { return nil, err } servers = append(servers, s) + case "nex": + s, err := parseNexServer(line, buf) + if err != nil { + return nil, err + } + servers = append(servers, s) } } @@ -241,6 +247,20 @@ func parseSpartanServer(line string, buf *bufio.Reader) (Server, error) { return server, nil } +func parseNexServer(line string, buf *bufio.Reader) (Server, error) { + server := Server{Type: "nex"} + + if err := parseServerLine(&server, line); err != nil { + return server, err + } + + if err := parseServerDirectives(&server, buf); err != nil { + return server, err + } + + return server, nil +} + func parseServerDirectives(server *Server, buf *bufio.Reader) error { for { line, err := buf.ReadString('\n') @@ -306,6 +326,10 @@ func validateRoute(serverType string, dir *RouteDirective) error { return errors.New("cgi directives only support the 'extendedgophermap' modifier") } + if dir.Type == "git" && serverType != "gemini" && serverType != "gopher" && serverType != "spartan" { + return fmt.Errorf("git directive not allowed in %s server", serverType) + } + if serverType == "finger" && (dir.Modifiers.DirDefault != "" || dir.Modifiers.DirList) { return errors.New("finger servers don't support directory 'with' modifiers") } @@ -558,6 +582,8 @@ func parseServerLine(server *Server, line string) error { defaultPort = "1965" case "spartan": defaultPort = "300" + case "nex": + defaultPort = "1900" default: return errors.New("invalid server") } diff --git a/routes.go b/routes.go index 172c45b..2f9695a 100644 --- a/routes.go +++ b/routes.go @@ -20,6 +20,8 @@ func addRoute(server Server, router *sr.Router, route RouteDirective) { addGeminiRoute(router, route) case "spartan": addSpartanRoute(router, route) + case "nex": + addNexRoute(router, route) default: panic("invalid server type '" + server.Type + "'") } diff --git a/servers.go b/servers.go index bad07a4..1218bec 100644 --- a/servers.go +++ b/servers.go @@ -23,6 +23,12 @@ func buildServers(config *Configuration) ([]sr.Server, error) { return nil, err } result = append(result, srv) + case "nex": + srv, err := buildNexServer(server, config) + if err != nil { + return nil, err + } + result = append(result, srv) case "gemini": geminis = append(geminis, server) case "spartan": -- cgit v1.2.3