How do I get file url after put file to amazon s3 in Go?

Viewed 2988

File is uploaded successfully, and I want to return file url after uploading.

_, err := s3.New(s).PutObject(&s3.PutObjectInput{
    Bucket:               aws.String("bucket"),
    Key:                  aws.String(tempFileName),
    ACL:                  aws.String("public-read"), // could be private if you want it to be access by only authorized users
    Body:                 bytes.NewReader(buffer),
    ContentLength:        aws.Int64(int64(size)),
    ContentType:          aws.String(http.DetectContentType(buffer)),
    ContentDisposition:   aws.String("attachment"),
    ServerSideEncryption: aws.String("AES256"),
    StorageClass:         aws.String("INTELLIGENT_TIERING"),
})

I have checked amazon doc for PutObject function, but PutObjectOutput struct type But there is no uploaded file url in this structure.

How can I get file url? Is there other way to return uploaded file url in amazon s3 sdk as soon as upload success?

Thanks

4 Answers

You can construct the URL as:

https://BUCKETNAME.s3-REGIONNAME.amazonaws.com/KEY

For example:

https://my-bucket.s3-ap-southeast-2.amazonaws.com/foo/bar.txt

You will need to reconstruct the file url

Using the s3 path to which you uploaded the file + the file name

Try this just after your code:

import "github.com/aws/aws-sdk-go/private/protocol/rest"

...

req, _ := s3.New(s).GetObjectRequest(&s3.GetObjectInput{
    Bucket: aws.String("bucket"),
    Key:    aws.String(tempFileName),
})
rest.Build(req)
uploadedResourceLocation := req.HTTPRequest.URL.String()

You can get the path of uploaded S3 object with the help of below code.

import (
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/credentials"
)

...

func configS3() *s3.Client {

    creds := credentials.NewStaticCredentialsProvider(os.Getenv("ACCESS_KEY_ID"), os.Getenv("SECRET_ACCESS_KEY"), "")

    cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithCredentialsProvider(creds), config.WithRegion(os.Getenv("S3_REGION")))

    if err != nil {
        log.Fatal(err)
    } else {
        fmt.Println(" S3 has been initializd ! ")
    }

    return s3.NewFromConfig(cfg)

}

func UploadImageToS3(imageFile string) error {

    // Open the file from the file path
    upFile, err := os.Open(imageFile)
    if err != nil {
        return fmt.Errorf("could not open local filepath [%v]: %+v", imageFile, err)
    }
    defer upFile.Close()


    uploader := manager.NewUploader(configS3())
    uploadResult, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{
        Bucket:      aws.String("BubblyBucket"),
        Key:         aws.String("folder1/Image.jpeg"),
        Body:        upFile,
        ContentType: aws.String("image/jpg"),
    })

    if err != nil {
        fmt.Printf("Error: %v  \n", err)
        return err
    }

    fmt.Println("Location: " + uploadResult.Location)
    fmt.Printf("Image has been uploaded ->>> %v \t \n", imageFile)
    return nil
}

The result will be like this

Location: https://BubblyBucket.s3.ap-southeast-1.amazonaws.com/folder1/Image.jpeg    
Image has been uploaded ->>> /home/my-machine/Pictures/Image-1.jpeg     
Related