I have the following code and everything works fine.
var view404 = template.Must(template.ParseFiles("views/404.html"))
func NotFound(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(404)
err := view404.Execute(w, nil)
check(err)
}
func main() {
router := mux.NewRouter()
router.StrictSlash(true)
router.NotFoundHandler = http.HandlerFunc(NotFound)
router.Handle("/", IndexHandler).Methods("GET")
router.PathPrefix("/public/").Handler(http.StripPrefix("/public/", http.FileServer(http.Dir("public"))))
http.Handle("/", router)
http.ListenAndServe(":8000", nil)
}
A request to a route like /cannot/find
shows my custom 404 template. All static files inside my /public/
directory are also properly served.
I have a problem handling non-existent static files and showing my custom NotFound
handler for them. A request to /public/cannot/find
calls the standard http.NotFoundHandler which replies with
404 page not found
How can I have the same custom NotFoundHandler for normal routes and static files?
Update
I ended up implementing my own FileHandler
by wrapping http.ServeFile
as @Dewy Broto suggested.
type FileHandler struct {
Path string
}
func (f FileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
prefix := "public"
http.ServeFile(w, r, path.Join(prefix, f.Path))
}
// ...
router.Handle("/css/styles.css", FileHandler{"/css/styles.css"}).Methods("GET")
Now my NotFound
handler catches all missing routes and even missing files.