Files
go-omni/config/config.go

105 lines
3.0 KiB
Go

package config
import (
"strings"
"time"
"git.yuntuo.hk/k2safe/go-omni/httpx"
"git.yuntuo.hk/k2safe/go-omni/logx"
)
const defaultRequestIDHeader = "X-Request-ID"
// Config controls the default runtime behavior of an App.
type Config struct {
Address string
RequestIDHeader string
EnableLogger bool
TrustedProxies []string
ShutdownTimeout time.Duration
Log logx.Config
}
func Default() Config {
return Config{
Address: ":8080",
RequestIDHeader: defaultRequestIDHeader,
ShutdownTimeout: 10 * time.Second,
Log: logx.Default(),
}
}
// Validate checks configuration values before an application starts.
func (c Config) Validate() error {
if strings.TrimSpace(c.Address) == "" {
return &ConfigError{Field: "address", Message: "is required"}
}
if strings.TrimSpace(c.RequestIDHeader) == "" {
return &ConfigError{Field: "request_id_header", Message: "is required"}
}
if c.ShutdownTimeout <= 0 {
return &ConfigError{Field: "shutdown_timeout", Message: "must be positive"}
}
if _, err := httpx.NewClientIPResolver(c.TrustedProxies...); err != nil {
return &ConfigError{Field: "trusted_proxies", Message: err.Error()}
}
return nil
}
// ConfigError describes an invalid application configuration field.
type ConfigError struct {
Field string
Message string
}
func (e *ConfigError) Error() string { return "config " + e.Field + " " + e.Message }
// Option changes an App's configuration.
type Option func(*Config)
// WithRequestIDHeader changes the header used to read and return request IDs.
func WithRequestIDHeader(header string) Option {
return func(cfg *Config) {
if value := strings.TrimSpace(header); value != "" {
cfg.RequestIDHeader = value
}
}
}
// WithLogger enables GoOmni's structured access logger.
func WithLogger(enabled bool) Option {
return func(cfg *Config) { cfg.EnableLogger = enabled }
}
// WithTrustedProxies allows only these IPs/CIDRs to supply X-Forwarded-For.
// An empty list disables forwarding-header trust. Invalid entries are rejected
// by Config.Validate and panic when passed directly to App.New.
func WithTrustedProxies(proxies ...string) Option {
proxies = append([]string(nil), proxies...)
return func(cfg *Config) { cfg.TrustedProxies = append([]string(nil), proxies...) }
}
// WithConfig applies a complete configuration loaded from a file or
// environment. Later options can still override individual fields.
func WithConfig(settings Config) Option {
settings.TrustedProxies = append([]string(nil), settings.TrustedProxies...)
return func(cfg *Config) {
*cfg = settings
cfg.TrustedProxies = append([]string(nil), settings.TrustedProxies...)
}
}
// WithLogConfig configures the logger used by the application runtime.
func WithLogConfig(settings logx.Config) Option {
return func(cfg *Config) { cfg.Log = settings }
}
// WithShutdownTimeout controls how long RunContext waits for active requests.
func WithShutdownTimeout(timeout time.Duration) Option {
return func(cfg *Config) {
if timeout > 0 {
cfg.ShutdownTimeout = timeout
}
}
}