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 }