oleynikd
oleynikd

Reputation: 932

How to get resource URL from AWS S3 in a golang

I need to get public permanent (not signed) URL of a resource using golang and official aws go sdk. In Java AWS S3 SDK there's a method called getResourceUrl() what's the equivalent in go?

Upvotes: 4

Views: 11647

Answers (3)

gmoinbong
gmoinbong

Reputation: 11

Updated version for sdk-go-v2 how to get presigned URLs

package aws

import (
    "context"
    "log"
    "os"
    "time"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

// GetFileLink returns a presigned URL for a file in AWS S3.
// This function utilizes the aws-go-v2 SDK.
func GetFileLink(cfg aws.Config, key string) (string, error) {
    // Get the bucket name from the environment variable.
    bucketName := os.Getenv("BUCKET_NAME")

    // Create a new S3 client from the configuration.
    s3Client := s3.NewFromConfig(cfg)
    presignClient := s3.NewPresignClient(s3Client)

    // Get the presigned URL for the file.
    presignUrl, err := presignClient.PresignGetObject(context.Background(),
        &s3.GetObjectInput{
            Bucket: aws.String(bucketName),
            Key:    aws.String(key)},

    s3.WithPresignExpires(time.Minute*15))
    if err != nil {
        // If there's an error getting the presigned URL, return the error.
        return "", err
    }

        return presignUrl.URL, nil
}

Example for using:

main.go

func main() {
    // Load the AWS SDK configuration.
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("unable to load AWS SDK config, %v", err)
    }

    // Set the file key.
    fileKey := "path/to_your/file.txt"

    // Get the presigned URL for the file.
    url, err := adminpanel.GetFileLink(cfg, fileKey)
    if err != nil {
        log.Fatalf("failed to get file link, %v", err)
    }

    // Print the file URL.
    fmt.Println("File URL:", url)
}

Upvotes: 1

Topo
Topo

Reputation: 5002

This is how you get presigned URLs using the go sdk:

func GetFileLink(key string) (string, error) {
    svc := s3.New(some params)

    params := &s3.GetObjectInput{
        Bucket: aws.String(a bucket name),
        Key:    aws.String(key),
    }

    req, _ := svc.GetObjectRequest(params)

    url, err := req.Presign(15 * time.Minute) // Set link expiration time
    if err != nil {
        global.Log("[AWS GET LINK]:", params, err)
    }

    return url, err
}

If what you want is just the URL of a public access object you can build the URL yourself:

https://<region>.amazonaws.com/<bucket-name>/<key>

Where <region> is something like us-east-2. So using go it will be something like:

url := "https://%s.amazonaws.com/%s/%s"
url = fmt.Sprintf(url, "us-east-2", "my-bucket-name", "some-file.txt")

Here is a list of all the available regions for S3.

Upvotes: 13

Dmitry
Dmitry

Reputation: 1

Looks almost clean:

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

...

params := &s3.GetObjectInput{
    Bucket: aws.String(a bucket name),
    Key:    aws.String(key),
}
req, _ := svc.GetObjectRequest(params)
rest.Build(req) // aws method to build URL in request object
url = req.HTTPRequest.URL.String() // complete URL to resource

Upvotes: -2

Related Questions