I have an *http.Response
Body I want to read multiple times. I have two functions that take in an io.Reader
, which in this case is the response body.
response, err := http.Get(url)
if err != nil {
return err
}
defer func() {
_ = response.Body.Close()
}()
// handle status code here
FirstFunction(response.Body)
SecondFunction(response.Body) // the body has been read at this point, its r/w pointer is at the end of the "file"
I'm aware of the very good io.Seeker
interface, notably available on an *os.File
, but response.Body
doesn't implement it.
How can I read a response body twice (or more)?
Multiple solutions are available, but I'm in favor of using io.Seeker
, as this interface allows for a single reader to be usable multiple times.
Here's my preferred solution:
response, err := http.Get(url)
if err != nil {
return err
}
defer func() {
_ = response.Body.Close()
}()
// handle status code here
wholeBody, err := io.ReadAll(response.Body)
if err != nil {
return err
}
bytesReader := bytes.NewReader(wholeBody)
FirstFunction(bytesReader)
_, err = bytesReader.Seek(0, io.SeekStart) // *bytes.Reader implements io.Seeker
if err != nil {
return err
}
SecondFunction(bytesReader) // we finally have the full body again!
Honorable mention also to https://github.com/jfbus/httprs, discovered while seeking for an answer to this problem, which could be an out-of-the-box fit for some people.