package config import ( "fmt" "os" "gopkg.in/yaml.v3" ) // Config is the top-level server configuration. type Config struct { Server ServerConfig `yaml:"server"` Auth AuthConfig `yaml:"auth"` Storage StorageConfig `yaml:"storage"` TLS TLSConfig `yaml:"tls"` Logging LoggingConfig `yaml:"logging"` } type ServerConfig struct { Host string `yaml:"host"` Port int `yaml:"port"` // Base URL used in DAV responses (e.g. https://dav.example.com) BaseURL string `yaml:"base_url"` } type AuthConfig struct { // Realm shown in WWW-Authenticate header Realm string `yaml:"realm"` } type StorageConfig struct { // Root directory for all data DataDir string `yaml:"data_dir"` } type TLSConfig struct { Enabled bool `yaml:"enabled"` CertFile string `yaml:"cert_file"` KeyFile string `yaml:"key_file"` } type LoggingConfig struct { Level string `yaml:"level"` // debug | info | warn | error Format string `yaml:"format"` // text | json } // Load reads and parses a YAML config file. func Load(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("reading config %q: %w", path, err) } cfg := &Config{} if err := yaml.Unmarshal(data, cfg); err != nil { return nil, fmt.Errorf("parsing config %q: %w", path, err) } cfg.applyDefaults() return cfg, cfg.validate() } func (c *Config) applyDefaults() { if c.Server.Host == "" { c.Server.Host = "0.0.0.0" } if c.Server.Port == 0 { c.Server.Port = 8080 } if c.Server.BaseURL == "" { scheme := "http" if c.TLS.Enabled { scheme = "https" } c.Server.BaseURL = fmt.Sprintf("%s://%s:%d", scheme, c.Server.Host, c.Server.Port) } if c.Auth.Realm == "" { c.Auth.Realm = "DAV Server" } if c.Storage.DataDir == "" { c.Storage.DataDir = "./data" } if c.Logging.Level == "" { c.Logging.Level = "info" } if c.Logging.Format == "" { c.Logging.Format = "text" } } func (c *Config) validate() error { if c.TLS.Enabled { if c.TLS.CertFile == "" || c.TLS.KeyFile == "" { return fmt.Errorf("tls.cert_file and tls.key_file are required when tls is enabled") } } return nil }