76 lines
1.7 KiB
Go
76 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
// proxyRule is the minimal structure we need from Zoraxy's proxy config files.
|
|
type proxyRule struct {
|
|
Domain string `json:"RootOrMatchingDomain"`
|
|
ActiveOrigins []struct {
|
|
Origin string `json:"OriginIpOrDomain"`
|
|
} `json:"ActiveOrigins"`
|
|
Disabled bool `json:"Disabled"`
|
|
}
|
|
|
|
// hostMap maps request Host headers to backend URLs.
|
|
var (
|
|
hostMap = make(map[string]string)
|
|
hostMapMu sync.RWMutex
|
|
)
|
|
|
|
// loadHostMap reads Zoraxy proxy configs and builds a host→backend map.
|
|
func loadHostMap() {
|
|
hostMapMu.Lock()
|
|
defer hostMapMu.Unlock()
|
|
|
|
hostMap = make(map[string]string)
|
|
proxyDir := "/opt/zoraxy/conf/proxy"
|
|
|
|
entries, err := os.ReadDir(proxyDir)
|
|
if err != nil {
|
|
log.Printf("WARN: cannot read proxy configs: %v", err)
|
|
return
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
if !strings.HasSuffix(entry.Name(), ".config") {
|
|
continue
|
|
}
|
|
path := filepath.Join(proxyDir, entry.Name())
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
var rule proxyRule
|
|
if err := json.Unmarshal(data, &rule); err != nil {
|
|
continue
|
|
}
|
|
if rule.Disabled || len(rule.ActiveOrigins) == 0 {
|
|
continue
|
|
}
|
|
hostMap[strings.ToLower(rule.Domain)] = rule.ActiveOrigins[0].Origin
|
|
}
|
|
log.Printf("Firewall: loaded %d proxy backends", len(hostMap))
|
|
}
|
|
|
|
// resolveBackend finds the backend URL for a given Host header.
|
|
// Falls back to the configured BackendURL if no match.
|
|
func resolveBackend(host string) string {
|
|
hostMapMu.RLock()
|
|
defer hostMapMu.RUnlock()
|
|
|
|
if backend, ok := hostMap[strings.ToLower(host)]; ok {
|
|
return backend
|
|
}
|
|
if backend, ok := hostMap[strings.ToLower(strings.Split(host, ":")[0])]; ok {
|
|
return backend
|
|
}
|
|
// Fallback
|
|
return getConfig().BackendURL
|
|
}
|