Suppose I have a chain of net/http Handlers, and an early one responds with an HTTP error (http.StatusInternalServerError
, for instance). How can I detect this in the following handlers, and avoid sending additional data to the client?
Or is this entirely the wrong approach to the problem?
http.ResponseWriter
is an interface. So just compose a new instance of it:
type MyResponseWriter struct {
http.ResponseWriter
WroteHeader bool
}
func (w *MyResponseWriter) Write(b []byte) (int, error) {
w.WroteHeader = true
return w.ResponseWriter.Write(b)
}
func (w *MyResponseWriter) WriteHeader(code int) {
w.WroteHeader = true
w.ResponseWriter.WriteHeader(code)
}
And in your handlers:
//...
if w, ok := w.(*MyResponseWriter); ok && w.WroteHeader {
log.Println("Already wrote, skipping")
return
}
EDIT: Another thing to consider. Most of the time if you have a "chain" of handlers that means that a handler is called inside a handler. So if you have something like
type Handler1 struct { http.Handler }
type Handler2 struct { http.Handler }
type Handler3 struct { http.Handler }
var MyHandler http.Handler = Handler1{Handler2{Handler3{h}}}
as long as each of those call the inner handler as the last thing they do with w
and r
, you should be fine because then w
and r
won't even reach the inner handler. E.g.
func (h Handler2) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if somethingBadHappened() {
w.WriteHeader(http.StatusInternalServerError)
return
}
h.ServeHTTP(w, r) // Not called if somethingBadHappened().
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments