76 lines
2.3 KiB
Go
76 lines
2.3 KiB
Go
|
|
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
|
||
|
|
}
|