Skip to content

Commit f2a67d3

Browse files
authored
feat: add redirect history feature #295 (#933)
1 parent fdf601a commit f2a67d3

File tree

4 files changed

+45
-3
lines changed

4 files changed

+45
-3
lines changed

client_test.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,23 @@ func TestClientRedirectPolicy(t *testing.T) {
116116
defer ts.Close()
117117

118118
c := dcnl().SetRedirectPolicy(FlexibleRedirectPolicy(20), DomainCheckRedirectPolicy("127.0.0.1"))
119-
_, err := c.R().
119+
res, err := c.R().
120120
SetHeader("Name1", "Value1").
121121
SetHeader("Name2", "Value2").
122122
SetHeader("Name3", "Value3").
123123
Get(ts.URL + "/redirect-1")
124124

125125
assertEqual(t, true, err.Error() == "Get \"/redirect-21\": resty: stopped after 20 redirects")
126126

127+
redirects := res.RedirectHistory()
128+
assertEqual(t, 20, len(redirects))
129+
130+
finalReq := redirects[0]
131+
assertEqual(t, 307, finalReq.StatusCode)
132+
assertEqual(t, ts.URL+"/redirect-20", finalReq.URL)
133+
127134
c.SetRedirectPolicy(NoRedirectPolicy())
128-
res, err := c.R().Get(ts.URL + "/redirect-1")
135+
res, err = c.R().Get(ts.URL + "/redirect-1")
129136
assertNil(t, err)
130137
assertEqual(t, http.StatusTemporaryRedirect, res.StatusCode())
131138
assertEqual(t, `<a href="/redirect-2">Temporary Redirect</a>.`, res.String())

redirect.go

+6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ type (
2727
// functions as [RedirectPolicy]. If `f` is a function with the appropriate
2828
// signature, RedirectPolicyFunc(f) is a RedirectPolicy object that calls `f`.
2929
RedirectPolicyFunc func(*http.Request, []*http.Request) error
30+
31+
// RedirectInfo struct is used to capture the URL and status code for the redirect history
32+
RedirectInfo struct {
33+
URL string
34+
StatusCode int
35+
}
3036
)
3137

3238
// Apply calls f(req, via).

request_test.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,13 @@ func TestHTTPAutoRedirectUpTo10(t *testing.T) {
911911
ts := createRedirectServer(t)
912912
defer ts.Close()
913913

914-
_, err := dcnl().R().Get(ts.URL + "/redirect-1")
914+
res, err := dcnl().R().Get(ts.URL + "/redirect-1")
915+
redirects := res.RedirectHistory()
916+
assertEqual(t, 10, len(redirects))
917+
918+
finalReq := redirects[0]
919+
assertEqual(t, 307, finalReq.StatusCode)
920+
assertEqual(t, ts.URL+"/redirect-10", finalReq.URL)
915921

916922
assertEqual(t, true, (err.Error() == "Get /redirect-11: stopped after 10 redirects" ||
917923
err.Error() == "Get \"/redirect-11\": stopped after 10 redirects"))
@@ -2338,6 +2344,9 @@ func TestRequestSettingsCoverage(t *testing.T) {
23382344
result := jsonIndent(invalidJsonBytes)
23392345
assertEqual(t, string(invalidJsonBytes), string(result))
23402346

2347+
res := &Response{}
2348+
assertNil(t, res.RedirectHistory())
2349+
23412350
defer func() {
23422351
if rec := recover(); rec != nil {
23432352
if err, ok := rec.(error); ok {

response.go

+20
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,26 @@ func (r *Response) IsError() bool {
153153
return r.StatusCode() > 399
154154
}
155155

156+
// RedirectHistory method returns a redirect history slice with the URL and status code
157+
func (r *Response) RedirectHistory() []*RedirectInfo {
158+
if r.RawResponse == nil {
159+
return nil
160+
}
161+
162+
redirects := make([]*RedirectInfo, 0)
163+
res := r.RawResponse
164+
for res != nil {
165+
req := res.Request
166+
redirects = append(redirects, &RedirectInfo{
167+
StatusCode: res.StatusCode,
168+
URL: req.URL.String(),
169+
})
170+
res = req.Response
171+
}
172+
173+
return redirects
174+
}
175+
156176
func (r *Response) setReceivedAt() {
157177
r.receivedAt = time.Now()
158178
if r.Request.trace != nil {

0 commit comments

Comments
 (0)