mirror of
https://github.com/valyala/fasthttp.git
synced 2026-06-14 15:56:44 +03:00
Allow redirect URI path to not be normalized. (#1638)
* Allow redirect URI path to not be normalized. * Introduce DisableRedirectPathNormalizing field to Request * Use field name as start of comment. Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com> --------- Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>
This commit is contained in:
@@ -1064,16 +1064,17 @@ func doRequestFollowRedirects(req *Request, resp *Response, url string, maxRedir
|
||||
err = ErrMissingLocation
|
||||
break
|
||||
}
|
||||
url = getRedirectURL(url, location)
|
||||
url = getRedirectURL(url, location, req.DisableRedirectPathNormalizing)
|
||||
}
|
||||
|
||||
return statusCode, body, err
|
||||
}
|
||||
|
||||
func getRedirectURL(baseURL string, location []byte) string {
|
||||
func getRedirectURL(baseURL string, location []byte, disablePathNormalizing bool) string {
|
||||
u := AcquireURI()
|
||||
u.Update(baseURL)
|
||||
u.UpdateBytes(location)
|
||||
u.DisablePathNormalizing = disablePathNormalizing
|
||||
redirectURL := u.String()
|
||||
ReleaseURI(u)
|
||||
return redirectURL
|
||||
|
||||
@@ -1589,6 +1589,10 @@ func TestClientFollowRedirects(t *testing.T) {
|
||||
u := ctx.URI()
|
||||
u.Update("/bar")
|
||||
ctx.Redirect(u.String(), StatusFound)
|
||||
case "/abc/*/123":
|
||||
u := ctx.URI()
|
||||
u.Update("/xyz/*/456")
|
||||
ctx.Redirect(u.String(), StatusFound)
|
||||
default:
|
||||
ctx.Success("text/plain", ctx.Path())
|
||||
}
|
||||
@@ -1710,6 +1714,31 @@ func TestClientFollowRedirects(t *testing.T) {
|
||||
ReleaseResponse(resp)
|
||||
}
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
req := AcquireRequest()
|
||||
resp := AcquireResponse()
|
||||
|
||||
req.SetRequestURI("http://xxx/abc/*/123")
|
||||
req.URI().DisablePathNormalizing = true
|
||||
req.DisableRedirectPathNormalizing = true
|
||||
|
||||
err := c.DoRedirects(req, resp, 16)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if statusCode := resp.StatusCode(); statusCode != StatusOK {
|
||||
t.Fatalf("unexpected status code: %d", statusCode)
|
||||
}
|
||||
|
||||
if body := string(resp.Body()); body != "/xyz/*/456" {
|
||||
t.Fatalf("unexpected response %q. Expecting %q", body, "/xyz/*/456")
|
||||
}
|
||||
|
||||
ReleaseRequest(req)
|
||||
ReleaseResponse(resp)
|
||||
}
|
||||
|
||||
req := AcquireRequest()
|
||||
resp := AcquireResponse()
|
||||
|
||||
@@ -3306,3 +3335,60 @@ func TestClientTransportEx(t *testing.T) {
|
||||
t.Errorf("round trip count should be: %v", roundTripCount)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_getRedirectURL(t *testing.T) {
|
||||
type args struct {
|
||||
baseURL string
|
||||
location []byte
|
||||
disablePathNormalizing bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "Path normalizing enabled, no special characters in path",
|
||||
args: args{
|
||||
baseURL: "http://foo.example.com/abc",
|
||||
location: []byte("http://bar.example.com/def"),
|
||||
disablePathNormalizing: false,
|
||||
},
|
||||
want: "http://bar.example.com/def",
|
||||
},
|
||||
{
|
||||
name: "Path normalizing enabled, special characters in path",
|
||||
args: args{
|
||||
baseURL: "http://foo.example.com/abc/*/def",
|
||||
location: []byte("http://bar.example.com/123/*/456"),
|
||||
disablePathNormalizing: false,
|
||||
},
|
||||
want: "http://bar.example.com/123/%2A/456",
|
||||
},
|
||||
{
|
||||
name: "Path normalizing disabled, no special characters in path",
|
||||
args: args{
|
||||
baseURL: "http://foo.example.com/abc",
|
||||
location: []byte("http://bar.example.com/def"),
|
||||
disablePathNormalizing: true,
|
||||
},
|
||||
want: "http://bar.example.com/def",
|
||||
},
|
||||
{
|
||||
name: "Path normalizing disabled, special characters in path",
|
||||
args: args{
|
||||
baseURL: "http://foo.example.com/abc/*/def",
|
||||
location: []byte("http://bar.example.com/123/*/456"),
|
||||
disablePathNormalizing: true,
|
||||
},
|
||||
want: "http://bar.example.com/123/*/456",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := getRedirectURL(tt.args.baseURL, tt.args.location, tt.args.disablePathNormalizing); got != tt.want {
|
||||
t.Errorf("getRedirectURL() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,12 @@ type Request struct {
|
||||
|
||||
// Use Host header (request.Header.SetHost) instead of the host from SetRequestURI, SetHost, or URI().SetHost
|
||||
UseHostHeader bool
|
||||
|
||||
// DisableRedirectPathNormalizing disables redirect path normalization when used with DoRedirects.
|
||||
//
|
||||
// By default redirect path values are normalized, i.e.
|
||||
// extra slashes are removed, special characters are encoded.
|
||||
DisableRedirectPathNormalizing bool
|
||||
}
|
||||
|
||||
// Response represents HTTP response.
|
||||
@@ -1080,6 +1086,7 @@ func (req *Request) Reset() {
|
||||
req.resetSkipHeader()
|
||||
req.timeout = 0
|
||||
req.UseHostHeader = false
|
||||
req.DisableRedirectPathNormalizing = false
|
||||
}
|
||||
|
||||
func (req *Request) resetSkipHeader() {
|
||||
|
||||
Reference in New Issue
Block a user