github.com/kaydxh/golang@v0.0.131/pkg/storage/s3/s3.go (about)

     1  package s3
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/url"
     7  	"strings"
     8  
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/aws/credentials"
    11  	"github.com/aws/aws-sdk-go/aws/session"
    12  	http_ "github.com/kaydxh/golang/go/net/http"
    13  	"gocloud.dev/blob"
    14  	"gocloud.dev/blob/s3blob"
    15  )
    16  
    17  // url: http://examplebucket-1250000000.cos.ap-beijing.myqcloud.com
    18  type StorageConfig struct {
    19  	// 机房分布区域, cos的数据存放在这些地域的存储桶中
    20  	Region string
    21  	// 存储桶名字,存储桶是对象的载体,可理解为存放对象的容器
    22  	BucketName string
    23  	// 对象被存放到存储桶中,用户可通过访问域名访问和下载对象
    24  	Endpoint string
    25  	// 与账户对应的ID
    26  	AppId string
    27  	// 密钥
    28  	SecretId     string
    29  	SecretKey    string
    30  	SessionToken string
    31  
    32  	DisableSSL bool
    33  }
    34  
    35  type Storage struct {
    36  	Conf StorageConfig
    37  	*blob.Bucket
    38  	opts struct {
    39  
    40  		// 前缀路径,一般以"/"结尾, 操作子目录
    41  		// the PrefixPath should end with "/", so that the resulting operates in a subfoleder
    42  		PrefixPath string
    43  	}
    44  }
    45  
    46  func NewStorage(ctx context.Context, conf StorageConfig, opts ...StorageOption) (*Storage, error) {
    47  	s := &Storage{
    48  		Conf: conf,
    49  	}
    50  	s.ApplyOptions(opts...)
    51  
    52  	client, _ := http_.NewClient()
    53  	s3Config := aws.NewConfig().
    54  		WithRegion(conf.Region).
    55  		WithCredentials(credentials.NewStaticCredentials(conf.SecretId, conf.SecretKey, conf.SessionToken)).
    56  		WithDisableSSL(conf.DisableSSL).
    57  		WithHTTPClient(&client.Client).
    58  		WithEndpoint(conf.Endpoint)
    59  
    60  	sess, err := session.NewSession(s3Config)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	bucket, err := s3blob.OpenBucket(ctx, sess, conf.BucketName, &s3blob.Options{
    66  		UseLegacyList: true,
    67  	})
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  
    72  	if s.opts.PrefixPath != "" {
    73  		bucket = blob.PrefixedBucket(bucket, s.opts.PrefixPath)
    74  	}
    75  
    76  	s.Bucket = bucket
    77  	return s, nil
    78  }
    79  
    80  // url: http://examplebucket-1250000000.cos.ap-beijing.myqcloud.com
    81  func ParseUrl(rawUrl string) (*StorageConfig, error) {
    82  	var conf StorageConfig
    83  	s3Url, err := url.Parse(rawUrl)
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  
    88  	if s3Url.Scheme != "https" {
    89  		conf.DisableSSL = true
    90  	}
    91  	ss := strings.Split(s3Url.Host, ".")
    92  	if len(ss) < 3 {
    93  		return nil, fmt.Errorf("the number of dot in %v too less", s3Url.Host)
    94  	}
    95  	bucketName := ss[0]
    96  	conf.Region = ss[2]
    97  
    98  	// len(ss) >= 3 so strings.Index(s3Url.Host, ".") must >= 0
    99  	conf.Endpoint = s3Url.Host[strings.Index(s3Url.Host, ".")+1:]
   100  
   101  	// bucket-AppId
   102  	idx := strings.LastIndex(bucketName, "-")
   103  	if idx < 0 {
   104  		return nil, fmt.Errorf("missed - in url")
   105  	}
   106  	conf.BucketName = bucketName
   107  	conf.AppId = bucketName[idx+1:]
   108  
   109  	return &conf, nil
   110  }