69 lines
1.5 KiB
Go
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
|
|
}
|
|
}
|