internal/cdn/generic.go
Rama main · réplica de lectura del repositorio original.
package cdn
import (
"log"
"net/url"
"strings"
"sync"
"xprem/config"
"xprem/internal/bucket"
)
var s3CDNPrefixDeprecationOnce sync.Once
// ResolveCDNBaseURL returns the base URL of the CDN fronting the storage
// bucket. It reads CDN_BASE_URL first and falls back to the legacy
// S3_CDN_PREFIX env var, which predates non-S3 storage backends.
func ResolveCDNBaseURL() string {
baseURL := config.GetEnv("CDN_BASE_URL")
if baseURL == "" {
// TODO: remove S3_CDN_PREFIX backward-compat once users migrated to CDN_BASE_URL
baseURL = config.GetEnv("S3_CDN_PREFIX")
if baseURL != "" {
s3CDNPrefixDeprecationOnce.Do(func() {
log.Println("WARNING: S3_CDN_PREFIX is deprecated and will be removed in a future release; use CDN_BASE_URL instead")
})
}
}
return baseURL
}
type GenericCDN struct{}
// A generic CDN serves the bucket's objects from a base URL, so it needs a
// storage backend whose objects are reachable over HTTP behind that URL.
// Cloud backends qualify; local storage has no object URLs a CDN could use
// as origin.
func (c *GenericCDN) isCDNAvailable() bool {
if ResolveCDNBaseURL() == "" {
return false
}
switch config.GetEnv("STORAGE_MODE") {
case "s3":
return config.GetEnv("S3_BUCKET_NAME") != ""
case "gcs":
return config.GetEnv("GCS_BUCKET_NAME") != ""
case "azure":
return config.GetEnv("AZURE_BLOB_CONTAINER_NAME") != ""
default:
return false
}
}
func (c *GenericCDN) ComputeRedirectionURLForAsset(appId, branch, runtimeVersion, updateId, asset string) (string, error) {
baseURL := ResolveCDNBaseURL()
keyPrefix := strings.TrimSuffix(bucket.ResolveKeyPrefix(), "/")
elems := []string{appId, branch, runtimeVersion, updateId, asset}
if keyPrefix != "" {
elems = append([]string{keyPrefix}, elems...)
}
cdnUrl, err := url.JoinPath(baseURL, elems...)
if err != nil {
return "", err
}
return cdnUrl, nil
}
func (c *GenericCDN) ComputeRedirectionURLForBlob(appId, hash string) (string, error) {
return c.objectURL(bucket.BlobObjectKey(appId, hash))
}
func (c *GenericCDN) ComputeRedirectionURLForPatch(appId, branch, targetUpdateUUID, sourceUpdateUUID string) (string, error) {
return c.objectURL(bucket.BSDiffObjectKey(appId, branch, targetUpdateUUID, sourceUpdateUUID))
}
func (c *GenericCDN) objectURL(key string) (string, error) {
baseURL := ResolveCDNBaseURL()
keyPrefix := strings.TrimSuffix(bucket.ResolveKeyPrefix(), "/")
elems := []string{key}
if keyPrefix != "" {
elems = append([]string{keyPrefix}, elems...)
}
cdnUrl, err := url.JoinPath(baseURL, elems...)
if err != nil {
return "", err
}
return cdnUrl, nil
}