0df28e9dd8
- Unify duplicate uTLS transports into shared internal/transport package - Extract shared version constant into internal/version - Move LoadDefaultCredentials from config to auth (remove config→auth import) - Deduplicate handler.go: extract telemetry/error helpers (324→268 lines) - Break up main.go::run() into initCredential/initEmbedded - Eliminate logging.Config duplication (use config.LoggingConfig directly) - Extract logWriter to embedded/log.go, SSE fixtures to consts in sniff.go - Use uTLS client for usage polling (consistent TLS fingerprint) - Handle sjson.SetBytes errors in sanitize.go instead of silently swallowing - Document reverse-engineered magic values in billing.go - Unexport Credential.CooldownUntil (internal state) - Replace hardcoded auth bypass paths with map in server.go
119 lines
3.0 KiB
Go
119 lines
3.0 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
type Config struct {
|
|
Port int `yaml:"port"`
|
|
APIKeys []string `yaml:"api_keys"`
|
|
ClaudeBinary string `yaml:"claude_binary"`
|
|
Sanitize SanitizeConfig `yaml:"sanitize"`
|
|
Logging LoggingConfig `yaml:"logging"`
|
|
Telemetry TelemetryConfig `yaml:"telemetry"`
|
|
}
|
|
|
|
type SanitizeConfig struct {
|
|
Tools []RenameRule `yaml:"tools"`
|
|
System []ReplaceRule `yaml:"system"`
|
|
Body []ReplaceRule `yaml:"body"`
|
|
}
|
|
|
|
type RenameRule struct {
|
|
From string `yaml:"from"`
|
|
To string `yaml:"to"`
|
|
}
|
|
|
|
type ReplaceRule struct {
|
|
Match string `yaml:"match"`
|
|
Replace string `yaml:"replace"`
|
|
}
|
|
|
|
type TelemetryConfig struct {
|
|
Export ExportConfig `yaml:"export"`
|
|
Embedded EmbeddedConfig `yaml:"embedded"`
|
|
ServiceName string `yaml:"service_name"`
|
|
}
|
|
|
|
type ExportConfig struct {
|
|
Endpoint string `yaml:"endpoint"`
|
|
Insecure bool `yaml:"insecure"`
|
|
Headers map[string]string `yaml:"headers"`
|
|
}
|
|
|
|
func (e ExportConfig) Enabled() bool { return e.Endpoint != "" }
|
|
|
|
type EmbeddedConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
Port int `yaml:"port"`
|
|
PersesBinary string `yaml:"perses_binary"`
|
|
VMBinary string `yaml:"vm_binary"`
|
|
VMPort int `yaml:"vm_port"`
|
|
BinDir string `yaml:"bin_dir"`
|
|
}
|
|
|
|
type LoggingConfig struct {
|
|
Level string `yaml:"level"`
|
|
File string `yaml:"file"`
|
|
MaxSizeMB int `yaml:"max_size_mb"`
|
|
MaxBackups int `yaml:"max_backups"`
|
|
MaxAgeDays int `yaml:"max_age_days"`
|
|
Compress bool `yaml:"compress"`
|
|
}
|
|
|
|
func Load(path string) (*Config, error) {
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("read config %s: %w", path, err)
|
|
}
|
|
|
|
cfg := &Config{Port: 8080}
|
|
if err := yaml.Unmarshal(data, cfg); err != nil {
|
|
return nil, fmt.Errorf("parse config: %w", err)
|
|
}
|
|
|
|
if cfg.Logging.Level == "" {
|
|
cfg.Logging.Level = "info"
|
|
}
|
|
if cfg.Logging.MaxSizeMB == 0 {
|
|
cfg.Logging.MaxSizeMB = 100
|
|
}
|
|
if cfg.Logging.MaxBackups == 0 {
|
|
cfg.Logging.MaxBackups = 5
|
|
}
|
|
if cfg.Logging.MaxAgeDays == 0 {
|
|
cfg.Logging.MaxAgeDays = 30
|
|
}
|
|
|
|
if cfg.Telemetry.ServiceName == "" {
|
|
cfg.Telemetry.ServiceName = "anthropic-proxy"
|
|
}
|
|
if cfg.Telemetry.Embedded.Port == 0 {
|
|
cfg.Telemetry.Embedded.Port = 8080
|
|
}
|
|
if cfg.Telemetry.Embedded.PersesBinary == "" {
|
|
cfg.Telemetry.Embedded.PersesBinary = "perses"
|
|
}
|
|
if cfg.Telemetry.Embedded.VMBinary == "" {
|
|
cfg.Telemetry.Embedded.VMBinary = "victoria-metrics"
|
|
}
|
|
if cfg.Telemetry.Embedded.VMPort == 0 {
|
|
cfg.Telemetry.Embedded.VMPort = 8428
|
|
}
|
|
|
|
// Check for deprecated claude_credentials field
|
|
var rawCfg map[string]interface{}
|
|
if err := yaml.Unmarshal(data, &rawCfg); err == nil {
|
|
if _, exists := rawCfg["claude_credentials"]; exists {
|
|
if val, ok := rawCfg["claude_credentials"].(string); ok && val != "" {
|
|
return nil, fmt.Errorf("claude_credentials is no longer supported, remove it from config.yaml — the proxy now manages credentials at ~/.claude/.credentials.json")
|
|
}
|
|
}
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|