4949// - ReaderOptions.BeforeRead: *s3.GetObjectInput or *[]func(*s3.Options)
5050// - Attributes: s3.HeadObjectOutput
5151// - CopyOptions.BeforeCopy: s3.CopyObjectInput
52- // - WriterOptions.BeforeWrite: *s3.PutObjectInput , *s3manager.Uploader
52+ // - WriterOptions.BeforeWrite: *transfermanager.UploadObjectInput , *transfermanager.Client
5353// - SignedURLOptions.BeforeSign: *s3.GetObjectInput, when Options.Method == http.MethodGet, or
5454// *s3.PutObjectInput, when Options.Method == http.MethodPut
5555
5656package s3blob // import "gocloud.dev/blob/s3blob"
5757
5858import (
5959 "context"
60- "encoding/base64"
6160 "encoding/hex"
6261 "errors"
6362 "fmt"
@@ -69,7 +68,8 @@ import (
6968 "strings"
7069
7170 "github.com/aws/aws-sdk-go-v2/aws"
72- s3manager "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
71+ "github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager"
72+ tmtypes "github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager/types"
7373 "github.com/aws/aws-sdk-go-v2/service/s3"
7474 "github.com/aws/aws-sdk-go-v2/service/s3/types"
7575 "github.com/aws/smithy-go"
@@ -311,9 +311,9 @@ type writer struct {
311311 // used to upload data.
312312 upload bool
313313
314- ctx context.Context
315- uploader * s3manager. Uploader
316- req * s3. PutObjectInput
314+ ctx context.Context
315+ tm * transfermanager. Client
316+ req * transfermanager. UploadObjectInput
317317
318318 donec chan struct {} // closed when done writing
319319 // The following fields will be written before donec closes:
@@ -358,7 +358,7 @@ func (w *writer) open(r io.Reader, closePipeOnError bool) {
358358 }
359359 var err error
360360 w .req .Body = r
361- _ , err = w .uploader . Upload (w .ctx , w .req )
361+ _ , err = w .tm . UploadObject (w .ctx , w .req )
362362 if err != nil {
363363 if closePipeOnError {
364364 w .pr .CloseWithError (err )
@@ -738,15 +738,13 @@ func unescapeKey(key string) string {
738738// NewTypedWriter implements driver.NewTypedWriter.
739739func (b * bucket ) NewTypedWriter (ctx context.Context , key , contentType string , opts * driver.WriterOptions ) (driver.Writer , error ) {
740740 key = escapeKey (key )
741- uploader := s3manager . NewUploader (b .client , func (u * s3manager. Uploader ) {
741+ tm := transfermanager . New (b .client , func (o * transfermanager. Options ) {
742742 if opts .BufferSize != 0 {
743- u . PartSize = int64 (opts .BufferSize )
743+ o . PartSizeBytes = int64 (opts .BufferSize )
744744 }
745745 if opts .MaxConcurrency != 0 {
746- u .Concurrency = opts .MaxConcurrency
746+ o .Concurrency = opts .MaxConcurrency
747747 }
748-
749- u .RequestChecksumCalculation = b .requestChecksumCalculation
750748 })
751749 md := make (map [string ]string , len (opts .Metadata ))
752750 for k , v := range opts .Metadata {
@@ -758,7 +756,7 @@ func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType string, op
758756 })
759757 md [k ] = url .PathEscape (v )
760758 }
761- req := & s3. PutObjectInput {
759+ req := & transfermanager. UploadObjectInput {
762760 Bucket : aws .String (b .name ),
763761 ContentType : aws .String (contentType ),
764762 Key : aws .String (key ),
@@ -781,32 +779,29 @@ func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType string, op
781779 if opts .ContentLanguage != "" {
782780 req .ContentLanguage = aws .String (opts .ContentLanguage )
783781 }
784- if len (opts .ContentMD5 ) > 0 {
785- req .ContentMD5 = aws .String (base64 .StdEncoding .EncodeToString (opts .ContentMD5 ))
786- }
782+ // S3 doesn't support ContentMD5 validation anymore.
787783 if b .encryptionType != "" {
788- req .ServerSideEncryption = b .encryptionType
784+ req .ServerSideEncryption = tmtypes . ServerSideEncryption ( b .encryptionType )
789785 }
790786 if b .kmsKeyId != "" {
791- req .SSEKMSKeyId = aws .String (b .kmsKeyId )
787+ req .SSEKMSKeyID = aws .String (b .kmsKeyId )
792788 }
793789 if opts .BeforeWrite != nil {
794790 asFunc := func (i any ) bool {
795791 // Note that since the Go CDK Blob
796792 // abstraction does not expose AWS's
797- // Uploader concept, there does not
793+ // Transfer Manager concept, there does not
798794 // appear to be any utility in
799795 // exposing the options list to the v2
800- // Uploader 's Upload () method.
796+ // Transfer Manager 's UploadObject () method.
801797 // Instead, applications can
802- // manipulate the exposed *Uploader
803- // directly, including by setting
804- // ClientOptions if needed.
805- if p , ok := i .(* * s3manager.Uploader ); ok {
806- * p = uploader
798+ // manipulate the exposed *Client
799+ // directly.
800+ if p , ok := i .(* * transfermanager.Client ); ok {
801+ * p = tm
807802 return true
808803 }
809- if p , ok := i .(* * s3. PutObjectInput ); ok {
804+ if p , ok := i .(* * transfermanager. UploadObjectInput ); ok {
810805 * p = req
811806 return true
812807 }
@@ -817,10 +812,10 @@ func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType string, op
817812 }
818813 }
819814 return & writer {
820- ctx : ctx ,
821- uploader : uploader ,
822- req : req ,
823- donec : make (chan struct {}),
815+ ctx : ctx ,
816+ tm : tm ,
817+ req : req ,
818+ donec : make (chan struct {}),
824819 }, nil
825820}
826821
0 commit comments