package server import ( "context" stdtls "crypto/tls" "io/ioutil" "log" "net" "net/http" "path/filepath" "time" "github.com/go-logr/logr" "github.com/gorilla/mux" ) // Server is the webapp and api server type Server struct { srv *http.Server mux *mux.Router log logr.Logger stop chan struct{} stopKeyReset chan struct{} cert string key string laddr string debug bool } // NewHTTPServer returns a new HTTPServer func NewServer(log logr.Logger) *Server { s := &Server{ mux: mux.NewRouter(), log: log, stop: make(chan struct{}), stopKeyReset: make(chan struct{}), cert: filepath.Join(core.C.DataDir, core.C.HTTP.Cert), key: filepath.Join(core.C.DataDir, core.C.HTTP.Key), laddr: net.JoinHostPort(core.C.HTTP.Address, core.C.HTTP.Port), debug: core.C.Debug, } s.mux.NotFoundHandler = ¬FoundHandler{s} for _, v := range routes { s.mux.HandleFunc(v.Path, s.contextWrapper(v.Handler)).Methods(v.Methods...) } s.start() return s } func (s *Server) start() error { l, err := tls.Listen("tcp", h.laddr, cfg) if err != nil { return err } h.srv = &http.Server{ Handler: h.mux, TLSConfig: cfg, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, } go func() { err := h.srv.Serve(l) if err != nil { s.log.Error(err, "") } }() return nil } func (s *Server) contextWrapper(h ctxHandler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { h(newContext(w, r, s)) } } // Stop stops listening for incoming connections and closes currently open connections func (s *Server) Stop() { s.log.Info("stopping") ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() err := h.srv.Shutdown(ctx) if err != nil { s.log.Error(err, "") } s.log.Info("stopped") }