Files
2026-09-29 10:47:38 +08:00

90 lines
2.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package utils
import (
"path"
"path/filepath"
"strconv"
"strings"
"github.com/PuerkitoBio/purell"
)
// PathSegment 路由路径段:有 slug 用 slug,否则回退为数字 id。
func PathSegment(slug string, id int64) string {
if s := strings.TrimSpace(slug); s != "" {
return s
}
if id > 0 {
return strconv.FormatInt(id, 10)
}
return ""
}
// PathInfo 路径信息
type PathInfo struct {
Dir string // 目录
Ext string // 扩展名
Filename string // 没有扩展名的文件名名称
FullFileName string // 文件全名
}
// PathForInfo 解析路径
// 返回文件,路径,文件名等信息
func PathForInfo(path string) (pi PathInfo) {
if path == "" {
return
}
ext := filepath.Ext(path)
dir, name := filepath.Split(path)
pi.Dir = dir
pi.Ext = ext
pi.Filename = strings.TrimRight(name, ext)
pi.FullFileName = name
return
}
// JoinUrlPath 域名与uri拼接(走 purell 标准化,会剥掉尾部斜杠)。
// 适用于 CDN 文件链接(m3u8 分段、vtt、静态图等)这类"不需要尾部斜杠"的场景。
// 需要保留尾部斜杠的页面 URL(sitemap/rss/indexnow)请使用 JoinUrlPathKeepSlash。
func JoinUrlPath(host string, uri string) (urlpath string) {
urlpath = joinRawUrlPath(host, uri)
if urlpath == "" {
return
}
// 标准化 URL
normalized, err := purell.NormalizeURLString(urlpath, purell.FlagsUsuallySafeGreedy)
if err != nil {
return urlpath
}
return normalized
}
// JoinUrlPathKeepSlash 域名与uri拼接,保留 uri 原始的尾部斜杠,不做任何标准化。
// sitemap/rss/indexnow 的页面 URL 必须与路由注册的 /archives/:id/ 等完全一致,
// 否则爬虫每次访问都会被 gin 的 RedirectTrailingSlash 301 到带 / 的地址,
// 浪费抓取预算并造成重定向链。
func JoinUrlPathKeepSlash(host string, uri string) string {
return joinRawUrlPath(host, uri)
}
// joinRawUrlPath 纯拼接,不做任何标准化。
func joinRawUrlPath(host string, uri string) (urlpath string) {
if uri == "" {
return
}
switch {
case strings.HasSuffix(host, "/") && strings.HasPrefix(uri, "/"):
urlpath = host[0:len(host)-1] + uri
case !strings.HasSuffix(host, "/") && !strings.HasPrefix(uri, "/"):
urlpath = host + "/" + uri
default:
urlpath = host + uri
}
return
}
func JoinUrlPathV2(host string, uri string) string {
return path.Join(host, uri)
}