Add MaxRedirects option

Add `MaxRedirects` option to set maximum redirection-followings allowed.
The option is only valid when `FollowRedirects` is `true`.

Being able to limit the amount of redirections is helpful in order to
avoid possible loops of redirections or just too long round trips.
This commit is contained in:
Jacopo 2021-11-15 15:29:18 +01:00 committed by Will Norris
parent 8fd838a5cc
commit 13bafdbf9e
2 changed files with 54 additions and 4 deletions

View file

@ -17,6 +17,8 @@ import (
"net/url"
"os"
"reflect"
"regexp"
"strconv"
"strings"
"testing"
)
@ -349,7 +351,17 @@ func (t testTransport) RoundTrip(req *http.Request) (*http.Response, error) {
raw = fmt.Sprintf("HTTP/1.1 200 OK\nContent-Length: %d\nContent-Type: image/png\n\n%s", len(img.Bytes()), img.Bytes())
default:
raw = "HTTP/1.1 404 Not Found\n\n"
redirectRegexp := regexp.MustCompile(`/redirects-(\d+)`)
if redirectRegexp.MatchString(req.URL.Path) {
redirectsLeft, _ := strconv.ParseUint(redirectRegexp.FindStringSubmatch(req.URL.Path)[1], 10, 8)
if redirectsLeft == 0 {
raw = "HTTP/1.1 200 OK\n\n"
} else {
raw = fmt.Sprintf("HTTP/1.1 302\nLocation: /http://redirect.test/redirects-%d\n\n", redirectsLeft-1)
}
} else {
raw = "HTTP/1.1 404 Not Found\n\n"
}
}
buf := bufio.NewReader(bytes.NewBufferString(raw))
@ -414,6 +426,34 @@ func TestProxy_ServeHTTP_is304(t *testing.T) {
}
}
func TestProxy_ServeHTTP_maxRedirects(t *testing.T) {
p := &Proxy{
Client: &http.Client{
Transport: testTransport{},
},
FollowRedirects: true,
}
tests := []struct {
url string
code int
}{
{"/http://redirect.test/redirects-0", http.StatusOK},
{"/http://redirect.test/redirects-2", http.StatusOK},
{"/http://redirect.test/redirects-11", http.StatusInternalServerError}, // too many redirects
}
for _, tt := range tests {
req, _ := http.NewRequest("GET", "http://localhost"+tt.url, nil)
resp := httptest.NewRecorder()
p.ServeHTTP(resp, req)
if got, want := resp.Code, tt.code; got != want {
t.Errorf("ServeHTTP(%v) returned status %d, want %d", req, got, want)
}
}
}
func TestProxy_log(t *testing.T) {
var b strings.Builder