package server import ( "time" "net/http" "context" "log" ) const ( defaultServerReadTimeout = 3 * time.Second defaultServerWriteTimeout = 35 * time.Second defaultServerShutdownTimeout = 10 * time.Second ) // Server holds the main HTTP server. It's a standard net/http Server. type Server struct { *http.Server ShutdownTimeout time.Duration } // New instantiates a new server. func New(addr string, handler http.Handler, opts ...func(*Server)) *Server { s := &Server{ Server: &http.Server{ Addr: addr, Handler: handler, ReadTimeout: defaultServerReadTimeout, WriteTimeout: defaultServerWriteTimeout, }, ShutdownTimeout: defaultServerShutdownTimeout, } for _, f := range opts { f(s) } return s } // Start starts the server instance. func (s *Server) Start() error { if err := s.ListenAndServe(); err != http.ErrServerClosed { return err } return nil } // Stop stops the server instance. func (s *Server) Stop() error { ctx, cancel := context.WithTimeout(context.Background(), s.ShutdownTimeout) defer cancel() return s.Shutdown(ctx) } // WithErrorLog sets the error logger for a http server. func WithErrorLog(logger *log.Logger) func(*Server) { return func(s *Server) { s.ErrorLog = logger } }