package nex import ( "bytes" "context" "crypto/tls" "fmt" "io" "net" "tildegit.org/tjp/sliderule/internal" "tildegit.org/tjp/sliderule/internal/types" "tildegit.org/tjp/sliderule/logging" ) type nexServer struct { internal.Server handler types.Handler } func (ns nexServer) Protocol() string { return "NEX" } // NewServer builds a new nex server func NewServer( ctx context.Context, hostname string, network string, address string, handler types.Handler, baseLog logging.Logger, ) (types.Server, error) { ns := &nexServer{handler: handler} hostname = internal.JoinDefaultPort(hostname, "1900") address = internal.JoinDefaultPort(address, "1900") var err error ns.Server, err = internal.NewServer(ctx, hostname, network, address, baseLog, ns.handleConn) if err != nil { return nil, err } return ns, err } func NewTLSServer( ctx context.Context, hostname string, network string, address string, handler types.Handler, baseLog logging.Logger, tlsConfig *tls.Config, ) (types.Server, error) { ns, err := NewServer(ctx, hostname, network, address, handler, baseLog) if err != nil { return nil, err } ns.(*nexServer).Listener = tls.NewListener(ns.(*nexServer).Listener, tlsConfig) return ns, nil } func (ns *nexServer) handleConn(conn net.Conn) { request, err := ParseRequest(conn) if err != nil { _, _ = fmt.Fprint(conn, err.Error()+"\n") } request.Server = ns request.RemoteAddr = conn.RemoteAddr() if tlsconn, ok := conn.(*tls.Conn); ok { state := tlsconn.ConnectionState() request.TLSState = &state } defer func() { if r := recover(); r != nil { _ = ns.LogError("msg", "panic in handler", "err", r) _, _ = fmt.Fprint(conn, "Error handling request.\n") } }() response := ns.handler.Handle(ns.Ctx, request) if response == nil { response = Response(bytes.NewBufferString("Document not found.")) } defer response.Close() _, _ = io.Copy(conn, response.Body) }