diff options
Diffstat (limited to 'finger.go')
| -rw-r--r-- | finger.go | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/finger.go b/finger.go new file mode 100644 index 0000000..6ae82dd --- /dev/null +++ b/finger.go @@ -0,0 +1,85 @@ +package main + +import ( + "context" + "fmt" + "os" + "os/user" + "path/filepath" + "strings" + + sr "tildegit.org/tjp/sliderule" + "tildegit.org/tjp/sliderule/contrib/cgi" + "tildegit.org/tjp/sliderule/finger" + "tildegit.org/tjp/sliderule/logging" +) + +func buildFingerServer(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 finger server", "addr", addr) + + if len(server.Routes) != 1 { + return nil, fmt.Errorf("finger server must have 1 route directive, found %d", len(server.Routes)) + } + + return finger.NewServer( + context.Background(), + "", + "tcp", + addr, + logging.LogRequests(info)(fingerHandler(server.Routes[0])), + errlog, + ) +} + +func fingerHandler(route RouteDirective) sr.Handler { + if route.Type != "static" && route.Type != "cgi" { + panic("invalid finger route type '" + route.Type + "'") + } + + return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response { + u, err := user.Lookup(strings.TrimPrefix(request.Path, "/")) + if err != nil { + return nil + } + + var fpath string + if strings.HasPrefix(route.FsPath, "~/") { + fpath = filepath.Join(u.HomeDir, route.FsPath[2:]) + } else { + fpath = strings.Replace(route.FsPath, "~", u.Username, 1) + } + + st, err := os.Stat(fpath) + if err != nil { + return finger.Error(err.Error()) + } + if !st.Mode().IsRegular() { + return nil + } + + if st.Mode()&5 == 5 && (route.Modifiers.Exec || route.Type == "cgi") { + buf, code, err := cgi.RunCGI(ctx, request, fpath, "/", nil) + if err != nil { + return finger.Error("execution error") + } + if code != 0 { + return finger.Error(fmt.Sprintf("execution error: code %d", code)) + } + + return finger.Success(buf) + } + + if route.Type != "static" { + return nil + } + + file, err := os.Open(fpath) + if err != nil { + return finger.Error(err.Error()) + } + return finger.Success(file) + }) +} |
