Skip to content

Commit

Permalink
Restore the Response and Request when read from Transport
Browse files Browse the repository at this point in the history
Since the Request.Body and Response.Body are read from any transport.RoundTrip,
it is needed to restore them before reusing it again;
otherwise, the Request.Body or Response.Body won't be readable.

Signed-off-by: David Pordomingo <[email protected]>
  • Loading branch information
dpordomingo committed Oct 15, 2019
1 parent 37b2c2a commit 00086cf
Showing 1 changed file with 14 additions and 8 deletions.
22 changes: 14 additions & 8 deletions examples/cmd/logtransport.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package main

import (
"bytes"
"io/ioutil"
"net/http"
"time"

"gopkg.in/src-d/go-log.v1"

"github.com/src-d/metadata-retrieval/utils"
)

func setLogTransport(client *http.Client, logger log.Logger) {
Expand All @@ -21,15 +21,23 @@ type logTransport struct {
func (t *logTransport) RoundTrip(r *http.Request) (*http.Response, error) {
t0 := time.Now()

reqBody, _ := ioutil.ReadAll(r.Body)
r.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody))

// Since the underlaying Transport.RoundTrip might consume the Request, and it's also needed later to log the process,
// it is needed to make an snapshot of the Request.Body in advance; otherwise, its will be no longer accessible.
bakupReqBody := utils.BackupRequestBody(r)
resp, err := t.T.RoundTrip(r)
restoreRequestBody(r, bakupReqBody)

// Since the outter Transport.RoundTrip calling this one might also consume the Request, and it is also needed here to log
// the process, it will be done over a snapshot of the Request.Body; otherwise, its will be no longer accessible by outer Transports.
reqBody, _ := utils.ReadRequestAndRestore(r)

if err != nil {
return resp, err
}

respBody, err := ioutil.ReadAll(resp.Body)
// Since the Response has been read, it is needed to restore it
// before reusing it; otherwise, its body will be unreadable again in other Transports.
respBody, err := utils.ReadResponseAndRestore(resp)
if err != nil {
return resp, err
}
Expand All @@ -38,7 +46,5 @@ func (t *logTransport) RoundTrip(r *http.Request) (*http.Response, error) {
log.Fields{"elapsed": time.Since(t0), "response-code": resp.StatusCode, "url": r.URL, "request-body": string(reqBody), "response-body": string(respBody)},
).Debugf("HTTP response")

resp.Body = ioutil.NopCloser(bytes.NewBuffer(respBody))

return resp, err
}

0 comments on commit 00086cf

Please sign in to comment.