diff --git a/fast-server/config/config.go b/fast-server/config/config.go index 5af926b..5620d27 100644 --- a/fast-server/config/config.go +++ b/fast-server/config/config.go @@ -116,12 +116,75 @@ func (d *Domain) validate() error { return fmt.Errorf("public_dir is required for type: %s", d.Type) } + // Always validate SSL for the regular validate method return d.SSL.validate() } +func (c *Config) validate() error { + if err := c.Server.validate(); err != nil { + return fmt.Errorf("server configuration error: %v", err) + } + + if err := c.Log.validate(); err != nil { + return fmt.Errorf("log configuration error: %v", err) + } + + if len(c.Domains) == 0 { + return fmt.Errorf("at least one domain must be configured") + } + + for _, domain := range c.Domains { + // Only require SSL validation if we're running on HTTPS port + if c.Server.IsHTTPS { + if err := domain.validate(); err != nil { + return fmt.Errorf("domain %s configuration error: %v", domain.Name, err) + } + } else { + // Skip SSL validation for non-HTTPS servers + if err := domain.validateWithoutSSL(); err != nil { + return fmt.Errorf("domain %s configuration error: %v", domain.Name, err) + } + } + } + + return nil +} + +// Add this new method to Domain +func (d *Domain) validateWithoutSSL() error { + if d.Name == "" { + return fmt.Errorf("domain name cannot be empty") + } + + validTypes := map[string]bool{ + "static": true, + "proxy": true, + "file_directory": true, + } + if !validTypes[d.Type] { + return fmt.Errorf("invalid domain type: %s", d.Type) + } + + if d.Type == "proxy" { + for _, loc := range d.Locations { + if loc.Path == "" { + return fmt.Errorf("location path cannot be empty") + } + if err := loc.Proxy.validate(); err != nil { + return fmt.Errorf("proxy configuration error for location %s: %v", loc.Path, err) + } + } + } else if d.PublicDir == "" { + return fmt.Errorf("public_dir is required for type: %s", d.Type) + } + + return nil +} + type ServerConfig struct { - Port int `yaml:"port"` - HTTPPort int `yaml:"http_port"` + Port int `yaml:"port"` + HTTPPort int `yaml:"http_port"` + IsHTTPS bool `yaml:"-"` } func (s *ServerConfig) setDefaults() { @@ -131,6 +194,7 @@ func (s *ServerConfig) setDefaults() { if s.HTTPPort == 0 { s.HTTPPort = 80 } + s.IsHTTPS = s.Port == 443 } func (s *ServerConfig) validate() error { @@ -199,28 +263,6 @@ func (c *Config) setDefaults() { } } -func (c *Config) validate() error { - if err := c.Server.validate(); err != nil { - return fmt.Errorf("server configuration error: %v", err) - } - - if err := c.Log.validate(); err != nil { - return fmt.Errorf("log configuration error: %v", err) - } - - if len(c.Domains) == 0 { - return fmt.Errorf("at least one domain must be configured") - } - - for _, domain := range c.Domains { - if err := domain.validate(); err != nil { - return fmt.Errorf("domain %s configuration error: %v", domain.Name, err) - } - } - - return nil -} - func isLaunchedByDebugger() bool { _, err := exec.LookPath("gops") if err != nil { diff --git a/fast-server/server/server.go b/fast-server/server/server.go index 36ddf11..edd105e 100644 --- a/fast-server/server/server.go +++ b/fast-server/server/server.go @@ -95,6 +95,13 @@ func New(cfg *config.Config) *Server { } func (s *Server) setupRoutes() { + // Add health check endpoint before domain middleware + s.echo.GET("/health", func(c echo.Context) error { + return c.JSON(http.StatusOK, map[string]string{ + "status": "ok", + }) + }) + // Create a map for quick domain lookup domainMap := make(map[string]config.Domain) for _, domain := range s.config.Domains { @@ -104,6 +111,11 @@ func (s *Server) setupRoutes() { // Single middleware to handle all domains s.echo.Use(func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { + // Skip domain check for health check endpoint + if c.Request().URL.Path == "/health" { + return next(c) + } + host := c.Request().Host if strings.Contains(host, ":") { host = strings.Split(host, ":")[0]