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

huangapple go评论81阅读模式
英文:

Reading a Buffer and Rewriting it to a http.Response in Go

问题

我想在golang中编写一个HTTP代理。我使用这个模块来实现代理:https://github.com/elazarl/goproxy。当有人使用我的代理时,它会调用一个函数,并将http.Response作为输入。我们称之为"resp"。resp.Body是一个io.ReadCloser。我可以通过使用其Read方法将其读入一个[]byte数组中。但是,这样一来,resp.Body的内容就会消失。但我必须返回一个http.Response,其中包含我读入的[]byte数组的内容。我该如何做到这一点?

代码示例:

proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
body := resp.Body
var readBody []byte
nread, readerr := body.Read(readBody)
// 现在body为空
// 我必须返回一个包含读取内容的body
// 我该如何做到这一点?
// 使用return resp会返回一个空body的Response
})

英文:

I want to program a HTTP-Proxy in golang. I use this module for the proxy: https://github.com/elazarl/goproxy. When someone uses my proxy, it calls a function with an http.Response as an Input. Let's call it "resp". resp.Body is an io.ReadCloser. I can read from it into a []byte array by using it's Read Method. But then the contents of it are gone from the resp.Body. But I have to return an http.Response with the Body that I read into a []byte array. How can I do that?

Greetings,

Max

My Code:

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
}

答案1

得分: 6

你需要先完整地读取整个响应体,这样才能正确关闭它。一旦你读取了整个响应体,你可以简单地用你的缓冲区替换Response.Body

readBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
    // 处理错误
}
resp.Body.Close()
// 使用 readBody

resp.Body = ioutil.NopCloser(bytes.NewReader(readBody))
英文:

You're going to have to read all of the body first, so you can properly close it. Once you have the entire body read, you can simply replace the Response.Body with your buffer.

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

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

答案2

得分: 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))
英文:

That's because the io.Reader acts more as a buffer, when you read it, you've consumed that data in the buffer and are left with an empty body. To solve that problem you just need to close the responses body and create a new ReadCloser out of the body which is now a string.

import "io/ioutil"

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

if err != nil {
     // 
}

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

huangapple
  • 本文由 发表于 2015年7月20日 22:39:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/31519365.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定