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"
|
|
|
|
|
2018-11-14 09:18:03 +00:00
|
|
|
"github.com/containous/traefik/config"
|
2018-01-31 18:10:04 +00:00
|
|
|
"github.com/containous/traefik/testhelpers"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
2019-01-22 07:30:04 +00:00
|
|
|
func TestRedirectRegexHandler(t *testing.T) {
|
2018-01-31 18:10:04 +00:00
|
|
|
testCases := []struct {
|
|
|
|
desc string
|
2019-01-22 07:30:04 +00:00
|
|
|
config config.RedirectRegex
|
2019-01-07 16:56:04 +00:00
|
|
|
method string
|
2018-01-31 18:10:04 +00:00
|
|
|
url string
|
2019-01-07 16:56:04 +00:00
|
|
|
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",
|
2019-01-22 07:30:04 +00:00
|
|
|
config: config.RedirectRegex{
|
2018-11-14 09:18:03 +00:00
|
|
|
Regex: `^(?:http?:\/\/)(foo)(\.com)(:\d+)(.*)$`,
|
|
|
|
Replacement: "https://${1}bar$2:443$4",
|
|
|
|
},
|
2018-02-08 08:30:06 +00:00
|
|
|
url: "http://foo.com:80",
|
|
|
|
expectedURL: "https://foobar.com:443",
|
|
|
|
expectedStatus: http.StatusFound,
|
|
|
|
},
|
|
|
|
{
|
2018-11-14 09:18:03 +00:00
|
|
|
desc: "use request header",
|
2019-01-22 07:30:04 +00:00
|
|
|
config: config.RedirectRegex{
|
2018-11-14 09:18:03 +00:00
|
|
|
Regex: `^(?:http?:\/\/)(foo)(\.com)(:\d+)(.*)$`,
|
|
|
|
Replacement: `https://${1}{{ .Request.Header.Get "X-Foo" }}$2:443$4`,
|
|
|
|
},
|
2018-01-31 18:10:04 +00:00
|
|
|
url: "http://foo.com:80",
|
|
|
|
expectedURL: "https://foobar.com:443",
|
|
|
|
expectedStatus: http.StatusFound,
|
|
|
|
},
|
|
|
|
{
|
2018-11-14 09:18:03 +00:00
|
|
|
desc: "URL doesn't match regex",
|
2019-01-22 07:30:04 +00:00
|
|
|
config: config.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",
|
2019-01-22 07:30:04 +00:00
|
|
|
config: config.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",
|
2019-01-22 07:30:04 +00:00
|
|
|
config: config.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",
|
2019-01-22 07:30:04 +00:00
|
|
|
config: config.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",
|
2019-01-22 07:30:04 +00:00
|
|
|
config: config.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",
|
2019-01-22 07:30:04 +00:00
|
|
|
config: config.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: "HTTPS to HTTP",
|
2019-01-22 07:30:04 +00:00
|
|
|
config: config.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",
|
2019-01-22 07:30:04 +00:00
|
|
|
config: config.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,
|
|
|
|
},
|
2019-01-07 16:56:04 +00:00
|
|
|
{
|
|
|
|
desc: "HTTP to HTTP POST",
|
2019-01-22 07:30:04 +00:00
|
|
|
config: config.RedirectRegex{
|
2019-01-07 16:56:04 +00:00
|
|
|
Regex: `^http://`,
|
|
|
|
Replacement: "https://$1",
|
|
|
|
},
|
|
|
|
url: "http://foo",
|
|
|
|
method: http.MethodPost,
|
|
|
|
expectedURL: "https://foo",
|
|
|
|
expectedStatus: http.StatusTemporaryRedirect,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "HTTP to HTTP POST permanent",
|
2019-01-22 07:30:04 +00:00
|
|
|
config: config.RedirectRegex{
|
2019-01-07 16:56:04 +00:00
|
|
|
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 {
|
|
|
|
test := test
|
|
|
|
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) {})
|
2019-01-22 07:30:04 +00:00
|
|
|
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()
|
2019-01-07 16:56:04 +00:00
|
|
|
|
|
|
|
method := http.MethodGet
|
|
|
|
if test.method != "" {
|
|
|
|
method = test.method
|
|
|
|
}
|
|
|
|
r := testhelpers.MustNewRequest(method, test.url, nil)
|
2018-11-14 09:18:03 +00:00
|
|
|
if test.secured {
|
|
|
|
r.TLS = &tls.ConnectionState{}
|
|
|
|
}
|
2018-02-08 08:30:06 +00:00
|
|
|
r.Header.Set("X-Foo", "bar")
|
2018-11-14 09:18:03 +00:00
|
|
|
handler.ServeHTTP(recorder, r)
|
2018-01-31 18:10:04 +00:00
|
|
|
|
2019-01-07 16:56:04 +00:00
|
|
|
assert.Equal(t, test.expectedStatus, recorder.Code)
|
|
|
|
if test.expectedStatus == http.StatusMovedPermanently ||
|
|
|
|
test.expectedStatus == http.StatusFound ||
|
|
|
|
test.expectedStatus == http.StatusTemporaryRedirect ||
|
|
|
|
test.expectedStatus == 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())
|
|
|
|
} else {
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|