From 319bc2f200ccb1873f1dd82842df99f8ab3ce66e Mon Sep 17 00:00:00 2001 From: ze0s <43699394+zze0s@users.noreply.github.com> Date: Tue, 2 May 2023 19:06:53 +0200 Subject: [PATCH] fix(web): PWA asset and route handling (#898) * fix(web): PWA asset and fallback route handling * fix(web): strip baseurl * fix(web): add back manifest.json * fix(web): add back manifest.json * fix(web): log file * fix(web): do not trim baseurl * fix(web): try different start_url * fix(web): pwa with subfolder --- .dockerignore | 31 +++++++------- internal/http/server.go | 6 +-- web/build.go | 74 +++++++++++++++++++++++++++++++-- web/index.html | 2 +- web/{public => }/manifest.json | 4 +- web/public/logo.png | Bin 0 -> 7418 bytes web/vite.config.ts | 23 +++++++--- 7 files changed, 110 insertions(+), 30 deletions(-) rename web/{public => }/manifest.json (95%) create mode 100644 web/public/logo.png diff --git a/.dockerignore b/.dockerignore index 3d48687..2e05ec5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,6 +3,7 @@ node_modules/ .gitignore .github .dev +dev/ config.toml .goreleaser.yml Dockerfile @@ -12,18 +13,18 @@ README.md bin config test -web/* -!web/public -!web/src -!web/dist* -!web/package.json -!web/yarn.lock -!web/.yarnrc.yml -!web/.yarn/releases -!web/.eslintrc.js -!web/postcss.config.js -!web/tailwind.config.js -!web/tsconfig.json -!web/index.html -!web/vite.config.ts -!web/build.go \ No newline at end of file +#web/* +#!web/public +#!web/src +#!web/dist* +#!web/package.json +#!web/yarn.lock +#!web/.yarnrc.yml +#!web/.yarn/releases +#!web/.eslintrc.js +#!web/postcss.config.js +#!web/tailwind.config.js +#!web/tsconfig.json +#!web/index.html +#!web/vite.config.ts +#!web/build.go \ No newline at end of file diff --git a/internal/http/server.go b/internal/http/server.go index 99aaf56..80e9956 100644 --- a/internal/http/server.go +++ b/internal/http/server.go @@ -108,7 +108,6 @@ func (s Server) Handler() http.Handler { r.Use(c.Handler) encoder := encoder{} - web.RegisterHandler(r) r.Route("/api", func(r chi.Router) { r.Route("/auth", newAuthHandler(encoder, s.log, s.config.Config, s.cookieStore, s.authService).Routes) @@ -145,9 +144,8 @@ func (s Server) Handler() http.Handler { }) }) - // serve the parsed index.html - r.Get("/", s.index) - r.Get("/*", s.index) + // serve the web + web.RegisterHandler(r, s.version, s.config.Config.BaseURL) return r } diff --git a/web/build.go b/web/build.go index a7a1482..97b31e8 100644 --- a/web/build.go +++ b/web/build.go @@ -14,6 +14,7 @@ import ( "net/http" "os" "path/filepath" + "strings" "github.com/go-chi/chi/v5" ) @@ -92,6 +93,7 @@ func StaticFS(r *chi.Mux, pathPrefix string, filesystem fs.FS) { // fsFile is a helper function to serve a file from the provided file system. func fsFile(w http.ResponseWriter, r *http.Request, file string, filesystem fs.FS) { + //fmt.Printf("file: %s\n", file) f, err := filesystem.Open(file) if err != nil { http.Error(w, "File not found", http.StatusNotFound) @@ -115,16 +117,74 @@ func fsFile(w http.ResponseWriter, r *http.Request, file string, filesystem fs.F http.ServeContent(w, r, file, stat.ModTime(), reader) } -func RegisterHandler(c *chi.Mux) { +var validRoutes = []string{"/", "filters", "releases", "settings", "logs", "onboard", "login", "logout"} + +func validRoute(route string) bool { + for _, valid := range validRoutes { + if strings.Contains(route, valid) { + return true + } + } + + return false +} + +// RegisterHandler register web routes and file serving +func RegisterHandler(c *chi.Mux, version, baseUrl string) { // Serve static files without a prefix assets, _ := fs.Sub(DistDirFS, "assets") static, _ := fs.Sub(DistDirFS, "static") StaticFS(c, "/assets", assets) StaticFS(c, "/static", static) + p := IndexParams{ + Title: "Dashboard", + Version: version, + BaseUrl: baseUrl, + } + + // serve on base route + c.Get("/", func(w http.ResponseWriter, r *http.Request) { + Index(w, p) + }) + + // handle all other routes c.Get("/*", func(w http.ResponseWriter, r *http.Request) { - // Serve index.html for unmatched routes - fsFile(w, r, "dist/index.html", Dist) + file := strings.TrimPrefix(r.RequestURI, "/") + + // if valid web route then serve html + if validRoute(file) || file == "index.html" { + Index(w, p) + return + } + + if strings.Contains(file, "manifest.webmanifest") { + Manifest(w, p) + return + } + + // if not valid web route then try and serve files + f, err := DistDirFS.Open(file) + if err != nil { + http.Error(w, "File not found", http.StatusNotFound) + return + } + defer f.Close() + + stat, err := f.Stat() + if err != nil { + http.Error(w, "File not found", http.StatusNotFound) + return + } + + data, err := io.ReadAll(f) + if err != nil { + http.Error(w, "Failed to read the file", http.StatusInternalServerError) + return + } + + reader := bytes.NewReader(data) + http.ServeContent(w, r, file, stat.ModTime(), reader) }) } @@ -135,3 +195,11 @@ func Index(w io.Writer, p IndexParams) error { func parseIndex() *template.Template { return template.Must(template.New("index.html").ParseFS(Dist, "dist/index.html")) } + +func Manifest(w io.Writer, p IndexParams) error { + return parseManifest().Execute(w, p) +} + +func parseManifest() *template.Template { + return template.Must(template.New("manifest.webmanifest").ParseFS(Dist, "dist/manifest.webmanifest")) +} diff --git a/web/index.html b/web/index.html index d92a461..c454413 100644 --- a/web/index.html +++ b/web/index.html @@ -19,7 +19,7 @@ - + autobrr