diff --git a/client_test.go b/client_test.go index 94e4c9d..db81f4c 100644 --- a/client_test.go +++ b/client_test.go @@ -116,7 +116,7 @@ func TestClientRedirectPolicy(t *testing.T) { defer ts.Close() c := dcnl().SetRedirectPolicy(FlexibleRedirectPolicy(20), DomainCheckRedirectPolicy("127.0.0.1")) - _, err := c.R(). + res, err := c.R(). SetHeader("Name1", "Value1"). SetHeader("Name2", "Value2"). SetHeader("Name3", "Value3"). @@ -124,8 +124,15 @@ func TestClientRedirectPolicy(t *testing.T) { assertEqual(t, true, err.Error() == "Get \"/redirect-21\": resty: stopped after 20 redirects") + redirects := res.RedirectHistory() + assertEqual(t, 20, len(redirects)) + + finalReq := redirects[0] + assertEqual(t, 307, finalReq.StatusCode) + assertEqual(t, ts.URL+"/redirect-20", finalReq.URL) + c.SetRedirectPolicy(NoRedirectPolicy()) - res, err := c.R().Get(ts.URL + "/redirect-1") + res, err = c.R().Get(ts.URL + "/redirect-1") assertNil(t, err) assertEqual(t, http.StatusTemporaryRedirect, res.StatusCode()) assertEqual(t, `Temporary Redirect.`, res.String()) diff --git a/redirect.go b/redirect.go index 32ab479..d78ce80 100644 --- a/redirect.go +++ b/redirect.go @@ -27,6 +27,12 @@ type ( // functions as [RedirectPolicy]. If `f` is a function with the appropriate // signature, RedirectPolicyFunc(f) is a RedirectPolicy object that calls `f`. RedirectPolicyFunc func(*http.Request, []*http.Request) error + + // RedirectInfo struct is used to capture the URL and status code for the redirect history + RedirectInfo struct { + URL string + StatusCode int + } ) // Apply calls f(req, via). diff --git a/request_test.go b/request_test.go index 091c446..f046466 100644 --- a/request_test.go +++ b/request_test.go @@ -911,7 +911,13 @@ func TestHTTPAutoRedirectUpTo10(t *testing.T) { ts := createRedirectServer(t) defer ts.Close() - _, err := dcnl().R().Get(ts.URL + "/redirect-1") + res, err := dcnl().R().Get(ts.URL + "/redirect-1") + redirects := res.RedirectHistory() + assertEqual(t, 10, len(redirects)) + + finalReq := redirects[0] + assertEqual(t, 307, finalReq.StatusCode) + assertEqual(t, ts.URL+"/redirect-10", finalReq.URL) assertEqual(t, true, (err.Error() == "Get /redirect-11: stopped after 10 redirects" || err.Error() == "Get \"/redirect-11\": stopped after 10 redirects")) @@ -2338,6 +2344,9 @@ func TestRequestSettingsCoverage(t *testing.T) { result := jsonIndent(invalidJsonBytes) assertEqual(t, string(invalidJsonBytes), string(result)) + res := &Response{} + assertNil(t, res.RedirectHistory()) + defer func() { if rec := recover(); rec != nil { if err, ok := rec.(error); ok { diff --git a/response.go b/response.go index 691f4e9..3299f79 100644 --- a/response.go +++ b/response.go @@ -153,6 +153,26 @@ func (r *Response) IsError() bool { return r.StatusCode() > 399 } +// RedirectHistory method returns a redirect history slice with the URL and status code +func (r *Response) RedirectHistory() []*RedirectInfo { + if r.RawResponse == nil { + return nil + } + + redirects := make([]*RedirectInfo, 0) + res := r.RawResponse + for res != nil { + req := res.Request + redirects = append(redirects, &RedirectInfo{ + StatusCode: res.StatusCode, + URL: req.URL.String(), + }) + res = req.Response + } + + return redirects +} + func (r *Response) setReceivedAt() { r.receivedAt = time.Now() if r.Request.trace != nil {