github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/conf/filesystem/amazonS3/s3_config.go (about)

     1  package amazonS3
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/aws/awserr"
    11  	"github.com/aws/aws-sdk-go/aws/credentials"
    12  	"github.com/aws/aws-sdk-go/aws/session"
    13  	"github.com/aws/aws-sdk-go/service/s3"
    14  
    15  	"github.com/machinefi/w3bstream/pkg/depends/base/types"
    16  	"github.com/machinefi/w3bstream/pkg/depends/conf/filesystem"
    17  )
    18  
    19  type AmazonS3 struct {
    20  	Endpoint         string         `env:""`
    21  	Region           string         `env:""`
    22  	AccessKeyID      string         `env:""`
    23  	SecretAccessKey  types.Password `env:""`
    24  	SessionToken     string         `env:""`
    25  	BucketName       string         `env:""`
    26  	UrlExpire        types.Duration `env:""`
    27  	S3ForcePathStyle bool           `env:""`
    28  
    29  	cli *s3.S3
    30  }
    31  
    32  func (s *AmazonS3) Init() error {
    33  	sess, err := session.NewSession(&aws.Config{
    34  		Endpoint:         aws.String(s.Endpoint),
    35  		Region:           aws.String(s.Region),
    36  		Credentials:      credentials.NewStaticCredentials(s.AccessKeyID, s.SecretAccessKey.String(), s.SessionToken),
    37  		S3ForcePathStyle: aws.Bool(s.S3ForcePathStyle),
    38  	})
    39  	if err != nil {
    40  		return err
    41  	}
    42  	s.cli = s3.New(sess)
    43  	return nil
    44  }
    45  
    46  func (s *AmazonS3) SetDefault() {
    47  	if s.UrlExpire == 0 {
    48  		s.UrlExpire = types.Duration(10 * time.Minute)
    49  	}
    50  }
    51  
    52  func (s *AmazonS3) IsZero() bool {
    53  	return s.Endpoint == "" ||
    54  		s.Region == "" ||
    55  		s.AccessKeyID == "" ||
    56  		s.SecretAccessKey == "" ||
    57  		s.BucketName == ""
    58  }
    59  
    60  func (s *AmazonS3) Name() string {
    61  	return "s3-cli"
    62  }
    63  
    64  func (s *AmazonS3) Upload(key string, data []byte) error {
    65  	_, err := s.cli.PutObject(&s3.PutObjectInput{
    66  		Bucket: aws.String(s.BucketName),
    67  		Key:    aws.String(key),
    68  		Body:   bytes.NewReader(data),
    69  	})
    70  	return err
    71  }
    72  
    73  func (s *AmazonS3) Read(key string) ([]byte, error) {
    74  	resp, err := s.cli.GetObject(&s3.GetObjectInput{
    75  		Bucket: aws.String(s.BucketName),
    76  		Key:    aws.String(key),
    77  	})
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	defer resp.Body.Close()
    82  
    83  	return io.ReadAll(resp.Body)
    84  }
    85  
    86  func (s *AmazonS3) Delete(key string) error {
    87  	_, err := s.cli.DeleteObject(&s3.DeleteObjectInput{
    88  		Bucket: aws.String(s.BucketName),
    89  		Key:    aws.String(key),
    90  	})
    91  	return err
    92  }
    93  
    94  func (s *AmazonS3) DownloadUrl(key string) (string, error) {
    95  	req, _ := s.cli.GetObjectRequest(&s3.GetObjectInput{
    96  		Bucket: aws.String(s.BucketName),
    97  		Key:    aws.String(key),
    98  	})
    99  	return req.Presign(s.UrlExpire.Duration())
   100  }
   101  
   102  func (s *AmazonS3) StatObject(key string) (*filesystem.ObjectMeta, error) {
   103  	resp, err := s.cli.HeadObject(&s3.HeadObjectInput{
   104  		Bucket: aws.String(s.BucketName),
   105  		Key:    aws.String(key),
   106  	})
   107  	if err != nil {
   108  		awsErr, ok := err.(awserr.RequestFailure)
   109  		if ok && awsErr.StatusCode() == 404 {
   110  			return nil, filesystem.ErrNotExistObjectKey
   111  		}
   112  		return nil, err
   113  	}
   114  
   115  	om, err := filesystem.ParseObjectMetaFromKey(key)
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  	om.ContentType = *resp.ContentType
   120  	om.ETag = strings.Trim(*resp.ETag, "\"")
   121  	om.Size = *resp.ContentLength
   122  
   123  	return om, nil
   124  }