package main import ( "context" "log/slog" "net/http" "os" "os/signal" "syscall" "time" ) func main() { cfg := loadConfig() slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, nil))) db, err := InitDB(cfg.DBPath) if err != nil { slog.Error("failed to init database", "error", err) os.Exit(1) } defer db.Close() go cleanupLoop(db, cfg.CleanupInterval) mux := http.NewServeMux() mux.HandleFunc("/auth", authHandler(cfg, db)) mux.HandleFunc("/api/whitelist/temp", whitelistTempHandler(cfg, db)) mux.HandleFunc("/api/whitelist/temp/list", whitelistListHandler(cfg, db)) mux.HandleFunc("/api/whitelist/temp/{ip}", whitelistDeleteHandler(cfg, db)) mux.HandleFunc("/api/whitelist/perm", permWhitelistAddHandler(cfg, db)) mux.HandleFunc("/api/whitelist/perm/list", permWhitelistListHandler(cfg, db)) mux.HandleFunc("/api/whitelist/perm/{entry}", permWhitelistDeleteHandler(cfg, db)) mux.HandleFunc("/api/logs", logsHandler(cfg, db)) mux.HandleFunc("/status", statusHandler) server := &http.Server{ Addr: ":" + cfg.Port, Handler: mux, } go func() { slog.Info("server listening", "addr", server.Addr) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { slog.Error("server error", "error", err) os.Exit(1) } }() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGTERM, syscall.SIGINT) <-quit slog.Info("shutting down...") ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() server.Shutdown(ctx) }