diff options
author | tjp <tjp@ctrl-c.club> | 2023-11-13 07:27:36 -0700 |
---|---|---|
committer | tjp <tjp@ctrl-c.club> | 2023-11-13 07:27:36 -0700 |
commit | 629e6a0e0c3a24f35888036f957ee3a631e62816 (patch) | |
tree | 76001a2311d3566bf0050b3ef2aa3119fe0823bf /nex/serve.go | |
parent | 1e0f8e0aaeaf1bd2ee39c02e922238b641bcf88b (diff) |
add nex protocol support
Diffstat (limited to 'nex/serve.go')
-rw-r--r-- | nex/serve.go | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/nex/serve.go b/nex/serve.go new file mode 100644 index 0000000..7e103e3 --- /dev/null +++ b/nex/serve.go @@ -0,0 +1,91 @@ +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) +} |