Luke Johnson
Luke Johnson

Reputation: 183

Handling custom 404 pages with http.FileServer

I'm currently using a basic http.FileServer setup to serve a simple static site. I need to handle 404 errors with a custom not found page. I've been looking into this issue quite a bit, and I cannot determine what the best solution is.

I've seen several responses on GitHub issues along the lines of:

You can implement your own ResponseWriter which writes a custom message after WriteHeader.

It seems like this is the best approach but I'm a bit unsure of how this would actually be implemented. If there are any simple examples of this implementation, it'd be greatly appreciated!

Upvotes: 2

Views: 1780

Answers (1)

squiguy
squiguy

Reputation: 33360

I think this can be solved with your own middleware. You can try to open the file first and if it doesn't exist, call your own 404 handler. Otherwise just dispatch the call to the static file server in the standard library.

Here is how that could look:

package main

import (
    "fmt"
    "net/http"
    "os"
    "path"
)

func notFound(w http.ResponseWriter, r *http.Request) {
    // Here you can send your custom 404 back.
    fmt.Fprintf(w, "404")
}

func customNotFound(fs http.FileSystem) http.Handler {
    fileServer := http.FileServer(fs)
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        _, err := fs.Open(path.Clean(r.URL.Path)) // Do not allow path traversals.
        if os.IsNotExist(err) {
            notFound(w, r)
            return
        }
        fileServer.ServeHTTP(w, r)
    })
}

func main() {
    http.ListenAndServe(":8080", customNotFound(http.Dir("/path/to/files")))
}

Upvotes: 4

Related Questions