package main import ( "context" "flag" "fmt" "log" "net/http" "os" "os/signal" "syscall" "time" "github.com/iwasforcedtobehere/goRZ/internal/config" "github.com/iwasforcedtobehere/goRZ/internal/logger" "github.com/iwasforcedtobehere/goRZ/internal/proxy" ) var ( configPath = flag.String("config", "config.yaml", "Path to configuration file") version = flag.Bool("version", false, "Show version information") ) // Version information set at build time var ( Version = "dev" BuildTime = "unknown" GitCommit = "unknown" ) func main() { flag.Parse() if *version { fmt.Printf("goRZ %s\n", Version) fmt.Printf("Build time: %s\n", BuildTime) fmt.Printf("Git commit: %s\n", GitCommit) os.Exit(0) } // Initialize logger appLogger := logger.NewLogger() appLogger.Info("Starting goRZ reverse proxy server") // Load configuration cfg, err := config.Load(*configPath) if err != nil { appLogger.Fatal("Failed to load configuration", logger.Error(err)) } // Create proxy server proxyServer, err := proxy.NewServer(cfg, appLogger) if err != nil { appLogger.Fatal("Failed to create proxy server", logger.Error(err)) } // Create HTTP server server := &http.Server{ Addr: fmt.Sprintf(":%d", cfg.Server.Port), Handler: proxyServer, ReadTimeout: time.Duration(cfg.Server.ReadTimeout) * time.Second, WriteTimeout: time.Duration(cfg.Server.WriteTimeout) * time.Second, IdleTimeout: time.Duration(cfg.Server.IdleTimeout) * time.Second, } // Start server in a goroutine go func() { appLogger.Info("Server starting", logger.String("address", server.Addr)) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { appLogger.Fatal("Server failed", logger.Error(err)) } }() // Wait for interrupt signal quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit appLogger.Info("Shutting down server...") // Graceful shutdown with timeout ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if err := server.Shutdown(ctx); err != nil { appLogger.Error("Server forced to shutdown", logger.Error(err)) } appLogger.Info("Server exited") }