mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-02 23:06:36 +08:00
77 lines
2.3 KiB
Go
77 lines
2.3 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Package routeidentity resolves proxy route site names and normalized domains
|
|
// for OpenFlare control-plane and edge rendering.
|
|
package routeidentity
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/Rain-kl/Wavelet/internal/model"
|
|
)
|
|
|
|
// NormalizeDomains lowercases, deduplicates, and validates proxy route domains.
|
|
func NormalizeDomains(rawDomains []string) ([]string, error) {
|
|
normalized := make([]string, 0, len(rawDomains))
|
|
seen := make(map[string]struct{}, len(rawDomains))
|
|
for _, rawDomain := range rawDomains {
|
|
domain := strings.ToLower(strings.TrimSpace(rawDomain))
|
|
if domain == "" {
|
|
continue
|
|
}
|
|
if strings.Contains(domain, "://") || strings.Contains(domain, "/") {
|
|
return nil, fmt.Errorf("domain %q is invalid", rawDomain)
|
|
}
|
|
if _, ok := seen[domain]; ok {
|
|
continue
|
|
}
|
|
seen[domain] = struct{}{}
|
|
normalized = append(normalized, domain)
|
|
}
|
|
if len(normalized) == 0 {
|
|
return nil, errors.New("domain is required")
|
|
}
|
|
return normalized, nil
|
|
}
|
|
|
|
// DecodeDomains parses stored domains JSON or falls back to a single domain value.
|
|
func DecodeDomains(raw string, fallbackDomain string) ([]string, error) {
|
|
text := strings.TrimSpace(raw)
|
|
if text == "" {
|
|
return NormalizeDomains([]string{fallbackDomain})
|
|
}
|
|
var domains []string
|
|
if err := json.Unmarshal([]byte(text), &domains); err != nil {
|
|
return nil, errors.New("domains payload is invalid")
|
|
}
|
|
return NormalizeDomains(domains)
|
|
}
|
|
|
|
// ResolveSiteName returns the runtime site identifier for a proxy route.
|
|
func ResolveSiteName(route *model.ProxyRoute, raw, primaryDomain string) string {
|
|
siteName := strings.TrimSpace(raw)
|
|
if siteName != "" {
|
|
return siteName
|
|
}
|
|
if route != nil && strings.TrimSpace(route.SiteName) != "" {
|
|
return strings.TrimSpace(route.SiteName)
|
|
}
|
|
return strings.TrimSpace(primaryDomain)
|
|
}
|
|
|
|
// ResolveFromRoute decodes domains and resolves the site name for a stored route.
|
|
func ResolveFromRoute(route *model.ProxyRoute) (siteName string, domains []string, err error) {
|
|
if route == nil {
|
|
return "", nil, errors.New("proxy route is nil")
|
|
}
|
|
domains, err = DecodeDomains(route.Domains, route.Domain)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
return ResolveSiteName(route, route.SiteName, domains[0]), domains, nil
|
|
}
|