package config import ( "fmt" "os" "go.yaml.in/yaml/v3" ) // Config 对应 DEVELOPMENT 第 11.1 节的配置文件。 type Config struct { Listen string `yaml:"listen"` AdminListen string `yaml:"admin_listen"` TLS TLSConfig `yaml:"tls"` TrustedProxies []string `yaml:"trusted_proxies"` DataDir string `yaml:"data_dir"` Limits LimitsConfig `yaml:"limits"` SessionIdleDays int `yaml:"session_idle_days"` RecordRetentionDays int `yaml:"record_retention_days"` IdempotencyHours int `yaml:"idempotency_hours"` ReceiptRetentionDays int `yaml:"receipt_retention_days"` SQLiteSynchronous string `yaml:"sqlite_synchronous"` Metrics MetricsConfig `yaml:"metrics"` Log LogConfig `yaml:"log"` } type TLSConfig struct { CertFile string `yaml:"cert_file"` KeyFile string `yaml:"key_file"` AllowPlaintext bool `yaml:"allow_plaintext"` } type LimitsConfig struct { MaxBodyBytes int `yaml:"max_body_bytes"` MaxMetaBytes int `yaml:"max_meta_bytes"` MaxFrameBytes int `yaml:"max_frame_bytes"` MaxTTLSeconds int `yaml:"max_ttl_seconds"` MaxScheduleSeconds int `yaml:"max_schedule_seconds"` MaxGroupMembers int `yaml:"max_group_members"` GraceSeconds int `yaml:"grace_seconds"` AckTimeoutSeconds int `yaml:"ack_timeout_seconds"` DeliveryWindow int `yaml:"delivery_window"` ReceiptWindow int `yaml:"receipt_window"` RequestsPerSecond int `yaml:"requests_per_second"` MaxPendingPerSender int `yaml:"max_pending_per_sender"` MaxPendingPerReceiver int `yaml:"max_pending_per_receiver"` } type MetricsConfig struct { Token string `yaml:"token"` } type LogConfig struct { Level string `yaml:"level"` } // Default 返回与 DEVELOPMENT 11.1 示例一致的默认值。 func Default() Config { return Config{ Listen: ":7443", AdminListen: "", TLS: TLSConfig{ AllowPlaintext: false, }, TrustedProxies: nil, DataDir: "./data", Limits: LimitsConfig{ MaxBodyBytes: 262144, MaxMetaBytes: 4096, MaxFrameBytes: 786432, MaxTTLSeconds: 2592000, MaxScheduleSeconds: 31536000, MaxGroupMembers: 1000, GraceSeconds: 60, AckTimeoutSeconds: 300, DeliveryWindow: 32, ReceiptWindow: 64, RequestsPerSecond: 50, MaxPendingPerSender: 10000, MaxPendingPerReceiver: 10000, }, SessionIdleDays: 30, RecordRetentionDays: 7, IdempotencyHours: 24, ReceiptRetentionDays: 7, SQLiteSynchronous: "FULL", Metrics: MetricsConfig{}, Log: LogConfig{ Level: "info", }, } } // Load 从路径加载 YAML 配置;空字段保留默认值。 func Load(path string) (Config, error) { cfg := Default() data, err := os.ReadFile(path) if err != nil { return Config{}, fmt.Errorf("read config: %w", err) } if err := yaml.Unmarshal(data, &cfg); err != nil { return Config{}, fmt.Errorf("parse config: %w", err) } if cfg.Listen == "" { cfg.Listen = Default().Listen } if cfg.DataDir == "" { cfg.DataDir = Default().DataDir } if cfg.SQLiteSynchronous == "" { cfg.SQLiteSynchronous = Default().SQLiteSynchronous } return cfg, nil } // PathFromEnv 返回 NIXMSG_CONFIG 或默认 ./config.yaml。 func PathFromEnv() string { if p := os.Getenv("NIXMSG_CONFIG"); p != "" { return p } return "./config.yaml" }