How can I tell if net / http ResponseWriter.Write () was called?

Suppose I have a chain of network / HTTP handlers and an early HTTP response error ( http.StatusInternalServerError

for example). How can I detect this in the following handlers and not send additional data to the client?

Or is this a completely wrong approach to the problem?

+3


source to share


2 answers


http.ResponseWriter

is an interface. So just create a new instance:

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. In most cases, if you have a "chain" of handlers, this means that the handler is called within the handler. Therefore, 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 they each 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. For example.

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().
}

      

+6


source


First: there might be a lighter weight solution.



However, if you can't find it, consider using x/net/context

it so you can take advantage of timeouts, deadlines, and of course, early termination of middleware networks.

0


source







All Articles