From 67cf80b5556d03ef6e6920d299b4d1b46522b063 Mon Sep 17 00:00:00 2001
From: Jeevanandam M
Date: Tue, 19 Nov 2024 21:21:09 -0800
Subject: [PATCH 1/2] fix: buffer reset issue in io.Reader with content length
enabled #917
---
request_test.go | 39 +++++++++++++++++++++++++++++++++++++++
util.go | 9 +++++++--
2 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/request_test.go b/request_test.go
index 44bec455..2d1e5bf4 100644
--- a/request_test.go
+++ b/request_test.go
@@ -12,11 +12,13 @@ import (
"io"
"net"
"net/http"
+ "net/http/httptest"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
+ "sync"
"testing"
"time"
@@ -2195,3 +2197,40 @@ func TestSetResultMustNotPanicOnNil(t *testing.T) {
}()
dc().R().SetResult(nil)
}
+
+func TestRequestGH917(t *testing.T) {
+ // Mock server returns 500 status code to cause client retries.
+ srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ b, err := io.ReadAll(r.Body)
+ assertError(t, err)
+ if len(b) > 0 {
+ // sometimes, the body is "testtest" instead of "test"
+ assertEqual(t, "test", string(b))
+ }
+ w.WriteHeader(http.StatusInternalServerError)
+ }))
+
+ client := New().AddRetryCondition(
+ func(r *Response, err error) bool {
+ return err != nil || r.StatusCode() > 499
+ },
+ ).SetRetryCount(3)
+
+ wg := sync.WaitGroup{}
+ // Run tests concurrently to make the issue easily to observe.
+ for i := 0; i < 100; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for j := 0; j < 10; j++ {
+ buf := bytes.NewBufferString("test")
+ // Trigger some retries
+ resp, err := client.R().SetBody(buf).SetContentLength(true).Execute(http.MethodPost, srv.URL)
+ assertNil(t, err)
+ assertEqual(t, http.StatusInternalServerError, resp.StatusCode())
+ assertEqual(t, "", string(resp.Body()))
+ }
+ }()
+ }
+ wg.Wait()
+}
diff --git a/util.go b/util.go
index e1a66ffe..9f58a3f5 100644
--- a/util.go
+++ b/util.go
@@ -286,12 +286,17 @@ func functionName(i interface{}) string {
}
func acquireBuffer() *bytes.Buffer {
- return bufPool.Get().(*bytes.Buffer)
+ buf := bufPool.Get().(*bytes.Buffer)
+ if buf.Len() == 0 {
+ buf.Reset()
+ return buf
+ }
+ bufPool.Put(buf)
+ return new(bytes.Buffer)
}
func releaseBuffer(buf *bytes.Buffer) {
if buf != nil {
- buf.Reset()
bufPool.Put(buf)
}
}
From 253540b9c966a35684a69439904d83c403a608ab Mon Sep 17 00:00:00 2001
From: Jeevanandam M
Date: Tue, 19 Nov 2024 21:33:12 -0800
Subject: [PATCH 2/2] release: version bump and readme update for v2.16.1
---
README.md | 6 +++---
resty.go | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 2bc05089..e513b24e 100644
--- a/README.md
+++ b/README.md
@@ -4,12 +4,12 @@
Features section describes in detail about Resty capabilities
-
+
## News
- * v2.16.0 [released](https://github.com/go-resty/resty/releases/tag/v2.16.0) and tagged on Nov 10, 2024.
+ * v2.16.1 [released](https://github.com/go-resty/resty/releases/tag/v2.16.1) and tagged on Nov 19, 2024.
* v2.0.0 [released](https://github.com/go-resty/resty/releases/tag/v2.0.0) and tagged on Jul 16, 2019.
* v1.12.0 [released](https://github.com/go-resty/resty/releases/tag/v1.12.0) and tagged on Feb 27, 2019.
* v1.0 released and tagged on Sep 25, 2017. - Resty's first version was released on Sep 15, 2015 then it grew gradually as a very handy and helpful library. Its been a two years since first release. I'm very thankful to Resty users and its [contributors](https://github.com/go-resty/resty/graphs/contributors).
@@ -105,7 +105,7 @@ Resty author also published following projects for Go Community.
```bash
# Go Modules
-require github.com/go-resty/resty/v2 v2.16.0
+require github.com/go-resty/resty/v2 v2.16.1
```
## Usage
diff --git a/resty.go b/resty.go
index 19f95ada..450aa66a 100644
--- a/resty.go
+++ b/resty.go
@@ -14,7 +14,7 @@ import (
)
// Version # of resty
-const Version = "2.16.0"
+const Version = "2.16.1"
// New method creates a new Resty client.
func New() *Client {