aws-sdk-go-v2 set custom header on PutObjectInput

1k views Asked by At

I am in a situation where i need to set a custom header on putting an object to an s3 compatible storage system.

    _, err := uploader.Upload(ctx, &s3.PutObjectInput{
    Bucket: aws.String(util.GlobalConfig.S3.Bucket),
    Key:    aws.String(filename),
    Body:   w,
    ContentMD5: func() *string {
        h := md5.New()
        h.Write(w.Bytes())
        return aws.String(base64.StdEncoding.EncodeToString(h.Sum(nil)))
    }(),
    Metadata:                  metadata,
    ObjectLockMode:            types.ObjectLockModeCompliance,
    ObjectLockRetainUntilDate: &objectLockTime,
})

How can one specify a custom header?

1

There are 1 answers

0
Hui Xie On

You can do this by registering BuildMiddleware to the middleware stack. Please see Customizing the AWS SDK for Go V2 Client Requests for more information.

Here is a simple example:

package main

import (
    "context"
    "fmt"
    "os"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/credentials"
    "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/smithy-go/middleware"
    smithyhttp "github.com/aws/smithy-go/transport/http"
)

func SetHttpHeader(key, value string) func(*middleware.Stack) error {
    return func(stack *middleware.Stack) error {
        return stack.Build.Add(middleware.BuildMiddlewareFunc("IDoEVaultGrant", func(
            ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler,
        ) (
            middleware.BuildOutput, middleware.Metadata, error,
        ) {
            switch v := in.Request.(type) {
            case *smithyhttp.Request:
                v.Header.Add(key, value)
            }
            return next.HandleBuild(ctx, in)
        }), middleware.Before)
    }
}

func main() {
    client := s3.New(s3.Options{
        Credentials: credentials.NewStaticCredentialsProvider("your-key-id", "your-key-secret", ""),
    }, s3.WithAPIOptions(SetHttpHeader("key", "value")))

    uploader := manager.NewUploader(client, func(uploader *manager.Uploader) {
        uploader.PartSize = 64 * 1024 * 1024 // 64MB
    })

    file, err := os.Open("your-file")
    if err != nil {
        fmt.Println(err)
        return
    }

    output, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{
        Bucket: aws.String("your-bucket"),
        Key:    aws.String("your-key"),
        Body:   file,
    })
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(output.Location)
    return
}