package http import ( "context" "fmt" "log/slog" "net/http" "time" "git.eeqj.de/sneak/ipapi/internal/config" "github.com/go-chi/chi/v5" ) // Server manages the HTTP server lifecycle. type Server struct { config *config.Config logger *slog.Logger router chi.Router httpServer *http.Server } // NewServer creates a new HTTP server instance. func NewServer(cfg *config.Config, logger *slog.Logger, router chi.Router) (*Server, error) { return &Server{ config: cfg, logger: logger, router: router, }, nil } // Start begins listening for HTTP requests. func (s *Server) Start(_ context.Context) error { addr := fmt.Sprintf(":%d", s.config.Port) s.httpServer = &http.Server{ Addr: addr, Handler: s.router, ReadTimeout: 15 * time.Second, //nolint:mnd WriteTimeout: 15 * time.Second, //nolint:mnd IdleTimeout: 60 * time.Second, //nolint:mnd } s.logger.Info("Starting HTTP server", "addr", addr) go func() { if err := s.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { s.logger.Error("HTTP server error", "error", err) } }() return nil } // Stop gracefully shuts down the HTTP server. func (s *Server) Stop(ctx context.Context) error { if s.httpServer == nil { return nil } s.logger.Info("Stopping HTTP server") const shutdownTimeout = 30 * time.Second shutdownCtx, cancel := context.WithTimeout(ctx, shutdownTimeout) defer cancel() return s.httpServer.Shutdown(shutdownCtx) }