1 Star 0 Fork 0

玟兵/go-util

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
oss.go 7.64 KB
一键复制 编辑 原始数据 按行查看 历史
玟兵 提交于 2024-07-13 19:33 +08:00 . bug fixed
package util
import (
"context"
"errors"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"github.com/aws/smithy-go"
redis2 "github.com/gomodule/redigo/redis"
"io"
"mime"
"path/filepath"
"time"
)
type OSS struct {
Client *s3.Client
PClient *s3.PresignClient
}
func NewOSS(accessKey, secretKey, endpoint, region string) (*OSS, error) {
if region == "" {
region = "us-east-1"
}
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
if err != nil {
return nil, err
}
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.Credentials = aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider(accessKey, secretKey, ""))
o.BaseEndpoint = aws.String(endpoint)
})
pClient := s3.NewPresignClient(client)
return &OSS{Client: client, PClient: pClient}, nil
}
func (o *OSS) ListBuckets(ctx context.Context) ([]types.Bucket, error) {
result, err := o.Client.ListBuckets(ctx, &s3.ListBucketsInput{})
if err != nil {
return nil, err
}
return result.Buckets, nil
}
func (o *OSS) BucketExists(ctx context.Context, bucketName string) (bool, error) {
_, err := o.Client.HeadBucket(ctx, &s3.HeadBucketInput{
Bucket: aws.String(bucketName),
})
exists := true
if err != nil {
var apiError smithy.APIError
if errors.As(err, &apiError) {
var notFound *types.NotFound
switch {
case errors.As(apiError, &notFound):
exists = false
err = nil
}
}
}
return exists, err
}
func (o *OSS) CreateBucket(ctx context.Context, bucketName, region string) error {
if region == "" {
region = "us-east-1"
}
_, err := o.Client.CreateBucket(ctx, &s3.CreateBucketInput{
Bucket: aws.String(bucketName),
CreateBucketConfiguration: &types.CreateBucketConfiguration{
LocationConstraint: types.BucketLocationConstraint(region),
},
})
return err
}
func (o *OSS) DeleteBucket(ctx context.Context, bucketName string) error {
_, err := o.Client.DeleteBucket(ctx, &s3.DeleteBucketInput{
Bucket: aws.String(bucketName),
})
return err
}
func (o *OSS) ListObjects(ctx context.Context, bucketName string) ([]types.Object, error) {
result, err := o.Client.ListObjectsV2(ctx, &s3.ListObjectsV2Input{
Bucket: aws.String(bucketName),
})
if err != nil {
return nil, err
}
return result.Contents, nil
}
func (o *OSS) PutObject(ctx context.Context, bucketName, objectKey string, body io.Reader) error {
contentType := mime.TypeByExtension(filepath.Ext(objectKey))
if contentType == "" {
contentType = "application/octet-stream"
}
_, err := o.Client.PutObject(ctx, &s3.PutObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
Body: body,
ContentType: aws.String(contentType),
})
return err
}
func (o *OSS) PutLarge(ctx context.Context, bucketName, objectKey string, body io.Reader, partSize int64) error {
if partSize <= 0 {
partSize = 8 << 20
}
uploader := manager.NewUploader(o.Client, func(u *manager.Uploader) {
u.PartSize = partSize
})
contentType := mime.TypeByExtension(filepath.Ext(objectKey))
if contentType == "" {
contentType = "application/octet-stream"
}
_, err := uploader.Upload(ctx, &s3.PutObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
Body: body,
ContentType: aws.String(contentType),
})
return err
}
func (o *OSS) GetObject(ctx context.Context, bucketName, objectKey string) (io.ReadCloser, error) {
result, err := o.Client.GetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
})
if err != nil {
return nil, err
}
return result.Body, nil
}
func (o *OSS) GetLarge(ctx context.Context, bucketName, objectKey string, partSize int64) ([]byte, error) {
if partSize <= 0 {
partSize = 8 << 20
}
downloader := manager.NewDownloader(o.Client, func(d *manager.Downloader) {
d.PartSize = partSize
})
buffer := manager.NewWriteAtBuffer([]byte{})
_, err := downloader.Download(ctx, buffer, &s3.GetObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
})
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
func (o *OSS) HeadObject(ctx context.Context, bucketName, objectKey string) (*s3.HeadObjectOutput, error) {
result, err := o.Client.HeadObject(ctx, &s3.HeadObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
})
if err != nil {
return nil, err
}
return result, nil
}
func (o *OSS) DeleteObjects(ctx context.Context, bucketName string, objectKeys ...string) error {
if len(objectKeys) == 0 {
return fmt.Errorf("length of object keys must be greater than zero")
}
keys := make([]types.ObjectIdentifier, 0, len(objectKeys))
for _, key := range objectKeys {
keys = append(keys, types.ObjectIdentifier{Key: aws.String(key)})
}
_, err := o.Client.DeleteObjects(ctx, &s3.DeleteObjectsInput{
Bucket: aws.String(bucketName),
Delete: &types.Delete{Objects: keys},
})
return err
}
func (o *OSS) CopyObject(ctx context.Context, sourceBucket string, destinationBucket string, objectKey, newKey string) error {
_, err := o.Client.CopyObject(ctx, &s3.CopyObjectInput{
Bucket: aws.String(destinationBucket),
Key: aws.String(newKey),
CopySource: aws.String(fmt.Sprintf("%s/%s", sourceBucket, objectKey)),
})
return err
}
func (o *OSS) PresignGetObject(ctx context.Context, bucketName, objectKey string, expires time.Duration) (*v4.PresignedHTTPRequest, error) {
return o.PClient.PresignGetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
}, func(options *s3.PresignOptions) {
options.Expires = expires
})
}
func (o *OSS) GetObjectSignedUrl(ctx context.Context, bucketName, objectKey string, expires time.Duration, redis *Redis) (string, error) {
if redis == nil {
r, err := o.PresignGetObject(ctx, bucketName, objectKey, expires)
if err != nil {
return "", err
}
return r.URL, nil
}
re, err := redis.GetOrSingleDo(fmt.Sprintf("oss:signed_url:%s:%s", bucketName, objectKey), func(key string, redis *Redis) (any, error) {
re, err := o.GetObjectSignedUrl(ctx, bucketName, objectKey, expires, nil)
if err != nil {
return re, err
}
if _, err = redis.Set(key, re, expires-3*time.Second, ""); err != nil {
return re, err
}
return re, nil
})
return redis2.String(re, err)
}
func (o *OSS) PresignPutObject(ctx context.Context, bucketName, objectKey string, expires time.Duration) (*v4.PresignedHTTPRequest, error) {
contentType := mime.TypeByExtension(filepath.Ext(objectKey))
if contentType == "" {
contentType = "application/octet-stream"
}
return o.PClient.PresignPutObject(ctx, &s3.PutObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
ContentType: aws.String(contentType),
}, func(options *s3.PresignOptions) {
options.Expires = expires
})
}
func (o *OSS) PresignDeleteObject(ctx context.Context, bucketName, objectKey string, expires time.Duration) (*v4.PresignedHTTPRequest, error) {
return o.PClient.PresignDeleteObject(ctx, &s3.DeleteObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
}, func(options *s3.PresignOptions) {
options.Expires = expires
})
}
func (o *OSS) PresignHeadObject(ctx context.Context, bucketName, objectKey string, expires time.Duration) (*v4.PresignedHTTPRequest, error) {
return o.PClient.PresignHeadObject(ctx, &s3.HeadObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
}, func(options *s3.PresignOptions) {
options.Expires = expires
})
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/binny_w/go-util.git
git@gitee.com:binny_w/go-util.git
binny_w
go-util
go-util
v0.0.49

搜索帮助