diff --git a/internal/server/server.go b/internal/server/server.go index cb6d699..b9fbbeb 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -5,7 +5,9 @@ import ( "embed" "encoding/json" "log" + "mime" "net/http" + "path" "sync" "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.HandleFunc("/", s.serveIndex).Methods("GET") + router.HandleFunc("/favicon.ico", s.serveFavicon).Methods("GET") router.HandleFunc("/ws", s.handleWebSocket).Methods("GET") 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("/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) } @@ -77,6 +80,11 @@ func (s *Server) serveIndex(w http.ResponseWriter, r *http.Request) { 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) { 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 { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*")