Files
ttstd-infinite-canvas/backend/internal/storage/settings.go
ddcat666 4272b0e499 fix(media): 资源访问 - 签名地址有效期跟随后台策略并放开服务器访问地址限制
平台展示与厂商读取的签名地址有效期改为读取「资源与请求策略」,默认均为 4 小时,不再硬编码 5 分钟。服务器访问地址只校验 http/https 格式,允许本机、局域网或 HTTP 地址,模型读取平台资源不再强制 HTTPS 公网地址。
2026-09-30 03:38:31 +08:00

110 lines
4.0 KiB
Go

package storage
import (
"strings"
"time"
)
const (
aliyunOSSProvider = "aliyun"
tencentCOSProvider = "tencent"
qiniuKodoProvider = "qiniu"
s3Provider = "s3"
defaultOSSPathPrefix = "open-ai-canvas"
resourceAccessURLTTL = 4 * time.Hour
)
type Settings struct {
Delivery DeliverySettings `json:"delivery"`
Enabled bool `json:"enabled"`
Provider string `json:"provider"`
Region string `json:"region"`
Endpoint string `json:"endpoint"`
CDNBaseURL string `json:"cdnBaseUrl"`
Bucket string `json:"bucket"`
AccessKeyID string `json:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret"`
PublicBaseURL string `json:"publicBaseUrl"`
PathPrefix string `json:"pathPrefix"`
S3Preset string `json:"s3Preset"`
PathStyle bool `json:"pathStyle"`
SessionToken string `json:"sessionToken"`
StorageLocationID string `json:"storageLocationId"`
AllowUserS3 bool `json:"allowUserS3"`
Runtime RuntimePolicy `json:"-"`
// 平台切换云厂商后仍需读取历史资源,因此仅归档非当前厂商的访问密钥。
ArchivedCredentials map[string]Credentials `json:"archivedCredentials,omitempty"`
}
type RuntimePolicy struct {
TransferTimeout time.Duration
AccessURLTTL time.Duration
ProviderAccessURLTTL time.Duration
MaxBufferedUploadSize int64
ErrorBodyLimit int64
}
type Credentials struct {
AccessKeyID string `json:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret"`
}
func CloneCredentials(source map[string]Credentials) map[string]Credentials {
if len(source) == 0 {
return nil
}
cloned := make(map[string]Credentials, len(source))
for provider, credentials := range source {
cloned[strings.ToLower(strings.TrimSpace(provider))] = Credentials{
AccessKeyID: strings.TrimSpace(credentials.AccessKeyID),
AccessKeySecret: strings.TrimSpace(credentials.AccessKeySecret),
}
}
return cloned
}
func NormalizeSettings(value Settings) Settings {
value.Provider = strings.ToLower(strings.TrimSpace(value.Provider))
if value.Provider == "" {
value.Provider = aliyunOSSProvider
}
value.Region = strings.TrimSpace(value.Region)
value.Endpoint = strings.TrimRight(strings.TrimSpace(value.Endpoint), "/")
if value.Provider == tencentCOSProvider && value.Endpoint == "" && value.Region != "" {
value.Endpoint = "https://cos." + value.Region + ".myqcloud.com"
}
value.CDNBaseURL = strings.TrimRight(strings.TrimSpace(value.CDNBaseURL), "/")
value.Delivery.CDNAuthMode = strings.ToLower(strings.TrimSpace(value.Delivery.CDNAuthMode))
value.Bucket = strings.TrimSpace(value.Bucket)
value.AccessKeyID = strings.TrimSpace(value.AccessKeyID)
value.AccessKeySecret = strings.TrimSpace(value.AccessKeySecret)
value.PublicBaseURL = strings.TrimRight(strings.TrimSpace(value.PublicBaseURL), "/")
value.PathPrefix = strings.Trim(strings.TrimSpace(value.PathPrefix), "/")
if value.PathPrefix == "" {
value.PathPrefix = defaultOSSPathPrefix
}
value.S3Preset = strings.ToLower(strings.TrimSpace(value.S3Preset))
if value.S3Preset == "" {
value.S3Preset = "custom"
}
value.SessionToken = strings.TrimSpace(value.SessionToken)
value.StorageLocationID = strings.TrimSpace(value.StorageLocationID)
if value.Runtime.TransferTimeout <= 0 {
value.Runtime.TransferTimeout = 2 * time.Minute
}
if value.Runtime.AccessURLTTL <= 0 {
value.Runtime.AccessURLTTL = resourceAccessURLTTL
}
if value.Runtime.ProviderAccessURLTTL <= 0 {
value.Runtime.ProviderAccessURLTTL = 4 * time.Hour
}
if value.Runtime.MaxBufferedUploadSize <= 0 {
value.Runtime.MaxBufferedUploadSize = 64 << 20
}
if value.Runtime.ErrorBodyLimit <= 0 {
value.Runtime.ErrorBodyLimit = 1024
}
value.ArchivedCredentials = CloneCredentials(value.ArchivedCredentials)
return value
}