Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

For v2.8.0 release #693

Merged
merged 3 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ jobs:
name: Build
strategy:
matrix:
go: [ '1.20.x', '1.19.x' ]
go: [ '1.21.x']
os: [ ubuntu-latest ]

runs-on: ${{ matrix.os }}

steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0

Expand Down
17 changes: 13 additions & 4 deletions .github/workflows/label-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,27 @@ on:

jobs:
build:
strategy:
matrix:
go: [ '1.21.x']
os: [ ubuntu-latest ]

name: Run Build
if: ${{ github.event.label.name == 'run-build' }}
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}

steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Setup Go
uses: actions/setup-go@v2
uses: actions/setup-go@v3
with:
go-version: '1.18.x'
go-version: ${{ matrix.go }}
cache: true
cache-dependency-path: go.sum

- name: Test
run: go test ./... -race -coverprofile=coverage.txt -covermode=atomic
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<p align="center"><a href="#features">Features</a> section describes in detail about Resty capabilities</p>
</p>
<p align="center">
<p align="center"><a href="https://github.com/go-resty/resty/actions/workflows/ci.yml?query=branch%3Amaster"><img src="https://github.com/go-resty/resty/actions/workflows/ci.yml/badge.svg" alt="Build Status"></a> <a href="https://codecov.io/gh/go-resty/resty/branch/master"><img src="https://codecov.io/gh/go-resty/resty/branch/master/graph/badge.svg" alt="Code Coverage"></a> <a href="https://goreportcard.com/report/go-resty/resty"><img src="https://goreportcard.com/badge/go-resty/resty" alt="Go Report Card"></a> <a href="https://github.com/go-resty/resty/releases/latest"><img src="https://img.shields.io/badge/version-2.7.0-blue.svg" alt="Release Version"></a> <a href="https://pkg.go.dev/github.com/go-resty/resty/v2"><img src="https://pkg.go.dev/badge/github.com/go-resty/resty" alt="GoDoc"></a> <a href="LICENSE"><img src="https://img.shields.io/github/license/go-resty/resty.svg" alt="License"></a> <a href="https://github.com/avelino/awesome-go"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Go"></a></p>
<p align="center"><a href="https://github.com/go-resty/resty/actions/workflows/ci.yml?query=branch%3Amaster"><img src="https://github.com/go-resty/resty/actions/workflows/ci.yml/badge.svg" alt="Build Status"></a> <a href="https://codecov.io/gh/go-resty/resty/branch/master"><img src="https://codecov.io/gh/go-resty/resty/branch/master/graph/badge.svg" alt="Code Coverage"></a> <a href="https://goreportcard.com/report/go-resty/resty"><img src="https://goreportcard.com/badge/go-resty/resty" alt="Go Report Card"></a> <a href="https://github.com/go-resty/resty/releases/latest"><img src="https://img.shields.io/badge/version-2.8.0-blue.svg" alt="Release Version"></a> <a href="https://pkg.go.dev/github.com/go-resty/resty/v2"><img src="https://pkg.go.dev/badge/github.com/go-resty/resty" alt="GoDoc"></a> <a href="LICENSE"><img src="https://img.shields.io/github/license/go-resty/resty.svg" alt="License"></a> <a href="https://github.com/avelino/awesome-go"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Go"></a></p>
</p>
<p align="center">
<h4 align="center">Resty Communication Channels</h4>
Expand All @@ -13,7 +13,7 @@

## News

* v2.7.0 [released](https://github.com/go-resty/resty/releases/tag/v2.7.0) and tagged on Nov 03, 2021.
* v2.8.0 [released](https://github.com/go-resty/resty/releases/tag/v2.8.0) and tagged on Sep 17, 2023.
* 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).
Expand Down Expand Up @@ -477,7 +477,7 @@ resp, err := client.R().
client := resty.New()

// Setting output directory path, If directory not exists then resty creates one!
// This is optional one, if you're planning using absoule path in
// This is optional one, if you're planning using absolute path in
// `Request.SetOutput` and can used together.
client.SetOutputDirectory("/Users/jeeva/Downloads")

Expand Down Expand Up @@ -822,7 +822,7 @@ client.SetCookies(cookies)
client.SetQueryParam("user_id", "00001")
client.SetQueryParams(map[string]string{ // sample of those who use this manner
"api_key": "api-key-here",
"api_secert": "api-secert",
"api_secret": "api-secret",
})
client.R().SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more")

Expand Down
48 changes: 35 additions & 13 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ func (c *Client) SetQueryParams(params map[string]string) *Client {
}

// SetFormData method sets Form parameters and their values in the client instance.
// It's applicable only HTTP method `POST` and `PUT` and requets content type would be set as
// It's applicable only HTTP method `POST` and `PUT` and request content type would be set as
// `application/x-www-form-urlencoded`. These form data will be added to all the request raised from
// this client instance. Also it can be overridden at request level form data.
//
Expand All @@ -352,7 +352,7 @@ func (c *Client) SetFormData(data map[string]string) *Client {
//
// client.SetBasicAuth("go-resty", "welcome")
//
// This basic auth information gets added to all the request rasied from this client instance.
// This basic auth information gets added to all the request raised from this client instance.
// Also it can be overridden or set one at the request level is supported.
//
// See `Request.SetBasicAuth`.
Expand All @@ -370,7 +370,7 @@ func (c *Client) SetBasicAuth(username, password string) *Client {
//
// client.SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F")
//
// This auth token gets added to all the requests rasied from this client instance.
// This auth token gets added to all the requests raised from this client instance.
// Also it can be overridden or set one at the request level is supported.
//
// See `Request.SetAuthToken`.
Expand All @@ -387,7 +387,7 @@ func (c *Client) SetAuthToken(token string) *Client {
//
// client.SetAuthScheme("OAuth")
//
// This auth scheme gets added to all the requests rasied from this client instance.
// This auth scheme gets added to all the requests raised from this client instance.
// Also it can be overridden or set one at the request level is supported.
//
// Information about auth schemes can be found in RFC7235 which is linked to below
Expand Down Expand Up @@ -476,7 +476,7 @@ func (c *Client) OnBeforeRequest(m RequestMiddleware) *Client {

// OnAfterResponse method appends response middleware into the after response chain.
// Once we receive response from host server, default Resty response middleware
// gets applied and then user assigened response middlewares applied.
// gets applied and then user assigned response middlewares applied.
//
// client.OnAfterResponse(func(c *resty.Client, r *resty.Response) error {
// // Now you have access to Client and Response instance
Expand Down Expand Up @@ -506,7 +506,7 @@ func (c *Client) OnAfterResponse(m ResponseMiddleware) *Client {
// })
//
// Out of the OnSuccess, OnError, OnInvalid, OnPanic callbacks, exactly one
// set will be invoked for each call to Request.Execute() that comletes.
// set will be invoked for each call to Request.Execute() that completes.
func (c *Client) OnError(h ErrorHook) *Client {
c.errorHooks = append(c.errorHooks, h)
return c
Expand All @@ -516,29 +516,35 @@ func (c *Client) OnError(h ErrorHook) *Client {
// succeeds. This is called after all retries have been attempted (if any).
//
// Out of the OnSuccess, OnError, OnInvalid, OnPanic callbacks, exactly one
// set will be invoked for each call to Request.Execute() that comletes.
// set will be invoked for each call to Request.Execute() that completes.
//
// Since v2.8.0
func (c *Client) OnSuccess(h SuccessHook) *Client {
c.successHooks = append(c.successHooks, h)
return c
}

// OnInvalid method adds a callback that will be run whever a request execution
// OnInvalid method adds a callback that will be run whenever a request execution
// fails before it starts because the request is invalid.
//
// Out of the OnSuccess, OnError, OnInvalid, OnPanic callbacks, exactly one
// set will be invoked for each call to Request.Execute() that comletes.
// set will be invoked for each call to Request.Execute() that completes.
//
// Since v2.8.0
func (c *Client) OnInvalid(h ErrorHook) *Client {
c.invalidHooks = append(c.invalidHooks, h)
return c
}

// OnPanic method adds a callback that will be run whever a request execution
// OnPanic method adds a callback that will be run whenever a request execution
// panics.
//
// Out of the OnSuccess, OnError, OnInvalid, OnPanic callbacks, exactly one
// set will be invoked for each call to Request.Execute() that completes.
// If an OnSuccess, OnError, or OnInvalid callback panics, then the exactly
// one rule can be violated.
//
// Since v2.8.0
func (c *Client) OnPanic(h ErrorHook) *Client {
c.panicHooks = append(c.panicHooks, h)
return c
Expand All @@ -547,7 +553,7 @@ func (c *Client) OnPanic(h ErrorHook) *Client {
// SetPreRequestHook method sets the given pre-request function into resty client.
// It is called right before the request is fired.
//
// Note: Only one pre-request hook can be registered. Use `client.OnBeforeRequest` for mutilple.
// Note: Only one pre-request hook can be registered. Use `client.OnBeforeRequest` for multiple.
func (c *Client) SetPreRequestHook(h PreRequestHook) *Client {
if c.preReqHook != nil {
c.log.Warnf("Overwriting an existing pre-request hook: %s", functionName(h))
Expand All @@ -561,6 +567,8 @@ func (c *Client) SetPreRequestHook(h PreRequestHook) *Client {
// For `Response` it logs information such as Status, Response Time, Headers, Body if it has one.
//
// client.SetDebug(true)
//
// Also it can be enabled at request level for particular request, see `Request.SetDebug`.
func (c *Client) SetDebug(d bool) *Client {
c.Debug = d
return c
Expand Down Expand Up @@ -655,7 +663,7 @@ func (c *Client) SetError(err interface{}) *Client {
return c
}

// SetRedirectPolicy method sets the client redirect poilicy. Resty provides ready to use
// SetRedirectPolicy method sets the client redirect policy. Resty provides ready to use
// redirect policies. Wanna create one for yourself refer to `redirect.go`.
//
// client.SetRedirectPolicy(FlexibleRedirectPolicy(20))
Expand Down Expand Up @@ -716,27 +724,35 @@ func (c *Client) SetRetryAfter(callback RetryAfterFunc) *Client {

// SetJSONMarshaler method sets the JSON marshaler function to marshal the request body.
// By default, Resty uses `encoding/json` package to marshal the request body.
//
// Since v2.8.0
func (c *Client) SetJSONMarshaler(marshaler func(v interface{}) ([]byte, error)) *Client {
c.JSONMarshal = marshaler
return c
}

// SetJSONUnmarshaler method sets the JSON unmarshaler function to unmarshal the response body.
// By default, Resty uses `encoding/json` package to unmarshal the response body.
//
// Since v2.8.0
func (c *Client) SetJSONUnmarshaler(unmarshaler func(data []byte, v interface{}) error) *Client {
c.JSONUnmarshal = unmarshaler
return c
}

// SetXMLMarshaler method sets the XML marshaler function to marshal the request body.
// By default, Resty uses `encoding/xml` package to marshal the request body.
//
// Since v2.8.0
func (c *Client) SetXMLMarshaler(marshaler func(v interface{}) ([]byte, error)) *Client {
c.XMLMarshal = marshaler
return c
}

// SetXMLUnmarshaler method sets the XML unmarshaler function to unmarshal the response body.
// By default, Resty uses `encoding/xml` package to unmarshal the response body.
//
// Since v2.8.0
func (c *Client) SetXMLUnmarshaler(unmarshaler func(data []byte, v interface{}) error) *Client {
c.XMLUnmarshal = unmarshaler
return c
Expand Down Expand Up @@ -914,7 +930,7 @@ func (c *Client) SetOutputDirectory(dirPath string) *Client {
// - It overwrites the Resty client transport instance and it's configurations.
//
// transport := &http.Transport{
// // somthing like Proxying to httptest.Server, etc...
// // something like Proxying to httptest.Server, etc...
// Proxy: func(req *http.Request) (*url.URL, error) {
// return url.Parse(server.URL)
// },
Expand Down Expand Up @@ -1020,6 +1036,8 @@ func (c *Client) SetPathParams(params map[string]string) *Client {
//
// Also it can be overridden at request level Path Params options,
// see `Request.SetPathParam` or `Request.SetPathParams`.
//
// Since v2.8.0
func (c *Client) SetRawPathParam(param, value string) *Client {
c.RawPathParams[param] = value
return c
Expand All @@ -1043,6 +1061,8 @@ func (c *Client) SetRawPathParam(param, value string) *Client {
//
// Also it can be overridden at request level Path Params options,
// see `Request.SetPathParam` or `Request.SetPathParams`.
//
// Since v2.8.0
func (c *Client) SetRawPathParams(params map[string]string) *Client {
for p, v := range params {
c.SetRawPathParam(p, v)
Expand Down Expand Up @@ -1207,6 +1227,8 @@ func (c *Client) tlsConfig() (*tls.Config, error) {

// Transport method returns `*http.Transport` currently in use or error
// in case currently used `transport` is not a `*http.Transport`.
//
// Since v2.8.0 become exported method.
func (c *Client) Transport() (*http.Transport, error) {
if transport, ok := c.httpClient.Transport.(*http.Transport); ok {
return transport, nil
Expand Down
6 changes: 3 additions & 3 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -711,12 +711,12 @@ func TestLogCallbacks(t *testing.T) {
c.outputLogTo(&lgr)

c.OnRequestLog(func(r *RequestLog) error {
// masking authorzation header
// masking authorization header
r.Header.Set("Authorization", "Bearer *******************************")
return nil
})
c.OnResponseLog(func(r *ResponseLog) error {
r.Header.Add("X-Debug-Resposne-Log", "Modified :)")
r.Header.Add("X-Debug-Response-Log", "Modified :)")
r.Body += "\nModified the response body content"
return nil
})
Expand All @@ -734,7 +734,7 @@ func TestLogCallbacks(t *testing.T) {
// Validating debug log updates
logInfo := lgr.String()
assertEqual(t, true, strings.Contains(logInfo, "Bearer *******************************"))
assertEqual(t, true, strings.Contains(logInfo, "X-Debug-Resposne-Log"))
assertEqual(t, true, strings.Contains(logInfo, "X-Debug-Response-Log"))
assertEqual(t, true, strings.Contains(logInfo, "Modified the response body content"))

// Error scenario
Expand Down
4 changes: 2 additions & 2 deletions middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ func addCredentials(c *Client, r *Request) error {
}

func requestLogger(c *Client, r *Request) error {
if c.Debug {
if c.Debug || r.Debug {
rr := r.RawRequest
rl := &RequestLog{Header: copyHeaders(rr.Header), Body: r.fmtBodyString(c.debugBodySizeLimit)}
if c.requestLog != nil {
Expand Down Expand Up @@ -303,7 +303,7 @@ func requestLogger(c *Client, r *Request) error {
//_______________________________________________________________________

func responseLogger(c *Client, res *Response) error {
if c.Debug {
if c.Debug || res.Request.Debug {
rl := &ResponseLog{Header: copyHeaders(res.Header()), Body: res.fmtBodyString(c.debugBodySizeLimit)}
if c.responseLog != nil {
if err := c.responseLog(rl); err != nil {
Expand Down
5 changes: 3 additions & 2 deletions redirect.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import (
)

var (
// Since v2.8.0
ErrAutoRedirectDisabled = errors.New("auto redirect is disabled")
)

type (
// RedirectPolicy to regulate the redirects in the resty client.
// Objects implementing the RedirectPolicy interface can be registered as
//
// Apply function should return nil to continue the redirect jounery, otherwise
// Apply function should return nil to continue the redirect journey, otherwise
// return error to stop the redirect.
RedirectPolicy interface {
Apply(req *http.Request, via []*http.Request) error
Expand Down Expand Up @@ -92,7 +93,7 @@ func getHostname(host string) (hostname string) {
}

// By default Golang will not redirect request headers
// after go throughing various discussion comments from thread
// after go throwing various discussion comments from thread
// https://github.com/golang/go/issues/4800
// Resty will add all the headers during a redirect for the same host
func checkHostAndAddHeaders(cur *http.Request, pre *http.Request) {
Expand Down
18 changes: 17 additions & 1 deletion request.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Request struct {
SRV *SRVRecord
UserInfo *User
Cookies []*http.Cookie
Debug bool

// Attempt is to represent the request attempt made during a Resty
// request execution flow, including retry count.
Expand Down Expand Up @@ -488,7 +489,7 @@ func (r *Request) SetAuthToken(token string) *Request {
//
// client.R().SetAuthScheme("OAuth")
//
// This auth header scheme gets added to all the request rasied from this client instance.
// This auth header scheme gets added to all the request raised from this client instance.
// Also it can be overridden or set one at the request level is supported.
//
// Information about Auth schemes can be found in RFC7235 which is linked to below along with the page containing
Expand Down Expand Up @@ -640,6 +641,8 @@ func (r *Request) SetPathParams(params map[string]string) *Request {
//
// Also you can override Path Params value, which was set at client instance
// level.
//
// Since v2.8.0
func (r *Request) SetRawPathParam(param, value string) *Request {
r.RawPathParams[param] = value
return r
Expand All @@ -663,6 +666,8 @@ func (r *Request) SetRawPathParam(param, value string) *Request {
//
// Also you can override Path Params value, which was set at client instance
// level.
//
// Since v2.8.0
func (r *Request) SetRawPathParams(params map[string]string) *Request {
for p, v := range params {
r.SetRawPathParam(p, v)
Expand Down Expand Up @@ -741,6 +746,17 @@ func (r *Request) SetLogger(l Logger) *Request {
return r
}

// SetDebug method enables the debug mode on current request Resty request, It logs
// the details current request and response.
// For `Request` it logs information such as HTTP verb, Relative URL path, Host, Headers, Body if it has one.
// For `Response` it logs information such as Status, Response Time, Headers, Body if it has one.
//
// client.R().SetDebug(true)
func (r *Request) SetDebug(d bool) *Request {
r.Debug = d
return r
}

// AddRetryCondition method adds a retry condition function to the request's
// array of functions that are checked to determine if the request is retried.
// The request will retry if any of the functions return true and error is nil.
Expand Down
Loading