From baf7c1219b781803557018eba206ad8fa544941f Mon Sep 17 00:00:00 2001
From: Jeevanandam M
Date: Fri, 10 May 2024 18:40:23 -0700
Subject: [PATCH 01/13] fix: correct resty version number which was missed in
the previous release (#793)
---
README.md | 4 ++--
resty.go | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index ef6ed1d5..eccca8bc 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
Features section describes in detail about Resty capabilities
-
+
Resty Communication Channels
@@ -13,7 +13,7 @@
## News
- * v2.13.0 [released](https://github.com/go-resty/resty/releases/tag/v2.13.0) and tagged on May 08, 2024.
+ * v2.13.1 [released](https://github.com/go-resty/resty/releases/tag/v2.13.1) and tagged on May 10, 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).
diff --git a/resty.go b/resty.go
index 985cff25..f8becec6 100644
--- a/resty.go
+++ b/resty.go
@@ -14,7 +14,7 @@ import (
)
// Version # of resty
-const Version = "2.12.0"
+const Version = "2.13.1"
// New method creates a new Resty client.
func New() *Client {
From 855d418e33b8791ece43ceaa9e242fc303454846 Mon Sep 17 00:00:00 2001
From: Ahuigo <1781999+ahuigo@users.noreply.github.com>
Date: Sat, 29 Jun 2024 07:17:32 +0800
Subject: [PATCH 02/13] feat(curl): generate curl cmd for request && example
for curl cmd (#794)
* feat(curl): generate curl cmd for request && example for curl cmd
* refactor(curl): Simplified code
1. refactor `GetCurlCommand` with the name `GenerateCurlCommand`
2. un-export this method `BuildCurlRequest`
3. remove SetResultCurlCmd
* cicd(test): add "-coverpkg=./..." to measure the test coverage of packages that are imported in different packages
---
.github/workflows/ci.yml | 2 +-
.github/workflows/label-actions.yml | 2 +-
.gitignore | 3 +-
README.md | 8 ++
client.go | 24 +++--
examples/debug_curl_test.go | 126 ++++++++++++++++++++++
examples/server_test.go | 162 ++++++++++++++++++++++++++++
middleware.go | 12 +++
request.go | 19 ++++
shellescape/shellescape.go | 34 ++++++
util_curl.go | 76 +++++++++++++
11 files changed, 457 insertions(+), 11 deletions(-)
create mode 100644 examples/debug_curl_test.go
create mode 100644 examples/server_test.go
create mode 100644 shellescape/shellescape.go
create mode 100644 util_curl.go
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 224dc3d3..3ea8441d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -43,7 +43,7 @@ jobs:
run: diff -u <(echo -n) <(go fmt $(go list ./...))
- name: Test
- run: go test ./... -race -coverprofile=coverage.txt -covermode=atomic
+ run: go test ./... -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./...
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
diff --git a/.github/workflows/label-actions.yml b/.github/workflows/label-actions.yml
index 5c4c8734..5747117a 100644
--- a/.github/workflows/label-actions.yml
+++ b/.github/workflows/label-actions.yml
@@ -29,7 +29,7 @@ jobs:
cache-dependency-path: go.sum
- name: Test
- run: go test ./... -race -coverprofile=coverage.txt -covermode=atomic
+ run: go test ./... -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./...
- name: Coverage
run: bash <(curl -s https://codecov.io/bash)
diff --git a/.gitignore b/.gitignore
index 9e856bd4..7542ac89 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,5 +26,6 @@ _testmain.go
coverage.out
coverage.txt
-# Exclude intellij IDE folders
+# Exclude IDE folders
.idea/*
+.vscode/*
diff --git a/README.md b/README.md
index eccca8bc..71cc0789 100644
--- a/README.md
+++ b/README.md
@@ -131,6 +131,11 @@ client := resty.New()
resp, err := client.R().
EnableTrace().
Get("https://httpbin.org/get")
+curlCmdExecuted := resp.Request.GenerateCurlCommand()
+
+
+// Explore curl command
+fmt.Println("Curl Command:\n ", curlCmdExecuted+"\n")
// Explore response object
fmt.Println("Response Info:")
@@ -160,6 +165,9 @@ fmt.Println(" RequestAttempt:", ti.RequestAttempt)
fmt.Println(" RemoteAddr :", ti.RemoteAddr.String())
/* Output
+Curl Command:
+ curl -X GET -H 'User-Agent: go-resty/2.12.0 (https://github.com/go-resty/resty)' https://httpbin.org/get
+
Response Info:
Error :
Status Code: 200
diff --git a/client.go b/client.go
index 1bcafba8..8a5539f5 100644
--- a/client.go
+++ b/client.go
@@ -1148,9 +1148,7 @@ func (c *Client) Clone() *Client {
// Client Unexported methods
//_______________________________________________________________________
-// Executes method executes the given `Request` object and returns response
-// error.
-func (c *Client) execute(req *Request) (*Response, error) {
+func (c *Client) executeBefore(req *Request) error {
// Lock the user-defined pre-request hooks.
c.udBeforeRequestLock.RLock()
defer c.udBeforeRequestLock.RUnlock()
@@ -1166,7 +1164,7 @@ func (c *Client) execute(req *Request) (*Response, error) {
// to modify the *resty.Request object
for _, f := range c.udBeforeRequest {
if err = f(c, req); err != nil {
- return nil, wrapNoRetryErr(err)
+ return wrapNoRetryErr(err)
}
}
@@ -1174,14 +1172,14 @@ func (c *Client) execute(req *Request) (*Response, error) {
// will return an error if the rate limit is exceeded.
if req.client.rateLimiter != nil {
if !req.client.rateLimiter.Allow() {
- return nil, wrapNoRetryErr(ErrRateLimitExceeded)
+ return wrapNoRetryErr(ErrRateLimitExceeded)
}
}
// resty middlewares
for _, f := range c.beforeRequest {
if err = f(c, req); err != nil {
- return nil, wrapNoRetryErr(err)
+ return wrapNoRetryErr(err)
}
}
@@ -1192,15 +1190,24 @@ func (c *Client) execute(req *Request) (*Response, error) {
// call pre-request if defined
if c.preReqHook != nil {
if err = c.preReqHook(c, req.RawRequest); err != nil {
- return nil, wrapNoRetryErr(err)
+ return wrapNoRetryErr(err)
}
}
if err = requestLogger(c, req); err != nil {
- return nil, wrapNoRetryErr(err)
+ return wrapNoRetryErr(err)
}
req.RawRequest.Body = newRequestBodyReleaser(req.RawRequest.Body, req.bodyBuf)
+ return nil
+}
+
+// Executes method executes the given `Request` object and returns response
+// error.
+func (c *Client) execute(req *Request) (*Response, error) {
+ if err := c.executeBefore(req); err != nil {
+ return nil, err
+ }
req.Time = time.Now()
resp, err := c.httpClient.Do(req.RawRequest)
@@ -1396,6 +1403,7 @@ func createClient(hc *http.Client) *Client {
parseRequestBody,
createHTTPRequest,
addCredentials,
+ createCurlCmd,
}
// user defined request middlewares
diff --git a/examples/debug_curl_test.go b/examples/debug_curl_test.go
new file mode 100644
index 00000000..9006caf0
--- /dev/null
+++ b/examples/debug_curl_test.go
@@ -0,0 +1,126 @@
+package examples
+
+import (
+ "io"
+ "net/http"
+ "os"
+ "strings"
+ "testing"
+
+ "github.com/go-resty/resty/v2"
+)
+
+// 1. Generate curl for unexecuted request(dry-run)
+func TestGenerateUnexcutedCurl(t *testing.T) {
+ ts := createHttpbinServer(0)
+ defer ts.Close()
+
+ req := resty.New().R().SetBody(map[string]string{
+ "name": "Alex",
+ }).SetCookies(
+ []*http.Cookie{
+ {Name: "count", Value: "1"},
+ },
+ )
+
+ curlCmdUnexecuted := req.GenerateCurlCommand()
+
+ if !strings.Contains(curlCmdUnexecuted, "Cookie: count=1") ||
+ !strings.Contains(curlCmdUnexecuted, "curl -X GET") ||
+ !strings.Contains(curlCmdUnexecuted, `-d '{"name":"Alex"}'`) {
+ t.Fatal("Incomplete curl:", curlCmdUnexecuted)
+ } else {
+ t.Log("curlCmdUnexecuted: \n", curlCmdUnexecuted)
+ }
+
+}
+
+// 2. Generate curl for executed request
+func TestGenerateExecutedCurl(t *testing.T) {
+ ts := createHttpbinServer(0)
+ defer ts.Close()
+
+ data := map[string]string{
+ "name": "Alex",
+ }
+ req := resty.New().R().SetBody(data).SetCookies(
+ []*http.Cookie{
+ {Name: "count", Value: "1"},
+ },
+ )
+
+ url := ts.URL + "/post"
+ resp, err := req.
+ EnableTrace().
+ Post(url)
+ if err != nil {
+ t.Fatal(err)
+ }
+ curlCmdExecuted := resp.Request.GenerateCurlCommand()
+ if !strings.Contains(curlCmdExecuted, "Cookie: count=1") ||
+ !strings.Contains(curlCmdExecuted, "curl -X POST") ||
+ !strings.Contains(curlCmdExecuted, `-d '{"name":"Alex"}'`) ||
+ !strings.Contains(curlCmdExecuted, url) {
+ t.Fatal("Incomplete curl:", curlCmdExecuted)
+ } else {
+ t.Log("curlCmdExecuted: \n", curlCmdExecuted)
+ }
+}
+
+// 3. Generate curl in debug mode
+func TestDebugModeCurl(t *testing.T) {
+ ts := createHttpbinServer(0)
+ defer ts.Close()
+
+ // 1. Capture stderr
+ getOutput, restore := captureStderr()
+ defer restore()
+
+ // 2. Build request
+ req := resty.New().R().SetBody(map[string]string{
+ "name": "Alex",
+ }).SetCookies(
+ []*http.Cookie{
+ {Name: "count", Value: "1"},
+ },
+ )
+
+ // 3. Execute request: set debug mode
+ url := ts.URL + "/post"
+ _, err := req.SetDebug(true).Post(url)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // 4. test output curl
+ output := getOutput()
+ if !strings.Contains(output, "Cookie: count=1") ||
+ !strings.Contains(output, `-d '{"name":"Alex"}'`) {
+ t.Fatal("Incomplete debug curl info:", output)
+ } else {
+ t.Log("Normal debug curl info: \n", output)
+ }
+}
+
+func captureStderr() (getOutput func() string, restore func()) {
+ old := os.Stdout
+ r, w, err := os.Pipe()
+ if err != nil {
+ panic(err)
+ }
+ os.Stderr = w
+ getOutput = func() string {
+ w.Close()
+ buf := make([]byte, 2048)
+ n, err := r.Read(buf)
+ if err != nil && err != io.EOF {
+ panic(err)
+ }
+ return string(buf[:n])
+ }
+ restore = func() {
+ os.Stderr = old
+ w.Close()
+ }
+ return getOutput, restore
+}
diff --git a/examples/server_test.go b/examples/server_test.go
new file mode 100644
index 00000000..285f8b64
--- /dev/null
+++ b/examples/server_test.go
@@ -0,0 +1,162 @@
+package examples
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ ioutil "io"
+ "net/http"
+ "net/http/httptest"
+ "net/url"
+ "strings"
+)
+
+const maxMultipartMemory = 4 << 30 // 4MB
+
+// tlsCert:
+//
+// 0 No certificate
+// 1 With self-signed certificate
+// 2 With custom certificate from CA(todo)
+func createHttpbinServer(tlsCert int) (ts *httptest.Server) {
+ ts = createTestServer(func(w http.ResponseWriter, r *http.Request) {
+ httpbinHandler(w, r)
+ }, tlsCert)
+
+ return ts
+}
+
+func httpbinHandler(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/json")
+ body, _ := ioutil.ReadAll(r.Body)
+ r.Body = ioutil.NopCloser(bytes.NewBuffer(body)) // important!!
+ m := map[string]interface{}{
+ "args": parseRequestArgs(r),
+ "headers": dumpRequestHeader(r),
+ "data": string(body),
+ "json": nil,
+ "form": map[string]string{},
+ "files": map[string]string{},
+ "method": r.Method,
+ "origin": r.RemoteAddr,
+ "url": r.URL.String(),
+ }
+
+ // 1. parse text/plain
+ if strings.HasPrefix(r.Header.Get("Content-Type"), "text/plain") {
+ m["data"] = string(body)
+ }
+
+ // 2. parse application/json
+ if strings.HasPrefix(r.Header.Get("Content-Type"), "application/json") {
+ var data interface{}
+ if err := json.Unmarshal(body, &data); err != nil {
+ m["err"] = err.Error()
+ } else {
+ m["json"] = data
+ }
+ }
+
+ // 3. parse application/x-www-form-urlencoded
+ if strings.HasPrefix(r.Header.Get("Content-Type"), "application/x-www-form-urlencoded") {
+ m["form"] = parseQueryString(string(body))
+ }
+
+ // 4. parse multipart/form-data
+ if strings.HasPrefix(r.Header.Get("Content-Type"), "multipart/form-data") {
+ form, files := readMultipartForm(r)
+ m["form"] = form
+ m["files"] = files
+ }
+ buf, _ := json.Marshal(m)
+ _, _ = w.Write(buf)
+}
+
+func readMultipartForm(r *http.Request) (map[string]string, map[string]string) {
+ if err := r.ParseMultipartForm(maxMultipartMemory); err != nil {
+ if err != http.ErrNotMultipart {
+ panic(fmt.Sprintf("error on parse multipart form array: %v", err))
+ }
+ }
+ // parse form data
+ formData := make(map[string]string)
+ for k, vs := range r.PostForm {
+ for _, v := range vs {
+ formData[k] = v
+ }
+ }
+ // parse files
+ files := make(map[string]string)
+ if r.MultipartForm != nil && r.MultipartForm.File != nil {
+ for key, fhs := range r.MultipartForm.File {
+ // if len(fhs)>0
+ // f, err := fhs[0].Open()
+ files[key] = fhs[0].Filename
+ }
+ }
+ return formData, files
+}
+
+func dumpRequestHeader(req *http.Request) string {
+ var res strings.Builder
+ headers := sortHeaders(req)
+ for _, kv := range headers {
+ res.WriteString(kv[0] + ": " + kv[1] + "\n")
+ }
+ return res.String()
+}
+
+// sortHeaders
+func sortHeaders(request *http.Request) [][2]string {
+ headers := [][2]string{}
+ for k, vs := range request.Header {
+ for _, v := range vs {
+ headers = append(headers, [2]string{k, v})
+ }
+ }
+ n := len(headers)
+ for i := 0; i < n; i++ {
+ for j := n - 1; j > i; j-- {
+ jj := j - 1
+ h1, h2 := headers[j], headers[jj]
+ if h1[0] < h2[0] {
+ headers[jj], headers[j] = headers[j], headers[jj]
+ }
+ }
+ }
+ return headers
+}
+
+func parseRequestArgs(request *http.Request) map[string]string {
+ query := request.URL.RawQuery
+ return parseQueryString(query)
+}
+
+func parseQueryString(query string) map[string]string {
+ params := map[string]string{}
+ paramsList, _ := url.ParseQuery(query)
+ for key, vals := range paramsList {
+ // params[key] = vals[len(vals)-1]
+ params[key] = strings.Join(vals, ",")
+ }
+ return params
+}
+
+/*
+*
+ - tlsCert:
+ 0 no certificate
+ 1 with self-signed certificate
+ 2 with custom certificate from CA(todo)
+*/
+func createTestServer(fn func(w http.ResponseWriter, r *http.Request), tlsCert int) (ts *httptest.Server) {
+ if tlsCert == 0 {
+ // 1. http test server
+ ts = httptest.NewServer(http.HandlerFunc(fn))
+ } else if tlsCert == 1 {
+ // 2. https test server: https://stackoverflow.com/questions/54899550/create-https-test-server-for-any-client
+ ts = httptest.NewUnstartedServer(http.HandlerFunc(fn))
+ ts.StartTLS()
+ }
+ return ts
+}
diff --git a/middleware.go b/middleware.go
index 603448df..c8079c94 100644
--- a/middleware.go
+++ b/middleware.go
@@ -307,6 +307,16 @@ func addCredentials(c *Client, r *Request) error {
return nil
}
+func createCurlCmd(c *Client, r *Request) (err error) {
+ if r.trace {
+ if r.resultCurlCmd == nil {
+ r.resultCurlCmd = new(string)
+ }
+ *r.resultCurlCmd = buildCurlRequest(r.RawRequest, c.httpClient.Jar)
+ }
+ return nil
+}
+
func requestLogger(c *Client, r *Request) error {
if r.Debug {
rr := r.RawRequest
@@ -329,6 +339,8 @@ func requestLogger(c *Client, r *Request) error {
}
reqLog := "\n==============================================================================\n" +
+ "~~~ REQUEST(curl) ~~~\n" +
+ fmt.Sprintf("CURL:\n %v\n", buildCurlRequest(r.RawRequest, r.client.httpClient.Jar)) +
"~~~ REQUEST ~~~\n" +
fmt.Sprintf("%s %s %s\n", r.Method, rr.URL.RequestURI(), rr.Proto) +
fmt.Sprintf("HOST : %s\n", rr.URL.Host) +
diff --git a/request.go b/request.go
index 4e13ff09..18468860 100644
--- a/request.go
+++ b/request.go
@@ -39,6 +39,7 @@ type Request struct {
Time time.Time
Body interface{}
Result interface{}
+ resultCurlCmd *string
Error interface{}
RawRequest *http.Request
SRV *SRVRecord
@@ -73,6 +74,24 @@ type Request struct {
retryConditions []RetryConditionFunc
}
+// Generate curl command for the request.
+func (r *Request) GenerateCurlCommand() string {
+ if r.resultCurlCmd != nil {
+ return *r.resultCurlCmd
+ } else {
+ if r.RawRequest == nil {
+ r.client.executeBefore(r) // mock with r.Get("/")
+ }
+ if r.resultCurlCmd == nil {
+ r.resultCurlCmd = new(string)
+ }
+ if *r.resultCurlCmd == "" {
+ *r.resultCurlCmd = buildCurlRequest(r.RawRequest, r.client.httpClient.Jar)
+ }
+ return *r.resultCurlCmd
+ }
+}
+
// Context method returns the Context if its already set in request
// otherwise it creates new one using `context.Background()`.
func (r *Request) Context() context.Context {
diff --git a/shellescape/shellescape.go b/shellescape/shellescape.go
new file mode 100644
index 00000000..5e6a3799
--- /dev/null
+++ b/shellescape/shellescape.go
@@ -0,0 +1,34 @@
+/*
+Package shellescape provides the shellescape.Quote to escape arbitrary
+strings for a safe use as command line arguments in the most common
+POSIX shells.
+
+The original Python package which this work was inspired by can be found
+at https://pypi.python.org/pypi/shellescape.
+*/
+package shellescape
+
+import (
+ "regexp"
+ "strings"
+)
+
+var pattern *regexp.Regexp
+
+func init() {
+ pattern = regexp.MustCompile(`[^\w@%+=:,./-]`)
+}
+
+// Quote returns a shell-escaped version of the string s. The returned value
+// is a string that can safely be used as one token in a shell command line.
+func Quote(s string) string {
+ if len(s) == 0 {
+ return "''"
+ }
+
+ if pattern.MatchString(s) {
+ return "'" + strings.ReplaceAll(s, "'", "'\"'\"'") + "'"
+ }
+
+ return s
+}
diff --git a/util_curl.go b/util_curl.go
new file mode 100644
index 00000000..e50c3b3a
--- /dev/null
+++ b/util_curl.go
@@ -0,0 +1,76 @@
+package resty
+
+import (
+ "bytes"
+ "io"
+ "net/http"
+ "net/http/cookiejar"
+
+ "net/url"
+ "strings"
+
+ "github.com/go-resty/resty/v2/shellescape"
+)
+
+func buildCurlRequest(req *http.Request, httpCookiejar http.CookieJar) (curl string) {
+ // 1. Generate curl raw headers
+ curl = "curl -X " + req.Method + " "
+ // req.Host + req.URL.Path + "?" + req.URL.RawQuery + " " + req.Proto + " "
+ headers := dumpCurlHeaders(req)
+ for _, kv := range *headers {
+ curl += `-H ` + shellescape.Quote(kv[0]+": "+kv[1]) + ` `
+ }
+
+ // 2. Generate curl cookies
+ if cookieJar, ok := httpCookiejar.(*cookiejar.Jar); ok {
+ cookies := cookieJar.Cookies(req.URL)
+ if len(cookies) > 0 {
+ curl += ` -H ` + shellescape.Quote(dumpCurlCookies(cookies)) + " "
+ }
+ }
+
+ // 3. Generate curl body
+ if req.Body != nil {
+ buf, _ := io.ReadAll(req.Body)
+ req.Body = io.NopCloser(bytes.NewBuffer(buf)) // important!!
+ curl += `-d ` + shellescape.Quote(string(buf))
+ }
+
+ urlString := shellescape.Quote(req.URL.String())
+ if urlString == "''" {
+ urlString = "'http://unexecuted-request'"
+ }
+ curl += " " + urlString
+ return curl
+}
+
+// dumpCurlCookies dumps cookies to curl format
+func dumpCurlCookies(cookies []*http.Cookie) string {
+ sb := strings.Builder{}
+ sb.WriteString("Cookie: ")
+ for _, cookie := range cookies {
+ sb.WriteString(cookie.Name + "=" + url.QueryEscape(cookie.Value) + "&")
+ }
+ return strings.TrimRight(sb.String(), "&")
+}
+
+// dumpCurlHeaders dumps headers to curl format
+func dumpCurlHeaders(req *http.Request) *[][2]string {
+ headers := [][2]string{}
+ for k, vs := range req.Header {
+ for _, v := range vs {
+ headers = append(headers, [2]string{k, v})
+ }
+ }
+ n := len(headers)
+ for i := 0; i < n; i++ {
+ for j := n - 1; j > i; j-- {
+ jj := j - 1
+ h1, h2 := headers[j], headers[jj]
+ if h1[0] < h2[0] {
+ headers[jj], headers[j] = headers[j], headers[jj]
+ }
+ }
+ }
+ return &headers
+}
From 7caa65bc7cc12ae66660d13224522c3ffb0fd10e Mon Sep 17 00:00:00 2001
From: Jeevanandam M
Date: Fri, 28 Jun 2024 16:30:11 -0700
Subject: [PATCH 03/13] resty dev version number and year update (#799)
---
LICENSE | 2 +-
client.go | 2 +-
client_test.go | 2 +-
context_test.go | 2 +-
digest.go | 2 +-
example_test.go | 2 +-
middleware.go | 2 +-
redirect.go | 2 +-
request.go | 2 +-
request_test.go | 2 +-
response.go | 2 +-
resty.go | 4 ++--
resty_test.go | 2 +-
retry.go | 2 +-
retry_test.go | 2 +-
trace.go | 2 +-
transport.go | 2 +-
transport112.go | 2 +-
util.go | 2 +-
util_test.go | 2 +-
20 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/LICENSE b/LICENSE
index 0c2d38a3..de30fea8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2015-2023 Jeevanandam M., https://myjeeva.com
+Copyright (c) 2015-2024 Jeevanandam M., https://myjeeva.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/client.go b/client.go
index 8a5539f5..aeb55077 100644
--- a/client.go
+++ b/client.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/client_test.go b/client_test.go
index 6ea3dbd5..c89d932d 100644
--- a/client_test.go
+++ b/client_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/context_test.go b/context_test.go
index f3c53450..5d60cfff 100644
--- a/context_test.go
+++ b/context_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com)
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com)
// 2016 Andrew Grigorev (https://github.com/ei-grad)
// All rights reserved.
// resty source code and usage is governed by a MIT style
diff --git a/digest.go b/digest.go
index 3cd19637..3a08477d 100644
--- a/digest.go
+++ b/digest.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com)
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com)
// 2023 Segev Dagan (https://github.com/segevda)
// 2024 Philipp Wolfer (https://github.com/phw)
// All rights reserved.
diff --git a/example_test.go b/example_test.go
index 7608f1df..7b7514de 100644
--- a/example_test.go
+++ b/example_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M. (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M. (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/middleware.go b/middleware.go
index c8079c94..41e6561f 100644
--- a/middleware.go
+++ b/middleware.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/redirect.go b/redirect.go
index ed58d735..19bd587d 100644
--- a/redirect.go
+++ b/redirect.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/request.go b/request.go
index 18468860..8cc0180f 100644
--- a/request.go
+++ b/request.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/request_test.go b/request_test.go
index 7312128f..518839b7 100644
--- a/request_test.go
+++ b/request_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/response.go b/response.go
index 63c95c41..58a8e816 100644
--- a/response.go
+++ b/response.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/resty.go b/resty.go
index f8becec6..5d63cd17 100644
--- a/resty.go
+++ b/resty.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -14,7 +14,7 @@ import (
)
// Version # of resty
-const Version = "2.13.1"
+const Version = "2.14.0-dev"
// New method creates a new Resty client.
func New() *Client {
diff --git a/resty_test.go b/resty_test.go
index c00ad1fb..22b483c1 100644
--- a/resty_test.go
+++ b/resty_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/retry.go b/retry.go
index c5eda26b..932a266d 100644
--- a/retry.go
+++ b/retry.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/retry_test.go b/retry_test.go
index 8d58cc16..84c12a48 100644
--- a/retry_test.go
+++ b/retry_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/trace.go b/trace.go
index be7555c2..7798a395 100644
--- a/trace.go
+++ b/trace.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/transport.go b/transport.go
index 191cd519..13c3de34 100644
--- a/transport.go
+++ b/transport.go
@@ -1,7 +1,7 @@
//go:build go1.13
// +build go1.13
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/transport112.go b/transport112.go
index d4aa4175..beb0301a 100644
--- a/transport112.go
+++ b/transport112.go
@@ -1,7 +1,7 @@
//go:build !go1.13
// +build !go1.13
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/util.go b/util.go
index 5a69e4fc..7bbba912 100644
--- a/util.go
+++ b/util.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/util_test.go b/util_test.go
index 74cf4b1f..6c030fd7 100644
--- a/util_test.go
+++ b/util_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
From 60a21497efba1c7fa82409004790620e935c9905 Mon Sep 17 00:00:00 2001
From: Jeevanandam M
Date: Fri, 28 Jun 2024 16:46:00 -0700
Subject: [PATCH 04/13] build: update bazel config with new files (#800)
---
BUILD.bazel | 2 ++
1 file changed, 2 insertions(+)
diff --git a/BUILD.bazel b/BUILD.bazel
index f461c29d..e41515b7 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -22,6 +22,8 @@ go_library(
"transport.go",
"transport112.go",
"util.go",
+ "util_curl.go",
+ "shellescape/shellescape.go"
],
importpath = "github.com/go-resty/resty/v2",
visibility = ["//visibility:public"],
From 30477b36ab69a7818bcde488eac2970923868755 Mon Sep 17 00:00:00 2001
From: Ahuigo <1781999+ahuigo@users.noreply.github.com>
Date: Wed, 3 Jul 2024 10:09:58 +0800
Subject: [PATCH 05/13] fix(examples): wrongly stderr written as stdout (#801)
---
examples/debug_curl_test.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/debug_curl_test.go b/examples/debug_curl_test.go
index 9006caf0..f506ae17 100644
--- a/examples/debug_curl_test.go
+++ b/examples/debug_curl_test.go
@@ -103,7 +103,7 @@ func TestDebugModeCurl(t *testing.T) {
}
func captureStderr() (getOutput func() string, restore func()) {
- old := os.Stdout
+ old := os.Stderr
r, w, err := os.Pipe()
if err != nil {
panic(err)
From d8fbff692952c87bc0dca846b333b7c38dd31cce Mon Sep 17 00:00:00 2001
From: Akira Tanimura
Date: Thu, 18 Jul 2024 01:40:53 +0900
Subject: [PATCH 06/13] fix: change resty.GET to resty.MethodGet in doc comment
(#803)
---
request.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/request.go b/request.go
index 8cc0180f..336925d5 100644
--- a/request.go
+++ b/request.go
@@ -905,7 +905,7 @@ func (r *Request) Patch(url string) (*Response, error) {
// for current `Request`.
//
// req := client.R()
-// req.Method = resty.GET
+// req.Method = resty.MethodGet
// req.URL = "http://httpbin.org/get"
// resp, err := req.Send()
func (r *Request) Send() (*Response, error) {
@@ -915,7 +915,7 @@ func (r *Request) Send() (*Response, error) {
// Execute method performs the HTTP request with given HTTP method and URL
// for current `Request`.
//
-// resp, err := client.R().Execute(resty.GET, "http://httpbin.org/get")
+// resp, err := client.R().Execute(resty.MethodGet, "http://httpbin.org/get")
func (r *Request) Execute(method, url string) (*Response, error) {
var addrs []*net.SRV
var resp *Response
From 87d54992a4be9ca50ae3550e50402eca6d558d26 Mon Sep 17 00:00:00 2001
From: shedyfreak <36332809+shedyfreak@users.noreply.github.com>
Date: Thu, 18 Jul 2024 20:48:33 +0200
Subject: [PATCH 07/13] update golang.org/x/net package for vuln CVE-2023-45288
(#804)
---
go.mod | 2 +-
go.sum | 22 +++++++++++++++++++++-
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/go.mod b/go.mod
index 1dca97c8..22d01860 100644
--- a/go.mod
+++ b/go.mod
@@ -3,6 +3,6 @@ module github.com/go-resty/resty/v2
go 1.16
require (
- golang.org/x/net v0.25.0
+ golang.org/x/net v0.27.0
golang.org/x/time v0.5.0
)
diff --git a/go.sum b/go.sum
index e21530d7..3e90e58c 100644
--- a/go.sum
+++ b/go.sum
@@ -1,21 +1,32 @@
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
+golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
-golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
+golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -23,25 +34,34 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
+golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
From c646328cb753e1bdace0392220208edb304c4277 Mon Sep 17 00:00:00 2001
From: "Jeevanandam M."
Date: Sun, 4 Aug 2024 19:40:37 -0700
Subject: [PATCH 08/13] chore: for release v2.14.0 (#816)
---
README.md | 4 ++--
go.mod | 2 +-
go.sum | 4 ++--
resty.go | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
index 71cc0789..2d3542b5 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
Features section describes in detail about Resty capabilities
-
+
Resty Communication Channels
@@ -13,7 +13,7 @@
## News
- * v2.13.1 [released](https://github.com/go-resty/resty/releases/tag/v2.13.1) and tagged on May 10, 2024.
+ * v2.14.0 [released](https://github.com/go-resty/resty/releases/tag/v2.14.0) and tagged on Aug 04, 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).
diff --git a/go.mod b/go.mod
index 22d01860..442c4ee6 100644
--- a/go.mod
+++ b/go.mod
@@ -4,5 +4,5 @@ go 1.16
require (
golang.org/x/net v0.27.0
- golang.org/x/time v0.5.0
+ golang.org/x/time v0.6.0
)
diff --git a/go.sum b/go.sum
index 3e90e58c..2d51ea97 100644
--- a/go.sum
+++ b/go.sum
@@ -56,8 +56,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
-golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
-golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
+golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
diff --git a/resty.go b/resty.go
index 5d63cd17..7458af76 100644
--- a/resty.go
+++ b/resty.go
@@ -14,7 +14,7 @@ import (
)
// Version # of resty
-const Version = "2.14.0-dev"
+const Version = "2.14.0"
// New method creates a new Resty client.
func New() *Client {
From 231e19c8b93083b9c765bb2d635732e4f177fbde Mon Sep 17 00:00:00 2001
From: Ahuigo <1781999+ahuigo@users.noreply.github.com>
Date: Sat, 10 Aug 2024 01:02:34 +0800
Subject: [PATCH 09/13] doc(readme): Add a note, GenerateCurlCommand needs to
turn on EnableTrace (#817)
---
README.md | 44 +++++++++++++++++++++++--------------
examples/debug_curl_test.go | 44 +++++++++++++++++++++----------------
2 files changed, 52 insertions(+), 36 deletions(-)
diff --git a/README.md b/README.md
index 2d3542b5..c0f387e6 100644
--- a/README.md
+++ b/README.md
@@ -62,6 +62,7 @@
* goroutine concurrent safe
* Resty Client trace, see [Client.EnableTrace](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.EnableTrace) and [Request.EnableTrace](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.EnableTrace)
* Since v2.4.0, trace info contains a `RequestAttempt` value, and the `Request` object contains an `Attempt` attribute
+ * Supports `GenerateCurlCommand`(**You should turn on `EnableTrace`**, otherwise the curl command will not contain the body)
* Debug mode - clean and informative logging presentation
* Gzip - Go does it automatically also resty has fallback handling too
* Works fine with `HTTP/2` and `HTTP/1.1`
@@ -122,18 +123,19 @@ The following samples will assist you to become as comfortable as possible with
import "github.com/go-resty/resty/v2"
```
-#### Simple GET
+#### Simple POST
+>Refer: [debug_curl_test.go](https://github.com/go-resty/resty/blob/v2/examples/debug_curl_test.go)
```go
// Create a Resty Client
client := resty.New()
resp, err := client.R().
- EnableTrace().
- Get("https://httpbin.org/get")
+ EnableTrace(). // You should turn on `EnableTrace`, otherwise the curl command will not contain the body
+ SetBody(map[string]string{"name": "Alex"}).
+ Post("https://httpbin.org/post")
curlCmdExecuted := resp.Request.GenerateCurlCommand()
-
// Explore curl command
fmt.Println("Curl Command:\n ", curlCmdExecuted+"\n")
@@ -166,7 +168,7 @@ fmt.Println(" RemoteAddr :", ti.RemoteAddr.String())
/* Output
Curl Command:
- curl -X GET -H 'User-Agent: go-resty/2.12.0 (https://github.com/go-resty/resty)' https://httpbin.org/get
+ curl -X POST -H 'Content-Type: application/json' -H 'User-Agent: go-resty/2.14.0 (https://github.com/go-resty/resty)' -d '{"name":"Alex"}' https://httpbin.org/post
Response Info:
Error :
@@ -174,19 +176,27 @@ Response Info:
Status : 200 OK
Proto : HTTP/2.0
Time : 457.034718ms
- Received At: 2020-09-14 15:35:29.784681 -0700 PDT m=+0.458137045
+ Received At: 2024-08-09 13:02:57.187544 +0800 CST m=+1.304888501
Body :
- {
- "args": {},
- "headers": {
- "Accept-Encoding": "gzip",
- "Host": "httpbin.org",
- "User-Agent": "go-resty/2.4.0 (https://github.com/go-resty/resty)",
- "X-Amzn-Trace-Id": "Root=1-5f5ff031-000ff6292204aa6898e4de49"
- },
- "origin": "0.0.0.0",
- "url": "https://httpbin.org/get"
- }
+ {
+ "args": {},
+ "data": "{\"name\":\"Alex\"}",
+ "files": {},
+ "form": {},
+ "headers": {
+ "Accept-Encoding": "gzip",
+ "Content-Length": "15",
+ "Content-Type": "application/json",
+ "Host": "httpbin.org",
+ "User-Agent": "go-resty/2.14.0 (https://github.com/go-resty/resty)",
+ "X-Amzn-Trace-Id": "Root=1-66b5a301-567c83c86562abd3092f5e19"
+ },
+ "json": {
+ "name": "Alex"
+ },
+ "origin": "0.0.0.0",
+ "url": "https://httpbin.org/post"
+}
Request Trace Info:
DNSLookup : 4.074657ms
diff --git a/examples/debug_curl_test.go b/examples/debug_curl_test.go
index f506ae17..72bb68d9 100644
--- a/examples/debug_curl_test.go
+++ b/examples/debug_curl_test.go
@@ -15,13 +15,15 @@ func TestGenerateUnexcutedCurl(t *testing.T) {
ts := createHttpbinServer(0)
defer ts.Close()
- req := resty.New().R().SetBody(map[string]string{
- "name": "Alex",
- }).SetCookies(
- []*http.Cookie{
- {Name: "count", Value: "1"},
- },
- )
+ req := resty.New().R().
+ SetBody(map[string]string{
+ "name": "Alex",
+ }).
+ SetCookies(
+ []*http.Cookie{
+ {Name: "count", Value: "1"},
+ },
+ )
curlCmdUnexecuted := req.GenerateCurlCommand()
@@ -43,11 +45,13 @@ func TestGenerateExecutedCurl(t *testing.T) {
data := map[string]string{
"name": "Alex",
}
- req := resty.New().R().SetBody(data).SetCookies(
- []*http.Cookie{
- {Name: "count", Value: "1"},
- },
- )
+ req := resty.New().R().
+ SetBody(data).
+ SetCookies(
+ []*http.Cookie{
+ {Name: "count", Value: "1"},
+ },
+ )
url := ts.URL + "/post"
resp, err := req.
@@ -77,13 +81,15 @@ func TestDebugModeCurl(t *testing.T) {
defer restore()
// 2. Build request
- req := resty.New().R().SetBody(map[string]string{
- "name": "Alex",
- }).SetCookies(
- []*http.Cookie{
- {Name: "count", Value: "1"},
- },
- )
+ req := resty.New().R().
+ SetBody(map[string]string{
+ "name": "Alex",
+ }).
+ SetCookies(
+ []*http.Cookie{
+ {Name: "count", Value: "1"},
+ },
+ )
// 3. Execute request: set debug mode
url := ts.URL + "/post"
From f575bf6ff178ccf6b23dec8eee2a2484eb25f8f2 Mon Sep 17 00:00:00 2001
From: PokeGuys <5060799+PokeGuys@users.noreply.github.com>
Date: Fri, 16 Aug 2024 00:20:49 +0800
Subject: [PATCH 10/13] feat: add ability to set custom multipart boundary
value (#820)
---
middleware.go | 7 +++++++
request.go | 10 ++++++++++
request_test.go | 23 +++++++++++++++++++++++
3 files changed, 40 insertions(+)
diff --git a/middleware.go b/middleware.go
index 41e6561f..805f4ce9 100644
--- a/middleware.go
+++ b/middleware.go
@@ -429,6 +429,13 @@ func handleMultipart(c *Client, r *Request) error {
r.bodyBuf = acquireBuffer()
w := multipart.NewWriter(r.bodyBuf)
+ // Set boundary if not set by user
+ if r.multipartBoundary != "" {
+ if err := w.SetBoundary(r.multipartBoundary); err != nil {
+ return err
+ }
+ }
+
for k, v := range c.FormData {
for _, iv := range v {
if err := w.WriteField(k, iv); err != nil {
diff --git a/request.go b/request.go
index 336925d5..91d432ca 100644
--- a/request.go
+++ b/request.go
@@ -69,6 +69,7 @@ type Request struct {
bodyBuf *bytes.Buffer
clientTrace *clientTrace
log Logger
+ multipartBoundary string
multipartFiles []*File
multipartFields []*MultipartField
retryConditions []RetryConditionFunc
@@ -458,6 +459,15 @@ func (r *Request) SetMultipartFields(fields ...*MultipartField) *Request {
return r
}
+// SetMultipartBoundary method sets the custom multipart boundary for the multipart request.
+// Typically, the `mime/multipart` package generates a random multipart boundary, if not provided.
+//
+// Since v2.15.0
+func (r *Request) SetMultipartBoundary(boundary string) *Request {
+ r.multipartBoundary = boundary
+ return r
+}
+
// SetContentLength method sets the HTTP header `Content-Length` value for current request.
// By default Resty won't set `Content-Length`. Also you have an option to enable for every
// request.
diff --git a/request_test.go b/request_test.go
index 518839b7..f2209394 100644
--- a/request_test.go
+++ b/request_test.go
@@ -1034,6 +1034,29 @@ func TestMultiPartMultipartFields(t *testing.T) {
assertEqual(t, true, strings.Contains(responseStr, "upload-file-2.json"))
}
+func TestMultiPartCustomBoundary(t *testing.T) {
+ ts := createFormPostServer(t)
+ defer ts.Close()
+ defer cleanupFiles(".testdata/upload")
+
+ _, err := dclr().
+ SetMultipartFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M", "zip_code": "00001"}).
+ SetMultipartBoundary(`"my-custom-boundary"`).
+ SetBasicAuth("myuser", "mypass").
+ Post(ts.URL + "/profile")
+
+ assertEqual(t, "mime: invalid boundary character", err.Error())
+
+ resp, err := dclr().
+ SetMultipartFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M", "zip_code": "00001"}).
+ SetMultipartBoundary("my-custom-boundary").
+ Post(ts.URL + "/profile")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "Success", resp.String())
+}
+
func TestGetWithCookie(t *testing.T) {
ts := createGetServer(t)
defer ts.Close()
From 10bf84feb224a161d5c9a24e5e72b2f6e055ace5 Mon Sep 17 00:00:00 2001
From: Trim21
Date: Fri, 30 Aug 2024 01:48:17 +0800
Subject: [PATCH 11/13] feat: add max reponse body limit (#830)
---
client.go | 61 +++++++++++++++++++++++++++++++++++++++++++++-----
client_test.go | 55 +++++++++++++++++++++++++++++++++++++++++++++
request.go | 15 +++++++++++++
resty_test.go | 2 ++
4 files changed, 127 insertions(+), 6 deletions(-)
diff --git a/client.go b/client.go
index aeb55077..d33d6297 100644
--- a/client.go
+++ b/client.go
@@ -128,6 +128,7 @@ type Client struct {
// HeaderAuthorizationKey is used to set/access Request Authorization header
// value when `SetAuthToken` option is used.
HeaderAuthorizationKey string
+ ResponseBodyLimit int
jsonEscapeHTML bool
setContentLength bool
@@ -442,11 +443,12 @@ func (c *Client) R() *Request {
RawPathParams: map[string]string{},
Debug: c.Debug,
- client: c,
- multipartFiles: []*File{},
- multipartFields: []*MultipartField{},
- jsonEscapeHTML: c.jsonEscapeHTML,
- log: c.log,
+ client: c,
+ multipartFiles: []*File{},
+ multipartFields: []*MultipartField{},
+ jsonEscapeHTML: c.jsonEscapeHTML,
+ log: c.log,
+ responseBodyLimit: c.ResponseBodyLimit,
}
return r
}
@@ -1089,6 +1091,20 @@ func (c *Client) SetJSONEscapeHTML(b bool) *Client {
return c
}
+// SetResponseBodyLimit set a max body size limit on response, avoid reading too many data to memory.
+//
+// Client will return [resty.ErrResponseBodyTooLarge] if uncompressed response body size if larger than limit.
+// Body size limit will not be enforced in following case:
+// - ResponseBodyLimit <= 0, which is the default behavior.
+// - [Request.SetOutput] is called to save a response data to file.
+// - "DoNotParseResponse" is set for client or request.
+//
+// this can be overridden at client level with [Request.SetResponseBodyLimit]
+func (c *Client) SetResponseBodyLimit(v int) *Client {
+ c.ResponseBodyLimit = v
+ return c
+}
+
// EnableTrace method enables the Resty client trace for the requests fired from
// the client using `httptrace.ClientTrace` and provides insights.
//
@@ -1238,7 +1254,7 @@ func (c *Client) execute(req *Request) (*Response, error) {
}
}
- if response.body, err = io.ReadAll(body); err != nil {
+ if response.body, err = readAllWithLimit(body, req.responseBodyLimit); err != nil {
response.setReceivedAt()
return response, err
}
@@ -1258,6 +1274,39 @@ func (c *Client) execute(req *Request) (*Response, error) {
return response, wrapNoRetryErr(err)
}
+var ErrResponseBodyTooLarge = errors.New("resty: response body too large")
+
+// https://github.com/golang/go/issues/51115
+// [io.LimitedReader] can only return [io.EOF]
+func readAllWithLimit(r io.Reader, maxSize int) ([]byte, error) {
+ if maxSize <= 0 {
+ return io.ReadAll(r)
+ }
+
+ var buf [512]byte // make buf stack allocated
+ result := make([]byte, 0, 512)
+ total := 0
+ for {
+ n, err := r.Read(buf[:])
+ total += n
+ if total > maxSize {
+ return nil, ErrResponseBodyTooLarge
+ }
+
+ if err != nil {
+ if err == io.EOF {
+ result = append(result, buf[:n]...)
+ break
+ }
+ return nil, err
+ }
+
+ result = append(result, buf[:n]...)
+ }
+
+ return result, nil
+}
+
// getting TLS client config if not exists then create one
func (c *Client) tlsConfig() (*tls.Config, error) {
transport, err := c.Transport()
diff --git a/client_test.go b/client_test.go
index c89d932d..acd31d44 100644
--- a/client_test.go
+++ b/client_test.go
@@ -6,6 +6,8 @@ package resty
import (
"bytes"
+ "compress/gzip"
+ "crypto/rand"
"crypto/tls"
"errors"
"fmt"
@@ -1097,3 +1099,56 @@ func TestClone(t *testing.T) {
assertEqual(t, "clone", parent.UserInfo.Username)
assertEqual(t, "clone", clone.UserInfo.Username)
}
+
+func TestResponseBodyLimit(t *testing.T) {
+ ts := createTestServer(func(w http.ResponseWriter, r *http.Request) {
+ io.CopyN(w, rand.Reader, 100*800)
+ })
+ defer ts.Close()
+
+ t.Run("Client body limit", func(t *testing.T) {
+ c := dc().SetResponseBodyLimit(1024)
+
+ _, err := c.R().Get(ts.URL + "/")
+ assertNotNil(t, err)
+ assertEqual(t, err, ErrResponseBodyTooLarge)
+ })
+
+ t.Run("request body limit", func(t *testing.T) {
+ c := dc()
+
+ _, err := c.R().SetResponseBodyLimit(1024).Get(ts.URL + "/")
+ assertNotNil(t, err)
+ assertEqual(t, err, ErrResponseBodyTooLarge)
+ })
+
+ t.Run("body less than limit", func(t *testing.T) {
+ c := dc()
+
+ res, err := c.R().SetResponseBodyLimit(800*100 + 10).Get(ts.URL + "/")
+ assertNil(t, err)
+ assertEqual(t, 800*100, len(res.body))
+ })
+
+ t.Run("no body limit", func(t *testing.T) {
+ c := dc()
+
+ res, err := c.R().Get(ts.URL + "/")
+ assertNil(t, err)
+ assertEqual(t, 800*100, len(res.body))
+ })
+
+ t.Run("read error", func(t *testing.T) {
+ tse := createTestServer(func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set(hdrContentEncodingKey, "gzip")
+ var buf [1024]byte
+ w.Write(buf[:])
+ })
+ defer tse.Close()
+
+ c := dc()
+
+ _, err := c.R().SetResponseBodyLimit(10240).Get(tse.URL + "/")
+ assertErrorIs(t, err, gzip.ErrHeader)
+ })
+}
diff --git a/request.go b/request.go
index 91d432ca..cfbe89b4 100644
--- a/request.go
+++ b/request.go
@@ -73,6 +73,7 @@ type Request struct {
multipartFiles []*File
multipartFields []*MultipartField
retryConditions []RetryConditionFunc
+ responseBodyLimit int
}
// Generate curl command for the request.
@@ -600,6 +601,20 @@ func (r *Request) SetDoNotParseResponse(parse bool) *Request {
return r
}
+// SetResponseBodyLimit set a max body size limit on response, avoid reading too many data to memory.
+//
+// Request will return [resty.ErrResponseBodyTooLarge] if uncompressed response body size if larger than limit.
+// Body size limit will not be enforced in following case:
+// - ResponseBodyLimit <= 0, which is the default behavior.
+// - [Request.SetOutput] is called to save a response data to file.
+// - "DoNotParseResponse" is set for client or request.
+//
+// This will override Client config.
+func (r *Request) SetResponseBodyLimit(v int) *Request {
+ r.responseBodyLimit = v
+ return r
+}
+
// SetPathParam method sets single URL path key-value pair in the
// Resty current request instance.
//
diff --git a/resty_test.go b/resty_test.go
index 22b483c1..95ef0b51 100644
--- a/resty_test.go
+++ b/resty_test.go
@@ -809,6 +809,7 @@ func dclr() *Request {
}
func assertNil(t *testing.T, v interface{}) {
+ t.Helper()
if !isNil(v) {
t.Errorf("[%v] was expected to be nil", v)
}
@@ -841,6 +842,7 @@ func assertErrorIs(t *testing.T, e, g error) (r bool) {
}
func assertEqual(t *testing.T, e, g interface{}) (r bool) {
+ t.Helper()
if !equal(e, g) {
t.Errorf("Expected [%v], got [%v]", e, g)
}
From ba508571e307db8e9104bd5052c10b0b50b74dc3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=AC=9D=E9=A8=B0=E7=B7=AF?=
Date: Fri, 30 Aug 2024 01:54:51 +0800
Subject: [PATCH 12/13] Feature/update bazel config (#833)
---
BUILD.bazel | 18 ++++++++++++------
examples/BUILD.bazel | 10 ++++++++++
shellescape/BUILD.bazel | 14 ++++++++++++++
3 files changed, 36 insertions(+), 6 deletions(-)
create mode 100644 examples/BUILD.bazel
create mode 100644 shellescape/BUILD.bazel
diff --git a/BUILD.bazel b/BUILD.bazel
index e41515b7..47da6c2e 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -1,5 +1,5 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@bazel_gazelle//:def.bzl", "gazelle")
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
# gazelle:prefix github.com/go-resty/resty/v2
# gazelle:go_naming_convention import_alias
@@ -17,17 +17,19 @@ go_library(
"resty.go",
"retry.go",
"trace.go",
- "transport_js.go",
- "transport_other.go",
"transport.go",
"transport112.go",
+ "transport_js.go",
+ "transport_other.go",
"util.go",
"util_curl.go",
- "shellescape/shellescape.go"
],
importpath = "github.com/go-resty/resty/v2",
visibility = ["//visibility:public"],
- deps = ["@org_golang_x_net//publicsuffix:go_default_library"],
+ deps = [
+ "//shellescape",
+ "@org_golang_x_net//publicsuffix",
+ ],
)
go_test(
@@ -36,6 +38,7 @@ go_test(
"client_test.go",
"context_test.go",
"example_test.go",
+ "middleware_test.go",
"request_test.go",
"resty_test.go",
"retry_test.go",
@@ -43,7 +46,10 @@ go_test(
],
data = glob([".testdata/*"]),
embed = [":resty"],
- deps = ["@org_golang_x_net//proxy:go_default_library"],
+ deps = [
+ "@org_golang_x_net//proxy",
+ "@org_golang_x_time//rate",
+ ],
)
alias(
diff --git a/examples/BUILD.bazel b/examples/BUILD.bazel
new file mode 100644
index 00000000..849ea4e6
--- /dev/null
+++ b/examples/BUILD.bazel
@@ -0,0 +1,10 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_test")
+
+go_test(
+ name = "examples_test",
+ srcs = [
+ "debug_curl_test.go",
+ "server_test.go",
+ ],
+ deps = ["//:resty"],
+)
diff --git a/shellescape/BUILD.bazel b/shellescape/BUILD.bazel
new file mode 100644
index 00000000..fe829e39
--- /dev/null
+++ b/shellescape/BUILD.bazel
@@ -0,0 +1,14 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "shellescape",
+ srcs = ["shellescape.go"],
+ importpath = "github.com/go-resty/resty/v2/shellescape",
+ visibility = ["//visibility:public"],
+)
+
+alias(
+ name = "go_default_library",
+ actual = ":shellescape",
+ visibility = ["//visibility:public"],
+)
From 82ae758b80366c89df5d72bb225c39d4d193e246 Mon Sep 17 00:00:00 2001
From: "Jeevanandam M."
Date: Thu, 29 Aug 2024 19:55:04 -0700
Subject: [PATCH 13/13] build: go min version and build config update #835
(#837)
---
.github/workflows/ci.yml | 8 +++-
.github/workflows/label-actions.yml | 15 +++++--
BUILD.bazel | 6 +--
WORKSPACE | 8 ++--
go.mod | 2 +-
go.sum | 63 -----------------------------
6 files changed, 26 insertions(+), 76 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3ea8441d..2449a72e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -6,12 +6,16 @@ on:
- v2
paths-ignore:
- '**.md'
+ - '**.bazel'
+ - 'WORKSPACE'
pull_request:
branches:
- main
- v2
paths-ignore:
- '**.md'
+ - '**.bazel'
+ - 'WORKSPACE'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
@@ -21,7 +25,7 @@ jobs:
name: Build
strategy:
matrix:
- go: [ '1.21.x']
+ go: [ 'stable', '1.19.x' ]
os: [ ubuntu-latest ]
runs-on: ${{ matrix.os }}
@@ -43,7 +47,7 @@ jobs:
run: diff -u <(echo -n) <(go fmt $(go list ./...))
- name: Test
- run: go test ./... -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./...
+ run: go test ./... -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./...
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
diff --git a/.github/workflows/label-actions.yml b/.github/workflows/label-actions.yml
index 5747117a..a3ab38f2 100644
--- a/.github/workflows/label-actions.yml
+++ b/.github/workflows/label-actions.yml
@@ -3,12 +3,16 @@ name: 'Label'
on:
pull_request:
types: [labeled]
+ paths-ignore:
+ - '**.md'
+ - '**.bazel'
+ - 'WORKSPACE'
jobs:
build:
strategy:
matrix:
- go: [ '1.21.x']
+ go: [ 'stable', '1.19.x' ]
os: [ ubuntu-latest ]
name: Run Build
@@ -28,8 +32,13 @@ jobs:
cache: true
cache-dependency-path: go.sum
+ - name: Format
+ run: diff -u <(echo -n) <(go fmt $(go list ./...))
+
- name: Test
run: go test ./... -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./...
- - name: Coverage
- run: bash <(curl -s https://codecov.io/bash)
+ - name: Upload coverage to Codecov
+ uses: codecov/codecov-action@v4
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/BUILD.bazel b/BUILD.bazel
index 47da6c2e..7248abc5 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -28,7 +28,7 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//shellescape",
- "@org_golang_x_net//publicsuffix",
+ "@org_golang_x_net//publicsuffix:go_default_library",
],
)
@@ -47,8 +47,8 @@ go_test(
data = glob([".testdata/*"]),
embed = [":resty"],
deps = [
- "@org_golang_x_net//proxy",
- "@org_golang_x_time//rate",
+ "@org_golang_x_net//proxy:go_default_library",
+ "@org_golang_x_time//rate:go_default_library",
],
)
diff --git a/WORKSPACE b/WORKSPACE
index 9ef03e95..504de145 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -4,10 +4,10 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "io_bazel_rules_go",
- sha256 = "69de5c704a05ff37862f7e0f5534d4f479418afc21806c887db544a316f3cb6b",
+ sha256 = "80a98277ad1311dacd837f9b16db62887702e9f1d1c4c9f796d0121a46c8e184",
urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.27.0/rules_go-v0.27.0.tar.gz",
- "https://github.com/bazelbuild/rules_go/releases/download/v0.27.0/rules_go-v0.27.0.tar.gz",
+ "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip",
+ "https://github.com/bazelbuild/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip",
],
)
@@ -24,7 +24,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
go_rules_dependencies()
-go_register_toolchains(version = "1.16")
+go_register_toolchains(version = "1.19")
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
diff --git a/go.mod b/go.mod
index 442c4ee6..d8b08d4c 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module github.com/go-resty/resty/v2
-go 1.16
+go 1.19
require (
golang.org/x/net v0.27.0
diff --git a/go.sum b/go.sum
index 2d51ea97..66793eb1 100644
--- a/go.sum
+++ b/go.sum
@@ -1,67 +1,4 @@
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
-golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
-golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
-golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
-golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
-golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
-golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
-golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
-golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
-golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
-golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
-golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=