49 lines
1.3 KiB
Go
49 lines
1.3 KiB
Go
|
|
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()
|
|||
|
|
}
|