Files
ai-agent/internal/services/public_asset_url.go
T

76 lines
2.3 KiB
Go
Raw Normal View History

package services
import (
"strings"
"sync"
)
var publicAssetURLRuntime struct {
sync.RWMutex
resolver func(string) string
}
// SetPublicAssetURLResolver configures how host-owned asset keys are exposed
// to standalone customer-service clients. A nil resolver keeps absolute URLs
// and legacy values unchanged.
func SetPublicAssetURLResolver(resolver func(string) string) {
publicAssetURLRuntime.Lock()
publicAssetURLRuntime.resolver = resolver
publicAssetURLRuntime.Unlock()
}
// SetPublicAssetURLSettings applies the same object-key joining rule used by
// the management frontend: cloud material keys use the active oss_domain,
// while absolute and same-origin URLs stay unchanged.
func SetPublicAssetURLSettings(settings map[string]string) {
engine := strings.TrimSpace(settings["oss_default_engine"])
if engine == "" || engine == "local" {
SetPublicAssetURLResolver(nil)
return
}
domain := strings.TrimSpace(settings["oss_"+engine+"_domain"])
SetPublicAssetURLResolver(func(value string) string {
return resolvePublicAssetURLWithDomain(value, domain)
})
}
func resolvePublicAssetURLWithDomain(value, domain string) string {
value = strings.TrimSpace(value)
if value == "" || strings.HasPrefix(value, "/") {
return value
}
lower := strings.ToLower(value)
if strings.HasPrefix(lower, "http://") || strings.HasPrefix(lower, "https://") || strings.HasPrefix(lower, "data:") {
return value
}
domain = strings.TrimSpace(domain)
if domain == "" {
return value
}
if !strings.HasPrefix(strings.ToLower(domain), "http://") && !strings.HasPrefix(strings.ToLower(domain), "https://") {
domain = "https://" + domain
}
return strings.TrimRight(domain, "/") + "/" + strings.TrimLeft(value, "/")
}
// ResolvePublicAssetURL converts a host-owned object key into a browser-ready
// URL. Resolver failures must fall back to the stored value so message delivery
// is never affected by an optional avatar.
func ResolvePublicAssetURL(value string) string {
value = strings.TrimSpace(value)
if value == "" {
return value
}
publicAssetURLRuntime.RLock()
resolver := publicAssetURLRuntime.resolver
publicAssetURLRuntime.RUnlock()
if resolver == nil {
return value
}
resolved := strings.TrimSpace(resolver(value))
if resolved == "" {
return value
}
return resolved
}