104 lines
2.4 KiB
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
|
|
}
|