From 8b32d99b5cf0d995907a1ebbbb84a184a555ab84 Mon Sep 17 00:00:00 2001 From: ShukeBta Date: Thu, 11 Jun 2026 18:57:02 +0800 Subject: [PATCH] fix spa fallback for library routes --- .gitignore | 1 + cmd/server/main.go | 30 ++++++++++++++++++++++++++++++ cmd/server/main_test.go | 3 ++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 51686e5..5bbbb17 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ logs/ .tmp-deploy-smoke-cache/ .tmp-deploy-cache/ .tmp-deploy-server.* +.tmp-live-server.* .mediastation.pid *.log *.db diff --git a/cmd/server/main.go b/cmd/server/main.go index 6072c7c..7ee0af6 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -200,6 +200,9 @@ func setNoCacheHeaders(c *gin.Context) { } func shouldBypassSPAFallback(path string) bool { + if isFrontendLibraryRoute(path) { + return false + } lower := strings.ToLower(path) for _, exact := range []string{ "/emby", @@ -233,6 +236,33 @@ func shouldBypassSPAFallback(path string) bool { return false } +func isFrontendLibraryRoute(path string) bool { + const prefix = "/library/" + if !strings.HasPrefix(path, prefix) { + return false + } + id := strings.TrimPrefix(path, prefix) + if strings.Contains(id, "/") { + return false + } + if len(id) != 36 { + return false + } + for i, ch := range id { + switch i { + case 8, 13, 18, 23: + if ch != '-' { + return false + } + default: + if !((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) { + return false + } + } + } + return true +} + func newLogger(cfg *config.Config) (*zap.Logger, error) { if cfg.App.Debug { return zap.NewDevelopment() diff --git a/cmd/server/main_test.go b/cmd/server/main_test.go index 56a78db..917fb71 100644 --- a/cmd/server/main_test.go +++ b/cmd/server/main_test.go @@ -30,7 +30,7 @@ func TestServeSPANoCachesIndexAndServesRoutes(t *testing.T) { router := gin.New() serveSPA(router, webDir) - for _, path := range []string{"/", "/login", "/media/abc"} { + for _, path := range []string{"/", "/login", "/library/e1c3507e-2878-40ae-a0e1-6b6e44b7fa7a", "/media/abc"} { req := httptest.NewRequest(http.MethodGet, path, nil) w := httptest.NewRecorder() router.ServeHTTP(w, req) @@ -76,6 +76,7 @@ func TestServeSPAServesAssetsImmutableAndBypassesAPIRoutes(t *testing.T) { "/api/missing", "/emby", "/emby/missing", + "/Library/VirtualFolders", "/Startup/Configuration", "/QuickConnect/Enabled", "/embywebsocket",