108 lines
2.2 KiB
Go
108 lines
2.2 KiB
Go
package app
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
func resolveAutoloopLocationSpec(locFile, defaultLoc string) autoloopLocationSpec {
|
|
raw := ""
|
|
if data, err := os.ReadFile(locFile); err == nil {
|
|
for _, ln := range strings.Split(string(data), "\n") {
|
|
t := strings.TrimSpace(ln)
|
|
if t != "" && !strings.HasPrefix(t, "#") {
|
|
raw = t
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if raw == "" {
|
|
raw = strings.TrimSpace(defaultLoc)
|
|
}
|
|
raw = strings.TrimSpace(raw)
|
|
primary := raw
|
|
iso := ""
|
|
if p := strings.SplitN(raw, "|", 2); len(p) == 2 {
|
|
primary = strings.TrimSpace(p[0])
|
|
iso = strings.ToUpper(strings.TrimSpace(p[1]))
|
|
}
|
|
if primary == "" {
|
|
primary = strings.TrimSpace(defaultLoc)
|
|
}
|
|
if isISO2(primary) {
|
|
iso = strings.ToUpper(primary)
|
|
}
|
|
if iso == "" {
|
|
if tokens := strings.Fields(primary); len(tokens) > 0 && isISO2(tokens[0]) {
|
|
iso = strings.ToUpper(tokens[0])
|
|
}
|
|
}
|
|
if iso == "" {
|
|
iso = lookupISOFromLocationsCache(primary)
|
|
}
|
|
if iso == "" && isISO2(defaultLoc) {
|
|
iso = strings.ToUpper(strings.TrimSpace(defaultLoc))
|
|
}
|
|
return autoloopLocationSpec{
|
|
Primary: primary,
|
|
ISO: iso,
|
|
}
|
|
}
|
|
|
|
func isISO2(v string) bool {
|
|
s := strings.TrimSpace(v)
|
|
if len(s) != 2 {
|
|
return false
|
|
}
|
|
for _, ch := range s {
|
|
if (ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func lookupISOFromLocationsCache(primary string) string {
|
|
want := strings.ToLower(strings.TrimSpace(primary))
|
|
if want == "" {
|
|
return ""
|
|
}
|
|
|
|
var disk struct {
|
|
Locations []struct {
|
|
ISO string `json:"iso"`
|
|
Label string `json:"label"`
|
|
Target string `json:"target"`
|
|
} `json:"locations"`
|
|
}
|
|
data, err := os.ReadFile(vpnLocationsCachePath)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
if err := json.Unmarshal(data, &disk); err != nil {
|
|
return ""
|
|
}
|
|
|
|
for _, it := range disk.Locations {
|
|
iso := strings.ToUpper(strings.TrimSpace(it.ISO))
|
|
if !isISO2(iso) {
|
|
continue
|
|
}
|
|
target := strings.ToLower(strings.TrimSpace(it.Target))
|
|
if target != "" && target == want {
|
|
return iso
|
|
}
|
|
labelNorm := strings.ToLower(strings.TrimSpace(it.Label))
|
|
if labelNorm != "" {
|
|
if inferVPNLocationTargetFromLabel(it.Label, iso) == primary {
|
|
return iso
|
|
}
|
|
if strings.Contains(labelNorm, want) {
|
|
return iso
|
|
}
|
|
}
|
|
}
|
|
return ""
|
|
}
|