Skip to content

Commit

Permalink
fix: retry not reset multipartField reader (#953)
Browse files Browse the repository at this point in the history
  • Loading branch information
wxip authored Jan 17, 2025
1 parent 16fd88a commit 414b364
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
15 changes: 15 additions & 0 deletions retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ func Backoff(operation func() (*Response, error), options ...Option) error {
if err := resetFileReaders(resp.Request.multipartFiles); err != nil {
return err
}
if err := resetFieldReaders(resp.Request.multipartFields); err != nil {
return err
}
}

for _, hook := range opts.retryHooks {
Expand Down Expand Up @@ -250,3 +253,15 @@ func resetFileReaders(files []*File) error {

return nil
}

func resetFieldReaders(fields []*MultipartField) error {
for _, f := range fields {
if rs, ok := f.Reader.(io.ReadSeeker); ok {
if _, err := rs.Seek(0, io.SeekStart); err != nil {
return err
}
}
}

return nil
}
55 changes: 55 additions & 0 deletions retry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -823,3 +823,58 @@ func TestResetMultipartReaders(t *testing.T) {
assertEqual(t, 500, resp.StatusCode())
assertNil(t, err)
}

func TestResetMultipartFieldReaderSeekStartError(t *testing.T) {
ts := createFilePostServer(t)
defer ts.Close()

testSeeker := &failingSeeker{
bytes.NewReader([]byte("test")),
}

c := dc().
SetRetryCount(2).
SetTimeout(time.Second * 3).
SetRetryResetReaders(true).
AddRetryAfterErrorCondition()

resp, err := c.R().
SetMultipartField("file", "audio.wav", "audio/wav", testSeeker).
Post(ts.URL + "/set-reset-multipart-readers-test")

assertEqual(t, 500, resp.StatusCode())
assertEqual(t, err.Error(), errSeekFailure.Error())
}

func TestResetMultipartFieldReaders(t *testing.T) {
ts := createFilePostServer(t)
defer ts.Close()

str := "test"
buf := []byte(str)

bufReader := bytes.NewReader(buf)
bufCpy := make([]byte, len(buf))

c := dc().
SetRetryCount(2).
SetTimeout(time.Second * 3).
SetRetryResetReaders(true).
AddRetryAfterErrorCondition().
AddRetryHook(
func(response *Response, _ error) {
read, err := bufReader.Read(bufCpy)

assertNil(t, err)
assertEqual(t, len(buf), read)
assertEqual(t, str, string(bufCpy))
},
)

resp, err := c.R().
SetMultipartField("file", "audio.wav", "audio/wav", bufReader).
Post(ts.URL + "/set-reset-multipart-readers-test")

assertEqual(t, 500, resp.StatusCode())
assertNil(t, err)
}

0 comments on commit 414b364

Please sign in to comment.