81 lines
1.7 KiB
Go
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
|
|
}
|