diff --git a/pkg/api/index.go b/pkg/api/index.go index 5d5a649e..2e1a2f15 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -2,12 +2,44 @@ package api import ( "net/http" + "os" "path" + "path/filepath" "github.com/ncarlier/readflow/pkg/config" "github.com/rs/zerolog/log" ) +type SPAHandler struct { + baseDir string + handler http.Handler +} + +func newSPAHandler(baseDir string) http.Handler { + return &SPAHandler{ + baseDir: baseDir, + handler: http.FileServer(http.Dir(baseDir)), + } +} + +func (s SPAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + path := filepath.Join(s.baseDir, r.URL.Path) + fi, err := os.Stat(path) + if os.IsNotExist(err) || fi.IsDir() { + // serve index.html if path does not exist + http.ServeFile(w, r, filepath.Join(s.baseDir, "index.html")) + return + } + + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // otherwise,serve static files + s.handler.ServeHTTP(w, r) +} + // index is the handler to show API details. func index(conf *config.Config) http.Handler { if conf.UI.Directory != "" { @@ -17,7 +49,7 @@ func index(conf *config.Config) http.Handler { if err := conf.WriteUIConfigFile(configFilename); err != nil { log.Warn().Err(err).Str("filename", configFilename).Msg("unable to generate UI config file") } - return http.FileServer(http.Dir(conf.UI.Directory)) + return newSPAHandler(conf.UI.Directory) } return http.RedirectHandler("/info", http.StatusSeeOther) }