This is a follow-up question to In go, how to inspect the http response that is written to http.ResponseWriter? since the solution there requires faking a request, which wor
This can be achieved by using a custom ServerMux
that does no routing, but replaces the response writer, and then forwards the request to a normal mux. Since ResponseWriter is just an interface we can fake it easily.
First, we wrap the ResponseWriter interface with our own response writer, that will log everything and pass all functionality to a real response writer:
type DumpResponseWriter struct {
// the underlying writer
w http.ResponseWriter
// more stuff you want to use for logging context (ip, headers, etc) here
}
func (w *DumpResponseWriter)Header() http.Header {
return w.w.Header()
}
func (w *DumpResponseWriter)Write(b []byte) (int, error) {
// You can add more context about the connection when initializing the writer and log it here
log.Println("Writing < more context details here> ", string(b) )
return w.w.Write(b)
}
func (w *DumpResponseWriter)WriteHeader(h int) {
log.Println("Writing Header< more context details here> ", h)
w.w.WriteHeader(h)
}
This leaves our handler func the same as before, and agnostic to the fact that we're using a "Fake" writer...
func MyHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello world"))
}
And then we simply replace the default mux with our own proxy mux, that replaces the writer and lets a regular ServeMux do its thing:
func main(){
// we don't use the default mux, but a custom one
mux := http.NewServeMux()
mux.HandleFunc("/", MyHandler)
// now we intercept each request and forward it to the mux to do the routing to the handlers.
err := http.ListenAndServe(":1337", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// we wrap the response writer with our own. Add more context here if you want to the writer's instance
writer := &DumpResponseWriter{w}
// and we let our ordinary mux take care of things from here
mux.ServeHTTP(writer, r)
// We can also dump the headers after the handler is done. It will not print the standard headers though
log.Printf("Response headers: %#v", w.Header())
}))
if err != nil {
panic(err)
}
}
http://play.golang.org/p/hT1PCNxI-V