读取缓冲区并将其重写为Go中的http.Response

时间:2015-07-20 14:39:24

标签: http go proxy

我想在golang中编写HTTP代理。我将此模块用于代理:https://github.com/elazarl/goproxy。当有人使用我的代理时,它会调用一个http.Response作为输入的函数。我们称之为" resp"。 resp.Body是一个io.ReadCloser。我可以通过它的Read方法从它读入一个[]字节数组。但是后来它的内容从resp.Body中消失了。但我必须返回一个http.Response与Body读取到[]字节数组。我怎么能这样做?

问候,

最高

我的代码:

proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {

   body := resp.Body
   var readBody []byte
   nread, readerr := body.Read(readBody)
   //the body is now empty
   //and i have to return a body
   //with the contents i read.
   //how can i do that?
   //doing return resp gives a Response with an empty body
}

2 个答案:

答案 0 :(得分:4)

您必须先阅读身体的所有,以便正确关闭它。读完整个实体后,只需用缓冲区替换Response.Body即可。

readBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
    // handle error
}
resp.Body.Close()
// use readBody

resp.Body = ioutil.NopCloser(bytes.NewReader(readBody))

答案 1 :(得分:2)

那是因为io.Reader更像是一个缓冲区,当你读取它时,你已经在缓冲区中消耗了这些数据并留下了一个空体。要解决这个问题,您只需要关闭响应主体并从主体中创建一个新的ReadCloser,现在是一个字符串。

import "io/ioutil"

readBody, err := ioutil.ReadAll(resp.Body)

if err != nil {
     // 
}

resp.Body.Close()
resp.Body = ioutil.NopCloser(bytes.NewReader(readBody))