126 lines
3.7 KiB
Go
126 lines
3.7 KiB
Go
package services
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
|
|
"server/models"
|
|
|
|
beego "github.com/beego/beego/v2/server/web"
|
|
)
|
|
|
|
// PublicRequestBaseURL 根据请求拼出对外访问的根(用于把 /uploads/... 拼成完整下载地址)
|
|
func PublicRequestBaseURL(c *beego.Controller) (scheme, host string) {
|
|
scheme = "http"
|
|
if c.Ctx.Request.TLS != nil {
|
|
scheme = "https"
|
|
}
|
|
if strings.EqualFold(strings.TrimSpace(c.Ctx.Request.Header.Get("X-Forwarded-Proto")), "https") {
|
|
scheme = "https"
|
|
}
|
|
host = strings.TrimSpace(c.Ctx.Request.Host)
|
|
return scheme, host
|
|
}
|
|
|
|
// ResolveSoftwareDownloadURL 优先使用自定义 download_url;否则根据 file_id 读附件 src 拼完整 URL
|
|
func ResolveSoftwareDownloadURLs(scheme, host string, downloadURLs *string) map[string]string {
|
|
result := map[string]string{}
|
|
if downloadURLs == nil || strings.TrimSpace(*downloadURLs) == "" {
|
|
return result
|
|
}
|
|
raw := strings.TrimSpace(*downloadURLs)
|
|
var values map[string]string
|
|
if err := json.Unmarshal([]byte(raw), &values); err != nil {
|
|
return result
|
|
}
|
|
for k, v := range values {
|
|
platform := strings.ToLower(strings.TrimSpace(k))
|
|
url := strings.TrimSpace(v)
|
|
if platform == "" || url == "" {
|
|
continue
|
|
}
|
|
result[platform] = ResolvePublicURL(scheme, host, url)
|
|
}
|
|
return result
|
|
}
|
|
|
|
// legacyStorageHosts 历史七牛 CDN 域名:这两个域名只支持 HTTP,HTTPS 页面直接引用会被
|
|
// 浏览器以 Mixed Content 拦截,需在返回给前端前改写为当前存储配置的访问入口。
|
|
var legacyStorageHosts = []string{"7colud.yunzer.cn", "7cloud.yunzer.cn"}
|
|
|
|
// ResolvePublicURL 把相对路径拼成公开 URL;http(s) 地址原样返回,
|
|
// 但历史七牛域名会改写为当前存储配置的访问基址(如 https://yunzer.com.cn/qiniu)。
|
|
func ResolvePublicURL(scheme, host, src string) string {
|
|
src = strings.TrimSpace(src)
|
|
if src == "" {
|
|
return ""
|
|
}
|
|
lowerSrc := strings.ToLower(src)
|
|
if strings.HasPrefix(lowerSrc, "http://") || strings.HasPrefix(lowerSrc, "https://") {
|
|
return rewriteLegacyStorageURL(src)
|
|
}
|
|
if host == "" {
|
|
return src
|
|
}
|
|
if !strings.HasPrefix(src, "/") {
|
|
src = "/" + src
|
|
}
|
|
if scheme == "" {
|
|
scheme = "http"
|
|
}
|
|
return scheme + "://" + host + src
|
|
}
|
|
|
|
// rewriteLegacyStorageURL 把历史七牛域名的 scheme+host 换成当前存储配置域名,
|
|
// 保留对象路径不变;非历史域名或配置缺失时原样返回。
|
|
func rewriteLegacyStorageURL(src string) string {
|
|
cfg, err := models.GetStorageConfig()
|
|
if err != nil {
|
|
return src
|
|
}
|
|
base := strings.TrimRight(strings.TrimSpace(cfg.QiniuDomain), "/")
|
|
if base == "" {
|
|
return src
|
|
}
|
|
if !strings.HasPrefix(base, "http://") && !strings.HasPrefix(base, "https://") {
|
|
base = "https://" + base
|
|
}
|
|
lowerSrc := strings.ToLower(src)
|
|
for _, legacyHost := range legacyStorageHosts {
|
|
for _, scheme := range []string{"http://", "https://"} {
|
|
prefix := scheme + legacyHost
|
|
if !strings.HasPrefix(lowerSrc, prefix) {
|
|
continue
|
|
}
|
|
rest := src[len(prefix):]
|
|
// 防止 7colud.yunzer.cn.example.com 这类前缀误匹配
|
|
if rest == "" || strings.HasPrefix(rest, "/") {
|
|
return base + rest
|
|
}
|
|
}
|
|
}
|
|
return src
|
|
}
|
|
|
|
// ResolveSoftwareDownloadURL 优先使用自定义 download_url;否则根据 file_id 读附件 src 拼完整 URL
|
|
func ResolveSoftwareDownloadURL(scheme, host string, downloadURL *string, fileID *uint64) string {
|
|
if downloadURL != nil {
|
|
u := strings.TrimSpace(*downloadURL)
|
|
if u != "" {
|
|
return u
|
|
}
|
|
}
|
|
if fileID == nil || *fileID == 0 {
|
|
return ""
|
|
}
|
|
var f models.SystemFile
|
|
err := models.Orm.QueryTable(new(models.SystemFile)).
|
|
Filter("id", *fileID).
|
|
Filter("delete_time__isnull", true).
|
|
One(&f)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return ResolvePublicURL(scheme, host, f.Src)
|
|
}
|