thread-master/old/backend/internal/library/storage/threads_image_url.go

49 lines
1.3 KiB
Go
Raw Normal View History

2026-07-09 03:45:28 +00:00
package storage
import (
"fmt"
"net"
"net/url"
"strings"
)
// ValidateThreadsFetchableURL ensures Meta servers can download an image for publish.
func ValidateThreadsFetchableURL(raw string) error {
raw = strings.TrimSpace(raw)
if raw == "" {
return fmt.Errorf("圖片網址不可為空")
}
parsed, err := url.Parse(raw)
if err != nil || parsed.Scheme == "" || parsed.Host == "" {
return fmt.Errorf("圖片網址格式無效")
}
scheme := strings.ToLower(parsed.Scheme)
if scheme != "https" && scheme != "http" {
return fmt.Errorf("圖片網址必須是 http 或 https")
}
host := strings.ToLower(parsed.Hostname())
if host == "" {
return fmt.Errorf("圖片網址缺少主機名稱")
}
if isPrivateOrLoopbackHost(host) {
return fmt.Errorf(
"圖片網址 %s 無法被 Threads 伺服器存取localhost / 內網)。請將 HAIXUN_STORAGE_S3_PUBLIC_BASE_URL 設為公開 HTTPS例如 https://你的網域/api/v1/public/assets",
raw,
)
}
if scheme != "https" {
return fmt.Errorf("Threads 附圖網址建議使用 HTTPS目前為 %s", scheme)
}
return nil
}
func isPrivateOrLoopbackHost(host string) bool {
if host == "localhost" {
return true
}
ip := net.ParseIP(host)
if ip == nil {
return false
}
return ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast()
}