Files
moteva/server/internal/infrastructure/objectstorage/aliyun.go
T

121 lines
2.7 KiB
Go
Raw Normal View History

package objectstorage
import (
"bytes"
"context"
"strings"
"img_infinite_canvas/internal/domain/design"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
type AliyunOptions struct {
Bucket string
Endpoint string
AccessKey string
SecretKey string
PublicBase string
ExpiresIn int64
}
type AliyunStorage struct {
bucketName string
publicBase string
expiresIn int64
bucket *oss.Bucket
}
func NewAliyunStorage(ctx context.Context, opts AliyunOptions) (*AliyunStorage, error) {
if err := ctx.Err(); err != nil {
return nil, err
}
client, err := oss.New(opts.Endpoint, opts.AccessKey, opts.SecretKey)
if err != nil {
return nil, err
}
exists, err := client.IsBucketExist(opts.Bucket)
if err != nil {
return nil, err
}
if !exists {
if err := client.CreateBucket(opts.Bucket); err != nil {
return nil, err
}
}
bucket, err := client.Bucket(opts.Bucket)
if err != nil {
return nil, err
}
if opts.ExpiresIn <= 0 {
opts.ExpiresIn = 900
}
return &AliyunStorage{
bucketName: opts.Bucket,
publicBase: strings.TrimRight(opts.PublicBase, "/"),
expiresIn: opts.ExpiresIn,
bucket: bucket,
}, nil
}
func (s *AliyunStorage) CreateUpload(ctx context.Context, req design.AssetUploadRequest) (design.AssetUpload, error) {
if err := ctx.Err(); err != nil {
return design.AssetUpload{}, err
}
objectKey := objectKey(req.FileName)
signedURL, err := s.bucket.SignURL(objectKey, oss.HTTPPut, s.expiresIn, oss.ContentType(req.ContentType))
if err != nil {
return design.AssetUpload{}, err
}
publicURL := signedURL
if s.publicBase != "" {
publicURL = publicObjectURL(s.publicBase, objectKey)
}
return design.AssetUpload{
Driver: "aliyun",
Bucket: s.bucketName,
ObjectKey: objectKey,
UploadURL: signedURL,
PublicURL: publicURL,
Headers: map[string]string{
"Content-Type": req.ContentType,
},
ExpiresIn: s.expiresIn,
}, nil
}
func (s *AliyunStorage) PutObject(ctx context.Context, req design.AssetObjectRequest) (design.AssetObject, error) {
if err := ctx.Err(); err != nil {
return design.AssetObject{}, err
}
objectKey := objectKey(req.FileName)
if err := s.bucket.PutObject(objectKey, bytes.NewReader(req.Data), oss.ContentType(req.ContentType)); err != nil {
return design.AssetObject{}, err
}
publicURL := publicObjectURL(s.publicBase, objectKey)
return design.AssetObject{
Driver: "aliyun",
Bucket: s.bucketName,
ObjectKey: objectKey,
PublicURL: publicURL,
}, nil
}
func (s *AliyunStorage) DeleteObject(ctx context.Context, publicURL string) error {
if err := ctx.Err(); err != nil {
return err
}
objectKey, ok := objectKeyFromPublicURL(s.publicBase, publicURL)
if !ok {
return nil
}
return s.bucket.DeleteObject(objectKey)
}