Files
GoLangProxy/config.go
T

161 lines
5.4 KiB
Go
Raw Normal View History

2025-03-01 11:39:07 +00:00
package main
import (
"fmt"
"os"
"time"
"gopkg.in/yaml.v2"
)
2025-03-01 19:13:22 +00:00
// Config defines the structure of the proxy configuration loaded from config.yaml
2025-03-01 11:39:07 +00:00
type Config struct {
2025-03-01 19:13:22 +00:00
ListenHTTP string `yaml:"listen_http"` // Port for HTTP server (e.g., ":80")
ListenHTTPS string `yaml:"listen_https"` // Port for HTTPS server (e.g., ":443")
CertDir string `yaml:"cert_dir"` // Directory for certificate files
CertFile string `yaml:"cert_file"` // Certificate filename
KeyFile string `yaml:"key_file"` // Private key filename
Routes map[string]string `yaml:"routes"` // Mapping of hostnames to target URLs
TrustTarget map[string]bool `yaml:"trust_target"` // Whether to skip TLS verification for targets
NoHTTPSRedirect map[string]bool `yaml:"no_https_redirect"` // Whether to skip HTTP->HTTPS redirect
2025-03-01 11:39:07 +00:00
}
2025-03-01 19:13:22 +00:00
// loadConfig reads and parses the config.yaml file
2025-03-01 11:39:07 +00:00
func loadConfig() (Config, error) {
data, err := os.ReadFile(configPath)
if err != nil {
return Config{}, fmt.Errorf("failed to read config %s: %v", configPath, err)
}
var cfg Config
2025-03-01 19:13:22 +00:00
if err := yaml.Unmarshal(data, &cfg); err != nil {
2025-03-01 11:39:07 +00:00
return Config{}, fmt.Errorf("failed to unmarshal config: %v", err)
}
return cfg, nil
}
2025-03-01 19:13:22 +00:00
// generateDefaultConfig creates a default configuration if config.yaml doesnt exist
2025-03-01 11:39:07 +00:00
func generateDefaultConfig() Config {
return Config{
ListenHTTP: ":80",
ListenHTTPS: ":443",
2025-03-01 19:13:22 +00:00
CertDir: "./certificate",
2025-03-01 11:39:07 +00:00
CertFile: "certificate.pem",
KeyFile: "key.pem",
Routes: map[string]string{
2025-03-01 19:13:22 +00:00
"*": "https://127.0.0.1:3000", // Wildcard route
"main.example.com": "https://10.100.111.254:4444", // Specific route
2025-03-01 11:39:07 +00:00
},
TrustTarget: map[string]bool{
2025-03-01 19:13:22 +00:00
"*": true, // Skip TLS verification by default
2025-03-01 18:07:52 +00:00
"main.example.com": true,
2025-03-01 11:39:07 +00:00
},
NoHTTPSRedirect: map[string]bool{
2025-03-01 19:13:22 +00:00
"*": false, // Redirect HTTP to HTTPS by default
2025-03-01 18:07:52 +00:00
"main.example.com": false,
2025-03-01 11:39:07 +00:00
},
}
}
2025-03-01 19:13:22 +00:00
// saveConfig writes the configuration to config.yaml
2025-03-01 11:39:07 +00:00
func saveConfig(cfg Config) error {
if err := os.MkdirAll(baseDir, 0755); err != nil {
return fmt.Errorf("failed to create base directory %s: %v", baseDir, err)
}
data, err := yaml.Marshal(cfg)
if err != nil {
return fmt.Errorf("failed to marshal config: %v", err)
}
2025-03-01 19:13:22 +00:00
if err := os.WriteFile(configPath, data, 0644); err != nil {
2025-03-01 11:39:07 +00:00
return fmt.Errorf("failed to write config to %s: %v", configPath, err)
}
return nil
}
2025-03-01 19:13:22 +00:00
// monitorConfig watches config.yaml for changes and updates the in-memory config
2025-03-01 11:39:07 +00:00
func monitorConfig() {
var lastModTime time.Time
for {
configInfo, err := os.Stat(configPath)
if err != nil {
2025-03-01 18:07:52 +00:00
errorLogger.Printf("Error checking config file: %v", err)
2025-03-01 11:39:07 +00:00
time.Sleep(5 * time.Second)
continue
}
if configInfo.ModTime() != lastModTime {
newConfig, err := loadConfig()
if err != nil {
2025-03-01 18:07:52 +00:00
errorLogger.Printf("Error reloading config: %v", err)
2025-03-01 11:39:07 +00:00
} else {
configMux.Lock()
2025-03-01 19:13:22 +00:00
// Update individual fields only if theyve changed
2025-03-01 11:39:07 +00:00
if newConfig.ListenHTTP != config.ListenHTTP {
config.ListenHTTP = newConfig.ListenHTTP
2025-03-01 18:07:52 +00:00
refreshLogger.Printf("Updated listen_http to %s", config.ListenHTTP)
2025-03-01 11:39:07 +00:00
}
if newConfig.ListenHTTPS != config.ListenHTTPS {
config.ListenHTTPS = newConfig.ListenHTTPS
2025-03-01 18:07:52 +00:00
refreshLogger.Printf("Updated listen_https to %s", config.ListenHTTPS)
2025-03-01 11:39:07 +00:00
}
if newConfig.CertDir != config.CertDir || newConfig.CertFile != config.CertFile || newConfig.KeyFile != config.KeyFile {
config.CertDir = newConfig.CertDir
config.CertFile = newConfig.CertFile
config.KeyFile = newConfig.KeyFile
updatePaths()
if err := loadCertificate(); err != nil {
2025-03-01 18:07:52 +00:00
errorLogger.Printf("Error reloading certificate after path change: %v", err)
2025-03-01 11:39:07 +00:00
} else {
2025-03-01 18:07:52 +00:00
refreshLogger.Println("Updated certificate paths and reloaded certificate")
2025-03-01 11:39:07 +00:00
}
}
2025-03-01 19:13:22 +00:00
// Update routes
2025-03-01 11:39:07 +00:00
for k, v := range newConfig.Routes {
if oldV, exists := config.Routes[k]; !exists || oldV != v {
config.Routes[k] = v
2025-03-01 18:07:52 +00:00
refreshLogger.Printf("Updated route %s to %s", k, v)
2025-03-01 11:39:07 +00:00
}
}
for k := range config.Routes {
if _, exists := newConfig.Routes[k]; !exists {
delete(config.Routes, k)
2025-03-01 18:07:52 +00:00
refreshLogger.Printf("Removed route %s", k)
2025-03-01 11:39:07 +00:00
}
}
2025-03-01 19:13:22 +00:00
// Update trust_target
2025-03-01 11:39:07 +00:00
for k, v := range newConfig.TrustTarget {
if oldV, exists := config.TrustTarget[k]; !exists || oldV != v {
config.TrustTarget[k] = v
2025-03-01 18:07:52 +00:00
refreshLogger.Printf("Updated trust_target %s to %v", k, v)
2025-03-01 11:39:07 +00:00
}
}
for k := range config.TrustTarget {
if _, exists := newConfig.TrustTarget[k]; !exists {
delete(config.TrustTarget, k)
2025-03-01 18:07:52 +00:00
refreshLogger.Printf("Removed trust_target %s", k)
2025-03-01 11:39:07 +00:00
}
}
2025-03-01 19:13:22 +00:00
// Update no_https_redirect
2025-03-01 11:39:07 +00:00
for k, v := range newConfig.NoHTTPSRedirect {
if oldV, exists := config.NoHTTPSRedirect[k]; !exists || oldV != v {
config.NoHTTPSRedirect[k] = v
2025-03-01 18:07:52 +00:00
refreshLogger.Printf("Updated no_https_redirect %s to %v", k, v)
2025-03-01 11:39:07 +00:00
}
}
for k := range config.NoHTTPSRedirect {
if _, exists := newConfig.NoHTTPSRedirect[k]; !exists {
delete(config.NoHTTPSRedirect, k)
2025-03-01 18:07:52 +00:00
refreshLogger.Printf("Removed no_https_redirect %s", k)
2025-03-01 11:39:07 +00:00
}
}
configMux.Unlock()
2025-03-01 18:07:52 +00:00
refreshLogger.Println("Config reloaded successfully")
2025-03-01 11:39:07 +00:00
lastModTime = configInfo.ModTime()
}
}
2025-03-01 19:13:22 +00:00
time.Sleep(5 * time.Second) // Poll every 5 seconds
2025-03-01 11:39:07 +00:00
}
}