From 3105a24542a6334608ee7bf82a59ecf66ab99a83 Mon Sep 17 00:00:00 2001 From: Matthew Jaffee Date: Mon, 20 Dec 2021 17:32:52 -0600 Subject: [PATCH] rewind Body on retry this is really not ideal, and there are libraries for this kind of thing, but I'd have to figure out how to make the libraries work with everywhere we're already creating stdlib http clients. --- http/client.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/http/client.go b/http/client.go index bb08478d6..0e2b1b428 100644 --- a/http/client.go +++ b/http/client.go @@ -1745,13 +1745,33 @@ func giveRawResponse(b bool) executeRequestOption { } } +type nopCloser struct { + *bytes.Reader +} + +func (n nopCloser) Close() error { + return nil +} + func (c *InternalClient) doWithRetry(req *http.Request) (*http.Response, error) { sleepDuration := time.Second + newBody := nopCloser{} + if req.Body != nil { + bod, err := ioutil.ReadAll(req.Body) + if err != nil { + return nil, errors.Wrap(err, "reading body") + } + newBody.Reader = bytes.NewReader(bod) + req.Body = newBody + } resp, err := c.httpClient.Do(req) // start timer after first request, so if retryPeriod > 0 we // pretty much always do at least one retry start := time.Now() for ; err != nil || resp.StatusCode < 200 || resp.StatusCode >= 300; resp, err = c.httpClient.Do(req) { + if newBody.Reader != nil { + newBody.Seek(0, io.SeekStart) + } if time.Since(start) > c.retryPeriod { break }