69 lines
1.5 KiB
Go

package main
import (
"net/http"
"os"
"path"
"path/filepath"
"strings"
)
func (a *app) handler() http.Handler {
api := a.routes()
webDir := strings.TrimSpace(a.cfg.WebDir)
if webDir == "" {
return api
}
indexPath := filepath.Join(webDir, "index.html")
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/health" {
a.healthHandler(w, r)
return
}
if isBackendPath(r.URL.Path) {
api.ServeHTTP(w, r)
return
}
cleanPath := path.Clean("/" + r.URL.Path)
relativePath := strings.TrimPrefix(cleanPath, "/")
if relativePath != "" {
candidate := filepath.Join(webDir, filepath.FromSlash(relativePath))
if info, err := os.Stat(candidate); err == nil && !info.IsDir() {
http.ServeFile(w, r, candidate)
return
}
// Missing static assets should be real 404s rather than the SPA shell.
if filepath.Ext(relativePath) != "" {
http.NotFound(w, r)
return
}
}
if _, err := os.Stat(indexPath); err != nil {
api.ServeHTTP(w, r)
return
}
http.ServeFile(w, r, indexPath)
})
}
func isBackendPath(requestPath string) bool {
switch {
case requestPath == "/api", strings.HasPrefix(requestPath, "/api/"):
return true
case requestPath == "/auth", strings.HasPrefix(requestPath, "/auth/"):
return true
case requestPath == "/.well-known", strings.HasPrefix(requestPath, "/.well-known/"):
return true
case requestPath == "/sitemap.xml", requestPath == "/robots.txt":
return true
default:
return false
}
}