Repo .git was damaged (refs/ missing, index truncated, object store near-empty). Repaired via git init (rebuilt refs), stale index preserved as .git/index.corrupt-20260910.bak, then full worktree committed as a rollback baseline.
82 lines
2.1 KiB
Go
82 lines
2.1 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
|
"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"
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/tamakyi/TamaBox/internal/conf"
|
|
)
|
|
|
|
var (
|
|
s3ClientOnce sync.Once
|
|
s3Client *s3.Client
|
|
s3ClientErr error
|
|
|
|
ossClientOnce sync.Once
|
|
ossBucket *oss.Bucket
|
|
ossClientErr error
|
|
)
|
|
|
|
// GetS3Client 返回共享的 S3 客户端(单例),避免每次上传重复创建。
|
|
func GetS3Client() (*s3.Client, error) {
|
|
s3ClientOnce.Do(func() {
|
|
if conf.Upload.ImageEndpoint == "" {
|
|
s3ClientErr = errors.New("S3 endpoint not configured")
|
|
return
|
|
}
|
|
|
|
r2Resolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
|
|
return aws.Endpoint{
|
|
URL: conf.Upload.ImageEndpoint,
|
|
HostnameImmutable: true,
|
|
Source: aws.EndpointSourceCustom,
|
|
}, nil
|
|
})
|
|
|
|
cfg, err := config.LoadDefaultConfig(context.Background(),
|
|
config.WithEndpointResolverWithOptions(r2Resolver),
|
|
config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(
|
|
conf.Upload.ImageAccessID,
|
|
conf.Upload.ImageAccessSecret,
|
|
"",
|
|
)),
|
|
config.WithRegion("auto"),
|
|
)
|
|
if err != nil {
|
|
s3ClientErr = errors.Wrap(err, "load S3 config")
|
|
return
|
|
}
|
|
s3Client = s3.NewFromConfig(cfg)
|
|
})
|
|
return s3Client, s3ClientErr
|
|
}
|
|
|
|
// GetOSSBucket 返回共享的 OSS Bucket(单例)。
|
|
func GetOSSBucket() (*oss.Bucket, error) {
|
|
ossClientOnce.Do(func() {
|
|
if conf.Upload.AliyunEndpoint == "" {
|
|
ossClientErr = errors.New("OSS endpoint not configured")
|
|
return
|
|
}
|
|
client, err := oss.New(conf.Upload.AliyunEndpoint, conf.Upload.AliyunAccessID, conf.Upload.AliyunAccessSecret)
|
|
if err != nil {
|
|
ossClientErr = errors.Wrap(err, "new OSS client")
|
|
return
|
|
}
|
|
bucket, err := client.Bucket(conf.Upload.AliyunBucket)
|
|
if err != nil {
|
|
ossClientErr = errors.Wrap(err, "get OSS bucket")
|
|
return
|
|
}
|
|
ossBucket = bucket
|
|
})
|
|
return ossBucket, ossClientErr
|
|
}
|