diff --git a/README.md b/README.md index 4c938ad..1602679 100644 --- a/README.md +++ b/README.md @@ -131,29 +131,29 @@ func main() { } ``` -### Custom handling of Not Found +### Custom error handling -If you need special treatment for resources that are not available in static server, you can use `Found` -to check them before serving. +Error states can be handled with the `staticgz.OnError` and `staticgz.OnNotFound` options. These allow you to customize +the response sent to the client when an error occurs or when no resource is found. ```go -fileServer := statigz.FileServer(st) -customHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Serve existing static resource. - if fileServer.Found(r) { - fileServer.ServeHTTP(w, r) - - return - } - - // Do something custom for non-existing resource, for example serve index page. - // (This is an example, serving index instead of 404 might not be the best idea in real life 😅). - r.URL.Path = "/" - fileServer.ServeHTTP(w, r) -}) - -// Plug static assets handler to your server or router. -if err := http.ListenAndServe("localhost:80", customHandler); err != nil { +fileServer := statigz.FileServer( + st, + staticgz.OnError(func(w http.ResponseWriter, r *http.Request, err error) { + // Handle error. + http.Error(w, err.Error(), http.StatusInternalServerError) + }), + staticgz.OnNotFound(func(w http.ResponseWriter, r *http.Request) { + // Handle not found. + http.Error(w, "Not found", http.StatusNotFound) + + // Or to serve a alternative path instead you could; + //r.URL.Path = "/alternative/path" + //fileServer.ServeHTTP(w, r) + }), +) + +if err := http.ListenAndServe("localhost:80", fileServer); err != nil { log.Fatal(err) } -``` \ No newline at end of file +``` diff --git a/server.go b/server.go index 96d796d..e840e6f 100644 --- a/server.go +++ b/server.go @@ -35,6 +35,9 @@ type Server struct { // OnError controls error handling during Serve. OnError func(rw http.ResponseWriter, r *http.Request, err error) + // OnNotFound controls handling of not found files. + OnNotFound func(rw http.ResponseWriter, r *http.Request) + // Encodings contains supported encodings, default GzipEncoding. Encodings []Encoding @@ -78,7 +81,8 @@ func FileServer(fs fs.ReadDirFS, options ...func(server *Server)) *Server { OnError: func(rw http.ResponseWriter, r *http.Request, err error) { http.Error(rw, "Internal Server Error", http.StatusInternalServerError) }, - Encodings: []Encoding{GzipEncoding()}, + OnNotFound: http.NotFound, + Encodings: []Encoding{GzipEncoding()}, } for _, o := range options { @@ -364,7 +368,7 @@ func (s *Server) ServeHTTP(rw http.ResponseWriter, req *http.Request) { return } - http.NotFound(rw, req) + s.OnNotFound(rw, req) } // Found returns true if http.Request would be fulfilled by Server. @@ -441,6 +445,13 @@ func OnError(onErr func(rw http.ResponseWriter, r *http.Request, err error)) fun } } +// OnNotFound is an option to customize not found (404) handling in Server. +func OnNotFound(onErr func(rw http.ResponseWriter, r *http.Request)) func(server *Server) { + return func(server *Server) { + server.OnNotFound = onErr + } +} + // GzipEncoding provides gzip Encoding. func GzipEncoding() Encoding { return Encoding{