108 lines
2.9 KiB
Go
108 lines
2.9 KiB
Go
package cmd
|
||
|
||
import (
|
||
"embed"
|
||
"io/fs"
|
||
"net/http"
|
||
"path/filepath"
|
||
"strings"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// embeddedFS объявлен в serve.go
|
||
|
||
// setupStaticRoutes настраивает роуты для статических файлов
|
||
func setupStaticRoutes(r *gin.Engine, embeddedFS embed.FS) {
|
||
// Получаем подфайловую систему для public
|
||
sub, err := fs.Sub(embeddedFS, "public")
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
|
||
// Обработчик для всех остальных маршрутов (статические файлы)
|
||
r.NoRoute(func(c *gin.Context) {
|
||
path := c.Request.URL.Path
|
||
|
||
// Убираем ведущий слеш для fs.Sub
|
||
path = strings.TrimPrefix(path, "/")
|
||
|
||
// Если путь пустой, показываем index.html
|
||
if path == "" {
|
||
path = "index.html"
|
||
}
|
||
|
||
// Читаем файл из встроенной файловой системы
|
||
data, err := fs.ReadFile(sub, path)
|
||
if err != nil {
|
||
// Если файл не найден, показываем index.html (SPA routing)
|
||
if strings.Contains(path, ".") {
|
||
// Это файл с расширением, возвращаем 404
|
||
c.Status(http.StatusNotFound)
|
||
return
|
||
}
|
||
// Это маршрут SPA, показываем index.html
|
||
data, err = fs.ReadFile(sub, "index.html")
|
||
if err != nil {
|
||
c.Status(http.StatusNotFound)
|
||
return
|
||
}
|
||
}
|
||
|
||
// Определяем Content-Type по расширению
|
||
contentType := getContentType(path)
|
||
c.Header("Content-Type", contentType)
|
||
|
||
// Специальные заголовки для шрифтов
|
||
if isFontFile(path) {
|
||
c.Header("Access-Control-Allow-Origin", "*")
|
||
c.Header("Cache-Control", "public, max-age=31536000")
|
||
}
|
||
|
||
c.Data(http.StatusOK, contentType, data)
|
||
})
|
||
}
|
||
|
||
// getContentType определяет Content-Type по расширению файла
|
||
func getContentType(path string) string {
|
||
ext := strings.ToLower(filepath.Ext(path))
|
||
switch ext {
|
||
case ".html":
|
||
return "text/html; charset=utf-8"
|
||
case ".css":
|
||
return "text/css; charset=utf-8"
|
||
case ".js":
|
||
return "application/javascript; charset=utf-8"
|
||
case ".json":
|
||
return "application/json; charset=utf-8"
|
||
case ".png":
|
||
return "image/png"
|
||
case ".jpg", ".jpeg":
|
||
return "image/jpeg"
|
||
case ".gif":
|
||
return "image/gif"
|
||
case ".svg":
|
||
return "image/svg+xml"
|
||
case ".ico":
|
||
return "image/x-icon"
|
||
case ".woff":
|
||
return "font/woff"
|
||
case ".woff2":
|
||
return "font/woff2"
|
||
case ".ttf":
|
||
return "font/ttf"
|
||
case ".eot":
|
||
return "application/vnd.ms-fontobject"
|
||
case ".webmanifest":
|
||
return "application/manifest+json"
|
||
default:
|
||
return "application/octet-stream"
|
||
}
|
||
}
|
||
|
||
// isFontFile проверяет, является ли файл шрифтом
|
||
func isFontFile(path string) bool {
|
||
ext := strings.ToLower(filepath.Ext(path))
|
||
return ext == ".woff" || ext == ".woff2" || ext == ".ttf" || ext == ".eot"
|
||
}
|