Files
谢宇宁andClaude Opus 5.5 0fbdba5ccf Initial commit
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 11:47:47 +07:00

81 lines
1.7 KiB
Go

package router
import (
"os"
"path/filepath"
"strings"
"videoweb/app/api/web"
"github.com/gin-gonic/gin"
)
// 其他项目(hgdjnet-server)写入 H5 目录的 sitemap 产物路径。
var sitemapShardDirs = []string{
"./template/pages/sitemaps",
}
var sitemapIndexFiles = []string{
"./template/pages/sitemaps/sitemap.xml",
"./template/pages/sitemap.xml",
}
// registerSitemapRoutes 只暴露静态 sitemap,不在本项目生成。
func registerSitemapRoutes(r *gin.Engine) {
r.GET("/sitemap.xml", serveSitemapIndex)
r.GET("/sitemaps/:name", serveSitemapShard)
}
func serveSitemapIndex(c *gin.Context) {
path, ok := firstExistingFile(sitemapIndexFiles...)
if !ok {
web.NotFound(c)
return
}
c.File(path)
}
func serveSitemapShard(c *gin.Context) {
name := c.Param("name")
if !isValidSitemapShardName(name) {
web.NotFound(c)
return
}
var candidates []string
for _, dir := range sitemapShardDirs {
candidates = append(candidates, filepath.Join(dir, name))
}
path, ok := firstExistingFile(candidates...)
if !ok {
web.NotFound(c)
return
}
c.File(path)
}
func firstExistingFile(paths ...string) (string, bool) {
for _, path := range paths {
info, err := os.Stat(path)
if err == nil && !info.IsDir() {
return path, true
}
}
return "", false
}
// isValidSitemapShardName 校验分片文件名,防止路径遍历。
func isValidSitemapShardName(name string) bool {
if !strings.HasPrefix(name, "sitemap-") || !strings.HasSuffix(name, ".xml") {
return false
}
base := strings.TrimSuffix(name, ".xml")
if len(base) <= len("sitemap-") {
return false
}
for _, ch := range base[len("sitemap-"):] {
if !((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '-') {
return false
}
}
return true
}