feat(fileserver): implement spa support; add spa and index fields to config

This commit is contained in:
yusing
2025-12-20 19:24:39 +08:00
parent 376ac61279
commit b134b92704
2 changed files with 30 additions and 4 deletions

View File

@@ -2,6 +2,7 @@ package route
import (
"net/http"
"os"
"path"
"path/filepath"
@@ -27,8 +28,25 @@ type (
var _ types.FileServerRoute = (*FileServer)(nil)
func handler(root string) http.Handler {
return http.FileServer(http.Dir(root))
func handler(root string, spa bool, index string) http.Handler {
if !spa {
return http.FileServer(http.Dir(root))
}
indexPath := filepath.Join(root, index)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
urlPath := path.Clean(r.URL.Path)
if urlPath == "/" {
http.ServeFile(w, r, indexPath)
return
}
fullPath := filepath.Join(root, filepath.FromSlash(urlPath))
stat, err := os.Stat(fullPath)
if err == nil && !stat.IsDir() {
http.ServeFile(w, r, fullPath)
return
}
http.ServeFile(w, r, indexPath)
})
}
func NewFileServer(base *Route) (*FileServer, gperr.Error) {
@@ -39,7 +57,12 @@ func NewFileServer(base *Route) (*FileServer, gperr.Error) {
return nil, gperr.New("`root` must be an absolute path")
}
s.handler = handler(s.Root)
if s.Index == "" {
s.Index = "/index.html"
} else if s.Index[0] != '/' {
s.Index = "/" + s.Index
}
s.handler = handler(s.Root, s.SPA, s.Index)
if len(s.Middlewares) > 0 {
mid, err := middleware.BuildMiddlewareFromMap(s.Alias, s.Middlewares)

View File

@@ -44,7 +44,10 @@ type (
Scheme route.Scheme `json:"scheme,omitempty" swaggertype:"string" enums:"http,https,tcp,udp,fileserver"`
Host string `json:"host,omitempty"`
Port route.Port `json:"port"`
Root string `json:"root,omitempty"`
Root string `json:"root,omitempty"`
SPA bool `json:"spa,omitempty"` // Single-page app mode: serves index for non-existent paths
Index string `json:"index,omitempty"` // Index file to serve for single-page app mode
route.HTTPConfig
PathPatterns []string `json:"path_patterns,omitempty" extensions:"x-nullable"`