github.com/defang-io/defang/src@v0.0.0-20240505002154-bdf411911834/pkg/clouds/aws/ecs/upload.go (about) 1 package ecs 2 3 import ( 4 "context" 5 "errors" 6 "regexp" 7 8 "github.com/aws/aws-sdk-go-v2/service/s3" 9 "github.com/aws/smithy-go/ptr" 10 "github.com/google/uuid" 11 ) 12 13 // From https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html 14 var s3InvalidCharsRegexp = regexp.MustCompile(`[^a-zA-Z0-9!_.*'()-]`) 15 16 const prefix = "uploads/" 17 18 func (a *AwsEcs) CreateUploadURL(ctx context.Context, name string) (string, error) { 19 cfg, err := a.LoadConfig(ctx) 20 if err != nil { 21 return "", err 22 } 23 24 if name == "" { 25 name = uuid.NewString() 26 } else { 27 if len(name) > 64 { 28 return "", errors.New("name must be less than 64 characters") 29 } 30 // Sanitize the digest so it's safe to use as a file name 31 name = s3InvalidCharsRegexp.ReplaceAllString(name, "_") 32 // name = path.Join(buildsPath, tenantId.String(), digest); TODO: avoid collisions between tenants 33 } 34 35 s3Client := s3.NewFromConfig(cfg) 36 // Use S3 SDK to create a presigned URL for uploading a file. 37 req, err := s3.NewPresignClient(s3Client).PresignPutObject(ctx, &s3.PutObjectInput{ 38 Bucket: &a.BucketName, 39 Key: ptr.String(prefix + name), 40 }) 41 if err != nil { 42 return "", err 43 } 44 return req.URL, nil 45 }