69 lines
1.3 KiB
Go
69 lines
1.3 KiB
Go
|
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)
|
||
|
}
|