Skip to content

Commit

Permalink
retry: set GetBody callback when request body is present
Browse files Browse the repository at this point in the history
This commit sets the `GetBody` callback when a request body
is present. The callback may be used by the underlying HTTP
stack eventually to obtain a new copy of the request body.

One example are server redirects. In case of a redirect the
client has to send the request again - including the request
body.

In particular, this should also fix the following HTTP/2 error:
```
http2: Transport: cannot retry err [http2: Transport received Server's graceful shutdown GOAWAY]
after Request.Body was written; define Request.GetBody to avoid this error (*url.Error)
```

Signed-off-by: Andreas Auernhammer <aead@mail.de>
  • Loading branch information
Andreas Auernhammer authored and harshavardhana committed May 20, 2021
1 parent f4581d9 commit 6c4ab49
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ func (r *retry) Do(req *http.Request) (*http.Response, error) {
// error since the caller has specified a wrong type.
panic("kes: request cannot be retried")
}

// If there is a request body, additionally set the
// GetBody callback - if not set already. The underlying
// HTTP stack will use the GetBody callback to obtain a new
// copy of the request body - e.g. in case of a redirect.
if req.GetBody == nil {
req.GetBody = func() (io.ReadCloser, error) {
if _, err := body.Seek(0, io.SeekStart); err != nil {
return nil, err
}
return body, nil
}
}
}

const (
Expand Down

0 comments on commit 6c4ab49

Please sign in to comment.