kra/pkg/upload/cloudflare.go

104 lines
2.4 KiB
Go

package upload
import (
"context"
"fmt"
"mime/multipart"
"path"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
// CloudflareR2 Cloudflare R2存储
type CloudflareR2 struct {
Bucket string
BaseURL string
Path string
AccountID string
AccessKeyID string
SecretAccessKey string
}
// NewCloudflareR2 创建Cloudflare R2
func NewCloudflareR2(bucket, baseURL, r2Path, accountID, accessKeyID, secretAccessKey string) *CloudflareR2 {
return &CloudflareR2{
Bucket: bucket,
BaseURL: baseURL,
Path: r2Path,
AccountID: accountID,
AccessKeyID: accessKeyID,
SecretAccessKey: secretAccessKey,
}
}
func (c *CloudflareR2) getClient(ctx context.Context) (*s3.Client, error) {
endpoint := fmt.Sprintf("https://%s.r2.cloudflarestorage.com", c.AccountID)
cfg, err := config.LoadDefaultConfig(ctx,
config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(c.AccessKeyID, c.SecretAccessKey, "")),
config.WithRegion("auto"),
)
if err != nil {
return nil, err
}
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.BaseEndpoint = aws.String(endpoint)
})
return client, nil
}
// UploadFile 上传文件
func (c *CloudflareR2) UploadFile(file *multipart.FileHeader) (string, string, error) {
ctx := context.Background()
client, err := c.getClient(ctx)
if err != nil {
return "", "", err
}
// 生成文件名和路径
fileName := GenerateFileName(file.Filename)
filePath := GeneratePath(c.Path)
key := path.Join(filePath, fileName)
// 打开文件
src, err := file.Open()
if err != nil {
return "", "", err
}
defer src.Close()
// 上传
contentType := file.Header.Get("Content-Type")
_, err = client.PutObject(ctx, &s3.PutObjectInput{
Bucket: aws.String(c.Bucket),
Key: aws.String(key),
Body: src,
ContentType: aws.String(contentType),
})
if err != nil {
return "", "", err
}
// 返回访问URL和key
accessURL := c.BaseURL + "/" + key
return accessURL, key, nil
}
// DeleteFile 删除文件
func (c *CloudflareR2) DeleteFile(key string) error {
ctx := context.Background()
client, err := c.getClient(ctx)
if err != nil {
return err
}
_, err = client.DeleteObject(ctx, &s3.DeleteObjectInput{
Bucket: aws.String(c.Bucket),
Key: aws.String(key),
})
return err
}