package server import ( "crypto/tls" "fmt" "io/fs" "log/slog" "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/middleware/static" "github.com/imbytecat/voicepaste/internal/config" ) // Server holds the Fiber app and related state. type Server struct { app *fiber.App token string lanIP string webFS fs.FS tlsCfg *tls.Config // nil = no TLS } // New creates a new Server instance. func New(token, lanIP string, webFS fs.FS, tlsCfg *tls.Config) *Server { app := fiber.New(fiber.Config{ AppName: "VoicePaste", }) s := &Server{ app: app, token: token, lanIP: lanIP, webFS: webFS, tlsCfg: tlsCfg, } s.setupRoutes() return s } // setupRoutes configures HTTP routes. func (s *Server) setupRoutes() { // Health check s.app.Get("/health", func(c fiber.Ctx) error { return c.SendString("ok") }) // Static files from embedded FS s.app.Use("/", static.New("", static.Config{ FS: s.webFS, Browse: false, })) } // App returns the underlying Fiber app for WebSocket route registration. func (s *Server) App() *fiber.App { return s.app } // Token returns the auth token. func (s *Server) Token() string { return s.token } // Start starts the HTTPS server. func (s *Server) Start() error { cfg := config.Get() addr := fmt.Sprintf(":%d", cfg.Server.Port) if s.tlsCfg != nil { slog.Info("starting HTTPS server", "addr", addr) return s.app.Listen(addr, fiber.ListenConfig{ TLSConfig: &tls.Config{ Certificates: s.tlsCfg.Certificates, MinVersion: tls.VersionTLS12, }, }) } slog.Info("starting HTTP server (no TLS)", "addr", addr) return s.app.Listen(addr) } // Shutdown gracefully shuts down the server. func (s *Server) Shutdown() error { return s.app.Shutdown() }