summaryrefslogtreecommitdiff
path: root/finger/serve.go
diff options
context:
space:
mode:
authortjpcc <tjp@ctrl-c.club>2023-01-30 11:34:13 -0700
committertjpcc <tjp@ctrl-c.club>2023-01-30 11:36:48 -0700
commit4f6f3dcd4b8c71f5caa52864092dbde22665a645 (patch)
tree19ae4d9203774173b83c25a91d7787d88bd3aa6a /finger/serve.go
parent9cbc5cdd467ccd8e68f0f5d1d971ab76c2946624 (diff)
finger protocol
Diffstat (limited to 'finger/serve.go')
-rw-r--r--finger/serve.go68
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)
+}