summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortjp <tjp@ctrl-c.club>2023-11-14 18:58:06 -0700
committertjp <tjp@ctrl-c.club>2023-11-14 18:58:06 -0700
commit2cdc569840f36dad139132c37de1b62e21a971b7 (patch)
tree2fd4b5c5626a50230ffcd0b6f28dcb048482ef56
parenta2b05982a2bbd2c7baee1efb7e98db8de9123330 (diff)
initial support for nex protocol
-rw-r--r--nex.go79
-rw-r--r--parse.go26
-rw-r--r--routes.go2
-rw-r--r--servers.go6
4 files changed, 113 insertions, 0 deletions
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":