// server.go package main import ( "fmt" "log" "net/http" "strings" ) var globalRoutes RouteMap // StartServer initializes the routing and starts the HTTP listener. func StartServer() { InitCache() // Initial Scan var err error globalRoutes, err = ScanContent("content") if err != nil { log.Fatalf("Failed to scan content: %v", err) } // SINGLE ENTRY POINT // We handle all routing manually to ensure strict control. http.HandleFunc("/", handleRequest) fmt.Println("Server is online at http://localhost:8080") if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal(err) } } func handleRequest(w http.ResponseWriter, r *http.Request) { // 1. Handle Test Mode (Re-scan on every request) if TestMode { w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0") // In test mode, we refresh the routes map every time so you can add files // without restarting. routes, err := ScanContent("content") if err == nil { globalRoutes = routes } } // 2. Normalize Request Path reqPath := strings.ToLower(r.URL.Path) // 3. Look up in Route Map file, found := globalRoutes[reqPath] if !found { // If not found in our map, it doesn't exist. 404. // This prevents the "Index Fallback" bug. http.NotFound(w, r) return } // 4. Get Content (From Cache or Parse) content, err := GetContent(file) if err != nil { log.Printf("Error serving %s: %v", file.OriginalPath, err) http.Error(w, "Internal Server Error", 500) return } // 5. Render RenderPage(w, content, file) }