package config import ( "encoding/json" "fmt" "os" "path/filepath" "gopkg.in/yaml.v3" ) // Config represents the root configuration of the proxy. type Config struct { HTTP HTTPConfig `yaml:"http" json:"http"` TCP TCPConfig `yaml:"tcp" json:"tcp"` UDP UDPConfig `yaml:"udp" json:"udp"` } type UDPConfig struct { Port int `yaml:"port" json:"port"` Backend string `yaml:"backend" json:"backend"` } type HTTPConfig struct { Port int `yaml:"port" json:"port"` TLS TLSConfig `yaml:"tls" json:"tls"` Routers []RouterRoute `yaml:"routers" json:"routers"` } type TLSConfig struct { Enabled bool `yaml:"enabled" json:"enabled"` Port int `yaml:"port" json:"port"` CertFile string `yaml:"cert_file" json:"cert_file"` KeyFile string `yaml:"key_file" json:"key_file"` } type TCPConfig struct { Port int `yaml:"port" json:"port"` Backend string `yaml:"backend" json:"backend"` } type RouterRoute struct { Path string `yaml:"path" json:"path"` Host string `yaml:"host" json:"host"` Backends []string `yaml:"backends" json:"backends"` // Used for Load Balancing BackendURL string `yaml:"backend_url" json:"backend_url"` // Legacy / Single backend StripPrefix bool `yaml:"strip_prefix" json:"strip_prefix"` } // LoadConfig reads a configuration file (YAML or JSON) and parses it into the Config struct. func LoadConfig(path string) (*Config, error) { file, err := os.Open(path) if err != nil { return nil, fmt.Errorf("failed to open config file: %w", err) } defer file.Close() var cfg Config ext := filepath.Ext(path) switch ext { case ".yaml", ".yml": decoder := yaml.NewDecoder(file) if err := decoder.Decode(&cfg); err != nil { return nil, fmt.Errorf("failed to parse yaml config: %w", err) } case ".json": decoder := json.NewDecoder(file) if err := decoder.Decode(&cfg); err != nil { return nil, fmt.Errorf("failed to parse json config: %w", err) } default: return nil, fmt.Errorf("unsupported config format: %s", ext) } return &cfg, nil }