package storage import ( "context" "io" "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" ) type S3Storage struct { client *s3.Client bucket string } func NewS3Storage(ctx context.Context, endpoint, region, accessKey, secretKey, bucket string, useSSL bool) (*S3Storage, error) { customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) { if endpoint != "" { return aws.Endpoint{ URL: endpoint, SigningRegion: region, HostnameImmutable: true, }, nil } return aws.Endpoint{}, &aws.EndpointNotFoundError{} }) cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region), config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")), config.WithEndpointResolverWithOptions(customResolver), ) if err != nil { return nil, err } client := s3.NewFromConfig(cfg) return &S3Storage{ client: client, bucket: bucket, }, nil } func (s *S3Storage) Save(ctx context.Context, path string, reader io.Reader) error { _, err := s.client.PutObject(ctx, &s3.PutObjectInput{ Bucket: aws.String(s.bucket), Key: aws.String(path), Body: reader, }) return err } func (s *S3Storage) Open(ctx context.Context, path string) (io.ReadCloser, error) { output, err := s.client.GetObject(ctx, &s3.GetObjectInput{ Bucket: aws.String(s.bucket), Key: aws.String(path), }) if err != nil { return nil, err } return output.Body, nil } func (s *S3Storage) Delete(ctx context.Context, path string) error { _, err := s.client.DeleteObject(ctx, &s3.DeleteObjectInput{ Bucket: aws.String(s.bucket), Key: aws.String(path), }) return err }