traefik/pkg/middlewares/redirect/redirect_regex_test.go

204 lines
5 KiB
Go
Raw Normal View History

2018-01-31 18:10:04 +00:00
package redirect
import (
2018-11-14 09:18:03 +00:00
"context"
"crypto/tls"
2018-01-31 18:10:04 +00:00
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
2023-02-03 14:24:05 +00:00
"github.com/traefik/traefik/v3/pkg/config/dynamic"
2018-01-31 18:10:04 +00:00
)
func TestRedirectRegexHandler(t *testing.T) {
2018-01-31 18:10:04 +00:00
testCases := []struct {
desc string
config dynamic.RedirectRegex
method string
2018-01-31 18:10:04 +00:00
url string
headers map[string]string
secured bool
2018-01-31 18:10:04 +00:00
expectedURL string
expectedStatus int
errorExpected bool
}{
{
2018-11-14 09:18:03 +00:00
desc: "simple redirection",
config: dynamic.RedirectRegex{
2018-11-14 09:18:03 +00:00
Regex: `^(?:http?:\/\/)(foo)(\.com)(:\d+)(.*)$`,
Replacement: "https://${1}bar$2:443$4",
},
url: "http://foo.com:80",
expectedURL: "https://foobar.com:443",
expectedStatus: http.StatusFound,
},
2018-01-31 18:10:04 +00:00
{
2018-11-14 09:18:03 +00:00
desc: "URL doesn't match regex",
config: dynamic.RedirectRegex{
2018-11-14 09:18:03 +00:00
Regex: `^(?:http?:\/\/)(foo)(\.com)(:\d+)(.*)$`,
Replacement: "https://${1}bar$2:443$4",
},
2018-01-31 18:10:04 +00:00
url: "http://bar.com:80",
expectedStatus: http.StatusOK,
},
{
2018-11-14 09:18:03 +00:00
desc: "invalid rewritten URL",
config: dynamic.RedirectRegex{
2018-11-14 09:18:03 +00:00
Regex: `^(.*)$`,
Replacement: "http://192.168.0.%31/",
},
2018-01-31 18:10:04 +00:00
url: "http://foo.com:80",
expectedStatus: http.StatusBadGateway,
},
{
2018-11-14 09:18:03 +00:00
desc: "invalid regex",
config: dynamic.RedirectRegex{
2018-11-14 09:18:03 +00:00
Regex: `^(.*`,
Replacement: "$1",
},
2018-01-31 18:10:04 +00:00
url: "http://foo.com:80",
errorExpected: true,
},
2018-11-14 09:18:03 +00:00
{
desc: "HTTP to HTTPS permanent",
config: dynamic.RedirectRegex{
2018-11-14 09:18:03 +00:00
Regex: `^http://`,
Replacement: "https://$1",
Permanent: true,
},
url: "http://foo",
expectedURL: "https://foo",
expectedStatus: http.StatusMovedPermanently,
},
{
desc: "HTTPS to HTTP permanent",
config: dynamic.RedirectRegex{
2018-11-14 09:18:03 +00:00
Regex: `https://foo`,
Replacement: "http://foo",
Permanent: true,
},
secured: true,
url: "https://foo",
expectedURL: "http://foo",
expectedStatus: http.StatusMovedPermanently,
},
{
desc: "HTTP to HTTPS",
config: dynamic.RedirectRegex{
2018-11-14 09:18:03 +00:00
Regex: `http://foo:80`,
Replacement: "https://foo:443",
},
url: "http://foo:80",
expectedURL: "https://foo:443",
expectedStatus: http.StatusFound,
},
{
desc: "HTTP to HTTPS, with X-Forwarded-Proto",
config: dynamic.RedirectRegex{
Regex: `http://foo:80`,
Replacement: "https://foo:443",
},
url: "http://foo:80",
headers: map[string]string{
"X-Forwarded-Proto": "https",
},
expectedURL: "https://foo:443",
expectedStatus: http.StatusFound,
},
2018-11-14 09:18:03 +00:00
{
desc: "HTTPS to HTTP",
config: dynamic.RedirectRegex{
2018-11-14 09:18:03 +00:00
Regex: `https://foo:443`,
Replacement: "http://foo:80",
},
secured: true,
url: "https://foo:443",
expectedURL: "http://foo:80",
expectedStatus: http.StatusFound,
},
{
desc: "HTTP to HTTP",
config: dynamic.RedirectRegex{
2018-11-14 09:18:03 +00:00
Regex: `http://foo:80`,
Replacement: "http://foo:88",
},
url: "http://foo:80",
expectedURL: "http://foo:88",
expectedStatus: http.StatusFound,
},
{
desc: "HTTP to HTTP POST",
config: dynamic.RedirectRegex{
Regex: `^http://`,
Replacement: "https://$1",
},
url: "http://foo",
method: http.MethodPost,
expectedURL: "https://foo",
expectedStatus: http.StatusTemporaryRedirect,
},
{
desc: "HTTP to HTTP POST permanent",
config: dynamic.RedirectRegex{
Regex: `^http://`,
Replacement: "https://$1",
Permanent: true,
},
url: "http://foo",
method: http.MethodPost,
expectedURL: "https://foo",
expectedStatus: http.StatusPermanentRedirect,
},
2018-01-31 18:10:04 +00:00
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
2018-11-14 09:18:03 +00:00
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
handler, err := NewRedirectRegex(context.Background(), next, test.config, "traefikTest")
2018-01-31 18:10:04 +00:00
if test.errorExpected {
require.Error(t, err)
2018-11-14 09:18:03 +00:00
require.Nil(t, handler)
2018-01-31 18:10:04 +00:00
} else {
require.NoError(t, err)
2018-11-14 09:18:03 +00:00
require.NotNil(t, handler)
2018-01-31 18:10:04 +00:00
recorder := httptest.NewRecorder()
method := http.MethodGet
if test.method != "" {
method = test.method
}
req := httptest.NewRequest(method, test.url, nil)
2018-11-14 09:18:03 +00:00
if test.secured {
req.TLS = &tls.ConnectionState{}
2018-11-14 09:18:03 +00:00
}
for k, v := range test.headers {
req.Header.Set(k, v)
}
req.Header.Set("X-Foo", "bar")
handler.ServeHTTP(recorder, req)
2018-01-31 18:10:04 +00:00
assert.Equal(t, test.expectedStatus, recorder.Code)
2019-09-26 09:00:06 +00:00
switch test.expectedStatus {
case http.StatusMovedPermanently, http.StatusFound, http.StatusTemporaryRedirect, http.StatusPermanentRedirect:
2018-01-31 18:10:04 +00:00
location, err := recorder.Result().Location()
require.NoError(t, err)
assert.Equal(t, test.expectedURL, location.String())
2019-09-26 09:00:06 +00:00
default:
2018-01-31 18:10:04 +00:00
location, err := recorder.Result().Location()
2018-02-19 00:04:45 +00:00
require.Errorf(t, err, "Location %v", location)
2018-01-31 18:10:04 +00:00
}
}
})
}
}