Fix MIME type handling for static files

- Add custom static file handler with proper Content-Type headers
- Fix CSS and JavaScript files being served as text/plain
- Add favicon handler to prevent 404 errors

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2025-08-23 22:14:19 +02:00
commit df0ead2657

View file

@ -5,7 +5,9 @@ import (
"embed" "embed"
"encoding/json" "encoding/json"
"log" "log"
"mime"
"net/http" "net/http"
"path"
"sync" "sync"
"github.com/gorilla/mux" "github.com/gorilla/mux"
@ -54,6 +56,7 @@ func New(cfg *config.Config, staticFiles embed.FS, ctx context.Context) http.Han
router := mux.NewRouter() router := mux.NewRouter()
router.HandleFunc("/", s.serveIndex).Methods("GET") router.HandleFunc("/", s.serveIndex).Methods("GET")
router.HandleFunc("/favicon.ico", s.serveFavicon).Methods("GET")
router.HandleFunc("/ws", s.handleWebSocket).Methods("GET") router.HandleFunc("/ws", s.handleWebSocket).Methods("GET")
apiRouter := router.PathPrefix("/api").Subrouter() apiRouter := router.PathPrefix("/api").Subrouter()
@ -61,7 +64,7 @@ func New(cfg *config.Config, staticFiles embed.FS, ctx context.Context) http.Han
apiRouter.HandleFunc("/stats", s.getStats).Methods("GET") apiRouter.HandleFunc("/stats", s.getStats).Methods("GET")
apiRouter.HandleFunc("/config", s.getConfig).Methods("GET") apiRouter.HandleFunc("/config", s.getConfig).Methods("GET")
router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.FS(s.staticFiles)))) router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", s.staticFileHandler()))
return s.enableCORS(router) return s.enableCORS(router)
} }
@ -77,6 +80,11 @@ func (s *Server) serveIndex(w http.ResponseWriter, r *http.Request) {
w.Write(data) w.Write(data)
} }
func (s *Server) serveFavicon(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "image/x-icon")
w.WriteHeader(http.StatusNotFound)
}
func (s *Server) getAircraft(w http.ResponseWriter, r *http.Request) { func (s *Server) getAircraft(w http.ResponseWriter, r *http.Request) {
data := s.dump1090.GetAircraftData() data := s.dump1090.GetAircraftData()
@ -194,6 +202,38 @@ func (s *Server) broadcastToWebSocketClients(message WebSocketMessage) {
} }
} }
func (s *Server) staticFileHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
filePath := "static" + r.URL.Path
data, err := s.staticFiles.ReadFile(filePath)
if err != nil {
http.NotFound(w, r)
return
}
ext := path.Ext(filePath)
contentType := mime.TypeByExtension(ext)
if contentType == "" {
switch ext {
case ".css":
contentType = "text/css"
case ".js":
contentType = "application/javascript"
case ".svg":
contentType = "image/svg+xml"
case ".html":
contentType = "text/html"
default:
contentType = "application/octet-stream"
}
}
w.Header().Set("Content-Type", contentType)
w.Write(data)
})
}
func (s *Server) enableCORS(handler http.Handler) http.Handler { func (s *Server) enableCORS(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Origin", "*")