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
}
}