diff --git a/server/pkg/controller/file.go b/server/pkg/controller/file.go index 1937afa0eab..f9eb5851528 100644 --- a/server/pkg/controller/file.go +++ b/server/pkg/controller/file.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "github.com/ente-io/museum/pkg/controller/access" + "net/url" "runtime/debug" "strconv" "strings" @@ -808,7 +809,16 @@ func (c *FileController) getHotDcSignedUrl(objectKey string) (string, error) { Bucket: c.S3Config.GetHotBucket(), Key: &objectKey, }) - return r.Presign(PreSignedRequestValidityDuration) + + presignedUrl, _ := r.Presign(PreSignedRequestValidityDuration) + + cdnUrl, err := c.resolveCdnIfNeeded(presignedUrl, c.S3Config.GetHotBackblazeDC()) + + if err != nil { + return "", err + } + + return cdnUrl, nil } func (c *FileController) getPreSignedURLForDC(objectKey string, dc string) (string, error) { @@ -817,7 +827,32 @@ func (c *FileController) getPreSignedURLForDC(objectKey string, dc string) (stri Bucket: c.S3Config.GetBucket(dc), Key: &objectKey, }) - return r.Presign(PreSignedRequestValidityDuration) + + presignedUrl, _ := r.Presign(PreSignedRequestValidityDuration) + + cdnUrl, err := c.resolveCdnIfNeeded(presignedUrl, dc) + + if err != nil { + return "", err + } + + return cdnUrl, nil +} + +func (c *FileController) resolveCdnIfNeeded(presignedUrl string, dc string) (string, error) { + cdn := c.S3Config.GetCDN(dc) + + if *cdn != "" { + parsedUrl, _ := url.Parse(presignedUrl) + + parsedUrl.Host = *cdn + + parsedUrl.Scheme = "https" + + return parsedUrl.String(), nil + } + + return presignedUrl, nil } func (c *FileController) sizeOf(objectKey string) (int64, error) { diff --git a/server/pkg/utils/s3config/s3config.go b/server/pkg/utils/s3config/s3config.go index 469d3fb632f..95e21bb8ccc 100644 --- a/server/pkg/utils/s3config/s3config.go +++ b/server/pkg/utils/s3config/s3config.go @@ -36,6 +36,8 @@ type S3Config struct { s3Configs map[string]*aws.Config // A map from data centers to pre-created S3 clients s3Clients map[string]s3.S3 + // Optional per-bucket CDN URL + cdns map[string]string // Indicates if compliance is enabled for the Wasabi DC. isWasabiComplianceEnabled bool // Indicates if local minio buckets are being used. Enables various @@ -123,6 +125,7 @@ func (config *S3Config) initialize() { config.buckets = make(map[string]string) config.s3Configs = make(map[string]*aws.Config) config.s3Clients = make(map[string]s3.S3) + config.cdns = make(map[string]string) usePathStyleURLs := viper.GetBool("s3.use_path_style_urls") areLocalBuckets := viper.GetBool("s3.are_local_buckets") @@ -150,6 +153,7 @@ func (config *S3Config) initialize() { s3Client := *s3.New(s3Session) config.s3Configs[dc] = &s3Config config.s3Clients[dc] = s3Client + config.cdns[dc] = viper.GetString("s3." + dc + ".cdn") if dc == dcWasabiEuropeCentral_v3 { config.isWasabiComplianceEnabled = viper.GetBool("s3." + dc + ".compliance") } @@ -167,6 +171,11 @@ func (config *S3Config) GetBucket(dcOrBucketID string) *string { return &bucket } +func (config *S3Config) GetCDN(dcOrBucketID string) *string { + cdn := config.cdns[dcOrBucketID] + return &cdn +} + // GetBucketID returns the bucket ID for the given object type. Note: existing dc are renamed as bucketID func (config *S3Config) GetBucketID(oType ente.ObjectType) string { if config.fileDataConfig.HasConfig(oType) {