package main import ( "context" "log" "net/http" "os" "os/signal" "syscall" "time" "git.dws.rip/DWS/dyn/internal/config" "git.dws.rip/DWS/dyn/internal/database" "git.dws.rip/DWS/dyn/internal/dns" "git.dws.rip/DWS/dyn/internal/handlers" "git.dws.rip/DWS/dyn/internal/middleware" "github.com/gin-gonic/gin" ) func main() { cfg := config.Load() if errs := cfg.Validate(); len(errs) > 0 { for _, err := range errs { log.Printf("Configuration error: %s", err) } os.Exit(1) } db, err := database.New(cfg.DatabasePath) if err != nil { log.Fatalf("Failed to initialize database: %v", err) } defer db.Close() dnsClient := dns.NewClient( cfg.TechnitiumURL, cfg.TechnitiumToken, cfg.TechnitiumUsername, cfg.TechnitiumPassword, ) rateLimiter := middleware.NewRateLimiter(cfg.RateLimitPerIP, cfg.RateLimitPerToken) gin.SetMode(gin.ReleaseMode) router := gin.New() router.Use(gin.Recovery()) if len(cfg.TrustedProxies) > 0 { router.SetTrustedProxies(cfg.TrustedProxies) } router.Static("/static", "./web/static") router.LoadHTMLGlob("web/templates/*") webHandler := handlers.NewWebHandler(db, cfg) dynHandler := handlers.NewDynDNSHandler(db, dnsClient, cfg) router.GET("/", webHandler.Index) api := router.Group("/api") api.Use(rateLimiter.RateLimitByIP()) { api.GET("/check", webHandler.CheckSubdomain) api.POST("/claim", webHandler.ClaimSpace) nic := api.Group("/nic") nic.Use(rateLimiter.RateLimitByToken()) nic.GET("/update", dynHandler.Update) } port := cfg.ServerPort if port == "" { port = "8080" } srv := &http.Server{ Addr: ":" + port, Handler: router, } go func() { log.Printf("Server starting on port %s", port) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("Failed to start server: %v", err) } }() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Println("Shutting down server...") ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { log.Printf("Server forced to shutdown: %v", err) } log.Println("Server exited") }