diff options
Diffstat (limited to 'finger/serve.go')
-rw-r--r-- | finger/serve.go | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/finger/serve.go b/finger/serve.go new file mode 100644 index 0000000..8623de5 --- /dev/null +++ b/finger/serve.go @@ -0,0 +1,68 @@ +package finger + +import ( + "context" + "fmt" + "io" + "net" + "strings" + + "tildegit.org/tjp/gus" + "tildegit.org/tjp/gus/internal" + "tildegit.org/tjp/gus/logging" +) + +type fingerServer struct { + internal.Server + handler gus.Handler +} + +func (fs fingerServer) Protocol() string { return "FINGER" } + +// NewServer builds a finger server. +func NewServer( + ctx context.Context, + hostname string, + network string, + address string, + handler gus.Handler, + errLog logging.Logger, +) (gus.Server, error) { + fs := &fingerServer{handler: handler} + + if strings.IndexByte(hostname, ':') < 0 { + hostname = net.JoinHostPort(hostname, "79") + } + + var err error + fs.Server, err = internal.NewServer(ctx, hostname, network, address, errLog, fs.handleConn) + if err != nil { + return nil, err + } + + return fs, nil +} + +func (fs *fingerServer) handleConn(conn net.Conn) { + request, err := ParseRequest(conn) + if err != nil { + _, _ = fmt.Fprint(conn, err.Error()+"\r\n") + } + + request.Server = fs + request.RemoteAddr = conn.RemoteAddr() + + defer func() { + if r := recover(); r != nil { + _ = fs.LogError("msg", "panic in handler", "err", r) + _, _ = fmt.Fprint(conn, "Error handling request.\r\n") + } + }() + response := fs.handler(fs.Ctx, request) + if response == nil { + response = Error("No result found.") + } + + defer response.Close() + _, _ = io.Copy(conn, response.Body) +} |