Go - Logging responses to incoming HTTP requests inside http.HandleFunc -


this follow-up question in go, how inspect http response written http.responsewriter? since solution there requires faking request, works great unit test not on live server.

i dump out http response web service returning in response requests receives users log file (or console). output should tell me headers , json payload.

how 1 go that?

if there httputil.dumpresponse equivalent takes http.responsewriter argument rather http.response perfect, can access header http.responsewriter

r = mux.newrouter() r.handlefunc("/path", func (w http.responsewriter, r *http.request) {      fmt.printf("r.handlefunc /path\n")      resp := server.newresponse()     defer resp.close()      r.parseform()      // server work here     // ...      // insert debug code here,     //     // dump = http.dumpresponsefromwriter(w)     // fmt.printf("%s\n", dump) }); http.handle("/path", r) 

middleware chaining

a common solution problem called middleware chain. there several libraries provide functionality e.g. negroni.

it's form of continuation-passing style write middleware functions (taken negroni's readme):

func mymiddleware(rw http.responsewriter, r *http.request, next http.handlerfunc) {   // stuff before   next(rw, r)   // stuff after } 

and negroni gives http handler calls middlewares in right order.

we implement solution differently less magical , more functional (as in functional programming) approach. define handler combinators follows:

func newfoohandler(next http.handlerfunc) http.handlerfunc {     return func(w http.responsewriter, r *http.request) {         // stuff before         next(r,w)         // stuff after     } } 

then define chain combination:

h := newfoohandler(newbarhandler(newbazhandler(sink))) 

now h http.handlerfunc foo, bar, baz. sink empty last handler, nothing (to "finish" chain.)

applying solution problem

define handler combinator:

func newresponselogginghandler(next http.handlerfunc) http.handlerfunc {     return func(w http.responsewriter, r *http.request) {          // switch out response writer recorder         // subsequent handlers         c := httptest.newrecorder()         next(c, r)          // copy response recorder         // actual response writer         k, v := range c.headermap {             w.header()[k] = v         }         w.writeheader(c.code)         c.body.writeto(w)      } } 

now problem boils down handler management. you'll want handler applied chains in category. this, can use combinators again (this equivalent negroni's classic() method):

func newdefaulthandler(next http.handlerfunc) http.handlerfunc {     return newresponselogginghandler(newotherstuffhandler(next)) } 

after this, whenever start chain this:

h := newdefaulthandler(...) 

it automatically include response logging , default stuff defined in newdefaulthandler.


Comments

Popular posts from this blog

google chrome - Developer tools - How to inspect the elements which are added momentarily (by JQuery)? -

angularjs - Showing an empty as first option in select tag -

php - Cloud9 cloud IDE and CakePHP -