Return signed OSS URLs for site images

This commit is contained in:
Frudrax Cheng
2026-06-02 11:14:42 +08:00
parent 35cd939b92
commit 044337ac03
5 changed files with 91 additions and 14 deletions
+66 -6
View File
@@ -20,19 +20,19 @@ func NewOSSService() OSSService {
return OSSService{cfg: config.GetAppConfig().OSS}
}
func (s OSSService) UploadObject(objectKey string, reader io.Reader, contentType string) (string, error) {
func (s OSSService) UploadObject(objectKey string, reader io.Reader, contentType string) error {
if err := s.validateConfig(); err != nil {
return "", err
return err
}
client, err := oss.New(normalizeOSSEndpoint(s.cfg.Endpoint), s.cfg.AccessKeyID, s.cfg.AccessKeySecret)
if err != nil {
return "", fmt.Errorf("初始化 OSS 客户端失败: %w", err)
return fmt.Errorf("初始化 OSS 客户端失败: %w", err)
}
bucket, err := client.Bucket(s.cfg.Bucket)
if err != nil {
return "", fmt.Errorf("打开 OSS Bucket 失败: %w", err)
return fmt.Errorf("打开 OSS Bucket 失败: %w", err)
}
options := []oss.Option{}
@@ -40,10 +40,10 @@ func (s OSSService) UploadObject(objectKey string, reader io.Reader, contentType
options = append(options, oss.ContentType(contentType))
}
if err := bucket.PutObject(objectKey, reader, options...); err != nil {
return "", fmt.Errorf("上传现场图片失败: %w", err)
return fmt.Errorf("上传现场图片失败: %w", err)
}
return s.publicURL(objectKey), nil
return nil
}
func (s OSSService) validateConfig() error {
@@ -68,6 +68,66 @@ func (s OSSService) publicURL(objectKey string) string {
return fmt.Sprintf("%s://%s.%s/%s", u.Scheme, s.cfg.Bucket, u.Host, objectKey)
}
func (s OSSService) AccessURL(objectRef string) string {
objectKey := s.objectKeyFromRef(objectRef)
if objectKey == "" {
return objectRef
}
if strings.TrimSpace(s.cfg.PublicBaseURL) != "" {
return s.publicURL(objectKey)
}
url, err := s.SignedURL(objectKey)
if err != nil {
return s.publicURL(objectKey)
}
return url
}
func (s OSSService) SignedURL(objectKey string) (string, error) {
if err := s.validateConfig(); err != nil {
return "", err
}
client, err := oss.New(normalizeOSSEndpoint(s.cfg.Endpoint), s.cfg.AccessKeyID, s.cfg.AccessKeySecret)
if err != nil {
return "", fmt.Errorf("初始化 OSS 客户端失败: %w", err)
}
bucket, err := client.Bucket(s.cfg.Bucket)
if err != nil {
return "", fmt.Errorf("打开 OSS Bucket 失败: %w", err)
}
expires := s.cfg.SignedURLExpire
if expires <= 0 {
expires = 3600
}
return bucket.SignURL(objectKey, oss.HTTPGet, int64(expires))
}
func (s OSSService) objectKeyFromRef(objectRef string) string {
objectRef = strings.TrimSpace(objectRef)
if objectRef == "" {
return ""
}
if !strings.HasPrefix(objectRef, "http://") && !strings.HasPrefix(objectRef, "https://") {
return strings.TrimLeft(objectRef, "/")
}
u, err := url.Parse(objectRef)
if err != nil {
return ""
}
host := strings.ToLower(u.Host)
bucketHostPrefix := strings.ToLower(s.cfg.Bucket) + "."
if strings.HasPrefix(host, bucketHostPrefix) {
return strings.TrimLeft(u.Path, "/")
}
if base := strings.TrimSpace(s.cfg.PublicBaseURL); base != "" {
baseURL, err := url.Parse(base)
if err == nil && strings.EqualFold(baseURL.Host, u.Host) {
return strings.TrimLeft(strings.TrimPrefix(u.Path, baseURL.Path), "/")
}
}
return ""
}
func normalizeOSSEndpoint(endpoint string) string {
endpoint = strings.TrimSpace(endpoint)
if endpoint == "" {