io - Reading from a Reader multiple times -
i'm building simple caching proxy intercepts http requests, grabs content in response.body, writes client. problem is, read response.body, write client contains empty body (everything else, headers, written expected).
here's current code:
func requesthandler(w http.responsewriter, r *http.request) { client := &http.client{} r.requesturi = "" response, err := client.do(r) defer response.body.close() if err != nil { log.fatal(err) } content, _ := ioutil.readall(response.body) cachepage(response.request.url.string(), content) response.write(w) }
if remove content, _
, cachepage
lines, works fine. lines included, requests return , empty body. idea how can just body
of http.response
, still write out response in full http.responsewriter
?
you not need read response second time. have data in hand , can write directly response writer.
the call
response.write(w)
writes response in wire format server's response body. not want proxy. need copy headers, status , body server response individually.
i have noted other issues in code comments below.
i recommend using standard library's reverseproxy or copying , modifying meet needs.
func requesthandler(w http.responsewriter, r *http.request) { // no need make client, use default // client := &http.client{} r.requesturi = "" response, err := http.defaultclient.do(r) // response can nil, close after error check // defer response.body.close() if err != nil { log.fatal(err) } defer response.body.close() // check errors! always. // content, _ := ioutil.readall(response.body) content, err := ioutil.readall(response.body) if err != nil { // handle error } cachepage(response.request.url.string(), content) // write method writes response in wire format w. // because server handles wire format, need // copy individual pieces. // response.write(w) // copy headers k, v := range response.header { w.header()[k] = v } // copy status code w.writeheader(response.statuscode) // write response body. w.write(content) }
Comments
Post a Comment