105 lines
3.0 KiB
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
|
|
}
|
|
}
|
|
}
|