package s3 import ( "context" "time" "ultone/internal/log" "ultone/internal/tool" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" ) type s3_client struct { client *s3.Client } // Delete implements S3. func (s *s3_client) Delete(ctx context.Context, bucket string, key string) error { var err error if _, err = s.client.DeleteObject(ctx, &s3.DeleteObjectInput{ Bucket: aws.String(bucket), Key: aws.String(key), }); err != nil { return err } return nil } // Get implements S3. func (s *s3_client) Get(ctx context.Context, bucket string, key string) (*Object, error) { var ( err error res *s3.GetObjectOutput ) if res, err = s.client.GetObject(ctx, &s3.GetObjectInput{ Bucket: aws.String(bucket), Key: aws.String(key), }); err != nil { return nil, err } return &Object{ ContentType: *res.ContentType, Body: res.Body, ExpireAt: res.Expires.UnixMilli(), Size: *res.ContentLength, }, nil } // Put implements S3. func (s *s3_client) Put(ctx context.Context, bucket string, key string, obj *Object) error { var err error if _, err = s.client.PutObject(ctx, &s3.PutObjectInput{ Bucket: aws.String(bucket), Key: aws.String(key), ACL: types.ObjectCannedACLPublicRead, Body: obj.Body, ContentType: aws.String(obj.ContentType), Expires: aws.Time(time.UnixMilli(obj.ExpireAt)), }); err != nil { return err } return nil } func newS3Client(ctx context.Context, endpoint, access, key string) (S3, error) { var ( err error sdkConfig aws.Config output *s3.ListBucketsOutput ) customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) { return aws.Endpoint{ URL: endpoint, }, nil }) if sdkConfig, err = config.LoadDefaultConfig( ctx, config.WithEndpointResolverWithOptions(customResolver), ); err != nil { return nil, err } s3Client := s3.NewFromConfig(sdkConfig, func(o *s3.Options) { // o.BaseEndpoint = aws.String(endpoint) // o.EndpointResolverV2 = &resolverV2{} o.Credentials = aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider(access, key, "")) o.UsePathStyle = true o.Region = "auto" }) if output, err = s3Client.ListBuckets(tool.Timeout(5), &s3.ListBucketsInput{}); err != nil { return nil, err } for _, item := range output.Buckets { log.Debug(ctx, "s3.New: list bucket name = %s", *item.Name) } return &s3_client{client: s3Client}, nil }