package hws import ( "context" "fmt" "net" "net/http" "time" "github.com/pkg/errors" ) type Server struct { server *http.Server logger *logger routes bool middleware bool gzip bool errorPage ErrorPage } // NewServer returns a new hws.Server with the specified parameters. // The timeout options are specified in seconds func NewServer( host string, port string, readHeaderTimeout time.Duration, writeTimeout time.Duration, idleTimeout time.Duration, gzip bool, ) (*Server, error) { // TODO: test that host and port are valid values httpServer := &http.Server{ Addr: net.JoinHostPort(host, port), ReadHeaderTimeout: readHeaderTimeout * time.Second, WriteTimeout: writeTimeout * time.Second, IdleTimeout: idleTimeout * time.Second, } server := &Server{ server: httpServer, routes: false, gzip: gzip, } return server, nil } func (server *Server) Start() error { if !server.routes { return errors.New("Server.AddRoutes must be run before starting the server") } if !server.middleware { err := server.AddMiddleware() if err != nil { return errors.Wrap(err, "server.AddMiddleware") } } go func() { if server.logger == nil { fmt.Printf("Listening for requests on %s", server.server.Addr) } else { server.logger.logger.Info().Str("address", server.server.Addr).Msg("Listening for requests") } if err := server.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { if server.logger == nil { fmt.Printf("Server encountered a fatal error: %s", err.Error()) } else { server.logger.logger.Error().Err(err).Msg("Server encountered a fatal error") } } }() return nil } func (server *Server) Shutdown(ctx context.Context) { if err := server.server.Shutdown(ctx); err != nil { if server.logger == nil { fmt.Printf("Failed to gracefully shutdown the server: %s", err.Error()) } else { server.logger.logger.Error().Err(err).Msg("Failed to gracefully shutdown the server") } } }