From 414b364478277881f91cf254659951b33b845f3c Mon Sep 17 00:00:00 2001 From: wxip <3455781820@qq.com> Date: Fri, 17 Jan 2025 11:18:58 +0800 Subject: [PATCH] fix: retry not reset multipartField reader (#953) --- retry.go | 15 ++++++++++++++ retry_test.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/retry.go b/retry.go index 416107e4..f3198a52 100644 --- a/retry.go +++ b/retry.go @@ -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 { @@ -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 +} diff --git a/retry_test.go b/retry_test.go index cef9e81c..34dcc645 100644 --- a/retry_test.go +++ b/retry_test.go @@ -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) +}