package rebound import ( "net" "forge.cadoles.com/wpetit/rebound/http" "forge.cadoles.com/wpetit/rebound/ssh" "github.com/pkg/errors" ) type Server struct { listener net.Listener opts *Options } func (s *Server) Start() error { s.log("[INFO] listening on %s", s.opts.Address) listener, err := net.Listen("tcp", s.opts.Address) if err != nil { return errors.WithStack(err) } s.listener = listener sshListener, httpListener := s.muxListener(listener) go func() { defer listener.Close() server := ssh.NewServer( ssh.WithHostKey(s.opts.SSH.HostKey), ssh.WithPublicHost(s.opts.SSH.PublicHost), ssh.WithPublicPort(s.opts.SSH.PublicPort), ssh.WithSockDir(s.opts.SSH.SockDir), ssh.WithLogger(s.opts.SSH.Logger), ) if err := server.Serve(sshListener); err != nil { s.log("[ERROR] %+v", errors.WithStack(err)) listener.Close() } }() go func() { defer listener.Close() server := http.NewServer( http.WithCustomDir(s.opts.HTTP.CustomDir), http.WithLogger(s.opts.HTTP.Logger), ) if err := server.Serve(httpListener); err != nil { s.log("[ERROR] %+v", errors.WithStack(err)) } }() return nil } func (s *Server) Stop() error { if s.listener == nil { return nil } if err := s.listener.Close(); err != nil { return errors.WithStack(err) } s.listener = nil return nil } func (s *Server) log(message string, args ...any) { s.opts.Logger(message, args...) } func NewServer(funcs ...OptionFunc) *Server { opts := DefaultOptions() for _, fn := range funcs { fn(opts) } return &Server{ opts: opts, } }