92 lines
1.9 KiB
Go
92 lines
1.9 KiB
Go
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)
|
|
}
|